[Scummvm-git-logs] scummvm master -> 3c61365692a31f80e2ebb7253f9be8e7d1fa6ac1
antoniou79
a.antoniou79 at gmail.com
Fri Apr 16 22:49:30 UTC 2021
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c0bcc5438f BLADERUNNER: Fix logic for asking Crazylegs about Dektora
f69fe5ee0b BLADERUNNER: JANITORIAL: Comment alignment fix
3c61365692 BLADERUNNER: Fix bad boundbox for corpses
Commit: c0bcc5438f285fb43b40889c53118ba4fa4a5959
https://github.com/scummvm/scummvm/commit/c0bcc5438f285fb43b40889c53118ba4fa4a5959
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-04-17T01:45:38+03:00
Commit Message:
BLADERUNNER: Fix logic for asking Crazylegs about Dektora
Changed paths:
engines/bladerunner/game_constants.h
engines/bladerunner/script/scene/hf05.cpp
engines/bladerunner/script/scene/nr05.cpp
diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h
index 373586534d..7b8f040b82 100644
--- a/engines/bladerunner/game_constants.h
+++ b/engines/bladerunner/game_constants.h
@@ -216,11 +216,11 @@ enum Clues {
kClueHoldensBadge = 110,
kClueCar = 111,
kClueCarIdentified = 112,
- kClueCarRegistration1 = 113,
- kClueCarRegistration2 = 114,
- kClueCarRegistration3 = 115,
- kClueCrazylegsInterview1 = 116,
- kClueCrazylegsInterview2 = 117,
+ kClueCarRegistration1 = 113, // Dektora bought the car
+ kClueCarRegistration2 = 114, // Gavin Kelly bought the car
+ kClueCarRegistration3 = 115, // Blake Williams bought the car
+ kClueCrazylegsInterview1 = 116, // new: acquired after bug fix. Original: Never acquired
+ kClueCrazylegsInterview2 = 117, // original: Never acquired
kClueLichenDogWrapper = 118,
kClueRequisitionForm = 119, // original: Never acquired
kClueScaryChair = 120,
diff --git a/engines/bladerunner/script/scene/hf05.cpp b/engines/bladerunner/script/scene/hf05.cpp
index b1937f5091..f1208c6f78 100644
--- a/engines/bladerunner/script/scene/hf05.cpp
+++ b/engines/bladerunner/script/scene/hf05.cpp
@@ -152,6 +152,10 @@ bool SceneScriptHF05::ClickedOn3DObject(const char *objectName, bool a2) {
bool SceneScriptHF05::ClickedOnActor(int actorId) {
if (actorId == kActorCrazylegs) {
+ // Note: dialogueWithCrazylegs1() makes sense only for Acts 3 and 4.
+ // by Act 5, McCoy is done interrogating, and it would also be weird
+ // if he is asking questions about Lucy or Dektora, with them standing next to him.
+ // TODO Recheck: Is McCoy allowed to click on CrazyLegs in Act5 while Dektora or Lucy are there too?
#if BLADERUNNER_ORIGINAL_BUGS
if (!Loop_Actor_Walk_To_Actor(kActorMcCoy, kActorCrazylegs, 60, true, false)) {
Actor_Face_Actor(kActorMcCoy, kActorCrazylegs, true);
@@ -395,11 +399,24 @@ void SceneScriptHF05::dialogueWithCrazylegs1() {
DM_Add_To_List_Never_Repeat_Once_Selected(1180, 3, 6, 7); // ADVERTISEMENT
}
if (Actor_Clue_Query(kActorMcCoy, kClueCrazylegsInterview1)) {
+ // kClueCrazylegsInterview1 is acquired (after bug fix)
+ // only when Dektora has bought the car (kClueCarRegistration1)
+ // and McCoy has asked Crazylegs for the CAR REGISTRATION topic already
DM_Add_To_List_Never_Repeat_Once_Selected(1190, 2, 7, 4); // WOMAN
}
+#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Clue_Query(kActorMcCoy, kClueDektorasDressingRoom)) {
DM_Add_To_List_Never_Repeat_Once_Selected(1200, 5, 5, 3); // WOMAN'S PHOTO
}
+#else
+ if ((Actor_Clue_Query(kActorMcCoy, kClueDektorasDressingRoom)
+ && Actor_Clue_Query(kActorMcCoy, kClueCrazylegsInterview1))
+ ) {
+ // kClueDektorasDressingRoom is acquired from EarlyQ at his office (nr04)
+ // McCoy should only ask about this if CrazyLegs already told him at least about the sexy blonde (kClueCrazylegsInterview1)
+ DM_Add_To_List_Never_Repeat_Once_Selected(1200, 5, 5, 3); // WOMAN'S PHOTO
+ }
+#endif // BLADERUNNER_ORIGINAL_BUGS
if (Actor_Clue_Query(kActorMcCoy, kClueLucy)
&& Actor_Query_Goal_Number(kActorLucy) != kGoalLucyGone
) {
@@ -410,11 +427,15 @@ void SceneScriptHF05::dialogueWithCrazylegs1() {
&& Global_Variable_Query(kVariableChapter) == 3
)
) {
+ // TODO recheck the condition here. The chapter check should probably be done in both cases
+ // either McCoy has kClueGrigoriansResources or kClueGrigoriansNote
DM_Add_To_List_Never_Repeat_Once_Selected(1220, -1, 2, 8); // GRIGORIAN
}
if (Actor_Clue_Query(kActorMcCoy, kClueCarRegistration1)
|| Actor_Clue_Query(kActorMcCoy, kClueCarRegistration3)
) {
+ // Dektora bought the car or Blake Williams (which is an alias, that Clovis used)
+ // Gordo is with Dektora when making the car purchase (as revealed by CrazyLegs in the "WOMAN" question).
DM_Add_To_List_Never_Repeat_Once_Selected(1230, 4, 7, -1); // CAR REGISTRATION
}
@@ -515,6 +536,13 @@ void SceneScriptHF05::dialogueWithCrazylegs1() {
Actor_Says(kActorMcCoy, 2080, kAnimationModeTalk);
Actor_Says(kActorCrazylegs, 860, 16);
Actor_Says(kActorCrazylegs, 870, kAnimationModeTalk);
+#if BLADERUNNER_ORIGINAL_BUGS
+#else
+ // This clue was never acquired, even though it is checked in KIA
+ // (so that it appears as a recording in KIA if acquired)
+ // It also enables the "WOMAN" conversation option with CrazyLegs.
+ Actor_Clue_Acquire(kActorMcCoy, kClueCrazylegsInterview1, true, kActorCrazylegs);
+#endif // BLADERUNNER_ORIGINAL_BUGS
} else if (Actor_Clue_Query(kActorMcCoy, kClueCarRegistration3)) {
Actor_Says(kActorCrazylegs, 880, 12);
Actor_Says(kActorCrazylegs, 890, 14);
diff --git a/engines/bladerunner/script/scene/nr05.cpp b/engines/bladerunner/script/scene/nr05.cpp
index 9151ae2acf..e294f9ab2d 100644
--- a/engines/bladerunner/script/scene/nr05.cpp
+++ b/engines/bladerunner/script/scene/nr05.cpp
@@ -305,6 +305,12 @@ void SceneScriptNR05::talkToEarlyQ() {
DM_Add_To_List_Never_Repeat_Once_Selected(900, 5, 6, 5); // LUCY
}
if (Actor_Clue_Query(kActorMcCoy, kClueDektorasDressingRoom)) {
+ // TODO A bug? kClueDektorasDressingRoom is acquired from EarlyQ
+ // at his office (nr04) while being threatened by McCoy.
+ // At which point EarlyQ already tells McCoy who the people on the photograph are.
+ // It makes no sense that McCoy will next find EarlyQ at the VIP area (this area, nr05)
+ // and casually ask him about who the woman is in this photo.
+ // (McCoy won't be able to even find EarlyQ there again).
DM_Add_To_List_Never_Repeat_Once_Selected(910, 5, 5, 5); // BLOND WOMAN
}
}
@@ -356,6 +362,8 @@ void SceneScriptNR05::talkToEarlyQ() {
Actor_Says(kActorMcCoy, 3515, 14);
Actor_Modify_Friendliness_To_Other(kActorEarlyQ, kActorMcCoy, -1);
if (Actor_Clue_Query(kActorMcCoy, kClueGrigoriansNote)) { // cut content? this clue is unobtanium
+ // TODO why is Grigorian's Note needed here, for EarlyQ to reveal who Hecuba is?
+ // maybe another clue should be required in its place or some additional ones?
Actor_Says(kActorEarlyQ, 580, 12);
Actor_Says(kActorMcCoy, 3560, 13);
Actor_Says(kActorEarlyQ, 590, 16);
Commit: f69fe5ee0b44f911b65edd4e8625517ef4d197a2
https://github.com/scummvm/scummvm/commit/f69fe5ee0b44f911b65edd4e8625517ef4d197a2
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-04-17T01:45:38+03:00
Commit Message:
BLADERUNNER: JANITORIAL: Comment alignment fix
Changed paths:
engines/bladerunner/script/scene/rc03.cpp
diff --git a/engines/bladerunner/script/scene/rc03.cpp b/engines/bladerunner/script/scene/rc03.cpp
index d55e944321..e173901fdb 100644
--- a/engines/bladerunner/script/scene/rc03.cpp
+++ b/engines/bladerunner/script/scene/rc03.cpp
@@ -54,7 +54,7 @@ void SceneScriptRC03::InitializeScene() {
#if BLADERUNNER_ORIGINAL_BUGS
Scene_Exit_Add_2D_Exit(2, 524, 350, 573, 359, 2);
#else
- // prevent Izo's corpse from blocking the exit hot-spot area
+ // prevent Izo's corpse from blocking the exit hot-spot area
Scene_Exit_Add_2D_Exit(2, 524, 340, 573, 359, 2);
#endif // BLADERUNNER_ORIGINAL_BUGS
}
Commit: 3c61365692a31f80e2ebb7253f9be8e7d1fa6ac1
https://github.com/scummvm/scummvm/commit/3c61365692a31f80e2ebb7253f9be8e7d1fa6ac1
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2021-04-17T01:45:38+03:00
Commit Message:
BLADERUNNER: Fix bad boundbox for corpses
Some of these issues were caused by commit 186de62ffb575a6c7fe5c27e1b6980364390e678
Others were original bugs (mutants 2 and 3), and both rats.
This commit includes a fix for Grayford's death animation when shot (in Act 4)
Changed paths:
engines/bladerunner/actor.cpp
engines/bladerunner/actor.h
engines/bladerunner/boundingbox.cpp
engines/bladerunner/debugger.cpp
engines/bladerunner/game_constants.h
engines/bladerunner/scene_objects.cpp
engines/bladerunner/scene_objects.h
engines/bladerunner/script/ai/free_slot_a.cpp
engines/bladerunner/script/ai/free_slot_b.cpp
engines/bladerunner/script/ai/mutant1.cpp
engines/bladerunner/script/ai/mutant2.cpp
engines/bladerunner/script/ai/mutant3.cpp
engines/bladerunner/script/ai/officer_grayford.cpp
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index 4b9dad1c3d..8898eb3431 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -202,6 +202,10 @@ void Actor::changeAnimationMode(int animationMode, bool force) {
}
}
+int Actor::getFPS() const {
+ return _fps;
+}
+
void Actor::setFPS(int fps) {
_fps = fps;
@@ -398,6 +402,7 @@ void Actor::movementTrackNext(bool omitAiScript) {
}
} else {
setSetId(waypointSetId);
+
setAtXYZ(waypointPosition, angle, true, false, false);
if (!delay) {
@@ -682,6 +687,13 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
int32 timeLeft = 0;
bool needsUpdate = false;
if (_fps > 0) {
+ // Note that when (some?) actors are retired (eg. Zuben)
+ // their _fps is still > 0 so they will periodically set needsUpdate to true in their tick() (here)
+ // Also, the moment an actor is retired does not necessarily means their death animation finished playing
+ // Their death animation may finish a while later.
+ // Thus, until it finished, their screen rectangle will be likely changing at the draw() operation.
+ // Typically at the end of a death animation, the actor keeps updating for the same frame
+ // (ie the last of the death animation). At that point their screen rectangle won't change at the draw() operation.
timerUpdate(kActorTimerAnimationFrame);
timeLeft = timerLeft(kActorTimerAnimationFrame);
needsUpdate = (timeLeft <= 0);
@@ -803,6 +815,9 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
bool isVisible = false;
if (!_isInvisible) {
+ // draw() will set the new screenRect for the actor
+ // based on the current animation frame
+ // the new screenRect may be empty, in which case draw returns false (thus isVisible will be false then).
isVisible = draw(screenRect);
if (isVisible) {
_screenRectangle = *screenRect;
@@ -813,19 +828,28 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
// For consistency we need to init the screen rectangle and bbox for the actor's *scene object*
// in a new scene (since we also reset the screen rectangle at Scene::open())
// for the case of the actor not moving
+
if (_vm->_scene->getSetId() == _setId
&& !_isInvisible
- && _vm->_sceneObjects->findById(_id + kSceneObjectOffsetActors) != -1
- && (_vm->_sceneObjects->isEmptyScreenRectangle(_id + kSceneObjectOffsetActors)
- || _vm->_sceneObjects->compareScreenRectangle(_id + kSceneObjectOffsetActors, _screenRectangle) != 0)
- ) {
- if (isVisible) {
- Vector3 pos = getPosition();
- int facing = getFacing();
- setAtXYZ(pos, facing, false, _isMoving, false);
- } else {
- resetScreenRectangleAndBbox();
- _vm->_sceneObjects->resetScreenRectangleAndBbox(_id + kSceneObjectOffsetActors);
+ && _vm->_sceneObjects->findById(_id + kSceneObjectOffsetActors) != -1) {
+ if (_vm->_sceneObjects->isEmptyScreenRectangle(_id + kSceneObjectOffsetActors)) {
+ if (isVisible) {
+ Vector3 pos = getPosition();
+ int facing = getFacing();
+ setAtXYZ(pos, facing, true, _isMoving, _isRetired);
+ } else {
+ resetScreenRectangleAndBbox();
+ _vm->_sceneObjects->resetScreenRectangleAndBbox(_id + kSceneObjectOffsetActors);
+ }
+ } else if (_vm->_sceneObjects->compareScreenRectangle(_id + kSceneObjectOffsetActors, _screenRectangle) != 0) {
+ if (isVisible) {
+ // keep actor's _screenRectangle synched with sceneObject's actor's screen rectange
+ // don't do a setAtXYZ here though
+ _vm->_sceneObjects->synchScreenRectangle(_id + kSceneObjectOffsetActors, _screenRectangle);
+ } else {
+ resetScreenRectangleAndBbox();
+ _vm->_sceneObjects->resetScreenRectangleAndBbox(_id + kSceneObjectOffsetActors);
+ }
}
}
@@ -965,7 +989,7 @@ void Actor::setFacing(int facing, bool halfOrSet) {
}
void Actor::setBoundingBox(const Vector3 &position, bool retired) {
- if (retired) {
+ if (retired || _isRetired) {
_bbox.setXYZ(position.x - (_retiredWidth / 2.0f),
position.y,
position.z - (_retiredWidth / 2.0f),
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index 1e7169dccf..36bfde8e32 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -140,6 +140,7 @@ public:
Vector3 getPosition() const { return _position; }
void changeAnimationMode(int animationMode, bool force = false);
+ int getFPS() const;
void setFPS(int fps);
void increaseFPS();
diff --git a/engines/bladerunner/boundingbox.cpp b/engines/bladerunner/boundingbox.cpp
index 40b7d4285a..eceac7b255 100644
--- a/engines/bladerunner/boundingbox.cpp
+++ b/engines/bladerunner/boundingbox.cpp
@@ -26,6 +26,11 @@
namespace BladeRunner {
+// TO VERIFY
+// First vertex is typically the bottom left point (x0, y0, z0)
+// and second vertex is the top right (x1, y1, z1)
+// Hence, we also assume that x0 < x1, y0 < y1 and z0 < z1 (ie. see how the inside() method makes its calculation)
+// TODO Maybe add a check here to catch any exceptions?
BoundingBox::BoundingBox(float x0, float y0, float z0, float x1, float y1, float z1) {
_vertices[0].x = x0;
_vertices[0].y = y0;
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index c0ac863dc2..7247e95da6 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -2056,11 +2056,12 @@ bool Debugger::cmdList(int argc, const char **argv) {
sceneObject->isPresent? "T" : "F",
sceneObject->isObstacle? "T" : "F",
sceneObject->isMoving? "T" : "F");
- debugPrintf(" Goal: %d, Set: %d, Anim mode: %d id:%d showDmg: %s inCombat: %s\n",
+ debugPrintf(" Goal: %d, Set: %d, Anim mode: %d id:%d fps: %d showDmg: %s inCombat: %s\n",
actor->getGoal(),
actor->getSetId(),
actor->getAnimationMode(),
actor->getAnimationId(),
+ actor->getFPS(),
actor->getFlagDamageAnimIfMoving()? "T" : "F",
actor->inCombat()? "T" : "F");
debugPrintf(" Pos(%02.2f,%02.2f,%02.2f)\n",
diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h
index 7b8f040b82..951e9784fd 100644
--- a/engines/bladerunner/game_constants.h
+++ b/engines/bladerunner/game_constants.h
@@ -3496,17 +3496,19 @@ enum GoalFreeSlotA { // Rat A
kGoalFreeSlotAAct5Default = 400,
kGoalFreeSlotAAct5Prepare = 405,
kGoalFreeSlotAAct5KP02Attack = 406,
+ kGoalFreeSlotAGoneIntermediate = 411,
kGoalFreeSlotAGone = 599
};
enum GoalFreeSlotB { // Rat B
- kGoalFreeSlotBAct4Default = 300,
- kGoalFreeSlotBAct4WalkAround = 301,
- kGoalFreeSlotBAct4AttackMcCoy = 302,
- kGoalFreeSlotBAct5Default = 400,
- kGoalFreeSlotBAct5Prepare = 405,
- kGoalFreeSlotBAct5KP02Attack = 406,
- kGoalFreeSlotBGone = 599
+ kGoalFreeSlotBAct4Default = 300,
+ kGoalFreeSlotBAct4WalkAround = 301,
+ kGoalFreeSlotBAct4AttackMcCoy = 302,
+ kGoalFreeSlotBAct5Default = 400,
+ kGoalFreeSlotBAct5Prepare = 405,
+ kGoalFreeSlotBAct5KP02Attack = 406,
+ kGoalFreeSlotBGoneIntermediate = 411,
+ kGoalFreeSlotBGone = 599
};
enum GoalMaggie {
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index 6f091c21d2..d19ed41ef8 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -373,6 +373,17 @@ void SceneObjects::resetScreenRectangleAndBbox(int sceneObjectId) {
}
}
+void SceneObjects::synchScreenRectangle(int sceneObjectId, const Common::Rect &targetScreenRect) {
+ int index = findById(sceneObjectId);
+ if (index != -1) {
+ SceneObject *sceneObject = &_sceneObjects[index];
+ sceneObject->screenRectangle.left = targetScreenRect.left;
+ sceneObject->screenRectangle.top = targetScreenRect.top;
+ sceneObject->screenRectangle.right = targetScreenRect.right;
+ sceneObject->screenRectangle.bottom = targetScreenRect.bottom;
+ }
+}
+
void SceneObjects::save(SaveFileWriteStream &f) {
f.writeInt(_count);
for (int i = 0; i < kSceneObjectCount; ++i) {
diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h
index a4471162e7..10b1b1d2d1 100644
--- a/engines/bladerunner/scene_objects.h
+++ b/engines/bladerunner/scene_objects.h
@@ -93,6 +93,7 @@ public:
bool isEmptyScreenRectangle(int sceneObjectId);
int compareScreenRectangle(int sceneObjectId, const Common::Rect &rectangle);
void resetScreenRectangleAndBbox(int sceneObjectId);
+ void synchScreenRectangle(int sceneObjectId, const Common::Rect &targetScreenRect);
void save(SaveFileWriteStream &f);
void load(SaveFileReadStream &f);
diff --git a/engines/bladerunner/script/ai/free_slot_a.cpp b/engines/bladerunner/script/ai/free_slot_a.cpp
index 2cd9df1259..7cc0e59580 100644
--- a/engines/bladerunner/script/ai/free_slot_a.cpp
+++ b/engines/bladerunner/script/ai/free_slot_a.cpp
@@ -106,7 +106,11 @@ bool AIScriptFreeSlotA::Update() {
if (Actor_Query_Which_Set_In(kActorFreeSlotA) != Player_Query_Current_Set()) {
Game_Flag_Reset(kFlagRatWalkingAround);
Game_Flag_Reset(kFlagUG15BridgeWillBreak);
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotADefault);
+#else
+ Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGoneIntermediate);
+#endif
}
break;
@@ -143,7 +147,11 @@ bool AIScriptFreeSlotA::Update() {
if (Actor_Query_Goal_Number(kActorFreeSlotA) == kGoalFreeSlotAGone) {
if (Actor_Query_Which_Set_In(kActorFreeSlotA) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotA);
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Default);
+#else
+ Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGoneIntermediate);
+#endif
return true;
}
}
@@ -244,11 +252,10 @@ void AIScriptFreeSlotA::OtherAgentExitedThisSet(int otherActorId) {
if (Global_Variable_Query(kVariableChapter) == 4) {
Game_Flag_Reset(kFlagRatWalkingAround);
Game_Flag_Reset(kFlagUG15BridgeWillBreak);
- Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotADefault);
} else if (Global_Variable_Query(kVariableChapter) == 5) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotA);
- Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Default);
}
+ Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGoneIntermediate);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// return false;
@@ -267,6 +274,12 @@ void AIScriptFreeSlotA::ShotAtAndMissed() {
bool AIScriptFreeSlotA::ShotAtAndHit() {
if (Actor_Query_In_Set(kActorFreeSlotA, kSetUG15)) {
checkIfOnBridge();
+ // This goal "kGoalFreeSlotAUG15Die" circumvents the proper process
+ // a proper combat with the rat and it dying when its health reaches <= 0
+ // ie. being "retired".
+ // Thus, since the rat never actually 'dies' from being shot,
+ // its Actor::retire() is not called in this case (UG15 bridge rat),
+ // and so its bounding box is not affected. Thus, the rat corpse remains clickable.
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15Die);
return true;
}
@@ -385,8 +398,23 @@ bool AIScriptFreeSlotA::GoalChanged(int currentGoalNumber, int newGoalNumber) {
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
+#if BLADERUNNER_ORIGINAL_BUGS
+#else
+ case kGoalFreeSlotAGoneIntermediate:
+ Actor_Set_Health(kActorFreeSlotA, 20, 20);
+ if (Global_Variable_Query(kVariableChapter) == 4) {
+ Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotADefault);
+ } else if (Global_Variable_Query(kVariableChapter) == 5) {
+ Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Default);
+ }
+ break;
+#endif
+
case kGoalFreeSlotAGone:
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Health(kActorFreeSlotA, 20, 20);
+#endif
+ // A bug? What does this friendliness affect?
Actor_Set_Friendliness_To_Other(kActorFreeSlotA, kActorMcCoy, 40);
break;
diff --git a/engines/bladerunner/script/ai/free_slot_b.cpp b/engines/bladerunner/script/ai/free_slot_b.cpp
index 3093bc32ae..639d3d8c91 100644
--- a/engines/bladerunner/script/ai/free_slot_b.cpp
+++ b/engines/bladerunner/script/ai/free_slot_b.cpp
@@ -81,7 +81,11 @@ bool AIScriptFreeSlotB::Update() {
case kGoalFreeSlotBGone:
if (Actor_Query_Which_Set_In(kActorFreeSlotB) != Player_Query_Current_Set()) {
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
+#else
+ Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGoneIntermediate);
+#endif
}
break;
@@ -104,7 +108,11 @@ bool AIScriptFreeSlotB::Update() {
if (Actor_Query_Goal_Number(kActorFreeSlotB) == kGoalFreeSlotBGone) {
if (Actor_Query_Which_Set_In(kActorFreeSlotB) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotB);
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Default);
+#else
+ Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGoneIntermediate);
+#endif
return true;
}
}
@@ -184,12 +192,10 @@ void AIScriptFreeSlotB::OtherAgentEnteredThisSet(int otherActorId) {
void AIScriptFreeSlotB::OtherAgentExitedThisSet(int otherActorId) {
#if !BLADERUNNER_ORIGINAL_BUGS
if (otherActorId == kActorMcCoy && Actor_Query_Goal_Number(kActorFreeSlotB) == kGoalFreeSlotBGone) {
- if (Global_Variable_Query(kVariableChapter) == 4) {
- Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
- } else if (Global_Variable_Query(kVariableChapter) == 5) {
+ if (Global_Variable_Query(kVariableChapter) == 5) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotB);
- Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Default);
}
+ Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGoneIntermediate);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
@@ -250,8 +256,22 @@ bool AIScriptFreeSlotB::GoalChanged(int currentGoalNumber, int newGoalNumber) {
AI_Movement_Track_Repeat(kActorFreeSlotB);
break;
+#if BLADERUNNER_ORIGINAL_BUGS
+#else
+ case kGoalFreeSlotBGoneIntermediate:
+ Actor_Set_Health(kActorFreeSlotB, 20, 20);
+ if (Global_Variable_Query(kVariableChapter) == 4) {
+ Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
+ } else if (Global_Variable_Query(kVariableChapter) == 5) {
+ Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Default);
+ }
+ break;
+#endif
+
case kGoalFreeSlotBGone:
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Health(kActorFreeSlotB, 20, 20);
+#endif
break;
default:
diff --git a/engines/bladerunner/script/ai/mutant1.cpp b/engines/bladerunner/script/ai/mutant1.cpp
index f88f741275..fd6f518163 100644
--- a/engines/bladerunner/script/ai/mutant1.cpp
+++ b/engines/bladerunner/script/ai/mutant1.cpp
@@ -372,6 +372,9 @@ bool AIScriptMutant1::GoalChanged(int currentGoalNumber, int newGoalNumber) {
Actor_Set_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 45);
}
+ // code repeated also in case 599 which precedes this one
+ // redundant?
+ // results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, -10);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
@@ -387,7 +390,8 @@ bool AIScriptMutant1::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 599:
AI_Movement_Track_Flush(kActorMutant1);
- Actor_Change_Animation_Mode(kActorMutant1, 48);
+ Actor_Change_Animation_Mode(kActorMutant1, kAnimationModeDie);
+ // results in additional reduction in friendlinees and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, -10);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
diff --git a/engines/bladerunner/script/ai/mutant2.cpp b/engines/bladerunner/script/ai/mutant2.cpp
index 0a6e85f293..76de5e6ee5 100644
--- a/engines/bladerunner/script/ai/mutant2.cpp
+++ b/engines/bladerunner/script/ai/mutant2.cpp
@@ -71,7 +71,12 @@ bool AIScriptMutant2::Update() {
case 599:
if (Actor_Query_Which_Set_In(kActorMutant2) != Player_Query_Current_Set()) {
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorMutant2, 403);
+#else
+ // intermediate goal to set new Health (revive for reuse)
+ Actor_Set_Goal_Number(kActorMutant2, 411);
+#endif // BLADERUNNER_ORIGINAL_BUGS
}
break;
}
@@ -337,6 +342,38 @@ bool AIScriptMutant2::GoalChanged(int currentGoalNumber, int newGoalNumber) {
}
return true;
+#if BLADERUNNER_ORIGINAL_BUGS
+#else
+ case 411:
+ // We need the additional intermediate goal 411 (as mutant1 has)
+ // so that we set the health here, instead of the when the goal is set to 599 (dying)
+ // Setting the health "revives" the mutant, which would result in their bound box being reduced to a point
+ // (see Actor::setHealth() call to retire(false, 0, 0, -1))
+ // and thus their corpse being unclickable after McCoy shot them.
+ // Goal 411 does this, but is set only when McCoy is no longer present in the scene/set.
+ AI_Movement_Track_Flush(kActorMutant2);
+ Actor_Set_Intelligence(kActorMutant2, 20);
+ Actor_Set_Health(kActorMutant2, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
+
+ if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
+ Actor_Set_Combat_Aggressiveness(kActorMutant2, 60);
+ Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 30);
+ } else {
+ Actor_Set_Combat_Aggressiveness(kActorMutant2, 40);
+ Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 50);
+ }
+
+ // code repeated also in case 599 which precedes this one
+ // redundant?
+ // results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
+ Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, -15);
+ Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
+ Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
+ Actor_Modify_Combat_Aggressiveness(kActorMutant3, 15);
+ Actor_Set_Goal_Number(kActorMutant2, 403);
+ return true;
+#endif // BLADERUNNER_ORIGINAL_BUGS
+
case 590:
AI_Movement_Track_Flush(kActorMutant2);
AI_Movement_Track_Append(kActorMutant2, 39, 100);
@@ -345,9 +382,10 @@ bool AIScriptMutant2::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 599:
AI_Movement_Track_Flush(kActorMutant2);
- Actor_Change_Animation_Mode(kActorMutant2, 48);
+ Actor_Change_Animation_Mode(kActorMutant2, kAnimationModeDie);
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Intelligence(kActorMutant2, 20);
- Actor_Set_Health(71, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
+ Actor_Set_Health(kActorMutant2, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 60);
@@ -356,7 +394,8 @@ bool AIScriptMutant2::GoalChanged(int currentGoalNumber, int newGoalNumber) {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 40);
Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 50);
}
-
+#endif // BLADERUNNER_ORIGINAL_BUGS
+ // results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, -15);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
diff --git a/engines/bladerunner/script/ai/mutant3.cpp b/engines/bladerunner/script/ai/mutant3.cpp
index b7aca072ee..f435754172 100644
--- a/engines/bladerunner/script/ai/mutant3.cpp
+++ b/engines/bladerunner/script/ai/mutant3.cpp
@@ -71,7 +71,12 @@ bool AIScriptMutant3::Update() {
case 599:
if (Actor_Query_Which_Set_In(kActorMutant3) != Player_Query_Current_Set()) {
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorMutant3, 403);
+#else
+ // intermediate goal to set new Health (revive for reuse)
+ Actor_Set_Goal_Number(kActorMutant3, 411);
+#endif // BLADERUNNER_ORIGINAL_BUGS
}
break;
}
@@ -348,6 +353,38 @@ bool AIScriptMutant3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
}
break;
+#if BLADERUNNER_ORIGINAL_BUGS
+#else
+ case 411:
+ // We need the additional intermediate goal 411 (as mutant1 has)
+ // so that we set the health here, instead of the when the goal is set to 599 (dying)
+ // Setting the health "revives" the mutant, which would result in their bound box being reduced to a point
+ // (see Actor::setHealth() call to retire(false, 0, 0, -1))
+ // and thus their corpse being unclickable after McCoy shot them.
+ // Goal 411 does this, but is set only when McCoy is no longer present in the scene/set.
+ AI_Movement_Track_Flush(kActorMutant3);
+ Actor_Set_Intelligence(kActorMutant3, 40);
+ Actor_Set_Health(kActorMutant3, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
+
+ if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
+ Actor_Set_Combat_Aggressiveness(kActorMutant3, 80);
+ Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 20);
+ } else {
+ Actor_Set_Combat_Aggressiveness(kActorMutant3, 50);
+ Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 40);
+ }
+
+ // code repeated also in case 599 which precedes this one
+ // redundant?
+ // results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
+ Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 20);
+ Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 15);
+ Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
+ Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
+ Actor_Set_Goal_Number(kActorMutant3, 403);
+ return true;
+#endif // BLADERUNNER_ORIGINAL_BUGS
+
case 590:
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 39, 100);
@@ -356,7 +393,8 @@ bool AIScriptMutant3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 599:
AI_Movement_Track_Flush(kActorMutant3);
- Actor_Change_Animation_Mode(kActorMutant3, 48);
+ Actor_Change_Animation_Mode(kActorMutant3, kAnimationModeDie);
+#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Intelligence(kActorMutant3, 40);
Actor_Set_Health(kActorMutant3, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
@@ -367,7 +405,8 @@ bool AIScriptMutant3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
Actor_Set_Combat_Aggressiveness(kActorMutant3, 50);
Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 40);
}
-
+#endif // BLADERUNNER_ORIGINAL_BUGS
+ // results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 20);
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 15);
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
diff --git a/engines/bladerunner/script/ai/officer_grayford.cpp b/engines/bladerunner/script/ai/officer_grayford.cpp
index c92790be78..5efcf6abaf 100644
--- a/engines/bladerunner/script/ai/officer_grayford.cpp
+++ b/engines/bladerunner/script/ai/officer_grayford.cpp
@@ -914,10 +914,22 @@ bool AIScriptOfficerGrayford::GoalChanged(int currentGoalNumber, int newGoalNumb
return true;
case kGoalOfficerGrayfordDead:
+#if BLADERUNNER_ORIGINAL_BUGS
_animationState = 32;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationOfficerGrayfordShotDead) - 1;
- return true;
-
+#else
+ // The original code sets Grayford flat "dead" immediately when he is "retired"
+ // His full death animation will not play, only the last frame.
+ // This is useful for Act5, where he should lie dying down (underground railway UG05),
+ // but looks bad in Act4 if McCoy shoots a Grayford cop hunting him
+ if (Game_Flag_Query(kFlagHF07Hole)
+ && Actor_Query_In_Set(kActorOfficerGrayford, kSetUG05)) {
+ _animationState = 32;
+ _animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationOfficerGrayfordShotDead) - 1;
+ return true;
+ }
+ return false;
+#endif
}
return false;
}
@@ -1549,6 +1561,7 @@ bool AIScriptOfficerGrayford::ChangeAnimationMode(int mode) {
break;
case kAnimationModeDie:
+#if BLADERUNNER_ORIGINAL_BUGS
switch (_animationState) {
case 0:
// fall through
@@ -1575,6 +1588,44 @@ bool AIScriptOfficerGrayford::ChangeAnimationMode(int mode) {
_animationFrame = 0;
break;
}
+#else
+ switch (_animationState) {
+ case 5:
+ // fall through
+ case 6:
+ // fall through
+ case 18:
+ // fall through
+ case 19:
+ // fall through
+ case 20:
+ // fall through
+ case 21:
+ // fall through
+ case 22:
+ // fall through
+ case 23:
+ // fall through
+ case 24:
+ // fall through
+ case 27:
+ // fall through
+ case 28:
+ // fall through
+ case 29:
+ // fall through
+ case 30:
+ // For all the states using combat animation (incl. holster/unholster gun)
+ _animationState = 31; // combat shot dead
+ _animationFrame = 0;
+ break;
+
+ default:
+ _animationState = 32; // shot dead
+ _animationFrame = 0;
+ break;
+ }
+#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 58:
More information about the Scummvm-git-logs
mailing list