[Scummvm-git-logs] scummvm master -> 5656ee3c065a3840da338229b63f5a5ef8210f21

antoniou79 a.antoniou79 at gmail.com
Wed Jul 21 14:24:34 UTC 2021


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
5656ee3c06 BLADERUNNER: RESTOREDCONTENT: Add more Maggie interactions


Commit: 5656ee3c065a3840da338229b63f5a5ef8210f21
    https://github.com/scummvm/scummvm/commit/5656ee3c065a3840da338229b63f5a5ef8210f21
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-07-21T17:12:00+03:00

Commit Message:
BLADERUNNER: RESTOREDCONTENT: Add more Maggie interactions

Also clean up Maggie's script.

Changed paths:
    engines/bladerunner/actor_combat.cpp
    engines/bladerunner/game_constants.h
    engines/bladerunner/movement_track.h
    engines/bladerunner/script/ai/maggie.cpp
    engines/bladerunner/script/ai_script.h
    engines/bladerunner/script/scene/kp05.cpp
    engines/bladerunner/script/scene/ma02.cpp


diff --git a/engines/bladerunner/actor_combat.cpp b/engines/bladerunner/actor_combat.cpp
index e1307f4669..91521e267e 100644
--- a/engines/bladerunner/actor_combat.cpp
+++ b/engines/bladerunner/actor_combat.cpp
@@ -258,9 +258,9 @@ void ActorCombat::hitAttempt() {
 
 		int sentenceId = _vm->_rnd.getRandomNumberRng(0, 1) ? 9000 : 9005;
 		if (enemy->inCombat()) {
-			enemy->changeAnimationMode(22, false);
+			enemy->changeAnimationMode(kAnimationModeCombatHit, false);
 		} else {
-			enemy->changeAnimationMode(21, false);
+			enemy->changeAnimationMode(kAnimationModeHit, false);
 		}
 
 		int damage = 0;
diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h
index acf9a48b37..039dd22e50 100644
--- a/engines/bladerunner/game_constants.h
+++ b/engines/bladerunner/game_constants.h
@@ -2610,17 +2610,17 @@ enum GameModelAnimations {
 	kModelAnimationMaggieWalking                   = 863,
 	kModelAnimationMaggieStandingIdle              = 864,
 	kModelAnimationMaggieBarking                   = 865,
-	kModelAnimationMaggieLayingDown                = 866,
-	kModelAnimationMaggieLayingIdleTailWagging     = 867,
-	kModelAnimationMaggieLayingStandingUp          = 868,
+	kModelAnimationMaggieLyingDown                 = 866,
+	kModelAnimationMaggieLyingIdleTailWagging      = 867,
+	kModelAnimationMaggieLyingStandingUp           = 868,
 	kModelAnimationMaggieStandingOnTwoFeet         = 869,
 	kModelAnimationMaggieBarkingOrHeadUp           = 870,
-	kModelAnimationMaggieLayingDead                = 871,
+	kModelAnimationMaggieLyingDead                 = 871,
 	kModelAnimationMaggieWalkingTrapped            = 872,
 	kModelAnimationMaggieStandingOnTwoFeetTrapped  = 873,
 	kModelAnimationMaggieExploding                 = 874,
 	kModelAnimationMaggieStandingIdleTrapped       = 875,
-	kModelAnimationMaggieToggleLaySleepingWakeUp   = 876,
+	kModelAnimationMaggieToggleSleepingWakeUp      = 876,
 	// 877 - 884: Hysteria Patron1 (dancer) animations
 	kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp = 877,
 	kModelAnimationHysteriaPatron1DanceStandingUpLeftMotion   = 878,
@@ -3514,13 +3514,19 @@ enum GoalFreeSlotB { // Rat B
 enum GoalMaggie {
 	kGoalMaggieMA02Default        =   0,
 	kGoalMaggieMA02WalkToEntrance =   1,
+	kGoalMaggieMA02Intermediate02 =   2, // unused (checked in MA02 but never assigned)
 	kGoalMaggieMA02GetFed         =   3,
+	kGoalMaggieMA02SitDownToGetUp =   6, // new - original: Unused
 	kGoalMaggieMA02WalkToMcCoy    =   7,
 	kGoalMaggieMA02Wait           =   8,
-	kGoalMaggieMA02SitDown        =  10, // not used
-	kGoalMaggieMA02Sleep          =  11, // not used
+	kGoalMaggieMA02GoingToSleep   =   9,
+	kGoalMaggieMA02SitDownToSleep =  10,
+	kGoalMaggieMA02Sleeping       =  11,
+	kGoalMaggieMA02Intermediate12 =  12,
+	kGoalMaggieAct5Default        = 400,
+	kGoalMaggieAct5Start          = 410,
 	kGoalMaggieKP05Wait           = 411,
-	kGoalMaggieKP05McCoyEntred    = 412,
+	kGoalMaggieKP05McCoyEntered   = 412,
 	kGoalMaggieKP05WalkToMcCoy    = 413,
 	kGoalMaggieKP05WillExplode    = 414,
 	kGoalMaggieKP05Explode        = 415,
diff --git a/engines/bladerunner/movement_track.h b/engines/bladerunner/movement_track.h
index e296e8a23b..76789c0459 100644
--- a/engines/bladerunner/movement_track.h
+++ b/engines/bladerunner/movement_track.h
@@ -37,6 +37,7 @@ class MovementTrack {
 
 	struct Entry {
 		int     waypointId;
+		// delay specifies how long (in milliseconds) to stay at the target waypoint (when reached)
 		int32   delay;
 		int     angle;
 		bool    run;
diff --git a/engines/bladerunner/script/ai/maggie.cpp b/engines/bladerunner/script/ai/maggie.cpp
index 39bf9fd4c9..17065ff001 100644
--- a/engines/bladerunner/script/ai/maggie.cpp
+++ b/engines/bladerunner/script/ai/maggie.cpp
@@ -32,8 +32,8 @@ enum kMaggieStates {
 	kMaggieStateJumping      = 2,
 	kMaggieStateHappyA       = 3,
 	kMaggieStateHappyB       = 4,
-	kMaggieStateLayingDown   = 5,
-	kMaggieStateLayingIdle   = 6,
+	kMaggieStateLyingDown    = 5,
+	kMaggieStateLyingIdle    = 6,
 	kMaggieStateStandingUp   = 7,
 	kMaggieStateGoingToSleep = 8,
 	kMaggieStateSleeping     = 9,
@@ -50,7 +50,7 @@ AIScriptMaggie::AIScriptMaggie(BladeRunnerEngine *vm) : AIScriptBase(vm) {
 	_varTimesToLoopWhenHappyB = 0;
 	_varTimesToBarkWhenHappyA = 0;
 	_varMaggieSoundPan = 0;
-	var_45F404 = 0;
+	_varMaggieClickResponse = 0;
 	var_45F408 = 0;
 }
 
@@ -62,14 +62,12 @@ void AIScriptMaggie::Initialize() {
 	_varTimesToLoopWhenHappyB = 0;
 	_varTimesToBarkWhenHappyA = 0;
 	_varMaggieSoundPan = 0;
-	var_45F404 = 0; // only assigned to 0. Never checked. Unused.
+	_varMaggieClickResponse = 0;
 	var_45F408 = 0; // only assigned to 0. Never checked. Unused.
 	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Default);
 }
 
 bool AIScriptMaggie::Update() {
-	int goal = Actor_Query_Goal_Number(kActorMaggie);
-
 	if (Actor_Query_Which_Set_In(kActorMaggie) == kSetMA02_MA04
 	 && Global_Variable_Query(kVariableChapter) == 4
 	) {
@@ -77,17 +75,21 @@ bool AIScriptMaggie::Update() {
 		Actor_Set_At_Waypoint(kActorMaggie, 39, 0);
 	}
 
-	if (goal == kGoalMaggieKP05WillExplode) {
-		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05Explode);
-	} else if (goal == kGoalMaggieKP05WalkToMcCoy
-	        && Actor_Query_Inch_Distance_From_Actor(kActorMcCoy, kActorMaggie) < 60
-	) {
+	switch (Actor_Query_Goal_Number(kActorMaggie)) {
+	case kGoalMaggieKP05WillExplode:
 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05Explode);
+		break;
+
+	case kGoalMaggieKP05WalkToMcCoy:
+		if (Actor_Query_Inch_Distance_From_Actor(kActorMcCoy, kActorMaggie) < 60) {
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05Explode);
+		}
+		break;
 	}
 
 	if (Global_Variable_Query(kVariableChapter) == 5) {
-		if (Actor_Query_Goal_Number(kActorMaggie) < 400) {
-			Actor_Set_Goal_Number(kActorMaggie, 400);
+		if (Actor_Query_Goal_Number(kActorMaggie) < kGoalMaggieAct5Default) {
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieAct5Default);
 		}
 		return true;
 	}
@@ -96,60 +98,114 @@ bool AIScriptMaggie::Update() {
 
 void AIScriptMaggie::TimerExpired(int timer) {
 	if (timer == kActorTimerAIScriptCustomTask0) {
-		int goal = Actor_Query_Goal_Number(kActorMaggie);
-		if (goal == kGoalMaggieMA02Wait) {
+		switch (Actor_Query_Goal_Number(kActorMaggie)) {
+		case kGoalMaggieMA02Wait:
 			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
 			if (Random_Query(0, 4)) {
 				AI_Movement_Track_Flush(kActorMaggie);
 				AI_Movement_Track_Append(kActorMaggie, randomWaypointMA02(), 0);
 				AI_Movement_Track_Repeat(kActorMaggie);
 			} else {
-				Actor_Change_Animation_Mode(kActorMaggie, 54); // sitting in place
+				if (_vm->_cutContent) {
+					// In the Restored Content Mode:
+					// With a Random Chance Maggie will either:
+					// walk to another (random) waypoint and then sleep (kGoalMaggieMA02GoingToSleep)
+					// or sleep here (again kGoalMaggieMA02GoingToSleep)
+					// or lie down awake (and maybe sleep or get up again)
+					if (Random_Query(0, 3) == 0) {
+						Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02GoingToSleep);
+					} else {
+						// At the end of the lying down animation, we will check for kGoalMaggieMA02Wait goal
+						// and act accordingly. See: AIScriptMaggie::UpdateAnimation()
+						Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+					}
+				} else {
+					// ORIGINAL: By setting the animation mode explicitly here, and not setting the goal,
+					// Maggie will lie awake and stay in that pose idling. She will not do anything else
+					// until McCoy leaves the room.
+					// NEW: At the end of the lying down animation, we will check for kGoalMaggieMA02Wait goal
+					//      and act accordingly. See: AIScriptMaggie::UpdateAnimation()
+					Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+				}
 			}
-			return; //true
-		}
+			break; // return true
+
+		case kGoalMaggieMA02SitDownToSleep:
+			// Untriggered in the original.
+			// Will put Maggie to sleep, if already lying down.
+			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+			// Changing animation mode to 55 (sleeping) is effective only if state is at kMaggieStateLyingIdle.
+			Actor_Change_Animation_Mode(kActorMaggie, 55); // Go to sleeping pose
+			break; // return true
 
-		if (goal == kGoalMaggieMA02SitDown) {
-			// if in process of laying down or already laying down
+		case kGoalMaggieMA02GoingToSleep:
+			// New case (end of lying idle - time to sleep)
 			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
-			// Changing animation mode to 55 (sleeping) is effective only if state is at kMaggieStateLayingIdle.
-			// So if current Maggie is currenty in *the process* of laying down,
-			// this won't do anything. But since we reset the timer, it will be effective in a next call.
-			Actor_Change_Animation_Mode(kActorMaggie, 55);
-			return; //true
+			// At the end of the lying down animation, we will check the goal
+			// and act accordingly. See: AIScriptMaggie::UpdateAnimation()
+			Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+			break;
+
+		case kGoalMaggieMA02SitDownToGetUp:
+			// New case (end of lying idle - time to get up)
+			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+			// At the end of the stand up animation, we will check the goal
+			// and act accordingly. See: AIScriptMaggie::UpdateAnimation()
+			Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle); // Go to stand up pose
+			break;
+
+		case kGoalMaggieMA02Sleeping:
+			// New case (end of sleeping session)
+			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+			// At the end of the wake-up animation, we will check the goal
+			// and act accordingly (set new goal, restart timer)
+			Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+			break;
 		}
 	}
 	return; //false
 }
 
 void AIScriptMaggie::CompletedMovementTrack() {
-	int goal = Actor_Query_Goal_Number(kActorMaggie);
-	if (goal == 0 || goal > 9) {
-		if (goal == kGoalMaggieKP05WalkToMcCoy) {
-			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05WillExplode);
-			return; //true
-		}
-	} else {
-		if (goal == kGoalMaggieMA02WalkToEntrance) {
-			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
-			return; //true
-		}
+	// Note, CompletedMovementTrack() is triggered *after* the delay at the last waypoint of the track has expired
+	switch (Actor_Query_Goal_Number(kActorMaggie)) {
+	case kGoalMaggieMA02WalkToEntrance:
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
+		break; // return true
 
-		if (goal == kGoalMaggieMA02Wait) {
-			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
-			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
-			AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(1, 5));
-			return; //true
-		}
+	case kGoalMaggieMA02Wait:
+		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(1, 5));
+		break; // return true
+
+	case kGoalMaggieMA02GoingToSleep:
+		// (In the original engine) when Maggie is moving to a random waypoint
+		// --due to having her goal changed to kGoalMaggieMA02GoingToSleep--
+		// the delay when reaching that waypoint is too long (486 seconds).
+		// So Maggie would stand at the target waypoint, waiting for the delay to pass
+		// without turning to face McCoy or sitting down.
+		// However, this goal is UNTRIGGERED in the original engine, so the bug was not visible.
+		// We changed the behavior to have no delay when reaching this waypoint,
+		// and start a timer with a random delay from 5 seconds to 486 seconds for Maggie to by lying awake.
+		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+		Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+#if !BLADERUNNER_ORIGINAL_BUGS
+		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(5, 486));
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+		break; // return true
 
-		if (goal == 9) {
-			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
-			Actor_Change_Animation_Mode(kActorMaggie, 54);
-			return; //true
-		}
+	case kGoalMaggieKP05WalkToMcCoy:
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05WillExplode);
+		break; // return true
+
+	case kGoalMaggieMA02Default:
+		//fall through
+	default:
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
+		break;  // return true
 	}
-	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
-	return; //true
 }
 
 void AIScriptMaggie::ReceivedClue(int clueId, int fromActorId) {
@@ -172,56 +228,168 @@ void AIScriptMaggie::ClickedByPlayer() {
 		return; // false
 	}
 
+#if !BLADERUNNER_ORIGINAL_BUGS
+	if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02WalkToMcCoy
+	 || Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02GetFed) {
+		// Don't do anything if Maggie's goal is already kGoalMaggieMA02WalkToMcCoy or kGoalMaggieMA02GetFed
+		// This is for the small time-gap when Maggie has to wake up and get up,
+		// during which the player/McCoy still has control
+		return; // false;
+	}
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+
 	Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
 
 	float mccoy_x, mccoy_y, mccoy_z;
 	Actor_Query_XYZ(kActorMcCoy, &mccoy_x, &mccoy_y, &mccoy_z);
 	if (distanceToActor(kActorMaggie, mccoy_x, mccoy_y, mccoy_z) > 60.0f) {
-		Actor_Says(0, 2430, 18);
+		if (_vm->_cutContent && Random_Query(0, 1)) {
+			Actor_Says(kActorMcCoy, 2395, 18);
+		} else {
+			Actor_Says(kActorMcCoy, 2430, 18);
+		}
 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
 		return; // true
 	}
 
-	int v6 = Random_Query(0, 4);
-	if (v6 == 1) {
-		Actor_Says(kActorMcCoy, 2440, 18);
+	// 1: McCoy told Maggie to sit down, 2: McCoy asks Maggie if hungry, 3: McCoy sits down in front of Maggie
+	_varMaggieClickResponse = 0;
+	int randMcCoyCueToMaggie = Random_Query(0, 4);
+	if (_vm->_cutContent) {
+		// enhance somewhat the probability of getting a cut cue and interaction
+		if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDownToSleep
+			 || Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDownToGetUp) {
+			int randFavorOfCutCue = Random_Query(1, 10);
+			if (randFavorOfCutCue < 4) {
+				randMcCoyCueToMaggie = 2;
+			} else if (randFavorOfCutCue > 6) {
+				randMcCoyCueToMaggie = 4;
+			}
+			// otherwise keep original randMcCoyCueToMaggie (0 to 4)
+		} else if (_animationState == kMaggieStateIdle) {
+			int randFavorOfCutCue = Random_Query(1, 5);
+			if (randFavorOfCutCue < 2) {
+				randMcCoyCueToMaggie = 3;
+			}
+			// otherwise keep original randMcCoyCueToMaggie (0 to 4)
+		}
 	}
-	if (v6 == 0) {
+
+	switch (randMcCoyCueToMaggie) {
+	case 0:
+		// Good doggy.
 		Actor_Says(kActorMcCoy, 2435, 13);
+		break;
+
+	case 1:
+		// Who's the best dog...?
+		Actor_Says(kActorMcCoy, 2440, 18);
+		break;
+
+	case 2:
+		if (_vm->_cutContent) {
+			if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02Sleeping
+			 || Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDownToSleep
+			 || Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDownToGetUp) {
+				// Hey, Maggie (if sitting or sleeping)
+				Actor_Says(kActorMcCoy, 2395, 18);
+			}
+		}
+		break;
+
+	case 3:
+		if (_vm->_cutContent) {
+			// Down Maggie, get down! That's my girl. (if standing still)
+			if (_animationState == kMaggieStateIdle) {
+				Actor_Start_Speech_Sample(kActorMcCoy, 2415);
+				_varMaggieClickResponse = 1;
+			}
+		}
+		break;
+
+	case 4:
+		if (_vm->_cutContent) {
+			// Are you hungry Mags? (if lying awake)
+			if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDownToSleep
+			 || Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDownToGetUp) {
+				// Set a var to trigger appropriate response
+				Actor_Says(kActorMcCoy, 2425, 18);
+				_varMaggieClickResponse = 2;
+			}
+		}
+		break;
+
+	default:
+		break;
 	}
 
-	int goal = Actor_Query_Goal_Number(kActorMaggie);
-	if (goal == kGoalMaggieMA02Wait) {
-		if (Random_Query(0, 1)) {
-			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
-			Actor_Change_Animation_Mode(kActorMaggie, 57);
+	switch (Actor_Query_Goal_Number(kActorMaggie)) {
+	case kGoalMaggieMA02Wait:
+		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+		if (_animationState == kMaggieStateIdle && _varMaggieClickResponse == 1) {
+			// (Cut Content; _varMaggieClickResponse only gets values > 0 in Cut Content)
+			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+			Delay(500);
+			Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
 		} else {
-			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
-			Actor_Change_Animation_Mode(kActorMaggie, 56);
+			if (Random_Query(0, 1)) {
+				Actor_Change_Animation_Mode(kActorMaggie, 57); // HappyB - Not Barking - Tail Wagging
+				if (_vm->_cutContent && Random_Query(1, 5) < 4) {
+					Player_Loses_Control();
+					Actor_Change_Animation_Mode(kActorMcCoy, 85); // McCoy sits down in front of Maggie
+					_varMaggieClickResponse = 3;
+				}
+			} else {
+				Actor_Change_Animation_Mode(kActorMaggie, 56); // HappyA - Barking
+			}
+			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+			if (_varMaggieClickResponse == 3) {
+				AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(6, 9));
+			} else {
+				AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(3, 9));
+			}
 		}
-		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
-		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(3, 9));
-		return; // true
-	}
+		break; // return true
 
