aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/script/ai
diff options
context:
space:
mode:
Diffstat (limited to 'engines/bladerunner/script/ai')
-rw-r--r--engines/bladerunner/script/ai/howie_lee.cpp192
1 files changed, 136 insertions, 56 deletions
diff --git a/engines/bladerunner/script/ai/howie_lee.cpp b/engines/bladerunner/script/ai/howie_lee.cpp
index 3675fc1b60..87012302b2 100644
--- a/engines/bladerunner/script/ai/howie_lee.cpp
+++ b/engines/bladerunner/script/ai/howie_lee.cpp
@@ -36,47 +36,79 @@ void AIScriptHowieLee::Initialize() {
var_45DFB8 = false;
Actor_Put_In_Set(kActorHowieLee, kSetCT01_CT12);
- Actor_Set_At_Waypoint(kActorHowieLee, 67, 605);
- Actor_Set_Goal_Number(kActorHowieLee, 0);
+ Actor_Set_At_Waypoint(kActorHowieLee, 67, 605); // in kSetCT01_CT12
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
}
bool AIScriptHowieLee::Update() {
- if (Actor_Query_Goal_Number(kActorHowieLee) < 100
- && Global_Variable_Query(kVariableChapter) == 2
- ) {
- Actor_Set_Goal_Number(kActorHowieLee, 100);
- }
- if (Global_Variable_Query(kVariableChapter) > 1) {
- return true;
+ if (_vm->_cutContent) {
+ // keep Howie in Acts 2 and 3
+ // Howie in Acts 2 and 3 will have a routine with existing waypoints/goals,
+ // so no need to add new goals (> 100) for those Acts
+ if (Actor_Query_Goal_Number(kActorHowieLee) < 100
+ && Global_Variable_Query(kVariableChapter) == 4
+ ) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToFreeSlotC);
+ }
+
+ if (Global_Variable_Query(kVariableChapter) > 3) {
+ return true;
+ }
+ } else {
+ if (Actor_Query_Goal_Number(kActorHowieLee) < 100
+ && Global_Variable_Query(kVariableChapter) == 2
+ ) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToFreeSlotC);
+ }
+
+ if (Global_Variable_Query(kVariableChapter) > 1) {
+ return true;
+ }
}
- if (Actor_Query_Goal_Number(kActorHowieLee) == 0) {
- Actor_Set_Goal_Number(kActorHowieLee, 1);
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeDefault) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeMovesInDiner01);
}
+ // In the original code this is used (in Act 1) to get Howie back to the Diner
+ // from goals kGoalHowieLeeGoesToCT04GarbageBin or kGoalHowieLeeGoesToFreeSlotH
+ // It might cause a blink-in issue, depending when update() will be called for Howie
+ // This is kept as a backup while similar code is placed in the CT01 and CT02 scenes InitializeScene()
+ // that will handle Howie appearing there immediately (fix for blink in)
if ( Game_Flag_Query(kFlagMcCoyInChinaTown)
&& !Actor_Query_In_Set(kActorHowieLee, kSetCT01_CT12)
+ && Global_Variable_Query(kVariableChapter) == 1 // added condition - in cut content don't force Howie to return to CT01 here after Act 1
) {
AI_Movement_Track_Flush(kActorHowieLee);
- AI_Movement_Track_Append(kActorHowieLee, 67, 0);
- Actor_Set_Goal_Number(kActorHowieLee, 0);
+ AI_Movement_Track_Append(kActorHowieLee, 67, 0); // in kSetCT01_CT12
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
}
- if ( Actor_Query_Goal_Number(kActorHowieLee) == 1
- && Game_Flag_Query(kFlagCT01BoughtHowieLeeFood)
- && !Game_Flag_Query(kFlagMcCoyInChinaTown)
#if BLADERUNNER_ORIGINAL_BUGS
+ if ( Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner01
+ && Game_Flag_Query(kFlagCT01BoughtHowieLeeFood)
+ && !Game_Flag_Query(kFlagMcCoyInChinaTown) ) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
+ return true;
+ }
#else
// Prevents possibility of Howie Lee from blinking in/out of existence
- // when the flyout loop is playing
- // and when McCoy enters and exits the Spinner with the spinner doors animation restored
- && Player_Query_Current_Scene() != kSceneCT01
-#endif // BLADERUNNER_ORIGINAL_BUGS
+ // when the fly-out loop is playing and/or when McCoy enters and exits the Spinner with the spinner doors animation restored
+ if ((Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner01
+ || Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner02
+ || Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner03
+ || Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner06
+ || Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeDefault)
+ && Game_Flag_Query(kFlagCT01BoughtHowieLeeFood)
+ && !Game_Flag_Query(kFlagMcCoyInChinaTown)
+ && Player_Query_Current_Scene() != kSceneCT01
+ && Player_Query_Current_Scene() != kSceneCT12
) {
- Actor_Set_Goal_Number(kActorHowieLee, 4);
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
return true;
}
+#endif // BLADERUNNER_ORIGINAL_BUGS
return false;
}
@@ -86,36 +118,73 @@ void AIScriptHowieLee::TimerExpired(int timer) {
}
void AIScriptHowieLee::CompletedMovementTrack() {
- if (Actor_Query_Goal_Number(kActorHowieLee) == 1) {
- Actor_Set_Goal_Number(kActorHowieLee, 2);
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner01) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeMovesInDiner02);
return; // true;
}
- if (Actor_Query_Goal_Number(kActorHowieLee) == 2) {
- Actor_Set_Goal_Number(kActorHowieLee, 3);
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner02) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeMovesInDiner03);
return; // true;
}
- if (Actor_Query_Goal_Number(kActorHowieLee) == 3) {
- Actor_Set_Goal_Number(kActorHowieLee, 0);
- return; // true;
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner03) {
+ if (_vm->_cutContent) {
+ //
+ // *after Act 1* Howie will be going to the Garbage Bin "regularly"
+ // if McCoy is not in scenes CT01 and CT12 (where Howie is visible working at the diner)
+ // otherwise he'll do the short cycle (goals 0, 1, 2, 3)
+ // This will result in Howie not being at the Diner sometimes even when McCoy is in Chinatown area
+ // This won't happen in Act 1, since he is most useful during that Act
+ if (Global_Variable_Query(kVariableChapter) > 1
+ && Player_Query_Current_Scene() != kSceneCT01
+ && Player_Query_Current_Scene() != kSceneCT12
+ && Player_Query_Current_Scene() != kSceneCT04
+ ) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
+ return; // true;
+ } else {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
+ return; // true;
+ }
+ } else {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
+ return; // true;
+ }
}
- // Bug/intentional in original game?
- if (Actor_Query_Goal_Number(kActorHowieLee) == 3) {
- Actor_Set_Goal_Number(kActorHowieLee, 4);
- return; // true;
+#if BLADERUNNER_ORIGINAL_BUGS
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner03) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
+ return; // true;
}
+#endif // BLADERUNNER_ORIGINAL_BUGS
- if (Actor_Query_Goal_Number(kActorHowieLee) == 4) {
- Actor_Set_Goal_Number(kActorHowieLee, 5);
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeGoesToCT04GarbageBin) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToFreeSlotH);
return; // true;
}
- if (Actor_Query_Goal_Number(kActorHowieLee) == 5) {
- Actor_Set_Goal_Number(kActorHowieLee, 0);
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeGoesToFreeSlotH) {
+#if BLADERUNNER_ORIGINAL_BUGS
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
return; // true;
+#else
+ // don't blink-in and also only return to diner routine if McCoy is actually in Chinatown
+ if (Game_Flag_Query(kFlagMcCoyInChinaTown)
+ && Player_Query_Current_Scene() != kSceneCT01
+ && Player_Query_Current_Scene() != kSceneCT12
+ ) {
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
+ return; // true;
+ } else {
+ // return to "garbage bin" goal instead of blinking in
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
+ return; // true;
+ }
+#endif // BLADERUNNER_ORIGINAL_BUGS
}
+
// return false;
}
@@ -128,7 +197,7 @@ void AIScriptHowieLee::ClickedByPlayer() {
}
void AIScriptHowieLee::EnteredScene(int sceneId) {
- if (Actor_Query_Goal_Number(kActorHowieLee) == 4
+ if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeGoesToCT04GarbageBin
&& Actor_Query_In_Set(kActorHowieLee, kSetCT03_CT04)
) {
if ( Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)
@@ -139,7 +208,7 @@ void AIScriptHowieLee::EnteredScene(int sceneId) {
// return false;
}
- if (!Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)
+ if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)
&& Game_Flag_Query(kFlagCT04HomelessBodyInDumpster)
&& !Game_Flag_Query(kFlagCT04HomelessBodyFound)
&& Random_Query(1, 10) == 1
@@ -152,6 +221,17 @@ void AIScriptHowieLee::EnteredScene(int sceneId) {
}
void AIScriptHowieLee::OtherAgentEnteredThisScene(int otherActorId) {
+#if BLADERUNNER_ORIGINAL_BUGS
+#else
+ // prevent player from actually meeting hovering Howie half-body in kSetCT03_CT04
+ if (otherActorId == kActorMcCoy
+ && Actor_Query_In_Set(kActorHowieLee, kSetCT03_CT04)
+ ) {
+ AI_Movement_Track_Flush(kActorHowieLee);
+ AI_Movement_Track_Append(kActorHowieLee, 67, 0); // in kSetCT01_CT12
+ Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
+ }
+#endif // BLADERUNNER_ORIGINAL_BUGS
// return false;
}
@@ -181,55 +261,55 @@ int AIScriptHowieLee::GetFriendlinessModifierIfGetsClue(int otherActorId, int cl
bool AIScriptHowieLee::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
- case 1:
+ case kGoalHowieLeeMovesInDiner01:
AI_Movement_Track_Flush(kActorHowieLee);
if (Random_Query(1, 2) == 1) {
- AI_Movement_Track_Append_With_Facing(kActorHowieLee, 67, Random_Query(3, 10), 720);
+ AI_Movement_Track_Append_With_Facing(kActorHowieLee, 67, Random_Query(3, 10), 720); // in kSetCT01_CT12
} else {
- AI_Movement_Track_Append_With_Facing(kActorHowieLee, 69, Random_Query(3, 10), 640);
+ AI_Movement_Track_Append_With_Facing(kActorHowieLee, 69, Random_Query(3, 10), 640); // in kSetCT01_CT12
}
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
- case 2:
+ case kGoalHowieLeeMovesInDiner02:
AI_Movement_Track_Flush(kActorHowieLee);
if (Random_Query(1, 2) == 1) {
- AI_Movement_Track_Append_With_Facing(kActorHowieLee, 68, Random_Query(3, 10), 641);
+ AI_Movement_Track_Append_With_Facing(kActorHowieLee, 68, Random_Query(3, 10), 641); // in kSetCT01_CT12
} else {
- AI_Movement_Track_Append_With_Facing(kActorHowieLee, 67, Random_Query(3, 10), 720);
+ AI_Movement_Track_Append_With_Facing(kActorHowieLee, 67, Random_Query(3, 10), 720); // in kSetCT01_CT12
}
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
- case 3:
+ case kGoalHowieLeeMovesInDiner03:
AI_Movement_Track_Flush(kActorHowieLee);
if (Random_Query(1, 2) == 1) {
- AI_Movement_Track_Append_With_Facing(kActorHowieLee, 69, Random_Query(3, 10), 640);
+ AI_Movement_Track_Append_With_Facing(kActorHowieLee, 69, Random_Query(3, 10), 640); // in kSetCT01_CT12
} else {
- AI_Movement_Track_Append_With_Facing(kActorHowieLee, 68, Random_Query(3, 10), 641);
+ AI_Movement_Track_Append_With_Facing(kActorHowieLee, 68, Random_Query(3, 10), 641); // in kSetCT01_CT12
}
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
- case 4:
+ case kGoalHowieLeeGoesToCT04GarbageBin:
AI_Movement_Track_Flush(kActorHowieLee);
- AI_Movement_Track_Append(kActorHowieLee, 66, 30);
+ AI_Movement_Track_Append(kActorHowieLee, 66, 30); // in kSetCT03_CT04
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
- case 5:
+ case kGoalHowieLeeGoesToFreeSlotH:
AI_Movement_Track_Flush(kActorHowieLee);
- AI_Movement_Track_Append(kActorHowieLee, 40, 60);
+ AI_Movement_Track_Append(kActorHowieLee, 40, 60); // in kSetFreeSlotH
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
- case 6:
+ case kGoalHowieLeeMovesInDiner06: // Unused goal?
AI_Movement_Track_Flush(kActorHowieLee);
- AI_Movement_Track_Append(kActorHowieLee, 67, 90);
+ AI_Movement_Track_Append(kActorHowieLee, 67, 90); // in kSetCT01_CT12
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
- case 50:
+ case kGoalHowieLeeStopMoving:
AI_Movement_Track_Flush(kActorHowieLee);
return false;
- case 100:
+ case kGoalHowieLeeGoesToFreeSlotC:
AI_Movement_Track_Flush(kActorHowieLee);
Actor_Put_In_Set(kActorHowieLee, kSetFreeSlotC);
- Actor_Set_At_Waypoint(kActorHowieLee, 35, 0);
+ Actor_Set_At_Waypoint(kActorHowieLee, 35, 0); // in kSetFreeSlotC
return false;
}
return false;