[Scummvm-git-logs] scummvm master -> 1740c490d710ec01d41c0b248eb43b782f383705

peterkohaut peterkohaut at users.noreply.github.com
Sat Apr 1 09:00:27 CEST 2017


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

Summary:
1740c490d7 BLADERUNNER: improvements to the walking code


Commit: 1740c490d710ec01d41c0b248eb43b782f383705
    https://github.com/scummvm/scummvm/commit/1740c490d710ec01d41c0b248eb43b782f383705
Author: Peter Kohaut (peter.kohaut at gmail.com)
Date: 2017-04-01T08:57:57+02:00

Commit Message:
BLADERUNNER: improvements to the walking code

path finding is still missing
video player has audio preloading
small fixes

Changed paths:
    engines/bladerunner/actor.cpp
    engines/bladerunner/actor.h
    engines/bladerunner/actor_walk.cpp
    engines/bladerunner/actor_walk.h
    engines/bladerunner/bladerunner.cpp
    engines/bladerunner/obstacles.cpp
    engines/bladerunner/scene.h
    engines/bladerunner/set.cpp
    engines/bladerunner/set.h
    engines/bladerunner/settings.cpp
    engines/bladerunner/vqa_player.cpp
    engines/bladerunner/waypoints.h


diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index d4613c1..52cebb6 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -247,7 +247,7 @@ void Actor::movementTrackNext(bool omitAiScript) {
 	int delay;
 	int waypointId;
 	Vector3 waypointPosition;
-	bool stopped;
+	bool arrived;
 
 	hasNextMovement = _movementTrack->next(&waypointId, &delay, &angle, &running);
 	_movementTrackNextWaypointId = waypointId;
@@ -262,11 +262,11 @@ 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, &stopped);
+			_walkInfo->setup(_id, running, _position, waypointPosition, false, &arrived);
 
 			_movementTrackWalkingToWaypointId = waypointId;
 			_movementTrackDelayOnNextWaypoint = delay;