-	if (goal == kGoalMaggieMA02SitDown) {
+	case kGoalMaggieMA02SitDownToSleep:
+		// fall through
+	case kGoalMaggieMA02SitDownToGetUp:
+		// Maggie just stands up
 		Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
-		return; // true
-	}
+		if (_varMaggieClickResponse == 2) {
+			// Maggie makes "Need" sounds 
+			// (Cut Content; _varMaggieClickResponse only gets values > 0 in Cut Content)
+			_varMaggieSoundPan = _vm->_actors[kActorMaggie]->soundPan(75);
+			Sound_Play(Random_Query(kSfxDOGNEED1, kSfxDOGNEED2), 50, _varMaggieSoundPan, _varMaggieSoundPan, 50);
+			_varMaggieClickResponse = 0;
+		}
+		break; // return true
 
-	if (goal == kGoalMaggieMA02Sleep) {
+	case kGoalMaggieMA02Sleeping:
+		// Go to lying awake pose from sleeping (onclick)
 		Actor_Change_Animation_Mode(kActorMaggie, 54);
-		return; // true
-	}
+		break; // return true
 
-	Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
-	return; // true
+	default:
+		// This effects basically in restarting the custom timer for Maggie
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
+		break; // return true
+	}
 }
 
 void AIScriptMaggie::EnteredSet(int setId) {
 }
 
 void AIScriptMaggie::OtherAgentEnteredThisSet(int otherActorId) {
+	// this is executed *after* the scene's script (eg. SceneScriptMA02::PlayerWalkedIn())
+	if (_vm->_cutContent
+	 && otherActorId == kActorMcCoy
+	 && Actor_Query_Which_Set_In(kActorMaggie) == kSetMA02_MA04
+	 && Global_Variable_Query(kVariableChapter) < 4
+	 && Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02Default) {
+		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
+	}
 }
 
 void AIScriptMaggie::OtherAgentExitedThisSet(int otherActorId) {
@@ -274,34 +442,77 @@ bool AIScriptMaggie::GoalChanged(int currentGoalNumber, int newGoalNumber) {
 		return true;
 
 	case kGoalMaggieMA02GetFed:
+#if BLADERUNNER_ORIGINAL_BUGS
 		Player_Loses_Control();
 		AI_Movement_Track_Flush(kActorMaggie);
-#if BLADERUNNER_ORIGINAL_BUGS
-#else
-		// Allows McCoy to perform both animated turns (first towards the BAR-MAIN and then towards Maggie)
-		// when Maggie is already too close
-		// original bug: When Maggie is close McCoy would alternate between
-		// - turning to Maggie and throw food at her
-		// - only performing the turn toward the BAR-MAIN and "throw" food to wrong direction
-		if (Actor_Query_Inch_Distance_From_Actor(kActorMaggie, kActorMcCoy) <= 85) {
-			Delay(500);
-		}
-#endif // BLADERUNNER_ORIGINAL_BUGS
 		Loop_Actor_Walk_To_Actor(kActorMaggie, kActorMcCoy, 48, false, false);
 		Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
 		Actor_Face_Actor(kActorMaggie, kActorMcCoy, false);
 		Actor_Says(kActorMcCoy, 2400, kAnimationModeFeeding);
 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
 		Player_Gains_Control();
+#else
+		if (_animationState != kMaggieStateSleeping
+		 && _animationState != kMaggieStateWakingUp
+		 && _animationState != kMaggieStateStandingUp
+		 && _animationState	!= kMaggieStateLyingDown
+		 && _animationState != kMaggieStateLyingIdle) {
+			// For specific animationStates we have to ignore this goal change,
+			// and go through animation chain until Maggie is standing up
+			// at which point (end of animation of standing up), the goal will change again to kGoalMaggieMA02GetFed
+			// to trigger this case
+			Player_Loses_Control();
+			AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+			AI_Movement_Track_Flush(kActorMaggie);
+			// Allows McCoy to perform both animated turns (first towards the BAR-MAIN and then towards Maggie)
+			// when Maggie is already too close
+			// original bug: When Maggie is close McCoy would alternate between
+			// - turning to Maggie and throw food at her
+			// - only performing the turn toward the BAR-MAIN and "throw" food to wrong direction
+			if (Actor_Query_Inch_Distance_From_Actor(kActorMaggie, kActorMcCoy) <= 85) {
+				Delay(500);
+			}
+			Loop_Actor_Walk_To_Actor(kActorMaggie, kActorMcCoy, 48, false, false);
+			Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
+			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+			Actor_Says(kActorMcCoy, 2400, kAnimationModeFeeding);
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
+			Player_Gains_Control();
+		}
+#endif // BLADERUNNER_ORIGINAL_BUGS
 		return true;
 
 	case kGoalMaggieMA02WalkToMcCoy:
 		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+#if BLADERUNNER_ORIGINAL_BUGS
 		AI_Movement_Track_Flush(kActorMaggie);
 		Loop_Actor_Walk_To_Actor(kActorMaggie, kActorMcCoy, 30, false, false);
 		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
 		Actor_Change_Animation_Mode(kActorMaggie, 56);
 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
+#else
+		if (_animationState != kMaggieStateSleeping
+		 && _animationState != kMaggieStateWakingUp
+		 && _animationState != kMaggieStateStandingUp
+		 && _animationState	!= kMaggieStateLyingDown
+		 && _animationState != kMaggieStateLyingIdle) {
+			// For specific animationStates we have to ignore this goal change,
+			// and go through animation chain until Maggie is standing up
+			// at which point (end of animation of standing up), the goal will change again to kGoalMaggieMA02WalkToMcCoy
+			// to trigger this case
+			AI_Movement_Track_Flush(kActorMaggie);
+			// When an actor other than McCoy does a loopWalk, their walk is non interruptible
+			// (we set it to false explicitly here, but this is also taken care of inside the Actor::loopWalk())
+			// This means McCoy loses control until the other Actor reaches the target waypoint
+			// Also Loop_Actor_Walk_To_Actor() is blocking. The commands following it will be executed
+			// after Maggie completes her loopWalk ie. reaches her target (McCoy).
+			Loop_Actor_Walk_To_Actor(kActorMaggie, kActorMcCoy, 30, false, false);
+			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+			Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
+			Actor_Change_Animation_Mode(kActorMaggie, 56);
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
+		}
+#endif
 		return true;
 
 	case kGoalMaggieMA02Wait:
@@ -309,48 +520,67 @@ bool AIScriptMaggie::GoalChanged(int currentGoalNumber, int newGoalNumber) {
 		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(3, 9));
 		return true;
 
-	case 9:
-		if (Random_Query(0, 2) <= 0) {
-			Actor_Face_Actor(kActorMaggie, kActorMcCoy, false);
-			Actor_Change_Animation_Mode(kActorMaggie, 54);
+	case kGoalMaggieMA02GoingToSleep:
+		// Maggie will (randomly) either:
+		// - sit and go to sleep at her current position,
+		// - or go to a random waypoint and then sit and go to sleep after a while.
+		//
+		// Note: Original checks for <= 0, but that is basically same as checking for == 0 here.
+		if (Random_Query(0, 2) == 0) {
+			Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
+			Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+			// At the end of the animation, if the mode change is not ignored,
+			// the goal will be set to kGoalMaggieMA02SitDownToSleep
+			// (specifically for the case of kGoalMaggieMA02GoingToSleep being the current goal)
+			// and the state to kMaggieStateLyingIdle
 		} else {
 			AI_Movement_Track_Flush(kActorMaggie);
 			if (Actor_Query_Which_Set_In(kActorMaggie) == kSetMA02_MA04) {
+#if BLADERUNNER_ORIGINAL_BUGS
+				// Maggie stays for 486 seconds at the target waypoint (8.1 minutes)
+				// This is a bug since CompletedMovementTrack() won't trigger until after this huge delay.
 				AI_Movement_Track_Append(kActorMaggie, randomWaypointMA02(), 486);
+#else
+				AI_Movement_Track_Append(kActorMaggie, randomWaypointMA02(), 0);
+#endif // BLADERUNNER_ORIGINAL_BUGS
 			}
 			AI_Movement_Track_Repeat(kActorMaggie);
 		}
 		return true;
 
-	case kGoalMaggieMA02SitDown:
-		Actor_Change_Animation_Mode(kActorMaggie, 54);
-		// TODO Why set _animationState and frame explicitly here,
-		//      when the Actor_Change_Animation_Mode() should take care of it?
-		//      does this not negate the "transition" animation?
-		_animationState = kMaggieStateLayingIdle;
+	case kGoalMaggieMA02SitDownToSleep:
+		// fall through
+	case kGoalMaggieMA02SitDownToGetUp:
+		Actor_Change_Animation_Mode(kActorMaggie, 54); // Go to lying (awake) pose
+		// By setting _animationState and frame explicitly here,
+		// the lying-down-idling pose is enforced, and the transition animation (from standing to sitting) will not play
+		_animationState = kMaggieStateLyingIdle;
 		_animationFrame = 0;
 		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
 		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(2, 9));
 		return true;
 
-	case kGoalMaggieMA02Sleep:
-		// When setting Maggie's *goal* to sleep, we expect it to be enforced
+	case kGoalMaggieMA02Sleeping:
+		// When setting Maggie's *goal* to "sleeping", we expect it to be enforced
 		// However, Actor_Change_Animation_Mode is not enforceable and could be ignored.
 		// The goal change here is *NOT* done in order to play the animation.
 		// It is to set the animation State, and by explicitly setting it, it overrides playing the animation transition.
-		// Actor_Change_Animation_Mode) is called to store the _animationMode on Maggie's actor object (see: Actor::changeAnimationMode())
-		Actor_Change_Animation_Mode(kActorMaggie, 55);
+		// Actor_Change_Animation_Mode() is called to store the _animationMode on Maggie's actor object (see: Actor::changeAnimationMode())
+		Actor_Change_Animation_Mode(kActorMaggie, 55); // Go to sleeping pose
 		_animationState = kMaggieStateSleeping;
 #if BLADERUNNER_ORIGINAL_BUGS
 		_animationFrame = 0;
 #else
 		// We actually need the final frame here to avoid Maggie glitching here
-		_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieToggleLaySleepingWakeUp) - 1;
+		_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieToggleSleepingWakeUp) - 1;
+		AI_Countdown_Timer_Reset(kActorMaggie, kActorTimerAIScriptCustomTask0);
+		// Sleep for 20 - 390 seconds, unless McCoy wakes Maggie up.
+		AI_Countdown_Timer_Start(kActorMaggie, kActorTimerAIScriptCustomTask0, Random_Query(20, 390));
 #endif // BLADERUNNER_ORIGINAL_BUGS
 		return true;
 
