aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/bladerunner/actor.cpp255
-rw-r--r--engines/bladerunner/actor.h45
-rw-r--r--engines/bladerunner/actor_walk.cpp14
-rw-r--r--engines/bladerunner/actor_walk.h1
-rw-r--r--engines/bladerunner/bladerunner.cpp436
-rw-r--r--engines/bladerunner/bladerunner.h39
-rw-r--r--engines/bladerunner/boundingbox.cpp4
-rw-r--r--engines/bladerunner/boundingbox.h1
-rw-r--r--engines/bladerunner/combat.cpp28
-rw-r--r--engines/bladerunner/combat.h15
-rw-r--r--engines/bladerunner/game_constants.h20
-rw-r--r--engines/bladerunner/item.cpp22
-rw-r--r--engines/bladerunner/item.h8
-rw-r--r--engines/bladerunner/items.cpp35
-rw-r--r--engines/bladerunner/items.h5
-rw-r--r--engines/bladerunner/mouse.cpp76
-rw-r--r--engines/bladerunner/mouse.h1
-rw-r--r--engines/bladerunner/movement_track.cpp16
-rw-r--r--engines/bladerunner/movement_track.h14
-rw-r--r--engines/bladerunner/scene.cpp6
-rw-r--r--engines/bladerunner/scene_objects.cpp93
-rw-r--r--engines/bladerunner/scene_objects.h20
-rw-r--r--engines/bladerunner/script/ai/leon.cpp9
-rw-r--r--engines/bladerunner/script/ai/maggie.cpp9
-rw-r--r--engines/bladerunner/script/ai/mccoy.cpp21
-rw-r--r--engines/bladerunner/script/ai/officer_leary.cpp3
-rw-r--r--engines/bladerunner/script/ai/runciter.cpp27
-rw-r--r--engines/bladerunner/script/ai_script.cpp29
-rw-r--r--engines/bladerunner/script/ai_script.h7
-rw-r--r--engines/bladerunner/script/scene_script.cpp11
-rw-r--r--engines/bladerunner/script/scene_script.h6
-rw-r--r--engines/bladerunner/script/script.cpp76
-rw-r--r--engines/bladerunner/set.cpp1
-rw-r--r--engines/bladerunner/settings.cpp44
-rw-r--r--engines/bladerunner/settings.h27
-rw-r--r--engines/bladerunner/ui/kia.cpp16
-rw-r--r--engines/bladerunner/vector.h17
37 files changed, 1049 insertions, 408 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index 4d66d74f5e..14c8ef9563 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -82,10 +82,10 @@ void Actor::setup(int actorId) {
_animationId = 0;
_animationFrame = 0;
_fps = 15;
- _frame_ms = 1000 / _fps;
+ _frameMs = 1000 / _fps;
_isMoving = false;
- _isTargetable = false;
+ _isTarget = false;
_inCombat = false;
_isInvisible = false;
_isImmuneToObstacles = false;
@@ -101,8 +101,8 @@ void Actor::setup(int actorId) {
_movementTrackDelayOnNextWaypoint = -1;
for (int i = 0; i != 7; ++i) {
- _timersRemain[i] = 0;
- _timersStart[i] = _vm->getTotalPlayTime();
+ _timersLeft[i] = 0;
+ _timersLast[i] = _vm->getTotalPlayTime();
}
_honesty = 50;
@@ -120,7 +120,9 @@ void Actor::setup(int actorId) {
_movementTrackNextAngle = -1;
_movementTrackNextRunning = false;
- _timersRemain[4] = 60000;
+ // Timer for exchanging clues
+ _timersLeft[4] = 60000;
+
_animationMode = -1;
_screenRectangle = Common::Rect(-1, -1, -1, -1);
@@ -154,73 +156,76 @@ void Actor::setFPS(int fps) {
_fps = fps;
if (fps == 0) {
- _frame_ms = 0;
+ _frameMs = 0;
} else if (fps == -1) {
- _frame_ms = -1000;
+ _frameMs = -1000;
} else if (fps == -2) {
_fps = _vm->_sliceAnimations->getFPS(_animationId);
- _frame_ms = 1000 / _fps;
+ _frameMs = 1000 / _fps;
} else {
- _frame_ms = 1000 / fps;
+ _frameMs = 1000 / fps;
}
}
-void Actor::countdownTimerStart(int timerId, int interval) {
+void Actor::increaseFPS() {
+ int fps = MIN(_fps + 3, 30);
+ setFPS(fps);
+}
+
+void Actor::timerStart(int timerId, int interval) {
assert(timerId >= 0 && timerId < 7);
- _timersRemain[timerId] = interval;
- _timersStart[timerId] = _vm->getTotalPlayTime();
+ _timersLeft[timerId] = interval;
+ _timersLast[timerId] = _vm->getTotalPlayTime();
}
-void Actor::countdownTimerReset(int timerId) {
+void Actor::timerReset(int timerId) {
assert(timerId >= 0 && timerId < 7);
- _timersRemain[timerId] = 0;
+ _timersLeft[timerId] = 0;
}
-int Actor::countdownTimerGetRemainingTime(int timerId) {
+int Actor::timerLeft(int timerId) {
assert(timerId >= 0 && timerId < 7);
- return _timersRemain[timerId];
+ return _timersLeft[timerId];
}
-void Actor::countdownTimersUpdate() {
+void Actor::timersUpdate() {
for (int i = 0; i <= 6; i++) {
- countdownTimerUpdate(i);
+ timerUpdate(i);
}
}
-void Actor::countdownTimerUpdate(int timerId) {
- if (_timersRemain[timerId] == 0) {
+void Actor::timerUpdate(int timerId) {
+ if (_timersLeft[timerId] == 0) {
return;
}
- uint32 now = _vm->getTotalPlayTime();
- int tickInterval = now - _timersStart[timerId];
- _timersStart[timerId] = now;
+ uint32 timeNow = _vm->getTotalPlayTime();
+ int timeDiff = timeNow - _timersLast[timerId];
+ _timersLast[timerId] = timeNow;
+ _timersLeft[timerId] -= timeDiff;
- //warning("tickInterval: %d", tickInterval);
- _timersRemain[timerId] -= tickInterval;
-
- if (_timersRemain[timerId] <= 0) {
+ if (_timersLeft[timerId] <= 0) {
switch (timerId) {
case 0:
case 1:
case 2:
if (!_vm->_aiScripts->isInsideScript() && !_vm->_sceneScript->isInsideScript()) {
- _vm->_aiScripts->timerExpired(this->_id, timerId);
- this->_timersRemain[timerId] = 0;
+ _vm->_aiScripts->timerExpired(_id, timerId);
+ _timersLeft[timerId] = 0;
} else {
- this->_timersRemain[timerId] = 1;
+ _timersLeft[timerId] = 1;
}
break;
case 3:
- _timersRemain[3] = 0;
+ _timersLeft[3] = 0;
if (_movementTrack->isPaused()) {
- _timersRemain[3] = 1;
+ _timersLeft[3] = 1;
} else {
movementTrackNext(false);
}
break;
case 4:
- // Something timer
+ // Exchange clues between actors
break;
case 5:
// Actor animation frame timer
@@ -235,7 +240,7 @@ void Actor::countdownTimerUpdate(int timerId) {
setFPS(newFps);
}
}
- _timersRemain[6] = 200;
+ _timersLeft[6] = 200;
break;
}
}
@@ -244,18 +249,18 @@ void Actor::countdownTimerUpdate(int timerId) {
void Actor::movementTrackNext(bool omitAiScript) {
bool hasNextMovement;
int waypointSetId;
- int running;
+ bool run;
int angle;
int delay;
int waypointId;
Vector3 waypointPosition;
bool arrived;
- hasNextMovement = _movementTrack->next(&waypointId, &delay, &angle, &running);
+ hasNextMovement = _movementTrack->next(&waypointId, &delay, &angle, &run);
_movementTrackNextWaypointId = waypointId;
_movementTrackNextDelay = delay;
_movementTrackNextAngle = angle;
- _movementTrackNextRunning = running;
+ _movementTrackNextRunning = run;
if (hasNextMovement) {
if (angle == -1) {
angle = 0;
@@ -264,7 +269,7 @@ void Actor::movementTrackNext(bool omitAiScript) {
_vm->_waypoints->getXYZ(waypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
if (_setId == waypointSetId && waypointSetId == _vm->_actors[0]->_setId) {
stopWalking(false);
- _walkInfo->setup(_id, running, _position, waypointPosition, false, &arrived);
+ _walkInfo->setup(_id, run, _position, waypointPosition, false, &arrived);
_movementTrackWalkingToWaypointId = waypointId;
_movementTrackDelayOnNextWaypoint = delay;
@@ -281,7 +286,7 @@ void Actor::movementTrackNext(bool omitAiScript) {
if (delay > 1) {
changeAnimationMode(kAnimationModeIdle, false);
}
- countdownTimerStart(3, delay);
+ timerStart(3, delay);
}
//return true;
} else {
@@ -315,19 +320,18 @@ void Actor::movementTrackUnpause() {
}
void Actor::movementTrackWaypointReached() {
- int seconds;
if (!_movementTrack->isPaused() && _id != kActorMcCoy) {
- if (_movementTrackWalkingToWaypointId >= 0 && _movementTrackDelayOnNextWaypoint) {
+ if (_movementTrackWalkingToWaypointId >= 0 && _movementTrackDelayOnNextWaypoint >= 0) {
if (!_movementTrackDelayOnNextWaypoint) {
_movementTrackDelayOnNextWaypoint = 1;
}
if (_vm->_aiScripts->reachedMovementTrackWaypoint(_id, _movementTrackWalkingToWaypointId)) {
- seconds = _movementTrackDelayOnNextWaypoint;
- if (seconds > 1) {
+ int delay = _movementTrackDelayOnNextWaypoint;
+ if (delay > 1) {
changeAnimationMode(kAnimationModeIdle, false);
- seconds = _movementTrackDelayOnNextWaypoint; // todo: analyze if movement is changed in some aiscript->ChangeAnimationMode?
+ delay = _movementTrackDelayOnNextWaypoint; // todo: analyze if movement is changed in some aiscript->ChangeAnimationMode?
}
- countdownTimerStart(3, seconds);
+ timerStart(3, delay);
}
}
_movementTrackWalkingToWaypointId = -1;
@@ -350,7 +354,7 @@ void Actor::setAtXYZ(const Vector3 &position, int facing, bool snapFacing, bool
_vm->_sceneObjects->remove(_id + kSceneObjectOffsetActors);
if (_vm->_scene->getSetId() == _setId) {
- _vm->_sceneObjects->addActor(_id + kSceneObjectOffsetActors, _bbox, &_screenRectangle, 1, moving, _isTargetable, retired);
+ _vm->_sceneObjects->addActor(_id + kSceneObjectOffsetActors, _bbox, &_screenRectangle, 1, moving, _isTarget, retired);
}
}
@@ -360,8 +364,8 @@ void Actor::setAtWaypoint(int waypointId, int angle, int moving, bool retired) {
setAtXYZ(waypointPosition, angle, true, moving, retired);
}
-bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, const Vector3 &start, float targetWidth, float targetSize, bool a8, bool *flagIsRunning, bool async) {
- *flagIsRunning = false;
+bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, const Vector3 &start, float targetWidth, float targetSize, bool a8, bool *isRunning, bool async) {
+ *isRunning = false;
if (destinationOffset > 0) {
float dist = distance(_position, destination);
@@ -397,7 +401,7 @@ bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool int
}
if (!walking) {
- faceXYZ(destination.x, destination.y, destination.z, false);
+ faceXYZ(destination, false);
return false;
}
@@ -406,8 +410,8 @@ bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool int
}
if (interruptible) {
- _vm->_isWalkingInterruptible = 1;
- _vm->_interruptWalking = 0;
+ _vm->_isWalkingInterruptible = true;
+ _vm->_interruptWalking = false;
} else {
_vm->playerLosesControl();
}
@@ -419,7 +423,7 @@ bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool int
bool wasInterrupted = false;
while (_walkInfo->isWalking() && _vm->_gameIsRunning) {
if (_walkInfo->isRunning()) {
- *flagIsRunning = true;
+ *isRunning = true;
}
_vm->gameTick();
if (_id == kActorMcCoy && interruptible && _vm->_interruptWalking) {
@@ -450,21 +454,21 @@ bool Actor::walkTo(bool run, const Vector3 &destination, bool a3) {
return _walkInfo->setup(_id, run, _position, destination, a3, &arrived);
}
-bool Actor::loopWalkToActor(int otherActorId, int destinationOffset, int interruptible, bool run, bool a5, bool *flagIsRunning) {
- return loopWalk(_vm->_actors[otherActorId]->_position, destinationOffset, interruptible, run, _position, 24.0f, 24.0f, a5, flagIsRunning, false);
+bool Actor::loopWalkToActor(int otherActorId, int destinationOffset, int interruptible, bool run, bool a5, bool *isRunning) {
+ return loopWalk(_vm->_actors[otherActorId]->_position, destinationOffset, interruptible, run, _position, 24.0f, 24.0f, a5, isRunning, false);
}
-bool Actor::loopWalkToItem(int itemId, int destinationOffset, int interruptible, bool run, bool a5, bool *flagIsRunning) {
+bool Actor::loopWalkToItem(int itemId, int destinationOffset, int interruptible, bool run, bool a5, bool *isRunning) {
float x, y, z;
int width, height;
_vm->_items->getXYZ(itemId, &x, &y, &z);
_vm->_items->getWidthHeight(itemId, &width, &height);
Vector3 itemPosition(x, y, z);
- return loopWalk(itemPosition, destinationOffset, interruptible, run, _position, width, 24.0f, a5, flagIsRunning, false);
+ return loopWalk(itemPosition, destinationOffset, interruptible, run, _position, width, 24.0f, a5, isRunning, false);
}
-bool Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset, bool interruptible, bool run, bool a5, bool *flagIsRunning) {
+bool Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset, bool interruptible, bool run, bool a5, bool *isRunning) {
int sceneObject = _vm->_scene->_set->findObject(objectName);
if (sceneObject < 0) {
return true;
@@ -506,41 +510,45 @@ bool Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset,
float y = _vm->_scene->_set->getAltitudeAtXZ(closestX, closestZ, &inWalkbox);
Vector3 destination(closestX, y, closestZ);
- return loopWalk(destination, destinationOffset, interruptible, run, _position, 0.0f, 24.0f, a5, flagIsRunning, false);
+ return loopWalk(destination, destinationOffset, interruptible, run, _position, 0.0f, 24.0f, a5, isRunning, false);
}
-bool Actor::loopWalkToWaypoint(int waypointId, int destinationOffset, int interruptible, bool run, bool a5, bool *flagIsRunning) {
+bool Actor::loopWalkToWaypoint(int waypointId, int destinationOffset, int interruptible, bool run, bool a5, bool *isRunning) {
Vector3 waypointPosition;
_vm->_waypoints->getXYZ(waypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
- return loopWalk(waypointPosition, destinationOffset, interruptible, run, _position, 0.0f, 24.0f, a5, flagIsRunning, false);
+ return loopWalk(waypointPosition, destinationOffset, interruptible, run, _position, 0.0f, 24.0f, a5, isRunning, false);
}
-bool Actor::loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, bool a5, bool *flagIsRunning) {
- return loopWalk(destination, destinationOffset, interruptible, run, _position, 0.0f, 24.0f, a5, flagIsRunning, false);
+bool Actor::loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, bool a5, bool *isRunning) {
+ return loopWalk(destination, destinationOffset, interruptible, run, _position, 0.0f, 24.0f, a5, isRunning, false);
}
bool Actor::asyncWalkToWaypoint(int waypointId, int destinationOffset, bool run, bool a5) {
- bool flagIsRunning;
+ bool isRunning;
Vector3 waypointPosition;
_vm->_waypoints->getXYZ(waypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
- return loopWalk(waypointPosition, destinationOffset, false, run, _position, 0.0f, 24.0f, a5, &flagIsRunning, true);
+ return loopWalk(waypointPosition, destinationOffset, false, run, _position, 0.0f, 24.0f, a5, &isRunning, true);
}
void Actor::asyncWalkToXYZ(const Vector3 &destination, int destinationOffset, bool run, int a6) {
- bool flagIsRunning;
- loopWalk(destination, destinationOffset, false, run, _position, 0.0f, 24.0f, a6, &flagIsRunning, true);
+ bool isRunning;
+ loopWalk(destination, destinationOffset, false, run, _position, 0.0f, 24.0f, a6, &isRunning, true);
+}
+
+void Actor::run() {
+ _walkInfo->run(_id);
}
bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
- int remain = 0;
+ int timeLeft = 0;
bool needsUpdate = false;
if (_fps > 0) {
- countdownTimerUpdate(5);
- remain = countdownTimerGetRemainingTime(5);
- needsUpdate = remain <= 0;
+ timerUpdate(5);
+ timeLeft = timerLeft(5);
+ needsUpdate = timeLeft <= 0;
} else if (forceDraw) {
needsUpdate = true;
- remain = 0;
+ timeLeft = 0;
}
if (needsUpdate) {
@@ -570,68 +578,68 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
positionChange.y = -4.0f;
}
- this->_targetFacing = -1;
+ _targetFacing = -1;
bool walked = _walkInfo->tick(_id, -positionChange.y, false);
Vector3 pos;
int facing;
_walkInfo->getCurrentPosition(_id, &pos, &facing);
- setAtXYZ(pos, facing, false, this->_isMoving, false);
+ setAtXYZ(pos, facing, false, _isMoving, false);
if (walked) {
_vm->_actors[_id]->changeAnimationMode(kAnimationModeIdle);
- this->movementTrackWaypointReached();
- if (this->inCombat()) {
- this->changeAnimationMode(this->_animationModeCombatIdle, false);
+ movementTrackWaypointReached();
+ if (inCombat()) {
+ changeAnimationMode(_animationModeCombatIdle, false);
} else {
- this->changeAnimationMode(kAnimationModeIdle, false);
+ changeAnimationMode(kAnimationModeIdle, false);
}
}
} else {
if (angleChange != 0.0f) {
int facingChange = angleChange * (512.0f / M_PI);
if (facingChange != 0) {
- this->_facing = this->_facing - facingChange;
- if (this->_facing < 0) {
- this->_facing += 1024;
+ _facing = _facing - facingChange;
+ if (_facing < 0) {
+ _facing += 1024;
}
- if (this->_facing >= 1024) {
- this->_facing = this->_facing - 1024;
+ if (_facing >= 1024) {
+ _facing = _facing - 1024;
}
}
}
if (0.0f != positionChange.x || 0.0f != positionChange.y || 0.0f != positionChange.z) {
- if (this->_actorSpeed.x != 0.0f) {
- positionChange.x = positionChange.x * this->_actorSpeed.x;
+ if (_actorSpeed.x != 0.0f) {
+ positionChange.x = positionChange.x * _actorSpeed.x;
}
- if (this->_actorSpeed.y != 0.0f) {
- positionChange.y = positionChange.y * this->_actorSpeed.y;
+ if (_actorSpeed.y != 0.0f) {
+ positionChange.y = positionChange.y * _actorSpeed.y;
}
- if (this->_actorSpeed.z != 0.0f) {
- positionChange.z = positionChange.z * this->_actorSpeed.z;
+ if (_actorSpeed.z != 0.0f) {
+ positionChange.z = positionChange.z * _actorSpeed.z;
}
float angle = _facing * (M_PI / 512.0f);
float sinx = sin(angle);
float cosx = cos(angle);
- float originalX = this->_position.x;
- float originalY = this->_position.y;
- float originalZ = this->_position.z;
+ float originalX = _position.x;
+ float originalY = _position.y;
+ float originalZ = _position.z;
- this->_position.x = this->_position.x + positionChange.x * cosx - positionChange.y * sinx;
- this->_position.z = this->_position.z + positionChange.x * sinx + positionChange.y * cosx;
- this->_position.y = this->_position.y + positionChange.z;
+ _position.x = _position.x + positionChange.x * cosx - positionChange.y * sinx;
+ _position.z = _position.z + positionChange.x * sinx + positionChange.y * cosx;
+ _position.y = _position.y + positionChange.z;
- if (_vm->_sceneObjects->existsOnXZ(this->_id + kSceneObjectOffsetActors, this->_position.x, this->_position.z, false, false) == 1 && !this->_isImmuneToObstacles) {
- this->_position.x = originalX;
- this->_position.y = originalY;
- this->_position.z = originalZ;
+ if (_vm->_sceneObjects->existsOnXZ(_id + kSceneObjectOffsetActors, _position.x, _position.z, false, false) == 1 && !_isImmuneToObstacles) {
+ _position.x = originalX;
+ _position.y = originalY;
+ _position.z = originalZ;
}
- setAtXYZ(this->_position, this->_facing, true, this->_isMoving, this->_isRetired);
+ setAtXYZ(_position, _facing, true, _isMoving, _isRetired);
}
}
}
@@ -645,16 +653,17 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
}
if (needsUpdate) {
- int nextFrameTime = remain + _frame_ms;
- if (nextFrameTime <= 0)
+ int nextFrameTime = timeLeft + _frameMs;
+ if (nextFrameTime <= 0) {
nextFrameTime = 1;
- countdownTimerStart(5, nextFrameTime);
+ }
+ timerStart(5, nextFrameTime);
}
- if (this->_targetFacing >= 0) {
- if (this->_targetFacing == this->_facing) {
- this->_targetFacing = -1;
+ if (_targetFacing >= 0) {
+ if (_targetFacing == _facing) {
+ _targetFacing = -1;
} else {
- this->setFacing(this->_targetFacing, false);
+ setFacing(_targetFacing, false);
}
}
return isVisible;
@@ -761,8 +770,8 @@ void Actor::setBoundingBox(const Vector3 &position, bool retired) {
}
float Actor::distanceFromView(View *view) const{
- float xDist = this->_position.x - view->_cameraPosition.x;
- float zDist = this->_position.z + view->_cameraPosition.z;
+ float xDist = _position.x - view->_cameraPosition.x;
+ float zDist = _position.z + view->_cameraPosition.z;
return sqrt(xDist * xDist + zDist * zDist);
}
@@ -799,7 +808,7 @@ void Actor::faceActor(int otherActorId, bool animate) {
return;
}
- faceXYZ(otherActor->_position.x, otherActor->_position.y, otherActor->_position.z, animate);
+ faceXYZ(otherActor->_position, animate);
}
void Actor::faceObject(const char *objectName, bool animate) {
@@ -843,6 +852,10 @@ void Actor::faceXYZ(float x, float y, float z, bool animate) {
faceHeading(heading, animate);
}
+void Actor::faceXYZ(const Vector3 &pos, bool animate) {
+ faceXYZ(pos.x, pos.y, pos.z, animate);
+}
+
void Actor::faceCurrentCamera(bool animate) {
faceXYZ(_vm->_view->_cameraPosition.x, _vm->_view->_cameraPosition.y, -_vm->_view->_cameraPosition.z, animate);
}
@@ -936,8 +949,8 @@ void Actor::retire(bool retired, int width, int height, int retiredByActorId) {
}
}
-void Actor::setTargetable(bool targetable) {
- _isTargetable = targetable;
+void Actor::setTarget(bool target) {
+ _isTarget = target;
}
void Actor::setHealth(int hp, int maxHp) {
@@ -1095,6 +1108,22 @@ int Actor::soundBalance() const {
return 35.0f * (CLIP(screenPosition.x / 640.0f, 0.0f, 1.0f) * 2.0f - 1.0f);
}
+bool Actor::isObstacleBetween(float targetX, float targetZ) {
+ return _vm->_sceneObjects->isObstacleBetween(_position.x, _position.z, targetX, targetZ, _position.y, -1);
+}
+
+int Actor::findTargetUnderMouse(BladeRunnerEngine *vm, int mouseX, int mouseY) {
+ int setId = vm->_scene->getSetId();
+ for (int i = 0; i < (int)vm->_gameInfo->getActorCount(); ++i) {
+ if (vm->_actors[i]->isTarget() && vm->_actors[i]->getSetId() == setId) {
+ if (vm->_actors[i]->_screenRectangle.contains(mouseX, mouseY)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
bool Actor::walkFindU1(const Vector3 &startPosition, const Vector3 &targetPosition, float size, Vector3 *newDestination) {
newDestination->x = 0.0f;
newDestination->y = 0.0f;
@@ -1163,9 +1192,9 @@ bool Actor::walkFindU2(Vector3 *newDestination, float targetWidth, int destinati
bool Actor::walkToNearestPoint(const Vector3 &destination, float distance) {
Vector3 out;
- bool flagIsRunning;
+ bool isRunning;
if (_walkInfo->findNearestEmptyPosition(_id, destination, distance, out)) {
- loopWalk(out, 0, false, false, _position, 0.0f, 24.0f, false, &flagIsRunning, false);
+ loopWalk(out, 0, false, false, _position, 0.0f, 24.0f, false, &isRunning, false);
return true;
}
return false;
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index b160ca3238..6bbcf93be5 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -71,7 +71,7 @@ private:
int _walkboxId;
// Flags
- bool _isTargetable;
+ bool _isTarget;
bool _isInvisible;
bool _isImmuneToObstacles;
bool _inWalkLoop;
@@ -98,15 +98,15 @@ private:
int _animationModeCombatWalk;
int _animationModeCombatRun;
int _fps;
- int _frame_ms;
+ int _frameMs;
int _animationId;
int _animationFrame;
int _retiredWidth;
int _retiredHeight;
- int _timersRemain[7];
- int _timersStart[7];
+ int _timersLeft[7];
+ int _timersLast[7];
float _scale;
@@ -132,25 +132,29 @@ public:
void changeAnimationMode(int animationMode, bool force = false);
void setFPS(int fps);
+ void increaseFPS();
- void countdownTimerStart(int timerId, int interval);
- void countdownTimerReset(int timerId);
- int countdownTimerGetRemainingTime(int timerId);
- void countdownTimersUpdate();
- void countdownTimerUpdate(int timerId);
+ void timerStart(int timerId, int interval);
+ void timerReset(int timerId);
+ int timerLeft(int timerId);
+ void timersUpdate();
+ void timerUpdate(int timerId);
void movementTrackNext(bool omitAiScript);
void movementTrackPause();
void movementTrackUnpause();
void movementTrackWaypointReached();
- bool loopWalkToActor(int otherActorId, int destinationOffset, int interruptible, bool run, bool a5, bool *flagIsRunning);
- bool loopWalkToItem(int itemId, int destinationOffset, int interruptible, bool run, bool a5, bool *flagIsRunning);
- bool loopWalkToSceneObject(const char *objectName, int destinationOffset, bool interruptible, bool run, bool a5, bool *flagIsRunning);
- bool loopWalkToWaypoint(int waypointId, int destinationOffset, int interruptible, bool run, bool a5, bool *flagIsRunning);
- bool loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, bool a5, bool *flagIsRunning);
+ bool loopWalk(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, const Vector3 &start, float a6, float a7, bool a8, bool *isRunning, bool async);
+ bool walkTo(bool run, const Vector3 &destination, bool a3);
+ bool loopWalkToActor(int otherActorId, int destinationOffset, int interruptible, bool run, bool a5, bool *isRunning);
+ bool loopWalkToItem(int itemId, int destinationOffset, int interruptible, bool run, bool a5, bool *isRunning);
+ bool loopWalkToSceneObject(const char *objectName, int destinationOffset, bool interruptible, bool run, bool a5, bool *isRunning);
+ bool loopWalkToWaypoint(int waypointId, int destinationOffset, int interruptible, bool run, bool a5, bool *isRunning);
+ bool loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, bool a5, bool *isRunning);
bool asyncWalkToWaypoint(int waypointId, int destinationOffset, bool run, bool a5);
void asyncWalkToXYZ(const Vector3 &destination, int destinationOffset, bool run, int a6);
+ void run();
bool tick(bool forceUpdate, Common::Rect *screenRect);
bool draw(Common::Rect *screenRect);
@@ -161,8 +165,8 @@ public:
Common::Rect *getScreenRectangle() { return &_screenRectangle; }
int getWalkbox() const { return _walkboxId; }
bool isRetired() const { return _isRetired; }
- bool isTargetable() const { return _isTargetable; }
- void setTargetable(bool targetable);
+ bool isTarget() const { return _isTarget; }
+ void setTarget(bool targetable);
bool isImmuneToObstacles() const { return _isImmuneToObstacles; }
bool inCombat() const { return _inCombat; }
bool isMoving() const { return _isMoving; }
@@ -177,6 +181,7 @@ public:
void faceItem(int itemId, bool animate);
void faceWaypoint(int waypointId, bool animate);
void faceXYZ(float x, float y, float z, bool animate);
+ void faceXYZ(const Vector3 &pos, bool animate);
void faceCurrentCamera(bool animate);
void faceHeading(int heading, bool animate);
void modifyFriendlinessToOther(int otherActorId, signed int change);
@@ -203,7 +208,7 @@ public:
void combatModeOff();
void setGoal(int goalNumber);
- int getGoal() const;
+ int getGoal() const;
float distanceFromActor(int otherActorId);
@@ -220,14 +225,14 @@ public:
int soundVolume() const;
int soundBalance() const;
+ bool isObstacleBetween(float targetX, float targetZ);
+
+ static int findTargetUnderMouse(BladeRunnerEngine *vm, int mouseX, int mouseY);
private:
void setFacing(int facing, bool halfOrSet = true);
void setBoundingBox(const Vector3 &position, bool retired);
float distanceFromView(View *view) const;
- bool loopWalk(const Vector3 &destination, int destinationOffset, bool interruptible, bool run, const Vector3 &start, float a6, float a7, bool a8, bool *isRunning, bool async);
- bool walkTo(bool run, const Vector3 &destination, bool a3);
-
bool walkFindU1(const Vector3 &startPosition, const Vector3 &targetPosition, float a3, Vector3 *newDestination);
bool walkFindU2(Vector3 *newDestination, float targetWidth, int destinationOffset, float targetSize, const Vector3 &startPosition, const Vector3 &targetPosition);
bool walkToNearestPoint(const Vector3 &destination, float distance);
diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp
index fccc8e22b3..3a2327a8df 100644
--- a/engines/bladerunner/actor_walk.cpp
+++ b/engines/bladerunner/actor_walk.cpp
@@ -37,8 +37,8 @@ namespace BladeRunner {
ActorWalk::ActorWalk(BladeRunnerEngine *vm) {
_vm = vm;
- _walking = 0;
- _running = 0;
+ _walking = false;
+ _running = false;
_facing = -1;
_status = 0;
@@ -228,6 +228,16 @@ void ActorWalk::stop(int actorId, bool immediately, int combatAnimationMode, int
}
}
+void ActorWalk::run(int actorId) {
+ _running = true;
+
+ int animationMode = kAnimationModeRun;
+ if (_vm->_actors[actorId]->inCombat()) {
+ animationMode = kAnimationModeCombatRun;
+ }
+ _vm->_actors[actorId]->changeAnimationMode(animationMode, false);
+}
+
bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) const {
if (_vm->_scene->_set->findWalkbox(x, z) == -1) {
return true;
diff --git a/engines/bladerunner/actor_walk.h b/engines/bladerunner/actor_walk.h
index 07e383ac25..e3e48b8b76 100644
--- a/engines/bladerunner/actor_walk.h
+++ b/engines/bladerunner/actor_walk.h
@@ -58,6 +58,7 @@ public:
bool findNearestEmptyPosition(int actorId, const Vector3 &from, int distance, Vector3 &out) const;
void stop(int actorId, bool immediately, int combatAnimationMode, int animationMode);
+ void run(int actorId);
private:
int nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 &next) const;
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 5f565d972c..a45c0e6d92 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -97,7 +97,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
_gameIsLoading = false;
_sceneIsLoading = false;
- _walkingActorId = -1;
+ _runningActorId = -1;
_isWalkingInterruptible = false;
_interruptWalking = false;
@@ -178,6 +178,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
for (int i = 0; i != kActorCount; ++i) {
_actors[i] = nullptr;
}
+ walkingReset();
}
BladeRunnerEngine::~BladeRunnerEngine() {
@@ -341,8 +342,7 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_playerActor = _actors[_gameInfo->getPlayerId()];
_playerActor->setFPS(15);
-
- // TODO: set _playerActor countdown timer 6
+ _playerActor->timerStart(6, 200);
// TODO: Set actor ids (redundant?)
@@ -863,16 +863,16 @@ void BladeRunnerEngine::gameTick() {
Vector3 pos = _view->calculateScreenPosition(0.5 * (a + b));
int color;
- switch (sceneObject->sceneObjectType) {
+ switch (sceneObject->type) {
case kSceneObjectTypeActor:
color = 0b111110000000000;
drawBBox(a, b, _view, &_surfaceFront, color);
- _mainFont->drawColor(_textActorNames->getText(sceneObject->sceneObjectId - kSceneObjectOffsetActors), _surfaceFront, pos.x, pos.y, color);
+ _mainFont->drawColor(_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors), _surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeItem:
char itemText[40];
drawBBox(a, b, _view, &_surfaceFront, color);
- sprintf(itemText, "item %i", sceneObject->sceneObjectId - kSceneObjectOffsetItems);
+ sprintf(itemText, "item %i", sceneObject->id - kSceneObjectOffsetItems);
_mainFont->drawColor(itemText, _surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeObject:
@@ -883,10 +883,10 @@ void BladeRunnerEngine::gameTick() {
color = 0b000001111100000;
}
drawBBox(a, b, _view, &_surfaceFront, color);
- _mainFont->drawColor(_scene->objectGetName(sceneObject->sceneObjectId - kSceneObjectOffsetObjects), _surfaceFront, pos.x, pos.y, color);
+ _mainFont->drawColor(_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects), _surfaceFront, pos.x, pos.y, color);
break;
}
- _surfaceFront.frameRect(sceneObject->screenRectangle, color);
+ _surfaceFront.frameRect(*sceneObject->screenRectangle, color);
}
}
@@ -1001,12 +1001,31 @@ void BladeRunnerEngine::actorsUpdate() {
Actor *actor = _actors[i];
if (actor->getSetId() == setId) {
_aiScripts->update(i);
- actor->countdownTimersUpdate();
+ actor->timersUpdate();
}
}
}
}
+void BladeRunnerEngine::walkingReset() {
+ _mouseClickTimeLast = 0;
+ _mouseClickTimeDiff = 0;
+ _walkingToExitId = -1;
+ _isInsideScriptExit = false;
+ _walkingToRegionId = -1;
+ _isInsideScriptRegion = false;
+ _walkingToObjectId = -1;
+ _isInsideScriptObject = false;
+ _walkingToItemId = -1;
+ _isInsideScriptItem = false;
+ _walkingToEmpty = false;
+ _walkingToEmptyX = 0;
+ _walkingToEmptyY = 0;
+ _isInsideScriptEmpty = false;
+ _walkingToActorId = -1;
+ _isInsideScriptActor = false;
+}
+
void BladeRunnerEngine::handleEvents() {
if (shouldQuit()) {
_gameIsRunning = false;
@@ -1149,16 +1168,23 @@ void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
}
}
-void BladeRunnerEngine::handleMouseAction(int x, int y, bool buttonLeft, bool buttonDown) {
+void BladeRunnerEngine::handleMouseAction(int x, int y, bool mainButton, bool buttonDown) {
+ int timeNow = getTotalPlayTime();
+
+ if (buttonDown) {
+ _mouseClickTimeDiff = timeNow - _mouseClickTimeLast;
+ _mouseClickTimeLast = timeNow;
+ }
+
if (!playerHasControl() || _mouse->isDisabled()) {
return;
}
if (_kia->isOpen()) {
if (buttonDown) {
- _kia->handleMouseDown(x, y, buttonLeft);
+ _kia->handleMouseDown(x, y, mainButton);
} else {
- _kia->handleMouseUp(x, y, buttonLeft);
+ _kia->handleMouseUp(x, y, mainButton);
}
return;
}
@@ -1174,18 +1200,18 @@ void BladeRunnerEngine::handleMouseAction(int x, int y, bool buttonLeft, bool bu
if (_esper->isOpen()) {
if (buttonDown) {
- _esper->handleMouseDown(x, y, buttonLeft);
+ _esper->handleMouseDown(x, y, mainButton);
} else {
- _esper->handleMouseUp(x, y, buttonLeft);
+ _esper->handleMouseUp(x, y, mainButton);
}
return;
}
if (_vk->isOpen()) {
if (buttonDown) {
- _vk->handleMouseDown(x, y, buttonLeft);
+ _vk->handleMouseDown(x, y, mainButton);
} else {
- _vk->handleMouseUp(x, y, buttonLeft);
+ _vk->handleMouseUp(x, y, mainButton);
}
return;
}
@@ -1200,91 +1226,379 @@ void BladeRunnerEngine::handleMouseAction(int x, int y, bool buttonLeft, bool bu
}
if (_dialogueMenu->waitingForInput()) {
- if (buttonLeft && !buttonDown) {
+ if (mainButton && !buttonDown) {
_dialogueMenu->mouseUp();
}
return;
}
- if (buttonLeft && !buttonDown) {
+ if (mainButton) {
Vector3 scenePosition = _mouse->getXYZ(x, y);
bool isClickable;
bool isObstacle;
bool isTarget;
- int sceneObjectId = _sceneObjects->findByXYZ(&isClickable, &isObstacle, &isTarget, scenePosition.x, scenePosition.y, scenePosition.z, true, false, true);
+ int sceneObjectId = _sceneObjects->findByXYZ(&isClickable, &isObstacle, &isTarget, scenePosition, true, false, true);
int exitIndex = _scene->_exits->getRegionAtXY(x, y);
+ int regionIndex = _scene->_regions->getRegionAtXY(x, y);
- if ((sceneObjectId < 0 || sceneObjectId > 73) && exitIndex >= 0) {
- handleMouseClickExit(x, y, exitIndex);
- return;
+ if ((sceneObjectId < kSceneObjectOffsetActors || sceneObjectId >= kSceneObjectOffsetActors) && exitIndex >= 0) {
+ handleMouseClickExit(exitIndex, x, y, buttonDown);
+ } else if (regionIndex >= 0) {
+ handleMouseClickRegion(regionIndex, x, y, buttonDown);
+ } else if (sceneObjectId == -1) {
+ handleMouseClickEmpty(x, y, scenePosition, buttonDown);
+ } else if (sceneObjectId >= kSceneObjectOffsetActors && sceneObjectId < kSceneObjectOffsetItems) {
+ handleMouseClickActor(sceneObjectId - kSceneObjectOffsetActors, mainButton, buttonDown, scenePosition, x, y);
+ } else if (sceneObjectId >= kSceneObjectOffsetItems && sceneObjectId < kSceneObjectOffsetObjects) {
+ handleMouseClickItem(sceneObjectId - kSceneObjectOffsetItems, buttonDown);
+ } else if (sceneObjectId >= kSceneObjectOffsetObjects && sceneObjectId <= 293) {
+ handleMouseClick3DObject(sceneObjectId - kSceneObjectOffsetObjects, buttonDown, isClickable, isTarget);
}
-
- int regionIndex = _scene->_regions->getRegionAtXY(x, y);
- if (regionIndex >= 0) {
- handleMouseClickRegion(x, y, regionIndex);
- return;
+ } else if (buttonDown) {
+ if (_playerActor->inWalkLoop()) {
+ _playerActor->stopWalking(false);
}
+ _combat->change();
+ }
+}
- if (sceneObjectId == -1) {
- handleMouseClickEmpty(x, y, scenePosition);
- return;
- } else if (sceneObjectId >= 0 && sceneObjectId <= 73) {
- handleMouseClickActor(x, y, sceneObjectId);
- return;
- } else if (sceneObjectId >= 74 && sceneObjectId <= 197) {
- handleMouseClickItem(x, y, sceneObjectId - 74);
- return;
- } else if (sceneObjectId >= 198 && sceneObjectId <= 293) {
- handleMouseClick3DObject(x, y, sceneObjectId - 198, isClickable, isTarget);
- return;
- }
+void BladeRunnerEngine::handleMouseClickExit(int exitId, int x, int y, bool buttonDown) {
+ debug("clicked on exit %d %d %d", exitId, x, y);
+
+ if (_isWalkingInterruptible && exitId != _walkingToExitId) {
+ _isWalkingInterruptible = false;
+ _interruptWalking = true;
+ walkingReset();
+ _walkingToExitId = exitId;
+ return;
}
- if (!buttonLeft && buttonDown) {
- // TODO: stop walking && switch combat mode
+
+ if (buttonDown) {
+ return;
}
+ if (_isInsideScriptExit && exitId == _walkingToExitId) {
+ _playerActor->run();
+ if (_mouseClickTimeDiff <= 10000) {
+ _playerActor->increaseFPS();
+ }
+ } else {
+ _walkingToExitId = exitId;
+ _walkingToRegionId = -1;
+ _walkingToObjectId = -1;
+ _walkingToItemId = -1;
+ _walkingToEmpty = false;
+ _walkingToActorId = -1;
+
+ _isInsideScriptExit = true;
+ _sceneScript->clickedOnExit(exitId);
+ _isInsideScriptExit = false;
+ }
}
-void BladeRunnerEngine::handleMouseClickExit(int x, int y, int exitIndex) {
- debug("clicked on exit %d %d %d", exitIndex, x, y);
- _sceneScript->clickedOnExit(exitIndex);
-}
+void BladeRunnerEngine::handleMouseClickRegion(int regionId, int x, int y, bool buttonDown) {
+ debug("clicked on region %d %d %d", regionId, x, y);
+
+ if (_isWalkingInterruptible && regionId != _walkingToRegionId) {
+ _isWalkingInterruptible = false;
+ _interruptWalking = true;
+ walkingReset();
+ _walkingToRegionId = regionId;
+ return;
+ }
-void BladeRunnerEngine::handleMouseClickRegion(int x, int y, int regionIndex) {
- debug("clicked on region %d %d %d", regionIndex, x, y);
- _sceneScript->clickedOn2DRegion(regionIndex);
+ if (buttonDown || _mouse->isInactive()) {
+ return;
+ }
+
+ if (_isInsideScriptRegion && regionId == _walkingToRegionId) {
+ _playerActor->run();
+ if (_mouseClickTimeDiff <= 10000) {
+ _playerActor->increaseFPS();
+ }
+ } else {
+ _walkingToExitId = -1;
+ _walkingToRegionId = regionId;
+ _walkingToObjectId = -1;
+ _walkingToItemId = -1;
+ _walkingToEmpty = false;
+ _walkingToActorId = -1;
+
+ _isInsideScriptRegion = true;
+ _sceneScript->clickedOn2DRegion(regionId);
+ _isInsideScriptRegion = false;
+ }
}
-void BladeRunnerEngine::handleMouseClick3DObject(int x, int y, int objectId, bool isClickable, bool isTarget) {
+void BladeRunnerEngine::handleMouseClick3DObject(int objectId, bool buttonDown, bool isClickable, bool isTarget) {
const char *objectName = _scene->objectGetName(objectId);
debug("Clicked on object %s", objectName);
- _sceneScript->clickedOn3DObject(objectName, false);
+
+ if (_isWalkingInterruptible && objectId != _walkingToObjectId) {
+ _isWalkingInterruptible = false;
+ _interruptWalking = true;
+ walkingReset();
+ _walkingToObjectId = objectId;
+ return;
+ }
+
+ if (_mouse->isInactive()) {
+ return;
+ }
+
+ if (!_combat->isActive()) {
+ if (buttonDown || !isClickable) {
+ return;
+ }
+
+ if (_isInsideScriptObject && objectId == _walkingToObjectId) {
+ _playerActor->run();
+ if (_mouseClickTimeDiff <= 10000) {
+ _playerActor->increaseFPS();
+ }
+ } else {
+ _walkingToExitId = -1;
+ _walkingToRegionId = -1;
+ _walkingToObjectId = objectId;
+ _walkingToItemId = -1;
+ _walkingToEmpty = false;
+ _walkingToActorId = -1;
+
+ _isInsideScriptObject = true;
+ _sceneScript->clickedOn3DObject(objectName, false);
+ _isInsideScriptObject = false;
+ }
+ } else {
+ if (!buttonDown || !isTarget) {
+ return;
+ }
+ _playerActor->stopWalking(false);
+ _playerActor->faceObject(objectName, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _settings->decreaseAmmo();
+ _audioPlayer->playAud(_gameInfo->getSfxTrack(_combat->getHitSound()), 100, 0, 0, 90, 0);
+
+ //TODO mouse::randomize(Mouse);
+
+ _isInsideScriptObject = true;
+ _sceneScript->clickedOn3DObject(objectName, true);
+ _isInsideScriptObject = false;
+ }
}
-void BladeRunnerEngine::handleMouseClickEmpty(int x, int y, Vector3 &mousePosition) {
+void BladeRunnerEngine::handleMouseClickEmpty(int x, int y, Vector3 &scenePosition, bool buttonDown) {
+ debug("Clicked on nothing %f, %f, %f", scenePosition.x, scenePosition.y, scenePosition.z);
+
+ if (_isWalkingInterruptible) {
+ _isWalkingInterruptible = false;
+ _interruptWalking = true;
+ walkingReset();
+ _walkingToEmpty = false;
+ return;
+ }
+
+ _isInsideScriptEmpty = true;
bool sceneMouseClick = _sceneScript->mouseClick(x, y);
+ _isInsideScriptEmpty = false;
if (sceneMouseClick) {
return;
}
- bool isRunning;
- debug("Clicked on nothing %f, %f, %f", mousePosition.x, mousePosition.y, mousePosition.z);
- _playerActor->loopWalkToXYZ(mousePosition, 0, false, false, false, &isRunning);
+ int actorId = Actor::findTargetUnderMouse(this, x, y);
+ int itemId = _items->findTargetUnderMouse(x, y);
+
+ if (_combat->isActive() && buttonDown && actorId > 0 && itemId > 0) {
+ _playerActor->stopWalking(false);
+ if (actorId > 0) {
+ _playerActor->faceActor(actorId, false);
+ } else {
+ _playerActor->faceItem(itemId, false);
+ }
+ _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _settings->decreaseAmmo();
+ _audioPlayer->playAud(_gameInfo->getSfxTrack(_combat->getMissSound()), 100, 0, 0, 90, 0);
+
+ //TODO mouse::randomize(Mouse);
+
+ if (actorId) {
+ _aiScripts->shotAtAndMissed(actorId);
+ }
+ } else {
+ if (buttonDown) {
+ return;
+ }
+
+ _walkingToExitId = -1;
+ _walkingToRegionId = -1;
+ _walkingToObjectId = -1;
+ _walkingToItemId = -1;
+ _walkingToEmpty = true;
+ _walkingToActorId = -1;
+
+ if (_combat->isActive() && (actorId > 0 || itemId > 0)) {
+ return;
+ }
+
+ int xDist = abs(_walkingToEmptyX - x);
+ int yDist = abs(_walkingToEmptyY - y);
+
+ _walkingToEmptyX = x;
+ _walkingToEmptyY = y;
+
+ bool inWalkbox = false;
+ float altitude = _scene->_set->getAltitudeAtXZ(scenePosition.x, scenePosition.z, &inWalkbox);
+
+ if (!inWalkbox || scenePosition.y >= altitude + 6.0f) {
+ return;
+ }
+
+ bool run = _playerActor->isRunning();;
+ if (_mouseClickTimeDiff <= 10000 && xDist < 10 && yDist < 10) {
+ run = true;
+ }
+
+ _playerActor->walkTo(run, scenePosition, false);
+
+ if (run && _playerActor->isWalking()) {
+ _playerActor->increaseFPS();
+ }
+ }
}
-void BladeRunnerEngine::handleMouseClickItem(int x, int y, int itemId) {
+void BladeRunnerEngine::handleMouseClickItem(int itemId, bool buttonDown) {
debug("Clicked on item %d", itemId);
- _sceneScript->clickedOnItem(itemId, false);
+
+ if (_isWalkingInterruptible && itemId != _walkingToItemId) {
+ _isWalkingInterruptible = false;
+ _interruptWalking = true;
+ walkingReset();
+ _walkingToItemId = itemId;
+ return;
+ }
+
+ if (_mouse->isInactive()) {
+ return;
+ }
+
+ if (!_combat->isActive()) {
+ if (buttonDown) {
+ return;
+ }
+
+ if (_isInsideScriptItem && itemId == _walkingToItemId) {
+ _playerActor->run();
+ if (_mouseClickTimeDiff <= 10000) {
+ _playerActor->increaseFPS();
+ }
+ } else {
+ _walkingToExitId = -1;
+ _walkingToRegionId = -1;
+ _walkingToObjectId = -1;
+ _walkingToItemId = itemId;
+ _walkingToEmpty = false;
+ _walkingToActorId = -1;
+
+ _isInsideScriptItem = true;
+ _sceneScript->clickedOnItem(itemId, false);
+ _isInsideScriptItem = false;
+ }
+ } else {
+ if (!buttonDown || !_items->isTarget(itemId) /* || _mouse->isRandomized() */) {
+ return;
+ }
+
+ _playerActor->stopWalking(false);
+ _playerActor->faceItem(itemId, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _settings->decreaseAmmo();
+ _audioPlayer->playAud(_gameInfo->getSfxTrack(_combat->getHitSound()), 100, 0, 0, 90, 0);
+
+ //TODO mouse::randomize(Mouse);
+ _isInsideScriptItem = true;
+ _sceneScript->clickedOnItem(itemId, true);
+ _isInsideScriptItem = false;
+ }
}
-void BladeRunnerEngine::handleMouseClickActor(int x, int y, int actorId) {
+void BladeRunnerEngine::handleMouseClickActor(int actorId, bool mainButton, bool buttonDown, Vector3 &scenePosition, int x, int y) {
debug("Clicked on actor %d", actorId);
- bool t = _sceneScript->clickedOnActor(actorId);
- if (!_combat->isActive() && !t) {
- _aiScripts->clickedByPlayer(actorId);
+
+ if (_isWalkingInterruptible && actorId != _walkingToActorId) {
+ _isWalkingInterruptible = false;
+ _interruptWalking = true;
+ walkingReset();
+ _walkingToActorId = actorId;
+ return;
+ }
+
+ if (_mouse->isInactive()) {
+ return;
+ }
+
+ if (!buttonDown) {
+ if (actorId == kActorMcCoy) {
+ if (mainButton) {
+ if (!_combat->isActive()) {
+ _kia->openLastOpened();
+ }
+ } else if (!_playerActor->inWalkLoop()) {
+ _combat->change();
+ }
+ return;
+ }
+
+ if (_isInsideScriptActor && actorId == _walkingToActorId) {
+ _playerActor->run();
+ if (_mouseClickTimeDiff <= 10000) {
+ _playerActor->increaseFPS();
+ }
+ } else {
+ _walkingToExitId = -1;
+ _walkingToRegionId = -1;
+ _walkingToObjectId = -1;
+ _walkingToItemId = -1;
+ _walkingToEmpty = false;
+ _walkingToActorId = actorId;
+
+ _isInsideScriptActor = true;
+ bool processedBySceneScript = _sceneScript->clickedOnActor(actorId);
+ _isInsideScriptActor = false;
+
+ if (!_combat->isActive() && !processedBySceneScript) {
+ _aiScripts->clickedByPlayer(actorId);
+ }
+ }
+ } else {
+ if (!_combat->isActive() || actorId == kActorMcCoy || !_actors[actorId]->isTarget() || _actors[actorId]->isRetired() /*|| _mouse->isRandomized()*/) {
+ return;
+ }
+ _playerActor->stopWalking(false);
+ _playerActor->faceActor(actorId, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _settings->decreaseAmmo();
+
+ float targetX = _actors[actorId]->getX();
+ float targetZ = _actors[actorId]->getZ();
+
+ bool missed = _playerActor->isObstacleBetween(targetX, targetZ);
+
+ _audioPlayer->playAud(_gameInfo->getSfxTrack(missed ? _combat->getMissSound() : _combat->getHitSound()), 100, 0, 0, 90, 0);
+
+ //TODO mouse::randomize(Mouse);
+
+ if (missed) {
+ _aiScripts->shotAtAndMissed(actorId);
+ } else {
+ _isInsideScriptActor = true;
+ bool canShoot = _aiScripts->shotAtAndHit(actorId);
+ _isInsideScriptActor = false;
+ if (!canShoot) {
+ _combat->shoot(actorId, scenePosition, x);
+ }
+ }
}
}
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 07e52de345..373974f238 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -174,7 +174,25 @@ public:
int _walkSoundId;
int _walkSoundVolume;
int _walkSoundBalance;
- int _walkingActorId;
+ int _runningActorId;
+
+ int _mouseClickTimeLast;
+ int _mouseClickTimeDiff;
+
+ int _walkingToExitId;
+ bool _isInsideScriptExit;
+ int _walkingToRegionId;
+ bool _isInsideScriptRegion;
+ int _walkingToObjectId;
+ bool _isInsideScriptObject;
+ int _walkingToItemId;
+ bool _isInsideScriptItem;
+ bool _walkingToEmpty;
+ int _walkingToEmptyX;
+ int _walkingToEmptyY;
+ bool _isInsideScriptEmpty;
+ int _walkingToActorId;
+ bool _isInsideScriptActor;
private:
MIXArchive _archives[kArchiveCount];
@@ -199,17 +217,22 @@ public:
void gameLoop();
void gameTick();
+
void actorsUpdate();
+
+ void walkingReset();
+
void handleEvents();
void handleKeyUp(Common::Event &event);
void handleKeyDown(Common::Event &event);
- void handleMouseAction(int x, int y, bool buttonLeft, bool buttonDown);
- void handleMouseClickExit(int x, int y, int exitIndex);
- void handleMouseClickRegion(int x, int y, int regionIndex);
- void handleMouseClickItem(int x, int y, int itemId);
- void handleMouseClickActor(int x, int y, int actorId);
- void handleMouseClick3DObject(int x, int y, int objectId, bool isClickable, bool isTarget);
- void handleMouseClickEmpty(int x, int y, Vector3 &mousePosition);
+ void handleMouseAction(int x, int y, bool mainButton, bool buttonDown);
+ void handleMouseClickExit(int exitId, int x, int y, bool buttonDown);
+ void handleMouseClickRegion(int regionId, int x, int y, bool buttonDown);
+ void handleMouseClickItem(int itemId, bool buttonDown);
+ void handleMouseClickActor(int actorId, bool mainButton, bool buttonDown, Vector3 &scenePosition, int x, int y);
+ void handleMouseClick3DObject(int objectId, bool buttonDown, bool isClickable, bool isTarget);
+ void handleMouseClickEmpty(int x, int y, Vector3 &scenePosition, bool buttonDown);
+
void gameWaitForActive();
void loopActorSpeaking();
diff --git a/engines/bladerunner/boundingbox.cpp b/engines/bladerunner/boundingbox.cpp
index f7e7eca190..a1c79a17e7 100644
--- a/engines/bladerunner/boundingbox.cpp
+++ b/engines/bladerunner/boundingbox.cpp
@@ -50,6 +50,10 @@ bool BoundingBox::inside(float x, float y, float z) const {
&& z >= _vertices[0].z && z <= _vertices[1].z;
}
+bool BoundingBox::inside(Vector3 &position) const {
+ return inside(position.x, position.y, position.z);
+}
+
void BoundingBox::setXYZ(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/boundingbox.h b/engines/bladerunner/boundingbox.h
index 3f42318cde..11922cbd14 100644
--- a/engines/bladerunner/boundingbox.h
+++ b/engines/bladerunner/boundingbox.h
@@ -36,6 +36,7 @@ public:
void expand(float x0, float y0, float z0, float x1, float y1, float z1);
bool inside(float x, float y, float z) const;
+ bool inside(Vector3 &position) const;
void setXYZ(float x0, float y0, float z0, float x1, float y1, float z1);
void getXYZ(float *x0, float *y0, float *z0, float *x1, float *y1, float *z1) const;
diff --git a/engines/bladerunner/combat.cpp b/engines/bladerunner/combat.cpp
index 26b8b5d785..c371f7bedd 100644
--- a/engines/bladerunner/combat.cpp
+++ b/engines/bladerunner/combat.cpp
@@ -33,6 +33,13 @@ namespace BladeRunner {
Combat::Combat(BladeRunnerEngine *vm) {
_vm = vm;
+ reset();
+}
+
+Combat::~Combat() {
+}
+
+void Combat::reset() {
_active = false;
_enabled = true;
@@ -40,15 +47,12 @@ Combat::Combat(BladeRunnerEngine *vm) {
_ammoDamage[1] = 20;
_ammoDamage[2] = 30;
- for (int i = 0; i < 9; i++) {
+ for (int i = 0; i < kSoundCount; i++) {
_hitSoundId[i] = -1;
_missSoundId[i] = -1;
}
}
-Combat::~Combat() {
-}
-
void Combat::activate() {
if(_enabled) {
_vm->_playerActor->combatModeOn(-1, -1, -1, -1, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, _vm->_combat->_ammoDamage[_vm->_settings->getAmmoType()], 0, 0);
@@ -63,7 +67,17 @@ void Combat::deactivate() {
}
}
-bool Combat::isActive() {
+void Combat::change() {
+ if (!_vm->_playerActor->inWalkLoop() && _enabled) {
+ if (_active) {
+ deactivate();
+ } else {
+ activate();
+ }
+ }
+}
+
+bool Combat::isActive() const{
return _active;
}
@@ -91,4 +105,8 @@ int Combat::getMissSound() {
return _hitSoundId[3 * _vm->_settings->getAmmoType() + _vm->_rnd.getRandomNumber(2)];
}
+void Combat::shoot(int actorId, Vector3 &to, int screenX) {
+
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/combat.h b/engines/bladerunner/combat.h
index 8f0119a854..21989dac52 100644
--- a/engines/bladerunner/combat.h
+++ b/engines/bladerunner/combat.h
@@ -25,15 +25,19 @@
namespace BladeRunner {
+class Vector3;
+
class BladeRunnerEngine;
class Combat {
+ static const int kSoundCount = 9;
+
BladeRunnerEngine *_vm;
bool _active;
bool _enabled;
- int _hitSoundId[9];
- int _missSoundId[9];
+ int _hitSoundId[kSoundCount];
+ int _missSoundId[kSoundCount];
// int _random1;
// int _random2;
@@ -44,9 +48,12 @@ public:
Combat(BladeRunnerEngine *vm);
~Combat();
+ void reset();
+
void activate();
void deactivate();
- bool isActive();
+ void change();
+ bool isActive() const;
void enable();
void disable();
@@ -55,6 +62,8 @@ public:
void setMissSound(int ammoType, int column, int soundId);
int getHitSound();
int getMissSound();
+
+ void shoot(int actorId, Vector3 &to, int screenX);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h
index 30b28de714..54f5fed9eb 100644
--- a/engines/bladerunner/game_constants.h
+++ b/engines/bladerunner/game_constants.h
@@ -559,8 +559,11 @@ enum AnimationModes {
kAnimationModeWalk = 1,
kAnimationModeRun = 2,
kAnimationModeCombatIdle = 4,
+ kAnimationModeCombatAim = 5,
+ kAnimationModeCombatShoot = 6,
kAnimationModeCombatWalk = 7,
- kAnimationModeCombatRun = 8
+ kAnimationModeCombatRun = 8,
+ kAnimationModeFeeding = 52
};
enum SceneLoopMode {
@@ -804,6 +807,21 @@ enum Elevators {
kElevatorPS = 2
};
+// enum SceneObjectOffset {
+// kSceneObjectActorIdStart = 0,
+// kSceneObjectActorIdEnd = kSceneObjectActorIdStart + 73,
+// kSceneObjectItemIdStart = kSceneObjectActorIdEnd + 1,
+// kSceneObjectItemIdEnd = kSceneObjectItemIdStart + 123,
+// kSceneObjectObjectIdStart = kSceneObjectItemIdEnd + 1,
+// kSceneObjectObjectIdEnd = kSceneObjectObjectIdStart + 95
+// };
+
+enum SceneObjectOffset {
+ kSceneObjectOffsetActors = 0,
+ kSceneObjectOffsetItems = 74,
+ kSceneObjectOffsetObjects = 198
+};
+
} // End of namespace BladeRunner
#endif
diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp
index eafc99c80f..1d2de92703 100644
--- a/engines/bladerunner/item.cpp
+++ b/engines/bladerunner/item.cpp
@@ -47,7 +47,7 @@ Item::Item(BladeRunnerEngine *vm) {
_screenX = 0;
_screenY = 0;
_depth = 0.0f;
- _isTargetable = false;
+ _isTarget = false;
_isSpinning = false;
_facingChange = 0;
_isVisible = true;
@@ -69,8 +69,8 @@ void Item::getWidthHeight(int *width, int *height) const {
*height = _height;
}
-bool Item::isTargetable() const {
- return _isTargetable;
+bool Item::isTarget() const {
+ return _isTarget;
}
bool Item::tick(Common::Rect *screenRect, bool special) {
@@ -134,7 +134,7 @@ void Item::setXYZ(Vector3 position) {
_depth = screenPosition.z * 25.5f;
}
-void Item::setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetableFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag) {
+void Item::setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTarget, bool isVisible, bool isPoliceMazeEnemy) {
_itemId = itemId;
_setId = setId;
_animationId = animationId;
@@ -142,9 +142,9 @@ void Item::setup(int itemId, int setId, int animationId, Vector3 position, int f
_angle = facing * (M_PI / 512.0f);
_width = width;
_height = height;
- _isTargetable = isTargetableFlag;
- _isVisible = isVisibleFlag;
- _isPoliceMazeEnemy = isPoliceMazeEnemyFlag;
+ _isTarget = isTarget;
+ _isVisible = isVisible;
+ _isPoliceMazeEnemy = isPoliceMazeEnemy;
setXYZ(position);
_screenRectangle.bottom = -1;
_screenRectangle.right = -1;
@@ -152,4 +152,12 @@ void Item::setup(int itemId, int setId, int animationId, Vector3 position, int f
_screenRectangle.left = -1;
}
+bool Item::isUnderMouse(int mouseX, int mouseY) const {
+ return _isVisible
+ && mouseX >= _screenRectangle.left - 10
+ && mouseX <= _screenRectangle.right + 10
+ && mouseY >= _screenRectangle.top - 10
+ && mouseY <= _screenRectangle.bottom + 10;
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h
index e14aaa5c4f..09f5ae6841 100644
--- a/engines/bladerunner/item.h
+++ b/engines/bladerunner/item.h
@@ -52,7 +52,7 @@ class Item {
int _screenX;
int _screenY;
float _depth;
- bool _isTargetable;
+ bool _isTarget;
bool _isSpinning;
int _facingChange;
bool _isVisible;
@@ -65,10 +65,12 @@ public:
void setXYZ(Vector3 position);
void getWidthHeight(int *width, int *height) const;
- bool isTargetable() const;
+ bool isTarget() const;
bool tick(Common::Rect *screenRect, bool special);
- void setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetableFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag);
+ void setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTarget, bool isVisible, bool isPoliceMazeEnemy);
+
+ bool isUnderMouse(int mouseX, int mouseY) const;
};
}
diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp
index e85366e3f6..5e79f7a39b 100644
--- a/engines/bladerunner/items.cpp
+++ b/engines/bladerunner/items.cpp
@@ -59,15 +59,15 @@ void Items::tick() {
if (_items[i]->_setId != setId) {
continue;
}
- bool set14NotTarget = setId == kSetPS10_PS11_PS12_PS13 && !_items[i]->isTargetable();
+ bool notPoliceMazeTarget = setId == kSetPS10_PS11_PS12_PS13 && !_items[i]->isTarget();
Common::Rect screenRect;
- if (_items[i]->tick(&screenRect, set14NotTarget)) {
+ if (_items[i]->tick(&screenRect, notPoliceMazeTarget)) {
_vm->_zbuffer->mark(screenRect);
}
}
}
-bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetableFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag, bool addToSetFlag) {
+bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTarget, bool isVisible, bool isPoliceMazeEnemy, bool addToSet) {
if (_items.size() >= 100) {
return false;
}
@@ -77,11 +77,11 @@ bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position,
}
Item *item = new Item(_vm);
- item->setup(itemId, setId, animationId, position, facing, height, width, isTargetableFlag, isVisibleFlag, isPoliceMazeEnemyFlag);
+ item->setup(itemId, setId, animationId, position, facing, height, width, isTarget, isVisible, isPoliceMazeEnemy);
_items.push_back(item);
- if (addToSetFlag && setId == _vm->_scene->getSetId()) {
- return _vm->_sceneObjects->addItem(itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, isTargetableFlag, isVisibleFlag);
+ if (addToSet && setId == _vm->_scene->getSetId()) {
+ return _vm->_sceneObjects->addItem(itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, isTarget, isVisible);
}
return true;
}
@@ -94,7 +94,7 @@ bool Items::addToSet(int setId) {
for (int i = 0; i < itemCount; i++) {
Item *item = _vm->_items->_items[i];
if (item->_setId == setId) {
- _vm->_sceneObjects->addItem(item->_itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, item->isTargetable(), item->_isVisible);
+ _vm->_sceneObjects->addItem(item->_itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, item->isTarget(), item->_isVisible);
}
}
return true;
@@ -116,10 +116,29 @@ bool Items::remove(int itemId) {
return true;
}
+bool Items::isTarget(int itemId) const {
+ int itemIndex = findItem(itemId);
+ if (itemIndex == -1) {
+ return false;
+ }
+ return _items[itemIndex]->isTarget();
+}
+
+int Items::findTargetUnderMouse(int mouseX, int mouseY) const {
+ int setId = _vm->_scene->getSetId();
+ for (int i = 0 ; i < (int)_items.size(); ++i) {
+ if (_items[i]->_setId == setId && _items[i]->isTarget() && _items[i]->isUnderMouse(mouseX, mouseY)) {
+ return _items[i]->_itemId;
+ }
+ }
+ return -1;
+}
+
int Items::findItem(int itemId) const {
for (int i = 0; i < (int)_items.size(); i++) {
- if (_items[i]->_itemId == itemId)
+ if (_items[i]->_itemId == itemId) {
return i;
+ }
}
return -1;
}
diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h
index c49231f30e..711abc606f 100644
--- a/engines/bladerunner/items.h
+++ b/engines/bladerunner/items.h
@@ -43,10 +43,13 @@ public:
void getWidthHeight(int itemId, int *width, int *height) const;
void tick();
- bool addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetableFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag, bool addToSetFlag);
+ bool addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTarget, bool isVisible, bool isPoliceMazeEnemy, bool addToSet);
bool addToSet(int itemId);
bool remove(int itemId);
+ bool isTarget(int itemId) const;
+ int findTargetUnderMouse(int mouseX, int mouseY) const;
+
private:
int findItem(int itemId) const;
};
diff --git a/engines/bladerunner/mouse.cpp b/engines/bladerunner/mouse.cpp
index 3dfd1fe57e..7d67e98de5 100644
--- a/engines/bladerunner/mouse.cpp
+++ b/engines/bladerunner/mouse.cpp
@@ -22,11 +22,16 @@
#include "bladerunner/mouse.h"
+#include "bladerunner/actor.h"
#include "bladerunner/bladerunner.h"
+#include "bladerunner/combat.h"
#include "bladerunner/dialogue_menu.h"
+#include "bladerunner/game_constants.h"
+#include "bladerunner/items.h"
#include "bladerunner/regions.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
+#include "bladerunner/settings.h"
#include "bladerunner/shape.h"
#include "bladerunner/view.h"
#include "bladerunner/zbuffer.h"
@@ -267,22 +272,25 @@ void Mouse::tick(int x, int y) {
return;
}
- Vector3 mousePosition = getXYZ(x, y);
+ Vector3 scenePosition = getXYZ(x, y);
int cursorId = 0;
bool isClickable = false;
bool isObstacle = false;
bool isTarget = false;
- int sceneObjectId = _vm->_sceneObjects->findByXYZ(&isClickable, &isObstacle, &isTarget, mousePosition.x, mousePosition.y, mousePosition.z, 1, 0, 1);
+ int sceneObjectId = _vm->_sceneObjects->findByXYZ(&isClickable, &isObstacle, &isTarget, scenePosition, true, false, true);
int exitType = _vm->_scene->_exits->getTypeAtXY(x, y);
- if (sceneObjectId >= 0 && sceneObjectId <= 74) {
+ if (sceneObjectId >= kSceneObjectOffsetActors && sceneObjectId < kSceneObjectOffsetItems) {
exitType = -1;
}
if (exitType != -1) {
switch (exitType) {
+ case 0:
+ cursorId = 12;
+ break;
case 1:
cursorId = 13;
break;
@@ -292,26 +300,76 @@ void Mouse::tick(int x, int y) {
case 3:
cursorId = 15;
break;
- default:
- cursorId = 12;
}
setCursor(cursorId);
return;
}
- if (true /* not in combat */) {
- if (sceneObjectId == 0
- || (sceneObjectId >= 0 && isClickable)
- || _vm->_scene->_regions->getRegionAtXY(x, y) >= 0) {
+ if (!_vm->_combat->isActive()) {
+ if (sceneObjectId == kActorMcCoy + kSceneObjectOffsetActors
+ || (sceneObjectId > 0 && isClickable)
+ || _vm->_scene->_regions->getRegionAtXY(x, y) >= 0) {
cursorId = 1;
}
setCursor(cursorId);
return;
}
+ int animationMode = _vm->_playerActor->getAnimationMode();
+ int actorId = Actor::findTargetUnderMouse(_vm, x, y);
+ int itemId = _vm->_items->findTargetUnderMouse(x, y);
+
+ bool isObject = isTarget && sceneObjectId >= kSceneObjectOffsetObjects && sceneObjectId <= 293;
+
+ if (!_vm->_playerActor->isMoving()) {
+ if (actorId >= 0) {
+ _vm->_playerActor->faceActor(actorId, false);
+ } else if (itemId >= 0) {
+ _vm->_playerActor->faceItem(itemId, false);
+ } else if (isObject) {
+ _vm->_playerActor->faceXYZ(scenePosition, false);
+ }
+ }
+
+ if (actorId >= 0 || itemId >= 0 || isObject) {
+ switch (_vm->_settings->getAmmoType()) {
+ case 0:
+ cursorId = 7;
+ break;
+ case 1:
+ cursorId = 9;
+ break;
+ case 2:
+ cursorId = 11;
+ break;
+ }
+
+ if (!_vm->_playerActor->isMoving() && animationMode != kAnimationModeCombatAim && animationMode != 22 && animationMode != 49) {
+ _vm->_playerActor->changeAnimationMode(kAnimationModeCombatAim, false);
+ }
+ } else {
+ switch (_vm->_settings->getAmmoType()) {
+ case 0:
+ cursorId = 6;
+ break;
+ case 1:
+ cursorId = 8;
+ break;
+ case 2:
+ cursorId = 10;
+ break;
+ }
+ if (!_vm->_playerActor->isMoving() && animationMode != kAnimationModeCombatIdle && animationMode != 22 && animationMode != 49) {
+ _vm->_playerActor->changeAnimationMode(kAnimationModeCombatIdle, false);
+ }
+ }
setCursor(cursorId);
}
+bool Mouse::isInactive() const {
+ return _cursor == 6 || _cursor == 8 || _cursor == 10;
+}
+
// TEST: RC01 after intro: [290, 216] -> [-204.589249 51.450668 7.659241]
Vector3 Mouse::getXYZ(int x, int y) const {
if (_vm->_scene->getSetId() == -1)
diff --git a/engines/bladerunner/mouse.h b/engines/bladerunner/mouse.h
index 64b01992d0..2f33d72583 100644
--- a/engines/bladerunner/mouse.h
+++ b/engines/bladerunner/mouse.h
@@ -62,6 +62,7 @@ public:
void updateCursorFrame();
void tick(int x, int y);
+ bool isInactive() const;
// private:
Vector3 getXYZ(int x, int y) const;
diff --git a/engines/bladerunner/movement_track.cpp b/engines/bladerunner/movement_track.cpp
index 13b60d1d93..47eb56a098 100644
--- a/engines/bladerunner/movement_track.cpp
+++ b/engines/bladerunner/movement_track.cpp
@@ -41,15 +41,15 @@ void MovementTrack::reset() {
_entries[i].waypointId = -1;
_entries[i].delay = -1;
_entries[i].angle = -1;
- _entries[i].running = 0;
+ _entries[i].run = false;
}
}
-int MovementTrack::append(int waypointId, int delay, int running) {
- return append(waypointId, delay, -1, running);
+int MovementTrack::append(int waypointId, int delay, bool run) {
+ return append(waypointId, delay, -1, run);
}
-int MovementTrack::append(int waypointId, int delay, int angle, int running) {
+int MovementTrack::append(int waypointId, int delay, int angle, bool run) {
if (_lastIndex >= kSize) {
return 0;
}
@@ -57,7 +57,7 @@ int MovementTrack::append(int waypointId, int delay, int angle, int running) {
_entries[_lastIndex].waypointId = waypointId;
_entries[_lastIndex].delay = delay;
_entries[_lastIndex].angle = angle;
- _entries[_lastIndex].running = running;
+ _entries[_lastIndex].run = run;
_lastIndex++;
_hasNext = true;
@@ -90,18 +90,18 @@ bool MovementTrack::hasNext() const {
return _hasNext;
}
-bool MovementTrack::next(int *waypointId, int *delay, int *angle, int *running) {
+bool MovementTrack::next(int *waypointId, int *delay, int *angle, bool *run) {
if (_currentIndex < _lastIndex && _hasNext) {
*waypointId = _entries[_currentIndex].waypointId;
*delay = _entries[_currentIndex].delay;
*angle = _entries[_currentIndex].angle;
- *running = _entries[_currentIndex++].running;
+ *run = _entries[_currentIndex++].run;
return true;
} else {
*waypointId = -1;
*delay = -1;
*angle = -1;
- *running = 0;
+ *run = false;
_hasNext = false;
return false;
}
diff --git a/engines/bladerunner/movement_track.h b/engines/bladerunner/movement_track.h
index 174b222b1e..cba9b690ff 100644
--- a/engines/bladerunner/movement_track.h
+++ b/engines/bladerunner/movement_track.h
@@ -34,10 +34,10 @@ class MovementTrack {
static const int kSize = 100;
struct Entry {
- int waypointId;
- int delay;
- int angle;
- int running;
+ int waypointId;
+ int delay;
+ int angle;
+ bool run;
};
int _currentIndex;
@@ -49,15 +49,15 @@ class MovementTrack {
public:
MovementTrack();
~MovementTrack();
- int append(int waypointId, int delay, int running);
- int append(int waypointId, int delay, int angle, int running);
+ int append(int waypointId, int delay, bool run);
+ int append(int waypointId, int delay, int angle, bool run);
void flush();
void repeat();
void pause();
void unpause();
bool isPaused() const;
bool hasNext() const;
- bool next(int *waypointId, int *delay, int *angle, int *running);
+ bool next(int *waypointId, int *delay, int *angle, bool *run);
//int saveGame();
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp
index f20c0be0ef..c327e80fa7 100644
--- a/engines/bladerunner/scene.cpp
+++ b/engines/bladerunner/scene.cpp
@@ -76,13 +76,15 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
_vm->_actorDialogueQueue->flush(1, false);
}
+ _vm->walkingReset();
+
_setId = setId;
_sceneId = sceneId;
const Common::String sceneName = _vm->_gameInfo->getSceneName(_sceneId);
if (isLoadingGame) {
- // TODO: Set up overlays
+ // TODO: _vm->overlays->resume()
} else {
_regions->clear();
_exits->clear();
@@ -162,7 +164,7 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
actor->getScreenRectangle(),
1,
0,
- actor->isTargetable(),
+ actor->isTarget(),
actor->isRetired());
}
}
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index 9f4adb5862..5d22be4a38 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -48,9 +48,9 @@ SceneObjects::~SceneObjects() {
void SceneObjects::clear() {
for (int i = 0; i < kSceneObjectCount; ++i) {
- _sceneObjects[i].sceneObjectId = -1;
- _sceneObjects[i].sceneObjectType = kSceneObjectTypeUnknown;
- _sceneObjects[i].distanceToCamera = 0;
+ _sceneObjects[i].id = -1;
+ _sceneObjects[i].type = kSceneObjectTypeUnknown;
+ _sceneObjects[i].distanceToCamera = 0.0f;
_sceneObjects[i].isPresent = false;
_sceneObjects[i].isClickable = false;
_sceneObjects[i].isObstacle = false;
@@ -95,7 +95,7 @@ bool SceneObjects::remove(int sceneObjectId) {
return true;
}
-int SceneObjects::findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget, float x, float y, float z, bool findClickables, bool findObstacles, bool findTargets) const {
+int SceneObjects::findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget, Vector3 &position, bool findClickables, bool findObstacles, bool findTargets) const {
*isClickable = false;
*isObstacle = false;
*isTarget = false;
@@ -110,16 +110,16 @@ int SceneObjects::findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget,
(findTargets && sceneObject->isTarget)) {
BoundingBox boundingBox = sceneObject->boundingBox;
- if (sceneObject->sceneObjectType == kSceneObjectTypeObject || sceneObject->sceneObjectType == kSceneObjectTypeItem) {
+ if (sceneObject->type == kSceneObjectTypeObject || sceneObject->type == kSceneObjectTypeItem) {
boundingBox.expand(-4.0, 0.0, -4.0, 4.0, 0.0, 4.0);
}
- if (boundingBox.inside(x, y, z)) {
+ if (boundingBox.inside(position)) {
*isClickable = sceneObject->isClickable;
*isObstacle = sceneObject->isObstacle;
*isTarget = sceneObject->isTarget;
- return sceneObject->sceneObjectId;
+ return sceneObject->id;
}
}
}
@@ -127,7 +127,7 @@ int SceneObjects::findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget,
return -1;
}
-bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5, bool a6) const {
+bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool movingActorIsObstacle, bool standingActorIsObstacle) const {
float xMin = x - 12.5f;
float xMax = x + 12.5f;
float zMin = z - 12.5f;
@@ -138,20 +138,20 @@ bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5
if (count > 0) {
for (int i = 0; i < count; i++) {
const SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]];
- bool v13 = false;
- if (sceneObject->sceneObjectType == kSceneObjectTypeActor) {
+ bool isObstacle = false;
+ if (sceneObject->type == kSceneObjectTypeActor) {
if (sceneObject->isRetired) {
- v13 = false;
+ isObstacle = false;
} else if (sceneObject->isMoving) {
- v13 = a5 != 0;
+ isObstacle = movingActorIsObstacle != 0;
} else {
- v13 = a6 != 0;
+ isObstacle = standingActorIsObstacle != 0;
}
} else {
- v13 = sceneObject->isObstacle;
+ isObstacle = sceneObject->isObstacle;
}
- if (v13 && sceneObject->sceneObjectId != exceptSceneObjectId) {
+ if (isObstacle && sceneObject->id != exceptSceneObjectId) {
float x1, y1, z1, x2, y2, z2;
sceneObject->boundingBox.getXYZ(&x1, &y1, &z1, &x2, &y2, &z2);
if (z1 <= zMax && z2 >= zMin && x1 <= xMax && x2 >= xMin) {
@@ -167,7 +167,7 @@ int SceneObjects::findById(int sceneObjectId) const {
for (int i = 0; i < _count; ++i) {
int j = this->_sceneObjectsSortedByDistance[i];
- if (_sceneObjects[j].isPresent && _sceneObjects[j].sceneObjectId == sceneObjectId) {
+ if (_sceneObjects[j].isPresent && _sceneObjects[j].id == sceneObjectId) {
return j;
}
}
@@ -180,11 +180,11 @@ bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObject
return false;
}
- _sceneObjects[index].sceneObjectId = sceneObjectId;
- _sceneObjects[index].sceneObjectType = sceneObjectType;
+ _sceneObjects[index].id = sceneObjectId;
+ _sceneObjects[index].type = sceneObjectType;
_sceneObjects[index].isPresent = true;
_sceneObjects[index].boundingBox = *boundingBox;
- _sceneObjects[index].screenRectangle = *screenRectangle;
+ _sceneObjects[index].screenRectangle = screenRectangle;
_sceneObjects[index].isClickable = isClickable;
_sceneObjects[index].isObstacle = isObstacle;
_sceneObjects[index].unknown1 = unknown1;
@@ -237,7 +237,7 @@ void SceneObjects::setRetired(int sceneObjectId, bool isRetired) {
_sceneObjects[i].isRetired = isRetired;
}
-bool SceneObjects::isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2) const {
+bool SceneObjects::isBetween(float sourceX, float sourceZ, float targetX, float targetZ, int sceneObjectId) const {
int i = findById(sceneObjectId);
if (i == -1) {
return false;
@@ -246,15 +246,46 @@ bool SceneObjects::isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x
float objectX1, objectY1, objectZ1, objectX2, objectY2, objectZ2;
_sceneObjects[i].boundingBox.getXYZ(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2);
- //TODO
- // if (!lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX1, objectZ1, objectX2, objectZ1, &intersectionX, &intersectionY, &v18)
- // && !lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX2, objectZ1, objectX2, objectZ2, &intersectionX, &intersectionY, &v18)
- // && !lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX2, objectZ2, objectX1, objectZ2, &intersectionX, &intersectionY, &v18)
- // && !lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX1, objectZ2, objectX1, objectZ1, &intersectionX, &intersectionY, &v18))
- // return false;
- return true;
+ Vector2 intersection;
+ return lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ1), Vector2(objectX2, objectZ1), &intersection)
+ || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX2, objectZ1), Vector2(objectX2, objectZ2), &intersection)
+ || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX2, objectZ2), Vector2(objectX1, objectZ2), &intersection)
+ || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ2), Vector2(objectX1, objectZ1), &intersection);
}
+bool SceneObjects::isObstacleBetween(float sourceX, float sourceZ, float targetX, float targetZ, float altitude, int exceptSceneObjectId) const {
+ for (int i = 0; i < _count; ++i) {
+ const SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]];
+
+ if (sceneObject->type == kSceneObjectTypeActor || !sceneObject->isObstacle || sceneObject->id == exceptSceneObjectId) {
+ continue;
+ }
+
+ float objectX1, objectY1, objectZ1, objectX2, objectY2, objectZ2;
+ _sceneObjects[i].boundingBox.getXYZ(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2);
+
+ if (84.0f <= objectY1 - altitude || 72.0f >= objectY2 - altitude) {
+ continue;
+ }
+
+ float xAdjustement = (objectX2 - objectX1) * 0.1f;
+ float zAdjustement = (objectZ2 - objectZ1) * 0.1f;
+
+ objectX1 = objectX1 + xAdjustement;
+ objectZ1 = objectZ1 + zAdjustement;
+ objectX2 = objectX2 - xAdjustement;
+ objectZ2 = objectZ2 - zAdjustement;
+
+ Vector2 intersection;
+ if (lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ1), Vector2(objectX2, objectZ1), &intersection)
+ || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX2, objectZ1), Vector2(objectX2, objectZ2), &intersection)
+ || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX2, objectZ2), Vector2(objectX1, objectZ2), &intersection)
+ || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ2), Vector2(objectX1, objectZ1), &intersection)) {
+ return true;
+ }
+ }
+ return false;
+}
void SceneObjects::setIsClickable(int sceneObjectId, bool isClickable) {
int i = findById(sceneObjectId);
@@ -282,12 +313,12 @@ void SceneObjects::setIsTarget(int sceneObjectId, bool isTarget) {
void SceneObjects::updateObstacles() {
_vm->_obstacles->clear();
- for(int i = 0; i < _count; i++) {
+ for (int i = 0; i < _count; ++i) {
int index = _sceneObjectsSortedByDistance[i];
- SceneObject sceneObject = _sceneObjects[index];
- if(sceneObject.isObstacle) {
+ const SceneObject *sceneObject = &_sceneObjects[index];
+ if (sceneObject->isObstacle) {
float x0, y0, z0, x1, y1, z1;
- sceneObject.boundingBox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1);
+ sceneObject->boundingBox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1);
_vm->_obstacles->add(x0, z0, x1, z1);
}
}
diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h
index 23f6f985ad..624deee119 100644
--- a/engines/bladerunner/scene_objects.h
+++ b/engines/bladerunner/scene_objects.h
@@ -39,12 +39,6 @@ enum SceneObjectType {
kSceneObjectTypeItem = 2
};
-enum SceneObjectOffset {
- kSceneObjectOffsetActors = 0,
- kSceneObjectOffsetItems = 74,
- kSceneObjectOffsetObjects = 198
-};
-
class SceneObjects {
#if BLADERUNNER_DEBUG_RENDERING
friend class BladeRunnerEngine;
@@ -52,10 +46,10 @@ class SceneObjects {
static const int kSceneObjectCount = 115;
struct SceneObject {
- int sceneObjectId;
- SceneObjectType sceneObjectType;
+ int id;
+ SceneObjectType type;
BoundingBox boundingBox;
- Common::Rect screenRectangle;
+ Common::Rect *screenRectangle;
float distanceToCamera;
bool isPresent;
bool isClickable;
@@ -82,16 +76,18 @@ public:
bool addItem(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isTarget, bool isObstacle);
bool remove(int sceneObjectId);
void clear();
- int findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget, float x, float y, float z, bool findClickables, bool findObstacles, bool findTargets) const;
- bool existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5, bool a6) const;
+ int findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget, Vector3 &position, bool findClickables, bool findObstacles, bool findTargets) const;
+ bool existsOnXZ(int exceptSceneObjectId, float x, float z, bool movingActorIsObstacle, bool standingActorIsObstacle) const;
void setMoving(int sceneObjectId, bool isMoving);
void setRetired(int sceneObjectId, bool isRetired);
- bool isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2) const;
+ bool isBetween(float sourceX, float sourceZ, float targetX, float targetZ, int sceneObjectId) const;
+ bool isObstacleBetween(float sourceX, float sourceZ, float targetX, float targetZ, float altitude, int exceptSceneObjectId) const;
void setIsClickable(int sceneObjectId, bool isClickable);
void setIsObstacle(int sceneObjectId, bool isObstacle);
void setIsTarget(int sceneObjectId, bool isTarget);
void updateObstacles();
+
private:
int findById(int sceneObjectId) const;
bool addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget, bool isMoving, bool isRetired);
diff --git a/engines/bladerunner/script/ai/leon.cpp b/engines/bladerunner/script/ai/leon.cpp
index 9d82464708..3d136eea4e 100644
--- a/engines/bladerunner/script/ai/leon.cpp
+++ b/engines/bladerunner/script/ai/leon.cpp
@@ -128,10 +128,11 @@ void AIScriptLeon::OtherAgentEnteredCombatMode(int otherActorId, int combatMode)
void AIScriptLeon::ShotAtAndMissed() {}
-void AIScriptLeon::ShotAtAndHit() {
+bool AIScriptLeon::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorLeon) != 7) {
Actor_Set_Goal_Number(kActorLeon, 7);
}
+ return false;
}
void AIScriptLeon::Retired(int byActorId) {}
@@ -351,7 +352,7 @@ bool AIScriptLeon::UpdateAnimation(int *animation, int *frame) {
bool AIScriptLeon::ChangeAnimationMode(int mode) {
switch (mode) {
- case 0:
+ case kAnimationModeIdle:
switch (_animationState) {
case 2:
case 3:
@@ -370,7 +371,7 @@ bool AIScriptLeon::ChangeAnimationMode(int mode) {
break;
}
break;
- case 1:
+ case kAnimationModeWalk:
_animationState = 1;
_animationFrame = 0;
break;
@@ -379,7 +380,7 @@ bool AIScriptLeon::ChangeAnimationMode(int mode) {
_animationFrame = 0;
var_45EDAC = 0;
break;
- case 6:
+ case kAnimationModeCombatShoot:
_animationState = 10;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai/maggie.cpp b/engines/bladerunner/script/ai/maggie.cpp
index 3fd213f1de..89dd651c01 100644
--- a/engines/bladerunner/script/ai/maggie.cpp
+++ b/engines/bladerunner/script/ai/maggie.cpp
@@ -139,7 +139,7 @@ void AIScriptMaggie::ClickedByPlayer() {
Actor_Set_Targetable(kActorMaggie, true);
AI_Movement_Track_Flush(kActorMaggie);
Actor_Face_Actor(kActorMcCoy, kActorMaggie, true);
- Actor_Says(kActorMcCoy, 2400, 52);
+ Actor_Says(kActorMcCoy, 2400, kAnimationModeFeeding);
}
return; // true
}
@@ -210,10 +210,11 @@ void AIScriptMaggie::OtherAgentEnteredCombatMode(int otherActorId, int combatMod
void AIScriptMaggie::ShotAtAndMissed() {
}
-void AIScriptMaggie::ShotAtAndHit() {
+bool AIScriptMaggie::ShotAtAndHit() {
AI_Movement_Track_Flush(kActorMaggie);
Actor_Set_Goal_Number(kActorMaggie, 414);
Actor_Set_Targetable(kActorMaggie, false);
+ return false;
}
void AIScriptMaggie::Retired(int byActorId) {
@@ -270,7 +271,7 @@ bool AIScriptMaggie::GoalChanged(int currentGoalNumber, int newGoalNumber) {
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, 52);
+ Actor_Says(kActorMcCoy, 2400, kAnimationModeFeeding);
Actor_Set_Goal_Number(kActorMaggie, 8);
Player_Gains_Control();
return true;
@@ -593,7 +594,7 @@ bool AIScriptMaggie::ChangeAnimationMode(int mode) {
}
}
break;
- case 52:
+ case kAnimationModeFeeding:
if (Game_Flag_Query(kFlagMaggieIsHurt)) {
_animationState = kMaggieStateHurtJumping;
_animationFrame = 0;
diff --git a/engines/bladerunner/script/ai/mccoy.cpp b/engines/bladerunner/script/ai/mccoy.cpp
index f84c9a9d52..3f3888f99f 100644
--- a/engines/bladerunner/script/ai/mccoy.cpp
+++ b/engines/bladerunner/script/ai/mccoy.cpp
@@ -219,7 +219,8 @@ void AIScriptMcCoy::OtherAgentEnteredCombatMode(int otherActorId, int combatMode
void AIScriptMcCoy::ShotAtAndMissed() {
}
-void AIScriptMcCoy::ShotAtAndHit() {
+bool AIScriptMcCoy::ShotAtAndHit() {
+ return false;
}
void AIScriptMcCoy::Retired(int byActorId) {
@@ -633,7 +634,7 @@ bool AIScriptMcCoy::UpdateAnimation(int *animation, int *frame) {
*animation = 32;
_animationFrame++;
if (_animationFrame == 7) {
- Actor_Change_Animation_Mode(kActorMaggie, 52);
+ Actor_Change_Animation_Mode(kActorMaggie, kAnimationModeFeeding);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = 19;
@@ -1244,7 +1245,7 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
_animationState = 70;
}
return true;
- case 52:
+ case kAnimationModeFeeding:
_animationState = 55;
_animationFrame = 0;
return true;
@@ -1488,19 +1489,19 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
dword_45A0F4 = 21;
}
return true;
- case 8:
+ case kAnimationModeCombatRun:
if (_animationState != 27 && _animationState != 50) {
_animationState = 37;
_animationFrame = 0;
}
return true;
- case 7:
+ case kAnimationModeCombatWalk:
if (_animationState != 27 && _animationState != 50) {
_animationState = 36;
_animationFrame = 0;
}
return true;
- case 6:
+ case kAnimationModeCombatShoot:
_animationState = 21;
_animationFrame = 0;
return true;
@@ -1524,7 +1525,7 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
break;
}
return true;
- case 4:
+ case kAnimationModeCombatIdle:
switch (_animationState) {
case 22:
_animationState = 19;
@@ -1586,7 +1587,7 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
_animationNext = 20;
}
return true;
- case 2:
+ case kAnimationModeRun:
if (_animationState == 27 || _animationState == 50) {
return true;
}
@@ -1598,7 +1599,7 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
_animationState = 58;
_animationFrame = 4;
return true;
- case 1:
+ case kAnimationModeWalk:
if (_animationState == 27 || _animationState == 50) {
return true;
}
@@ -1610,7 +1611,7 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
_animationState = 58;
_animationFrame = 0;
return true;
- case 0:
+ case kAnimationModeIdle:
if (Game_Flag_Query(550)) {
if (_animationFrame > 6) {
_animationState = 57;
diff --git a/engines/bladerunner/script/ai/officer_leary.cpp b/engines/bladerunner/script/ai/officer_leary.cpp
index 86b3ace09c..c95ba202ca 100644
--- a/engines/bladerunner/script/ai/officer_leary.cpp
+++ b/engines/bladerunner/script/ai/officer_leary.cpp
@@ -209,10 +209,11 @@ void AIScriptOfficerLeary::OtherAgentEnteredCombatMode(int otherActorId, int com
void AIScriptOfficerLeary::ShotAtAndMissed() {}
-void AIScriptOfficerLeary::ShotAtAndHit() {
+bool AIScriptOfficerLeary::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorOfficerLeary) == 307) {
Actor_Set_Health(kActorOfficerLeary, 50, 50);
}
+ return false;
}
void AIScriptOfficerLeary::Retired(int byActorId) {
diff --git a/engines/bladerunner/script/ai/runciter.cpp b/engines/bladerunner/script/ai/runciter.cpp
index c18dd2d5f0..d1d7a08182 100644
--- a/engines/bladerunner/script/ai/runciter.cpp
+++ b/engines/bladerunner/script/ai/runciter.cpp
@@ -139,7 +139,7 @@ void AIScriptRunciter::OtherAgentEnteredCombatMode(int otherActorId, int combatM
void AIScriptRunciter::ShotAtAndMissed() {}
-void AIScriptRunciter::ShotAtAndHit() {
+bool AIScriptRunciter::ShotAtAndHit() {
Actor_Set_Targetable(kActorRunciter, false);
Actor_Change_Animation_Mode(kActorRunciter, 48);
Actor_Set_Goal_Number(kActorRunciter, 599);
@@ -153,6 +153,7 @@ void AIScriptRunciter::ShotAtAndHit() {
Actor_Voice_Over(2090, kActorVoiceOver);
}
Actor_Modify_Friendliness_To_Other(kActorClovis, kActorMcCoy, 3);
+ return false;
}
void AIScriptRunciter::Retired(int byActorId) {}
@@ -472,8 +473,8 @@ bool AIScriptRunciter::UpdateAnimation(int *animation, int *frame) {
bool AIScriptRunciter::ChangeAnimationMode(int mode) {
switch (mode) {
- case kAnimationModeCombatIdle:
- if (_animationState <= 11) {
+ case kAnimationModeIdle:
+ if (_animationState >= 2 && _animationState <= 11) {
var_45CD88 = 1;
} else {
_animationState = 0;
@@ -485,14 +486,14 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
if (_animationState > 1) {
_animationState = 1;
_animationFrame = 0;
- } else if (!_animationState) {
+ } else if (_animationState == 0) {
_animationState = 13;
_animationStateNext = 1;
_animationNext = 526;
}
break;
case 3:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -503,7 +504,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 12:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -514,7 +515,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 13:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -525,7 +526,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 14:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -536,7 +537,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 15:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -547,7 +548,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 16:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -558,7 +559,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 17:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -569,7 +570,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 18:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
@@ -580,7 +581,7 @@ bool AIScriptRunciter::ChangeAnimationMode(int mode) {
var_45CD88 = 0;
break;
case 19:
- if (_animationState) {
+ if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
diff --git a/engines/bladerunner/script/ai_script.cpp b/engines/bladerunner/script/ai_script.cpp
index 503fb733df..7b211aaa4c 100644
--- a/engines/bladerunner/script/ai_script.cpp
+++ b/engines/bladerunner/script/ai_script.cpp
@@ -144,6 +144,35 @@ void AIScripts::otherAgentExitedThisScene(int actor, int otherActorId) {
_inScriptCounter--;
}
+void AIScripts::otherAgentEnteredCombatMode(int actorId, int otherActorId, int combatMode) {
+ assert(actorId < _actorCount);
+ _inScriptCounter++;
+ if (_AIScripts[actorId]) {
+ _AIScripts[actorId]->OtherAgentEnteredCombatMode(otherActorId, combatMode);
+ }
+ _inScriptCounter--;
+}
+
+void AIScripts::shotAtAndMissed(int actorId) {
+ assert(actorId < _actorCount);
+ _inScriptCounter++;
+ if (_AIScripts[actorId]) {
+ _AIScripts[actorId]->ShotAtAndMissed();
+ }
+ _inScriptCounter--;
+}
+
+bool AIScripts::shotAtAndHit(int actorId) {
+ assert(actorId < _actorCount);
+ bool result = true;
+ _inScriptCounter++;
+ if (_AIScripts[actorId]) {
+ result = _AIScripts[actorId]->ShotAtAndHit();
+ }
+ _inScriptCounter--;
+ return result;
+}
+
void AIScripts::retired(int actor, int retiredByActorId) {
assert(actor < _actorCount);
_inScriptCounter++;
diff --git a/engines/bladerunner/script/ai_script.h b/engines/bladerunner/script/ai_script.h
index 40df2fb0d8..4be79c650b 100644
--- a/engines/bladerunner/script/ai_script.h
+++ b/engines/bladerunner/script/ai_script.h
@@ -50,7 +50,7 @@ public:
virtual void OtherAgentExitedThisScene(int otherActorId) = 0;
virtual void OtherAgentEnteredCombatMode(int otherActorId, int combatMode) = 0;
virtual void ShotAtAndMissed() = 0;
- virtual void ShotAtAndHit() = 0;
+ virtual bool ShotAtAndHit() = 0;
virtual void Retired(int byActorId) = 0;
virtual int GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) = 0;
virtual bool GoalChanged(int currentGoalNumber, int newGoalNumber) = 0;
@@ -79,7 +79,7 @@ public: \
void OtherAgentExitedThisScene(int otherActorId); \
void OtherAgentEnteredCombatMode(int otherActorId, int combatMode); \
void ShotAtAndMissed(); \
- void ShotAtAndHit(); \
+ bool ShotAtAndHit(); \
void Retired(int byActorId); \
int GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId); \
bool GoalChanged(int currentGoalNumber, int newGoalNumber); \
@@ -176,6 +176,9 @@ public:
void enteredScene(int actor, int setId);
void otherAgentEnteredThisScene(int actor, int otherActorId);
void otherAgentExitedThisScene(int actor, int otherActorId);
+ void otherAgentEnteredCombatMode(int actorId, int otherActorId, int combatMode);
+ void shotAtAndMissed(int actorId);
+ bool shotAtAndHit(int actorId);
void retired(int actor, int retiredByActorId);
void goalChanged(int actor, int currentGoalNumber, int newGoalNumber);
bool reachedMovementTrackWaypoint(int actor, int waypointId);
diff --git a/engines/bladerunner/script/scene_script.cpp b/engines/bladerunner/script/scene_script.cpp
index 639bca8c4e..01fe3e3b1e 100644
--- a/engines/bladerunner/script/scene_script.cpp
+++ b/engines/bladerunner/script/scene_script.cpp
@@ -174,20 +174,21 @@ bool SceneScript::mouseClick(int x, int y) {
//MouseX = x;
//MouseY = y;
bool result = _currentScript->MouseClick(x, y);
- //SelectedEntity = -1;
+ _vm->_runningActorId = -1;
_inScriptCounter--;
//MouseX = -1;
//MouseY = -1;
return result;
}
-bool SceneScript::clickedOn3DObject(const char *objectName, bool a2) {
+bool SceneScript::clickedOn3DObject(const char *objectName, bool attack) {
if (_inScriptCounter > 0) {
return true;
}
_inScriptCounter++;
- bool result = _currentScript->ClickedOn3DObject(objectName, a2);
+ bool result = _currentScript->ClickedOn3DObject(objectName, attack);
+ _vm->_runningActorId = -1;
_inScriptCounter--;
return result;
}
@@ -199,6 +200,7 @@ bool SceneScript::clickedOnActor(int actorId) {
_inScriptCounter++;
bool result = _currentScript->ClickedOnActor(actorId);
+ _vm->_runningActorId = -1;
_inScriptCounter--;
return result;
}
@@ -210,6 +212,7 @@ bool SceneScript::clickedOnItem(int itemId, bool a2) {
_inScriptCounter++;
bool result = _currentScript->ClickedOnItem(itemId, a2);
+ _vm->_runningActorId = -1;
_inScriptCounter--;
return result;
}
@@ -221,6 +224,7 @@ bool SceneScript::clickedOnExit(int exitId) {
_inScriptCounter++;
bool result = _currentScript->ClickedOnExit(exitId);
+ _vm->_runningActorId = -1;
_inScriptCounter--;
return result;
}
@@ -232,6 +236,7 @@ bool SceneScript::clickedOn2DRegion(int region) {
_inScriptCounter++;
bool result = _currentScript->ClickedOn2DRegion(region);
+ _vm->_runningActorId = -1;
_inScriptCounter--;
return result;
}
diff --git a/engines/bladerunner/script/scene_script.h b/engines/bladerunner/script/scene_script.h
index ece96690d3..086388c2d6 100644
--- a/engines/bladerunner/script/scene_script.h
+++ b/engines/bladerunner/script/scene_script.h
@@ -36,7 +36,7 @@ public:
virtual void InitializeScene() = 0;
virtual void SceneLoaded() = 0;
virtual bool MouseClick(int x, int y) = 0;
- virtual bool ClickedOn3DObject(const char *objectName, bool a2) = 0;
+ virtual bool ClickedOn3DObject(const char *objectName, bool attack) = 0;
virtual bool ClickedOnActor(int actorId) = 0;
virtual bool ClickedOnItem(int itemId, bool a2) = 0;
virtual bool ClickedOnExit(int exitId) = 0;
@@ -57,7 +57,7 @@ public: \
void InitializeScene(); \
void SceneLoaded(); \
bool MouseClick(int x, int y); \
- bool ClickedOn3DObject(const char *objectName, bool a2); \
+ bool ClickedOn3DObject(const char *objectName, bool attack); \
bool ClickedOnActor(int actorId); \
bool ClickedOnItem(int itemId, bool a2); \
bool ClickedOnExit(int exitId); \
@@ -536,7 +536,7 @@ public:
void initializeScene();
void sceneLoaded();
bool mouseClick(int x, int y);
- bool clickedOn3DObject(const char *objectName, bool a2);
+ bool clickedOn3DObject(const char *objectName, bool attack);
bool clickedOnActor(int actorId);
bool clickedOnItem(int itemId, bool a2);
bool clickedOnExit(int exitId);
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index c4b0de81d9..f88f330e2f 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -231,7 +231,7 @@ void ScriptBase::Actor_Set_Health(int actorId, int hp, int maxHp) {
}
void ScriptBase::Actor_Set_Targetable(int actorId, bool targetable) {
- _vm->_actors[actorId]->setTargetable(targetable);
+ _vm->_actors[actorId]->setTarget(targetable);
}
@@ -258,7 +258,7 @@ void ScriptBase::Actor_Says_With_Pause(int actorId, int sentenceId, float pause,
if (actorId != kActorMcCoy) {
actor->changeAnimationMode(animationMode, false);
animationModeChanged = true;
- } else if (_vm->_combat->isActive()) {
+ } else if (!_vm->_combat->isActive()) {
actor->changeAnimationMode(animationMode, false);
animationModeChanged = true;
}
@@ -364,11 +364,11 @@ bool ScriptBase::Actor_Query_In_Between_Two_Actors(int actorId, int otherActor1I
float z1 = _vm->_actors[otherActor1Id]->getZ();
float x2 = _vm->_actors[otherActor2Id]->getX();
float z2 = _vm->_actors[otherActor2Id]->getZ();
- return _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1, z1, x2, z1)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 - 12.0f, z1 - 12.0f, x2 - 12.0f, z2 - 12.0f)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 + 12.0f, z1 - 12.0f, x2 + 12.0f, z2 - 12.0f)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 + 12.0f, z1 + 12.0f, x2 + 12.0f, z2 + 12.0f)
- || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 - 12.0f, z1 + 12.0f, x2 - 12.0f, z2 + 12.0f);
+ return _vm->_sceneObjects->isBetween(x1, z1, x2, z1, actorId + kSceneObjectOffsetActors)
+ || _vm->_sceneObjects->isBetween(x1 - 12.0f, z1 - 12.0f, x2 - 12.0f, z2 - 12.0f, actorId + kSceneObjectOffsetActors)
+ || _vm->_sceneObjects->isBetween(x1 + 12.0f, z1 - 12.0f, x2 + 12.0f, z2 - 12.0f, actorId + kSceneObjectOffsetActors)
+ || _vm->_sceneObjects->isBetween(x1 + 12.0f, z1 + 12.0f, x2 + 12.0f, z2 + 12.0f, actorId + kSceneObjectOffsetActors)
+ || _vm->_sceneObjects->isBetween(x1 - 12.0f, z1 + 12.0f, x2 - 12.0f, z2 + 12.0f, actorId + kSceneObjectOffsetActors);
}
void ScriptBase::Actor_Set_Goal_Number(int actorId, int goalNumber) {
@@ -408,20 +408,21 @@ int ScriptBase::Actor_Query_Animation_Mode(int actorId) {
bool ScriptBase::Loop_Actor_Walk_To_Actor(int actorId, int otherActorId, int distance, bool interruptible, bool run) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
run = true;
}
+
_vm->_playerActorIdle = false;
- bool isRunning;
+ bool isRunning;
bool result = _vm->_actors[actorId]->loopWalkToActor(otherActorId, distance, interruptible, run, true, &isRunning);
if (_vm->_playerActorIdle) {
result = true;
_vm->_playerActorIdle = false;
}
- if (isRunning == 1) {
- _vm->_walkingActorId = actorId;
+ if (isRunning) {
+ _vm->_runningActorId = actorId;
}
Global_Variable_Set(kVariableWalkLoopActor, actorId);
Global_Variable_Set(kVariableWalkLoopRun, isRunning);
@@ -431,20 +432,21 @@ bool ScriptBase::Loop_Actor_Walk_To_Actor(int actorId, int otherActorId, int dis
bool ScriptBase::Loop_Actor_Walk_To_Item(int actorId, int itemId, int destinationOffset, bool interruptible, bool run) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
run = true;
}
+
_vm->_playerActorIdle = false;
- bool isRunning;
+ bool isRunning;
bool result = _vm->_actors[actorId]->loopWalkToItem(itemId, destinationOffset, interruptible, run, true, &isRunning);
- if (_vm->_playerActorIdle == 1) {
+ if (_vm->_playerActorIdle) {
result = true;
_vm->_playerActorIdle = false;
}
- if (isRunning == 1) {
- _vm->_walkingActorId = actorId;
+ if (isRunning) {
+ _vm->_runningActorId = actorId;
}
Global_Variable_Set(kVariableWalkLoopActor, actorId);
Global_Variable_Set(kVariableWalkLoopRun, isRunning);
@@ -454,20 +456,21 @@ bool ScriptBase::Loop_Actor_Walk_To_Item(int actorId, int itemId, int destinatio
bool ScriptBase::Loop_Actor_Walk_To_Scene_Object(int actorId, const char *objectName, int destinationOffset, bool interruptible, bool run) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
run = true;
}
+
_vm->_playerActorIdle = false;
- bool isRunning;
+ bool isRunning;
bool result = _vm->_actors[actorId]->loopWalkToSceneObject(objectName, destinationOffset, interruptible, run, true, &isRunning);
if (_vm->_playerActorIdle) {
result = true;
_vm->_playerActorIdle = false;
}
- if (isRunning == 1) {
- _vm->_walkingActorId = actorId;
+ if (isRunning) {
+ _vm->_runningActorId = actorId;
}
Global_Variable_Set(kVariableWalkLoopActor, actorId);
Global_Variable_Set(kVariableWalkLoopRun, isRunning);
@@ -477,20 +480,21 @@ bool ScriptBase::Loop_Actor_Walk_To_Scene_Object(int actorId, const char *object
bool ScriptBase::Loop_Actor_Walk_To_Waypoint(int actorId, int waypointId, int destinationOffset, bool interruptible, bool run) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
run = true;
}
+
_vm->_playerActorIdle = false;
- bool isRunning;
+ bool isRunning;
bool result = _vm->_actors[actorId]->loopWalkToWaypoint(waypointId, destinationOffset, interruptible, run, true, &isRunning);
if (_vm->_playerActorIdle) {
result = true;
_vm->_playerActorIdle = false;
}
- if (isRunning == 1) {
- _vm->_walkingActorId = actorId;
+ if (isRunning) {
+ _vm->_runningActorId = actorId;
}
Global_Variable_Set(kVariableWalkLoopActor, actorId);
Global_Variable_Set(kVariableWalkLoopRun, isRunning);
@@ -500,16 +504,16 @@ bool ScriptBase::Loop_Actor_Walk_To_Waypoint(int actorId, int waypointId, int de
bool ScriptBase::Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int destinationOffset, bool interruptible, bool run, int a7) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
if (a7) {
- _vm->_walkingActorId = -1;
+ _vm->_runningActorId = -1;
} else {
run = true;
}
}
_vm->_playerActorIdle = false;
- bool isRunning;
+ bool isRunning;
bool result = _vm->_actors[actorId]->loopWalkToXYZ(Vector3(x, y, z), destinationOffset, interruptible, run, true, &isRunning);
if (_vm->_playerActorIdle) {
@@ -517,7 +521,7 @@ bool ScriptBase::Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z,
_vm->_playerActorIdle = false;
}
if (isRunning) {
- _vm->_walkingActorId = actorId;
+ _vm->_runningActorId = actorId;
}
Global_Variable_Set(kVariableWalkLoopActor, actorId);
Global_Variable_Set(kVariableWalkLoopRun, isRunning);
@@ -527,7 +531,7 @@ bool ScriptBase::Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z,
void ScriptBase::Async_Actor_Walk_To_Waypoint(int actorId, int waypointId, int destinationOffset, bool run) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
run = true;
}
@@ -537,7 +541,7 @@ void ScriptBase::Async_Actor_Walk_To_Waypoint(int actorId, int waypointId, int d
void ScriptBase::Async_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int destinationOffset, bool run) {
_vm->gameWaitForActive();
- if (_vm->_walkingActorId == actorId) {
+ if (_vm->_runningActorId == actorId) {
run = true;
}
@@ -1234,13 +1238,13 @@ void ScriptBase::I_Sez(const char *str) {
void ScriptBase::AI_Countdown_Timer_Start(int actorId, signed int timer, int seconds) {
if (timer >= 0 && timer <= 2) {
- _vm->_actors[actorId]->countdownTimerStart(timer, 1000 * seconds);
+ _vm->_actors[actorId]->timerStart(timer, 1000 * seconds);
}
}
void ScriptBase::AI_Countdown_Timer_Reset(int actorId, int timer) {
if (timer >= 0 && timer <= 2) {
- _vm->_actors[actorId]->countdownTimerReset(timer);
+ _vm->_actors[actorId]->timerReset(timer);
}
}
@@ -1258,19 +1262,19 @@ void ScriptBase::AI_Movement_Track_Repeat(int actorId) {
}
void ScriptBase::AI_Movement_Track_Append_Run_With_Facing(int actorId, int waypointId, int delay, int angle) {
- _vm->_actors[actorId]->_movementTrack->append(waypointId, delay, angle, 1);
+ _vm->_actors[actorId]->_movementTrack->append(waypointId, delay * 1000, angle, true);
}
void ScriptBase::AI_Movement_Track_Append_With_Facing(int actorId, int waypointId, int delay, int angle) {
- _vm->_actors[actorId]->_movementTrack->append(waypointId, delay, angle, 0);
+ _vm->_actors[actorId]->_movementTrack->append(waypointId, delay * 1000, angle, false);
}
void ScriptBase::AI_Movement_Track_Append_Run(int actorId, int waypointId, int delay) {
- _vm->_actors[actorId]->_movementTrack->append(waypointId, delay, 1);
+ _vm->_actors[actorId]->_movementTrack->append(waypointId, delay * 1000, true);
}
void ScriptBase::AI_Movement_Track_Append(int actorId, int waypointId, int delay) {
- _vm->_actors[actorId]->_movementTrack->append(waypointId, delay, 0);
+ _vm->_actors[actorId]->_movementTrack->append(waypointId, delay * 1000, false);
}
void ScriptBase::AI_Movement_Track_Flush(int actorId) {
diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp
index a68799a232..fe10c189b6 100644
--- a/engines/bladerunner/set.cpp
+++ b/engines/bladerunner/set.cpp
@@ -23,6 +23,7 @@
#include "bladerunner/set.h"
#include "bladerunner/bladerunner.h"
+#include "bladerunner/game_constants.h"
#include "bladerunner/lights.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/set_effects.h"
diff --git a/engines/bladerunner/settings.cpp b/engines/bladerunner/settings.cpp
index d0ba84321c..a5540fcb04 100644
--- a/engines/bladerunner/settings.cpp
+++ b/engines/bladerunner/settings.cpp
@@ -111,31 +111,51 @@ bool Settings::openNewScene() {
return true;
}
-int Settings::getAmmoType() {
+int Settings::getAmmoType() const {
return _ammoType;
}
-int Settings::getAmmoAmount(int ammoType) {
- return _ammoAmounts[ammoType];
-}
-
void Settings::setAmmoType(int ammoType) {
if (_ammoAmounts[ammoType] > 0) {
_ammoType = ammoType;
}
}
+int Settings::getAmmo(int ammoType) const {
+ return _ammoAmounts[ammoType];
+}
+
void Settings::addAmmo(int ammoType, int ammo) {
- if (ammoType > _ammoType || _ammoAmounts[_ammoType] == 0)
+ if (ammoType > _ammoType || _ammoAmounts[_ammoType] == 0) {
_ammoType = ammoType;
+ }
_ammoAmounts[ammoType] += ammo;
}
-int Settings::getDifficulty() {
+void Settings::decreaseAmmo() {
+ if (_difficulty == 0 || _ammoType == 0) {
+ return;
+ }
+
+ if (_ammoAmounts[_ammoType] > 0) {
+ --_ammoAmounts[_ammoType];
+ }
+
+ if (_ammoAmounts[_ammoType] == 0) {
+ for (int i = 2; i >= 0; --i) {
+ if (_ammoAmounts[i] > 0) {
+ _ammoType = i;
+ return;
+ }
+ }
+ }
+}
+
+int Settings::getDifficulty() const {
return _difficulty;
}
-int Settings::getPlayerAgenda() {
+int Settings::getPlayerAgenda() const {
return _playerAgenda;
}
@@ -143,4 +163,12 @@ void Settings::setPlayerAgenda(int agenda) {
_playerAgenda = agenda;
}
+bool Settings::getLearyMode() const {
+ return _learyMode;
+}
+
+void Settings::setLearyMode(bool learyMode) {
+ _learyMode = learyMode;
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/settings.h b/engines/bladerunner/settings.h
index 85674d25c4..bf2d2d3162 100644
--- a/engines/bladerunner/settings.h
+++ b/engines/bladerunner/settings.h
@@ -77,11 +77,11 @@ public:
_newScene = -1;
}
- int getNewScene() {
+ int getNewScene() const {
return _newScene;
}
- int getNewSet() {
+ int getNewSet() const {
return _newSet;
}
@@ -94,7 +94,7 @@ public:
_loadingGame = loadingGame;
}
- bool getLoadingGame() {
+ bool getLoadingGame() const {
return _loadingGame;
}
@@ -104,22 +104,19 @@ public:
bool openNewScene();
- int getAmmoType();
- int getAmmoAmount(int ammoType);
+ int getAmmoType() const;
void setAmmoType(int ammoType);
-
- int getDifficulty();
- int getPlayerAgenda();
- void setPlayerAgenda(int agenda);
+ int getAmmo(int ammoType) const;
void addAmmo(int ammoType, int ammo);
+ void decreaseAmmo();
- bool getLearyMode() {
- return _learyMode;
- }
+ int getDifficulty() const;
- void setLearyMode(bool learyMode) {
- _learyMode = learyMode;
- }
+ int getPlayerAgenda() const;
+ void setPlayerAgenda(int agenda);
+
+ bool getLearyMode() const;
+ void setLearyMode(bool learyMode);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp
index a738923a06..9f7ec13ea0 100644
--- a/engines/bladerunner/ui/kia.cpp
+++ b/engines/bladerunner/ui/kia.cpp
@@ -329,21 +329,21 @@ void KIA::tick() {
_currentSection->draw(_vm->_surfaceFront);
}
}
- if (_vm->_settings->getAmmoAmount(0) > 0) {
+ if (_vm->_settings->getAmmo(0) > 0) {
if (_vm->_settings->getAmmoType() == 0) {
_shapes->get(42)->draw(_vm->_surfaceFront, 147, 405);
} else {
_shapes->get(45)->draw(_vm->_surfaceFront, 140, 446);
}
}
- if (_vm->_settings->getAmmoAmount(1) > 0) {
+ if (_vm->_settings->getAmmo(1) > 0) {
if (_vm->_settings->getAmmoType() == 1) {
_shapes->get(43)->draw(_vm->_surfaceFront, 167, 394);
} else {
_shapes->get(46)->draw(_vm->_surfaceFront, 160, 446);
}
}
- if (_vm->_settings->getAmmoAmount(2) > 0) {
+ if (_vm->_settings->getAmmo(2) > 0) {
if (_vm->_settings->getAmmoType() == 2) {
_shapes->get(44)->draw(_vm->_surfaceFront, 189, 385);
} else {
@@ -826,21 +826,21 @@ void KIA::createButtons(int sectionId) {
_buttons->defineImage(19, kiaButton19, nullptr, nullptr, nullptr, _vm->_textKIA->getText(44));
- if (_vm->_settings->getAmmoAmount(0) > 0) {
+ if (_vm->_settings->getAmmo(0) > 0) {
_buttons->defineImage(16, kiaButton16, nullptr, nullptr, nullptr, _vm->_textKIA->getText(50));
}
Common::String tooltip;
- if (_vm->_settings->getAmmoAmount(1) > 0) {
+ if (_vm->_settings->getAmmo(1) > 0) {
if (_vm->_settings->getDifficulty() > 0) {
- tooltip = Common::String::format("%d", _vm->_settings->getAmmoAmount(1));
+ tooltip = Common::String::format("%d", _vm->_settings->getAmmo(1));
} else {
tooltip = _vm->_textKIA->getText(50);
}
_buttons->defineImage(17, kiaButton17, nullptr, nullptr, nullptr, tooltip.c_str());
}
- if (_vm->_settings->getAmmoAmount(2) > 0) {
+ if (_vm->_settings->getAmmo(2) > 0) {
if (_vm->_settings->getDifficulty() > 0) {
- tooltip = Common::String::format("%d", _vm->_settings->getAmmoAmount(2));
+ tooltip = Common::String::format("%d", _vm->_settings->getAmmo(2));
} else {
tooltip = _vm->_textKIA->getText(50);
}
diff --git a/engines/bladerunner/vector.h b/engines/bladerunner/vector.h
index d04070f7c5..f3cc1f1e6d 100644
--- a/engines/bladerunner/vector.h
+++ b/engines/bladerunner/vector.h
@@ -143,6 +143,23 @@ inline float cos_1024(int angle1024) {
inline float sin_1024(int angle1024) {
return sin(angle1024 * (M_PI / 512.0f));
}
+
+inline bool lineIntersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2, Vector2 *intersection) {
+ Vector2 s1(a2.x - a1.x, a2.y - a1.y);
+ Vector2 s2(b2.x - b1.x, b2.y - b1.y);
+
+ float s = (s1.x * (a1.y - b1.y) - s1.y * (a1.x - b1.x)) / (s1.x * s2.y - s2.x * s1.y);
+ float t = (s2.x * (a1.y - b1.y) - s2.y * (a1.x - b1.x)) / (s1.x * s2.y - s2.x * s1.y);
+
+ if (s >= 0.0f && s <= 1.0f && t >= 0.0f && t <= 1.0f) {
+ intersection->x = a1.x + (t * s1.x);
+ intersection->y = a1.y + (t * s1.y);
+ return true;
+ }
+
+ return false; // No collision
+}
+
} // End of namespace BladeRunner
#endif