-			if (stopped) {
+			if (arrived) {
 				movementTrackWaypointReached();
 			}
 		} else {
@@ -302,12 +302,12 @@ void Actor::movementTrackPause() {
 
 void Actor::movementTrackUnpause() {
 	Vector3 waypointPosition;
-	bool stopped;
+	bool arrived;
 
 	_movementTrack->unpause();
 	if (_movementTrackNextWaypointId >= 0 && _movementTrackPaused) {
 		_vm->_waypoints->getXYZ(_movementTrackNextWaypointId, &waypointPosition.x, &waypointPosition.y, &waypointPosition.z);
-		_walkInfo->setup(_id, _movementTrackNextRunning, _position, waypointPosition, false, &stopped);
+		_walkInfo->setup(_id, _movementTrackNextRunning, _position, waypointPosition, false, &arrived);
 		_movementTrackPaused = false;
 	}
 }
@@ -351,7 +351,7 @@ void Actor::setAtXYZ(const Vector3 &position, int facing, bool snapFacing, bool
 	_position = position;
 	setFacing(facing, snapFacing);
 
-	if (_vm->_scene->_setId == _setId) {
+	if (_vm->_scene->getSetId() == _setId) {
 		_walkboxId = _vm->_scene->_set->findWalkbox(_position.x, _position.y);
 	} else {
 		_walkboxId = -1;
@@ -375,8 +375,8 @@ void Actor::setAtWaypoint(int waypointId, int angle, int moving, bool retired) {
 bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool a3, bool run, const Vector3 &start, float targetWidth, float targetSize, bool a8, bool *flagIsRunning, bool async) {
 	if (true) { // simple walking
 		*flagIsRunning = false;
-		bool stopped;
-		_walkInfo->setup(_id, false, _position, destination, false, &stopped);
+		bool arrived;
+		_walkInfo->setup(_id, false, _position, destination, false, &arrived);
 
 		for (;;) {
 			_vm->gameTick();
@@ -400,7 +400,7 @@ bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool a3,
 
 		if (a8 && !async && _id && destinationOffset <= 24) {
 			if (distance(_vm->_playerActor->_position, destination) <= 24.0f) {
-				_vm->_playerActor->walkToU(destination, 48.0f);
+				_vm->_playerActor->walkToNearestPoint(destination, 48.0f);
 			}
 		}
 
@@ -476,9 +476,9 @@ bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool a3,
 }
 
 bool Actor::walkTo(bool run, const Vector3 &destination, bool a3) {
-	bool flagIsRunning;
+	bool arrived;
 
-	return _walkInfo->setup(_id, run, _position, destination, a3, &flagIsRunning);
+	return _walkInfo->setup(_id, run, _position, destination, a3, &arrived);
 }
 
 bool Actor::loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool a3, bool run, bool a5, bool *flagIsRunning) {
@@ -765,17 +765,17 @@ void Actor::setBoundingBox(const Vector3 &position, bool retired) {
 	}
 }
 
-float Actor::distanceFromView(View *view) {
+float Actor::distanceFromView(View *view) const{
 	float xDist = this->_position.x - view->_cameraPosition.x;
 	float zDist = this->_position.z - view->_cameraPosition.z;
 	return sqrt(xDist * xDist + zDist * zDist);
 }
 
-bool Actor::isWalking() {
+bool Actor::isWalking() const {
 	return _walkInfo->isWalking();
 }
 
-bool Actor::isRunning() {
+bool Actor::isRunning() const {
 	return _walkInfo->isRunning();
 }
 
@@ -794,7 +794,7 @@ void Actor::stopWalking(bool value) {
 }
 
 void Actor::faceActor(int otherActorId, bool animate) {
-	if (_setId != _vm->_scene->_setId) {
+	if (_setId != _vm->_scene->getSetId()) {
 		return;
 	}
 
@@ -1085,12 +1085,12 @@ void Actor::copyClues(int actorId) {
 	}
 }
 
-int Actor::soundVolume() {
+int Actor::soundVolume() const {
 	float dist = distanceFromView(_vm->_view);
 	return 255.0f * MAX(MIN(dist / 1200.0f, 1.0f), 0.0f);
 }
 
-int Actor::soundBalance() {
+int Actor::soundBalance() const {
 	Vector3 screenPosition = _vm->_view->calculateScreenPosition(_position);
 	return 127.0f * (MAX(MIN(screenPosition.x / 640.0f, 1.0f), 0.0f) * 2.0f - 1.0f);
 }
@@ -1105,8 +1105,8 @@ bool Actor::walkFindU1(const Vector3 &startPosition, const Vector3 &targetPositi
 	int facing2 = facing;
 	int facing3 = 0;
 	while (true) {
-		float rotatedX = size * sin_1024(facing) + targetPosition.x;
-		float rotatedZ = size * cos_1024(facing) + targetPosition.z;
+		float rotatedX = targetPosition.x + size * sin_1024(facing);
+		float rotatedZ = targetPosition.z - size * cos_1024(facing);
 
 		if (!_walkInfo->isXYZEmpty(rotatedX, targetPosition.y, rotatedZ, _id)) {
 			if (_vm->_scene->_set->findWalkbox(rotatedX, rotatedZ) >= 0) {
@@ -1161,10 +1161,10 @@ bool Actor::walkFindU2(Vector3 *newDestination, float targetWidth, int destinati
 	}
 }
 
-bool Actor::walkToU(const Vector3 &destination, float distance) {
+bool Actor::walkToNearestPoint(const Vector3 &destination, float distance) {
 	Vector3 out;
 	bool flagIsRunning;
-	if (_walkInfo->findU1(_id, destination, distance, &out)) {
+	if (_walkInfo->findNearestEmptyPosition(_id, destination, distance, out)) {
 		loopWalk(out, 0, false, false, _position, 0.0f, 24.0f, false, &flagIsRunning, false);
 		return true;
 	}
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index ea77e88..cf93a7f 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -153,18 +153,19 @@ public:
 
 	int getSetId();
 	void setSetId(int setId);
-	BoundingBox *getBoundingBox() { return _bbox; }
+	BoundingBox *getBoundingBox() const { return _bbox; }
 	Common::Rect *getScreenRectangle() { return &_screenRectangle; }
-	int getWalkbox() { return _walkboxId; }
-	bool isRetired() { return _isRetired; }
-	bool isTargetable() { return _isTargetable; }	
+	int getWalkbox() const { return _walkboxId; }
+	bool isRetired()const { return _isRetired; }
+	bool isTargetable() const { return _isTargetable; }
 	void setTargetable(bool targetable);
-	bool isImmuneToObstacles() { return _isImmuneToObstacles; }
-	bool inCombat() { return _inCombat; }
-	bool isMoving() { return _isMoving; }
+	bool isImmuneToObstacles() const { return _isImmuneToObstacles; }
+	bool inCombat() const { return _inCombat; }
+	bool isMoving() const { return _isMoving; }
 	void setMoving(bool value) { _isMoving = value; }
-	bool isWalking();
-	bool isRunning();
+	bool inWalkLoop() const { return _inWalkLoop; }
+	bool isWalking() const;
+	bool isRunning() const;
 	void stopWalking(bool value);
 
 	void faceActor(int otherActorId, bool animate);
@@ -212,19 +213,19 @@ public:
 	bool hasClue(int clueId);
 	void copyClues(int actorId);
 
-	int soundVolume();
-	int soundBalance();
+	int soundVolume() const;
+	int soundBalance() const;
 private:
 	void setFacing(int facing, bool halfOrSet = true);
 	void setBoundingBox(const Vector3 &position, bool retired);
-	float distanceFromView(View* view);
+	float distanceFromView(View* view) const;
 	
 	bool loopWalk(const Vector3 &destination, int destinationOffset, bool a3, 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 walkToU(const Vector3 &destination, float distance);
+	bool walkToNearestPoint(const Vector3 &destination, float distance);
 	//bool walkFindU3(int actorId, Vector3 from, int distance, Vector3 *out);
 };
 
diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp
index 54f6c2d..ddf8b4c 100644
--- a/engines/bladerunner/actor_walk.cpp
+++ b/engines/bladerunner/actor_walk.cpp
@@ -25,6 +25,7 @@
 #include "bladerunner/bladerunner.h"
 
 #include "bladerunner/actor.h"
+#include "bladerunner/gameinfo.h"
 #include "bladerunner/obstacles.h"
 #include "bladerunner/scene.h"
 #include "bladerunner/scene_objects.h"
@@ -35,40 +36,41 @@ namespace BladeRunner {
 ActorWalk::ActorWalk(BladeRunnerEngine *vm) {
 	_vm = vm;
 
-	_walking =  0;
-	_running =  0;
-	_facing  = -1;
-	_status  =  0;
+	_walking = 0;
+	_running = 0;
+	_facing = -1;
+	_status = 0;
 
-	_entries.clear();
+	_nearActors.clear();
 }
 
-ActorWalk::~ActorWalk() {
-}
+ActorWalk::~ActorWalk() {}
 
-bool ActorWalk::setup(int actorId, bool run, const Vector3 &from, const Vector3 &to, bool unk1, bool *stopped) {
+bool ActorWalk::setup(int actorId, bool run, const Vector3 &from, const Vector3 &to, bool unk1, bool *arrived) {
 	Vector3 next;
 
-	*stopped = false;
-	int r = nextOnPath(actorId, from, to, &next);
+	*arrived = false;
+
+	int r = nextOnPath(actorId, from, to, next);
 
 	if (r == 0) {
 		if (actorId != 0) {
 			_current = from;
 			_destination = to;
-			stop(actorId, false, 4, 0);
+			stop(actorId, false, kAnimationModeCombatIdle, kAnimationModeIdle);
 		} else {
-			stop(actorId, true, 4, 0);
+			stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle);
 		}
 		return false;
 	}
+
 	if (r == -1) {
-		stop(actorId, true, 4, 0);
-		*stopped = true;
+		stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle);
+		*arrived = true;
 		return false;
 	}
 
-	resetList();
+	_nearActors.clear();
 	_vm->_sceneObjects->setMoving(actorId + SCENE_OBJECTS_ACTORS_OFFSET, true);
 	_vm->_actors[actorId]->setMoving(true);
 
@@ -86,65 +88,125 @@ bool ActorWalk::setup(int actorId, bool run, const Vector3 &from, const Vector3
 	_vm->_actors[actorId]->changeAnimationMode(animationMode);
 
 	_destination = to;
+	_originalDestination = to;
 	_current = from;
 	_next = next;
 
-	if (next.x != _current.x || next.z != _current.z) {
-		_facing = angle_1024(_current, next);
-		_walking = true;
-		_running = run;
-		_status = 2;
-
-		return true;
+	if (next.x == _current.x && next.z == _current.z) {
+		stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle);
+		*arrived = true;
+		return false;
 	}
 
-	stop(actorId, true, 4, 0);
-	return false;
+	_facing = angle_1024(_current, next);
+	_walking = true;
+	_running = run;
+	_status = 2;
+
+	return true;
 }
 
-bool ActorWalk::tick(int actorId, float stepDistance, bool flag) {
+bool ActorWalk::tick(int actorId, float stepDistance, bool inWalkLoop) {
+	bool walkboxFound;
+
 	if (_status == 5) {
-		if (flag) {
-			stop(actorId, true, 4, 0);
+		if (inWalkLoop) {
+			stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle);
 			return true;
 		}
 
-		if (actorId != 0 && _vm->_rnd.getRandomNumberRng(1, 15) != 1) {
+		if (actorId != 0 && _vm->_rnd.getRandomNumberRng(1, 15) != 1) { // why random?
 			return false;
 		}
 		_status = 3;
 	}
-	// TODO: Handle collisions?
+
+	bool nearActorExists = addNearActors(actorId);
+	if (_nearActors.size() > 0) {
+		nearActorExists = true;
+		if (_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, _destination.x, _destination.z, true, true)) {
+			if (actorId > 0) {
+				if (_vm->_actors[actorId]->inWalkLoop()) {
+					stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle);
+					_nearActors.clear();
+					return true;
+				} else {
+					Vector3 newDestination;
+					findNearestEmptyPositionToOriginalDestination(actorId, newDestination);
+					_destination = newDestination;
+					return false;
+				}
+			} else {
+				if (_vm->_playerActor->inWalkLoop()) {
+					_destination = _current;
+				}
+				stop(0, true, kAnimationModeCombatIdle, kAnimationModeIdle);
+				_nearActors.clear();
+				return true;
+			}
+		}
+	}
+	_status = 3;
 
 	if (stepDistance > distance(_current, _destination)) {
-		stop(actorId, true, 4, 0);
+		stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle);
 		_current = _destination;
-		// TODO: Update y from walkbox
+		_current.y = _vm->_scene->_set->getAltitudeAtXZ(_current.x, _current.z, &walkboxFound);
 		return true;
 	}
 
+	float distanceToNext = distance(_current, _next);
+	if (1.0f < distanceToNext) {
+		_facing = angle_1024(_current, _next);
+	}
+
+	bool nextIsCloseEnough = stepDistance > distanceToNext;
+
+	if (nextIsCloseEnough || nearActorExists || _status == 3) {
+		if (nextIsCloseEnough) {
+			_current = _next;
+		}
+		_status = 1;
+		Vector3 next;
+		obstaclesAddNearActors(actorId);
+		int r = nextOnPath(actorId, _current, _destination, next);
+		obstaclesRestore();
+		if (r == 0) {
+			stop(actorId, actorId == 0, kAnimationModeCombatIdle, kAnimationModeIdle);
+			return false;
+		}
+		if (r != -1) {
+			_next = next;
+			_facing = angle_1024(_current, _next);
+			_status = 2;
+			int animationMode;
+			if (_vm->_actors[actorId]->inCombat()) {
+				animationMode = _running ? kAnimationModeCombatRun : kAnimationModeCombatWalk;
+			} else {
+				animationMode = _running ? kAnimationModeRun : kAnimationModeWalk;
+			}
+			_vm->_actors[actorId]->changeAnimationMode(animationMode);
+			if (nextIsCloseEnough) {
+				return false;
+			}
+		}
+	}
+
 	float angle_rad = _facing / 512.0 * M_PI;
 
-	_current = Vector3(
-		_current.x + stepDistance * sinf(angle_rad),
-		_current.y, // TODO: Update from walkbox
-		_current.z - stepDistance * cosf(angle_rad)
-	);
+	_current.x += stepDistance * sinf(angle_rad);
+	_current.z -= stepDistance * cosf(angle_rad);
+	_current.y = _vm->_scene->_set->getAltitudeAtXZ(_current.x, _current.z, &walkboxFound);
 
 	return false;
 }
 
-void ActorWalk::getCurrentPosition(int actorId, Vector3 *pos, int *facing) {
+void ActorWalk::getCurrentPosition(int actorId, Vector3 *pos, int *facing) const {
 	*pos = _current;
 	*facing = _facing;
 }
 
-void ActorWalk::setRunning() {
-	_running = true;
-	// TODO: Set animation mode
-}
-
-void ActorWalk::stop(int actorId, bool unknown, int combatAnimationMode, int animationMode) {
+void ActorWalk::stop(int actorId, bool immediately, int combatAnimationMode, int animationMode) {
 	_vm->_sceneObjects->setMoving(actorId + SCENE_OBJECTS_ACTORS_OFFSET, false);
 	_vm->_actors[actorId]->setMoving(false);
 
@@ -154,7 +216,7 @@ void ActorWalk::stop(int actorId, bool unknown, int combatAnimationMode, int ani
 		_vm->_actors[actorId]->changeAnimationMode(animationMode, false);
 	}
 
-	if (unknown) {
+	if (immediately) {
 		_walking = false;
 		_running = false;
 		_status = 0;
@@ -165,7 +227,7 @@ void ActorWalk::stop(int actorId, bool unknown, int combatAnimationMode, int ani
 	}
 }
 
-bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) {
+bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) const {
 	if (_vm->_scene->_set->findWalkbox(x, z) == -1) {
 		return true;
 	}
@@ -175,77 +237,125 @@ bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) {
 	return _vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, false, false);
 }
 
-int ActorWalk::findU1(int actorId, const Vector3 &to, int dist, Vector3 *out) {
+bool ActorWalk::findNearestEmptyPosition(int actorId, const Vector3 &destination, int dist, Vector3 &out) const {
 	bool inWalkbox;
 
-	int facingFound = -1;
-	float distFound = -1.0f;
+	int facingToMinDistance = -1;
+	float minDistance = -1.0f;
 	float x = 0.0f;
 	float z = 0.0f;
 
-	out->x = 0.0f;
-	out->y = 0.0f;
-	out->z = 0.0f;
+	out.x = 0.0f;
+	out.y = 0.0f;
+	out.z = 0.0f;
 
 	for (int facing = 0; facing < 1024; facing += 128) {
-		x = to.x + sin_1024(facing) * dist;
-		z = to.z + cos_1024(facing) * dist;
-		float dist2 = distance(x, z, _vm->_actors[actorId]->getX(), _vm->_actors[actorId]->getZ());
+		x = destination.x + sin_1024(facing) * dist;
+		z = destination.z - cos_1024(facing) * dist;
+		float distanceBetweenActorAndDestination = distance(x, z, _vm->_actors[actorId]->getX(), _vm->_actors[actorId]->getZ());
 
-		if (distFound == -1.0f || distFound > dist2) {
-			distFound = dist2;
-			facingFound = facing;
+		if (minDistance == -1.0f || minDistance > distanceBetweenActorAndDestination) {
+			minDistance = distanceBetweenActorAndDestination;
+			facingToMinDistance = facing;
 		}
 	}
 
-	int v23 = facingFound;
-	int v24 = facingFound;
-	int v25 = -1024;
-	while (v25 < 0) {
-		x = to.x + sin_1024(v24) * dist;
-		z = to.z + cos_1024(v24) * dist;
+	int facingLeft = facingToMinDistance;
+	int facingRight = facingToMinDistance;
+	int facing = -1024;
+	while (facing < 0) {
+		x = destination.x + sin_1024(facingRight) * dist;
+		z = destination.z - cos_1024(facingRight) * dist;
 
 		if (!_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) {
 			break;
 		}
 
-		x = to.x + sin_1024(v23) * dist;
-		z = to.z + cos_1024(v23) * dist;
+		x = destination.x + sin_1024(facingLeft) * dist;
+		z = destination.z - cos_1024(facingLeft) * dist;
 
 		if (!_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) {
 			break;
 		}
 
-		v24 -= 64;
-		if (v24 < 0) {
-			v24 += 1024;
+		facingRight -= 64;
+		if (facingRight < 0) {
+			facingRight += 1024;
 		}
-		v23 += 64;
-		if (v23 >= 1024) {
-			v23 -= 1024;
+		facingLeft += 64;
+		if (facingLeft >= 1024) {
+			facingLeft -= 1024;
 		}
-		v25 += 64;
+		facing += 64;
 	}
 
 	float y = _vm->_scene->_set->getAltitudeAtXZ(x, z, &inWalkbox);
 	if (inWalkbox) {
-		out->x = x;
-		out->y = y;
-		out->z = z;
+		out.x = x;
+		out.y = y;
+		out.z = z;
 		return true;
 	}
 	return false;
 }
 
-int ActorWalk::nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 *next) {
-	*next = from;
+bool ActorWalk::findNearestEmptyPositionToOriginalDestination(int actorId, Vector3 &out) const {
+	return findNearestEmptyPosition(actorId, _originalDestination, 30, out);
+}
+
+bool ActorWalk::addNearActors(int skipActorId) {
+	bool added = false;
+	int setId = _vm->_scene->getSetId();
+	for (int i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {
+		// TODO: remove null check after implemetantion of all actors
+		if (_vm->_actors[i] != nullptr
+			&& _vm->_actors[skipActorId] != nullptr
+			&& _vm->_actors[i]->getSetId() == setId
+			&& i != skipActorId) {
+
+			if (_nearActors.contains(i)) {
+				_nearActors.setVal(i, false);
+			} else if (_vm->_actors[skipActorId]->distanceFromActor(i) <= 48.0f) {
+				_nearActors.setVal(i, true);
+				added = true;
+			}
+		}
+	}
+	return added;
+}
+
+void ActorWalk::obstaclesAddNearActors(int actorId) const {
+	Vector3 position = _vm->_actors[actorId]->getPosition();
+	for (Common::HashMap<int, bool>::const_iterator it = _nearActors.begin(); it != _nearActors.end(); ++it) {
+		Actor *otherActor = _vm->_actors[it->_key];
+		// TODO: remove null check after implemetantion of all actors
+		if (otherActor == nullptr || otherActor->isRetired()) {
+			continue;
+		}
+		Vector3 otherPosition = otherActor->getPosition();
+		float x0 = otherPosition.x - 12.0f;
+		float z0 = otherPosition.z - 12.0f;
+		float x1 = otherPosition.x + 12.0f;
+		float z1 = otherPosition.z + 12.0f;
+		if (position.x < (x0 - 12.0f) || position.z < (z0 - 12.0f) || position.x > (x1 + 12.0f) || position.z > (z1 + 12.0f)) {
+			_vm->_obstacles->add(x0, z0, x1, z1);
+		}
+	}
+}
+
+void ActorWalk::obstaclesRestore() const {
+	_vm->_obstacles->restore();
+}
+
+int ActorWalk::nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 &next) const {
+	next = from;
 
 	if (distance(from, to) < 6.0) {
 		return -1;
 	}
 
 	if (_vm->_actors[actorId]->isImmuneToObstacles()) {
-		*next = to;
+		next = to;
 		return 1;
 	}
 	if (_vm->_scene->_set->findWalkbox(to.x, to.z) == -1) {
@@ -256,13 +366,10 @@ int ActorWalk::nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, V
 	}
 	Vector3 next1;
 	if (_vm->_obstacles->find(from, to, &next1)) {
-		*next = next1;
+		next = next1;
 		return 1;
 	}
 	return 0;
 }
 
-void ActorWalk::resetList() {
-	_entries.clear();
-}
 } // End of namespace BladeRunner
diff --git a/engines/bladerunner/actor_walk.h b/engines/bladerunner/actor_walk.h
index e0558a6..c6f2ed7 100644
--- a/engines/bladerunner/actor_walk.h
+++ b/engines/bladerunner/actor_walk.h
@@ -24,17 +24,12 @@
 #define BLADERUNNER_ACTOR_WALK_H
 
 #include "bladerunner/vector.h"
-#include "common/array.h"
+#include "common/hashmap.h"
 
 namespace BladeRunner {
 
 class BladeRunnerEngine;
 
-struct ActorWalkEntry {
-	int _actorId;
-	int _present;
-};
-
 class ActorWalk {
 	BladeRunnerEngine *_vm;
 
@@ -42,36 +37,38 @@ private:
 	int     _walking;
 	int     _running;
 	Vector3 _destination;
-	Vector3 _unknown;
+	Vector3 _originalDestination;
 	Vector3 _current;
 	Vector3 _next;
 	int     _facing;
-	Common::Array<ActorWalk> _entries;
-//	int     _field15;
+	Common::HashMap<int, bool> _nearActors;
 	int     _status;
 
 public:
 	ActorWalk(BladeRunnerEngine *vm);
 	~ActorWalk();
-
 	
-	bool setup(int actorId, bool run, const Vector3 &from, const Vector3 &to, bool unk1, bool *stopped);
-	void getCurrentPosition(int actorId, Vector3 *pos, int *facing);
+	bool setup(int actorId, bool run, const Vector3 &from, const Vector3 &to, bool unk1, bool *arrived);
+	void getCurrentPosition(int actorId, Vector3 *pos, int *facing) const;
 	bool tick(int actorId, float stepDistance, bool flag);
 
-	bool isWalking() { return _walking; }
-	bool isRunning() { return _running; }
-	void setRunning();
+	bool isWalking() const { return _walking; }
+	bool isRunning() const { return _running; }
 
-	void stop(int actorId, bool unknown, int combatAnimationMode, int animationMode);
-	// void setWalkingMode(int actorId, int active, int unk2 = 4, int unk3 = 0);
+	bool isXYZEmpty(float x, float y, float z, int actorId) const;
+	bool findNearestEmptyPosition(int actorId, const Vector3 &from, int distance, Vector3 &out) const;
+
+	void stop(int actorId, bool immediately, int combatAnimationMode, int animationMode);
+
+private:
+	int nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 &next) const;
 
-	int nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 *next);
+	bool findNearestEmptyPositionToOriginalDestination(int actorId, Vector3 &out) const;
 
-	void resetList();
+	bool addNearActors(int skipActorId);
 
-	bool isXYZEmpty(float x, float y, float z, int actorId);
-	int findU1(int actorId, const Vector3 &to, int distance, Vector3 *out);
+	void obstaclesAddNearActors(int actorId) const;
+	void obstaclesRestore() const;
 };
 
 } // End of namespace BladeRunner
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 57159c2..e11cc0b 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -803,8 +803,6 @@ void BladeRunnerEngine::handleMouseClick(int x, int y) {
 	int sceneObjectId = _sceneObjects->findByXYZ(&isClickable, &isObstacle, &isTarget, mousePosition.x, mousePosition.y, mousePosition.z, 1, 0, 1);
 	int exitIndex = _scene->_exits->getRegionAtXY(x, y);
 
-	debug("%d %d", sceneObjectId, exitIndex);
-
 	if ((sceneObjectId < 0 || sceneObjectId > 73) && exitIndex >= 0) {
 		handleMouseClickExit(x, y, exitIndex);
 		return;
diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp
index 9e701a9..9fbdc0a 100644
--- a/engines/bladerunner/obstacles.cpp
+++ b/engines/bladerunner/obstacles.cpp
@@ -66,5 +66,7 @@ bool Obstacles::find(const Vector3 &from, const Vector3 &to, Vector3 *next) {
 void Obstacles::backup() {
 }
 
+void Obstacles::restore() {}
+
 
 } // End of namespace BladeRunner
diff --git a/engines/bladerunner/scene.h b/engines/bladerunner/scene.h
index fac67ff..90cb936 100644
--- a/engines/bladerunner/scene.h
+++ b/engines/bladerunner/scene.h
@@ -37,8 +37,7 @@ class BladeRunnerEngine;
 class Scene {
 	BladeRunnerEngine *_vm;
 
-public:
-	Set        *_set;
+private:
 	int         _setId;
 	int         _sceneId;
 	VQAPlayer  *_vqaPlayer;
@@ -57,6 +56,8 @@ public:
 	int         _actorStartFacing;
 	bool        _playerWalkedIn;
 
+public:
+	Set        *_set;
 	Regions*    _regions;
 	Regions*    _exits;
 
@@ -66,15 +67,15 @@ public:
 public:
 	Scene(BladeRunnerEngine *vm)
 		: _vm(vm),
-		  _set(new Set(vm)),
 		  _setId(-1),
 		  _sceneId(-1),
 		  _vqaPlayer(nullptr),
 		  _defaultLoop(0),
+		  _introFinished(false),
 		  _nextSetId(-1),
 		  _nextSceneId(-1),
 		  _playerWalkedIn(false),
-		  _introFinished(false),
+		  _set(new Set(vm)),
 		  _regions(new Regions()),
 		  _exits(new Regions())
 	{}
@@ -94,8 +95,8 @@ public:
 	void loopSetDefault(int a);
 	void loopStartSpecial(int a, int b, int c);
 
-	int getSetId()   { return _setId; }
-	int getSceneId() { return _sceneId; }
+	int getSetId() const { return _setId; }
+	int getSceneId() const { return _sceneId; }
 
 	bool didPlayerWalkIn() { bool r = _playerWalkedIn; _playerWalkedIn = false; return r; }
 
diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp
index f8a480c..5501f27 100644
--- a/engines/bladerunner/set.cpp
+++ b/engines/bladerunner/set.cpp
@@ -126,7 +126,7 @@ bool Set::open(const Common::String &name) {
 	return true;
 }
 
-void Set::addObjectsToScene(SceneObjects *sceneObjects) {
+void Set::addObjectsToScene(SceneObjects *sceneObjects) const {
 	for (int i = 0; i < _objectCount; i++) {
 		sceneObjects->addObject(i + SCENE_OBJECTS_OBJECTS_OFFSET, &_objects[i]._bbox, _objects[i]._isClickable, _objects[i]._isObstacle, _objects[i]._unknown1, _objects[i]._isTarget);
 	}
@@ -172,17 +172,17 @@ static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox) {
 	return found & 1;
 }
 
-float Set::getAltitudeAtXZ(float x, float z, bool *inWalkbox) {
+float Set::getAltitudeAtXZ(float x, float z, bool *inWalkbox) const {
 	float altitude = _walkboxes[0]._altitude;
 	*inWalkbox = false;
 
 	for (int i = 0; i < _walkboxCount; ++i) {
-		const Walkbox &w = _walkboxes[i];
+		const Walkbox &walkbox = _walkboxes[i];
 
-		if (isXZInWalkbox(x, z, w)) {
-			*inWalkbox = true;
-			if (w._altitude > altitude) {
-				altitude = w._altitude;
+		if (isXZInWalkbox(x, z, walkbox)) {
+			if (!*inWalkbox || altitude < walkbox._altitude) {
+				altitude = walkbox._altitude;
+				*inWalkbox = true;
 			}
 		}
 	}
@@ -190,7 +190,7 @@ float Set::getAltitudeAtXZ(float x, float z, bool *inWalkbox) {
 	return altitude;
 }
 
-int Set::findWalkbox(float x, float z) {
+int Set::findWalkbox(float x, float z) const {
 	int result = -1;
 
 	for (int i = 0; i < _walkboxCount; ++i) {
@@ -206,7 +206,7 @@ int Set::findWalkbox(float x, float z) {
 	return result;
 }
 
-int Set::findObject(const char *objectName) {
+int Set::findObject(const char *objectName) const {
 	int i;
 	for (i = 0; i < (int)_objectCount; i++) {
 		if (scumm_stricmp(objectName, _objects[i]._name) == 0) {
@@ -219,7 +219,7 @@ int Set::findObject(const char *objectName) {
 	return -1;
 }
 
-bool Set::objectSetHotMouse(int objectId) {
+bool Set::objectSetHotMouse(int objectId) const {
 	if (!_objects || objectId < 0 || objectId >= (int)_objectCount) {
 		return false;
 	}
@@ -228,7 +228,7 @@ bool Set::objectSetHotMouse(int objectId) {
 	return true;
 }
 
-bool Set::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) {
+bool Set::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) const {
 	assert(boundingBox);
 
 	if (!_objects || objectId < 0 || objectId >= (int)_objectCount) {
@@ -243,19 +243,19 @@ bool Set::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) {
 	return true;
 }
 
-void Set::objectSetIsClickable(int objectId, bool isClickable) {
+void Set::objectSetIsClickable(int objectId, bool isClickable) const {
 	_objects[objectId]._isClickable = isClickable;
 }
 
-void Set::objectSetIsObstacle(int objectId, bool isObstacle) {
+void Set::objectSetIsObstacle(int objectId, bool isObstacle) const {
 	_objects[objectId]._isObstacle = isObstacle;
 }
 
-void Set::objectSetIsTarget(int objectId, bool isTarget) {
+void Set::objectSetIsTarget(int objectId, bool isTarget) const {
 	_objects[objectId]._isTarget = isTarget;
 }
 
-const char *Set::objectGetName(int objectId) {
+const char *Set::objectGetName(int objectId) const {
 	return _objects[objectId]._name;
 }
 
diff --git a/engines/bladerunner/set.h b/engines/bladerunner/set.h
index 4b4a4d9..d3540c5 100644
--- a/engines/bladerunner/set.h
+++ b/engines/bladerunner/set.h
@@ -77,20 +77,20 @@ public:
 
 	bool open(const Common::String &name);
 
-	void addObjectsToScene(SceneObjects *sceneObjects);
-	uint32 getObjectCount() { return _objectCount; }
+	void addObjectsToScene(SceneObjects *sceneObjects) const;
+	uint32 getObjectCount() const { return _objectCount; }
 
-	float getAltitudeAtXZ(float x, float z, bool *inWalkbox);
+	float getAltitudeAtXZ(float x, float z, bool *inWalkbox) const;
 
-	int findWalkbox(float x, float z);
-	int findObject(const char *objectName);
+	int findWalkbox(float x, float z) const;
+	int findObject(const char *objectName) const;
 
-	bool objectSetHotMouse(int objectId);
-	bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox);
-	void objectSetIsClickable(int objectId, bool isClickable);
-	void objectSetIsObstacle(int objectId, bool isObstacle);
-	void objectSetIsTarget(int objectId, bool isTarget);
-	const char *objectGetName(int objectId);
+	bool objectSetHotMouse(int objectId) const;
+	bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox) const;
+	void objectSetIsClickable(int objectId, bool isClickable) const;
+	void objectSetIsObstacle(int objectId, bool isObstacle) const;
+	void objectSetIsTarget(int objectId, bool isTarget) const;
+	const char *objectGetName(int objectId) const;
 
 	void setWalkboxStepSound(int walkboxId, int soundId);
 	void setFoodstepSoundOverride(int soundId);
diff --git a/engines/bladerunner/settings.cpp b/engines/bladerunner/settings.cpp
index 679db51..81def7e 100644
--- a/engines/bladerunner/settings.cpp
+++ b/engines/bladerunner/settings.cpp
@@ -60,7 +60,7 @@ bool Settings::openNewScene() {
 //		music::stop(Music, 2);
 	}
 
-	int currentSet = _vm->_scene->_setId;
+	int currentSet = _vm->_scene->getSetId();
 	int newSet     = _newSet;
 	int newScene   = _newScene;
 
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index da4749b..845e2ee 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -108,31 +108,29 @@ int VQAPlayer::update() {
 	}
 
 
-//	TODO: preload audio
-//	int audioPreloadFrames = 1;
+//	TODO: preload audio in better way
+	int audioPreloadFrames = 3;
 
 	if (now >= _frameNextTime) {
 		int frame = _frameNext;
-//		_decoder.readFrame(_frameNext, 0x2);
-		_decoder.readFrame(_frameNext, 0);
+		_decoder.readFrame(_frameNext, 0x2);
 		_surface = _decoder.decodeVideoFrame();
 
 		if (_hasAudio) {
-			queueAudioFrame(_decoder.decodeAudioFrame());
 			if (!_audioStarted) {
-//				for (int i = 0; i < audioPreloadFrames; i++) {
-//					if (_frameNext + i < _frameEnd) {
-//						_decoder.readFrame(_frameNext + i, 0x1);
-//						queueAudioFrame(_decoder.decodeAudioFrame());
-//					}
-//				}
+				for (int i = 0; i < audioPreloadFrames; i++) {
+					if (_frameNext + i < _frameEnd) {
+						_decoder.readFrame(_frameNext + i, 0x1);
+						queueAudioFrame(_decoder.decodeAudioFrame());
+					}
+				}
 				_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, _audioStream);
 				_audioStarted = true;
 			}
-//			if (_frameNext + audioPreloadFrames < _frameEnd) {
-//				_decoder.readFrame(_frameNext + audioPreloadFrames, 0x1);
-//				queueAudioFrame(_decoder.decodeAudioFrame());
-//			}
+			if (_frameNext + audioPreloadFrames < _frameEnd) {
+				_decoder.readFrame(_frameNext + audioPreloadFrames, 0x1);
+				queueAudioFrame(_decoder.decodeAudioFrame());
+			}
 		}
 		if (_frameNextTime == 0) {
 			_frameNextTime = now + 60000 / 15;
diff --git a/engines/bladerunner/waypoints.h b/engines/bladerunner/waypoints.h
index c75cf00..8319c77 100644
--- a/engines/bladerunner/waypoints.h
+++ b/engines/bladerunner/waypoints.h
@@ -39,7 +39,7 @@ struct Waypoint {
 class Waypoints {
 	BladeRunnerEngine *_vm;
 
-private:
+public:
 	int       _count;
 	Waypoint *_waypoints;
 





More information about the Scummvm-git-logs mailing list