-	case 400:
-		Actor_Set_Goal_Number(kActorMaggie, 410);
+	case kGoalMaggieAct5Default:
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieAct5Start);
 		break;
 
 	case kGoalMaggieKP05Wait:
@@ -361,7 +591,7 @@ bool AIScriptMaggie::GoalChanged(int currentGoalNumber, int newGoalNumber) {
 		Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
 		break;
 
-	case kGoalMaggieKP05McCoyEntred:
+	case kGoalMaggieKP05McCoyEntered:
 		Scene_Exits_Disable();
 		Loop_Actor_Walk_To_XYZ(kActorMaggie, -734.0, 0.0, -432.0, 0, false, false, false);
 		Actor_Face_Actor(kActorMaggie, kActorMcCoy, true);
@@ -418,10 +648,9 @@ bool AIScriptMaggie::GoalChanged(int currentGoalNumber, int newGoalNumber) {
 }
 
 bool AIScriptMaggie::UpdateAnimation(int *animation, int *frame) {
-	int goal;
 	switch (_animationState) {
 	case kMaggieStateDead:
-		*animation = kModelAnimationMaggieLayingDead;
+		*animation = kModelAnimationMaggieLyingDead;
 		_animationFrame = 0;
 		break;
 
@@ -469,80 +698,190 @@ bool AIScriptMaggie::UpdateAnimation(int *animation, int *frame) {
 		break;
 
 	case kMaggieStateWakingUp:
-		*animation = kModelAnimationMaggieToggleLaySleepingWakeUp;
+		*animation = kModelAnimationMaggieToggleSleepingWakeUp;
 		--_animationFrame;
 		if (_animationFrame > 0) {
 			break;
 		}
-		_animationState = kMaggieStateLayingIdle;
+		// At the end of the wake-up animation
+		_animationState = kMaggieStateLyingIdle;
 		_animationFrame = 0;
-		*animation = kModelAnimationMaggieLayingIdleTailWagging;
-		goal = Actor_Query_Goal_Number(kActorMaggie);
-		if (goal == kGoalMaggieMA02GetFed) {
+		*animation = kModelAnimationMaggieLyingIdleTailWagging;
+		switch (Actor_Query_Goal_Number(kActorMaggie)) {
+		case kGoalMaggieMA02GetFed:
 			_animationState = kMaggieStateStandingUp;
 			_animationFrame = 0;
-			*animation = kModelAnimationMaggieLayingStandingUp;
-		} else if (goal == kGoalMaggieMA02WalkToMcCoy) {
-			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDown);
+			*animation = kModelAnimationMaggieLyingStandingUp;
+			break;
+
+		case kGoalMaggieMA02WalkToMcCoy:
+#if BLADERUNNER_ORIGINAL_BUGS
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToSleep);
 			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
-		} else {
-			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDown);
+#else
+			// Stand up, similar to GetFed case above
+			_animationState = kMaggieStateLyingIdle;
+			_animationFrame = 0;
+			*animation = kModelAnimationMaggieLyingStandingUp;
+#endif
+			break;
+
+		case kGoalMaggieMA02Sleeping:
+			// New behavior:
+			// Decide randomly whether Maggie will:
+			// - Stand up or
+			// - Go back to sleep (which is the default case too)
+			// Both animations will happen after a small delay period,
+			// which is set via timer, restarted in the GoalChanged() code
+			if (Random_Query(0, 1)) {
+				// sleep after a while
+				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToSleep);
+			} else {
+				// get up after a while
+				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToGetUp);
+			}
+			break;
+
+		default:
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToSleep);
+			break;
 		}
 		break;
 
 	case kMaggieStateSleeping:
