aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/actor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/bladerunner/actor.cpp')
-rw-r--r--engines/bladerunner/actor.cpp255
1 files changed, 142 insertions, 113 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;