-		*animation = kModelAnimationMaggieToggleLaySleepingWakeUp;
-		_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieToggleLaySleepingWakeUp) - 1;
+		*animation = kModelAnimationMaggieToggleSleepingWakeUp;
+		_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieToggleSleepingWakeUp) - 1;
+#if !BLADERUNNER_ORIGINAL_BUGS
+		switch (Actor_Query_Goal_Number(kActorMaggie)) {
+		case kGoalMaggieMA02GetFed:
+			// fall through
+		case kGoalMaggieMA02WalkToMcCoy:
+			// _animationFrame and model do not change here, just the state
+			_animationState = kMaggieStateWakingUp;
+			break;
+
+		default:
+			break;
+		}
+#endif // !BLADERUNNER_ORIGINAL_BUGS
 		break;
 
 	case kMaggieStateGoingToSleep:
-		*animation = kModelAnimationMaggieToggleLaySleepingWakeUp;
+		*animation = kModelAnimationMaggieToggleSleepingWakeUp;
 		++_animationFrame;
-		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieToggleLaySleepingWakeUp) - 1) {
+		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieToggleSleepingWakeUp) - 1) {
 			_animationState = kMaggieStateSleeping;
-			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Sleep);
+			Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Sleeping);
 		}
 		break;
 
 	case kMaggieStateStandingUp:
-		*animation = kModelAnimationMaggieLayingStandingUp;
+		*animation = kModelAnimationMaggieLyingStandingUp;
 		++_animationFrame;
-		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieLayingStandingUp)) {
+		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieLyingStandingUp)) {
 			*animation = kModelAnimationMaggieStandingIdle;
 			_animationState = kMaggieStateIdle;
 			_animationFrame = 0;
-			if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02SitDown) {
+			switch (Actor_Query_Goal_Number(kActorMaggie)) {
+			case kGoalMaggieMA02SitDownToGetUp: // new
+				// fall through
+			case kGoalMaggieMA02SitDownToSleep:
 				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Wait);
-			} else if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieMA02WalkToMcCoy) {
-				Actor_Set_Goal_Number(kActorMaggie, 12); // this is never used
+				break;
+
+			case kGoalMaggieMA02WalkToMcCoy:
+				// kGoalMaggieMA02Intermediate12 is a dummy goal, used only
+				// to trigger a GoalChanged case, when we set back to kGoalMaggieMA02WalkToMcCoy below
+				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Intermediate12);
 				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToMcCoy);
+				break;
+
+#if !BLADERUNNER_ORIGINAL_BUGS
+			case kGoalMaggieMA02GetFed:
+				// kGoalMaggieMA02Intermediate12 is a dummy goal, used only
+				// to trigger a GoalChanged case, when we set back to kGoalMaggieMA02GetFed below
+				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02Intermediate12);
+				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02GetFed);
+				break;
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+
+			default:
+				break;
 			}
 		}
 		break;
 
-	case kMaggieStateLayingIdle:
-		*animation = kModelAnimationMaggieLayingIdleTailWagging;
+	case kMaggieStateLyingIdle:
+		*animation = kModelAnimationMaggieLyingIdleTailWagging;
 		++_animationFrame;
-		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieLayingIdleTailWagging)) {
+		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieLyingIdleTailWagging)) {
 			_animationFrame = 0;
+#if !BLADERUNNER_ORIGINAL_BUGS
+			switch (Actor_Query_Goal_Number(kActorMaggie)) {
+			case kGoalMaggieMA02GetFed:
+				// fall through
+			case kGoalMaggieMA02WalkToMcCoy:
+				_animationState = kMaggieStateStandingUp;
+				*animation = kModelAnimationMaggieLyingStandingUp;
+				break;
+
+			default:
+				break;
+			}
+#endif // !BLADERUNNER_ORIGINAL_BUGS
 		}
 		break;
 
-	case kMaggieStateLayingDown:
-		*animation = kModelAnimationMaggieLayingDown;
+	case kMaggieStateLyingDown:
+		*animation = kModelAnimationMaggieLyingDown;
 		++_animationFrame;
-		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieLayingDown)) {
-			_animationState = kMaggieStateLayingIdle;
+		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieLyingDown)) {
+			_animationState = kMaggieStateLyingIdle;
 			_animationFrame = 0;
-			*animation = kModelAnimationMaggieLayingIdleTailWagging;
-			if (Actor_Query_Goal_Number(kActorMaggie) == 9) {
-				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDown);
+			*animation = kModelAnimationMaggieLyingIdleTailWagging;
+			switch (Actor_Query_Goal_Number(kActorMaggie)) {
+			case kGoalMaggieMA02GoingToSleep:
+				// sleep after a while
+				Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToSleep);
+				break;
+
+#if !BLADERUNNER_ORIGINAL_BUGS
+			case kGoalMaggieMA02Wait:
+				// This case was missing from the original engine
+				// but is required in order to set Maggie's goal properly,
+				// so that when she get's up she will go through the proper standing up animation.
+				// This could be guarded with a _cutContent clause check, 
+				// since this fix restores untriggered cases,
+				// but since it's fixing a missing animation glitch,
+				// it will be part of vanilla mode, as well.
+				if (Random_Query(0, 1) && _varMaggieClickResponse != 1) {
+					// sleep after a while
+					Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToSleep);
+				} else {
+					// get up after a while
+					Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02SitDownToGetUp);
+					if (_varMaggieClickResponse == 1) {
+						_varMaggieClickResponse = 0;
+					}
+				}
+				break;
+
+			case kGoalMaggieMA02GetFed:
+				// fall through
+			case kGoalMaggieMA02WalkToMcCoy:
+				_animationState = kMaggieStateStandingUp;
+				*animation = kModelAnimationMaggieLyingStandingUp;
+				break;
+#endif // !BLADERUNNER_ORIGINAL_BUGS
+
+			default:
+				break;
 			}
 		}
 		break;
 
 	case kMaggieStateHappyB:
-		// Not actually barking in this case
+		// Not actually barking in this case, but tail wagging (with breathing sounds)
 		*animation = kModelAnimationMaggieBarking;
 		++_animationFrame;
 		if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieBarking)) {
@@ -551,6 +890,13 @@ bool AIScriptMaggie::UpdateAnimation(int *animation, int *frame) {
 			if (_varTimesToLoopWhenHappyB <= 0) {
 				Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeIdle);
 				*animation = kModelAnimationMaggieStandingIdle;
+				if (_varMaggieClickResponse == 3) {
+					// (Cut Content; _varMaggieClickResponse only gets values > 0 in Cut Content)
+					Actor_Start_Speech_Sample(kActorMcCoy, 2705);
+					Actor_Change_Animation_Mode(kActorMcCoy, 29); // Get up
+					Player_Gains_Control();
+					_varMaggieClickResponse = 0;
+				}
 			}
 		}
 		break;
@@ -624,12 +970,12 @@ bool AIScriptMaggie::ChangeAnimationMode(int mode) {
 				_animationState = kMaggieStateWakingUp;
 				break;
 
-			case kMaggieStateLayingIdle:
+			case kMaggieStateLyingIdle:
 				_animationState = kMaggieStateStandingUp;
 				_animationFrame = 0;
 				break;
 
-			case kMaggieStateLayingDown:
+			case kMaggieStateLyingDown:
 				_animationState = kMaggieStateStandingUp;
 				_animationFrame = 0;
 				break;
@@ -692,17 +1038,19 @@ bool AIScriptMaggie::ChangeAnimationMode(int mode) {
 #endif // BLADERUNNER_ORIGINAL_BUGS
 				}
 			} else {
-				_animationState = kMaggieStateLayingDown;
+				_animationState = kMaggieStateLyingDown;
 				_animationFrame = 0;
 			}
 		}
+		// otherwise, the request for animation 54 (ie. assume lying awake pose) is ignored
 		break;
 
 	case 55:
-		if (_animationState == kMaggieStateLayingIdle) {
+		if (_animationState == kMaggieStateLyingIdle) {
 			_animationState = kMaggieStateGoingToSleep;
 			_animationFrame = 0;
 		}
+		// otherwise, the request for animation 55 (ie. assume sleeping pose) is ignored
 		break;
 
 	case 56:
@@ -718,7 +1066,14 @@ bool AIScriptMaggie::ChangeAnimationMode(int mode) {
 			_animationFrame = 0;
 			_animationState = kMaggieStateHappyB;
 		}
-		_varTimesToLoopWhenHappyB = Random_Query(2, 6);
+
+		if (_varMaggieClickResponse == 3) {
+			// (Cut Content; _varMaggieClickResponse only gets values > 0 in Cut Content)
+			// Allow for time for McCoy to sit down
+			_varTimesToLoopWhenHappyB = Random_Query(4, 6);
+		} else {
+			_varTimesToLoopWhenHappyB = Random_Query(2, 6);
+		}
 		_varMaggieSoundPan = _vm->_actors[kActorMaggie]->soundPan(75);
 		if (_vm->_cutContent) {
 			Sound_Play(Random_Query(kSfxDOGTAIL1, kSfxDOGTAIL2), 50, _varMaggieSoundPan, _varMaggieSoundPan, 50);
@@ -764,15 +1119,19 @@ void AIScriptMaggie::FledCombat() {
 int AIScriptMaggie::randomWaypointMA02() {
 	switch (Random_Query(0, 3)) {
 	case 0:
+		// near counter and apartment door (eg. when greeting McCoy)
 		return 264;
 
 	case 1:
+		// bottom right of screen
 		return 265;
 
 	case 2:
+		// near bedroom door (left)
 		return 266;
 
 	default:
+		// in front of windows (near counter)
 		return 267;
 	}
 }
diff --git a/engines/bladerunner/script/ai_script.h b/engines/bladerunner/script/ai_script.h
index 2a4f1977e7..fbecaf16ef 100644
--- a/engines/bladerunner/script/ai_script.h
+++ b/engines/bladerunner/script/ai_script.h
@@ -473,9 +473,9 @@ END_SCRIPT
 DECLARE_SCRIPT(Maggie)
 	int _varTimesToLoopWhenHappyB;
 	int _varTimesToBarkWhenHappyA;
-	int _varMaggieSoundPan; // Repurposed - Original: unused only set to 0 (var_45F400)
-	int var_45F404;     // only set to 0. unused
-	int var_45F408;     // only set to 0. unused
+	int _varMaggieSoundPan;      // Repurposed - Original: unused, only set to 0 (var_45F400)
+	int _varMaggieClickResponse; // Repurposed - Original: unused, only set to 0 (var_45F404)
+	int var_45F408;              // unused, only set to 0
 
 	int randomWaypointMA02();
 	float distanceToActor(int actorId, float x, float y, float z);
diff --git a/engines/bladerunner/script/scene/kp05.cpp b/engines/bladerunner/script/scene/kp05.cpp
index fadc087e2c..cf52c8f566 100644
--- a/engines/bladerunner/script/scene/kp05.cpp
+++ b/engines/bladerunner/script/scene/kp05.cpp
@@ -143,7 +143,7 @@ void SceneScriptKP05::PlayerWalkedIn() {
 	}
 
 	if (Actor_Query_Goal_Number(kActorMaggie) == kGoalMaggieKP05Wait) {
-		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05McCoyEntred);
+		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieKP05McCoyEntered);
 	}
 
 	if (Actor_Query_Goal_Number(kActorSteele) == 450) {
diff --git a/engines/bladerunner/script/scene/ma02.cpp b/engines/bladerunner/script/scene/ma02.cpp
index 7b7d8058a6..be25ac6ae8 100644
--- a/engines/bladerunner/script/scene/ma02.cpp
+++ b/engines/bladerunner/script/scene/ma02.cpp
@@ -207,8 +207,9 @@ void SceneScriptMA02::PlayerWalkedIn() {
 
 	if ( Global_Variable_Query(kVariableChapter) < 4
 	 && !Game_Flag_Query(kFlagMA04ToMA02)
-	 &&  Actor_Query_Goal_Number(kActorMaggie) != 2
-	) {
+	 &&  Actor_Query_Goal_Number(kActorMaggie) != kGoalMaggieMA02Intermediate02) {
+		// Note, clause Actor_Query_Goal_Number(kActorMaggie) != kGoalMaggieMA02Intermediate02 is always true,
+		// as kGoalMaggieMA02Intermediate02 is never set as Maggie's goal.
 		Actor_Set_Goal_Number(kActorMaggie, kGoalMaggieMA02WalkToEntrance);
 
 		if (!Game_Flag_Query(kFlagMA02MaggieIntroduced)) {




More information about the Scummvm-git-logs mailing list