diff options
25 files changed, 707 insertions, 210 deletions
| diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index 1ea2b17de8..d1493b9300 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -31,6 +31,7 @@  #include "bladerunner/boundingbox.h"  #include "bladerunner/gameinfo.h"  #include "bladerunner/items.h" +#include "bladerunner/mouse.h"  #include "bladerunner/movement_track.h"  #include "bladerunner/scene.h"  #include "bladerunner/scene_objects.h" @@ -39,8 +40,6 @@  #include "bladerunner/slice_renderer.h"  #include "bladerunner/waypoints.h" -#include "common/system.h" -  namespace BladeRunner {  Actor::Actor(BladeRunnerEngine *vm, int actorId) { @@ -176,7 +175,21 @@ void Actor::processMovement() {  	}*/  } -void Actor::setAtXYZ(Vector3 position, int facing, bool snapFacing, bool moving, bool retired) { +bool Actor::loopWalkToActor(int otherActorId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning) { +	return loopWalk(_vm->_actors[otherActorId]->_position, destinationOffset, a3, run, _position, 24.0f, 24.0f, a5, isRunning, false); +} + +bool Actor::loopWalkToItem(int itemId, int destinationOffset, int a3, 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, a3, run, _position, width, 24.0f, a5, isRunning, false); +} + +void Actor::setAtXYZ(const Vector3 &position, int facing, bool snapFacing, bool moving, bool retired) {  	_position = position;  	setFacing(facing, snapFacing); @@ -201,76 +214,170 @@ void Actor::setAtWaypoint(int waypointId, int angle, int moving, bool retired) {  	setAtXYZ(waypointPosition, angle, true, moving, retired);  } -void Actor::loopWalkToXYZ(float x, float y, float z, int a4, int a5, int a6, int a7) { -	this->loopWalkToXYZ(Vector3(x, y, z)); -} +bool Actor::loopWalk(const Vector3 &destination, int destinationOffset, bool a3, bool run, const Vector3 &start, float targetWidth, float targetSize, bool a8, bool *isRunning, bool async) { +	if (true) { // simple walking +		*isRunning = false; +		bool stopped; +		_walkInfo->setup(_id, false, _position, destination, false, &stopped); + +		for (;;) { +			_vm->gameTick(); +			if (!_walkInfo->isWalking() && !_walkInfo->isRunning()) +				break; +			if (!_vm->_gameIsRunning) +				break; +		} +		return false; +	} else {  +		//TODO: +		// original code, not yet working +		*isRunning = false; + +		if (destinationOffset > 0) { +			float dist = distance(_position, destination); +			if (dist - targetSize <= destinationOffset) { +				return false; +			} +		} + +		if (a8 && !async && _id && destinationOffset <= 24) { +			if (distance(_vm->_playerActor->_position, destination) <= 24.0f) { +				_vm->_playerActor->walkToU(destination, 48.0f); +			} +		} -void Actor::loopWalkToXYZ(Vector3 destination) { -	int unk1; -	_walkInfo->setup(_id, false, _position, destination, 0, &unk1); +		if (_id) { +			a3 = false; +		} -	for (;;) { -		_vm->gameTick(); -		if (!_walkInfo->isWalking() && !_walkInfo->isRunning()) -			break; -		if (!_vm->_gameIsRunning) -			break; +		Vector3 destinationX(destination); + +		if (destinationOffset > 0) { +			walkFindU2(&destinationX, targetWidth, destinationOffset, targetSize, _position, destination); +		} + +		bool walking = walkTo(run, destinationX, a8); + +		if (async) { +			return false; +		} + +		if (!walking && destinationOffset > 0) { +			walking = walkTo(run, destination, a8); +		} + +		if (!walking) { +			return false; +		} + +		if (async) { +			return false; +		} +		if (_id) { +			_vm->_mouse->disable(); +		} +		if (a3) { +			//			TODO: +			//			dword_482990 = 1; +			//			dword_482994 = 0; +		} else { +			_vm->playerLosesControl(); +		} + +		if (a8) { +			_inWalkLoop = true; +		} + +		bool v46 = false; +		while (_walkInfo->isWalking() && _vm->_gameIsRunning) { +			if (_walkInfo->isRunning()) { +				*isRunning = true; +			} +			_vm->gameTick(); +			if (_id == 0 && a3 /*&& dword_482994*/) { +				stopWalking(false); +				v46 = true; +			} +		} +		if (a8) { +			_inWalkLoop = false; +		} +		if (a3) { +			//			dword_482990 = 1; +		} else { +			_vm->playerGainsControl(); +		} +		if (!v46 && destinationOffset == 0 /* && !PlayerActorIdle*/) { +			setAtXYZ(destination, _facing, true, false, false); +		} +		if (_id) { +			_vm->_mouse->enable(); +		} +		return v46;  	}  } -float distance(float, float, float, float); -float distance(Vector3 &v1, Vector3 &v2); +bool Actor::walkTo(bool run, const Vector3 &destination, bool a3) { +	bool isRunning; + +	return _walkInfo->setup(_id, run, _position, destination, a3, &isRunning); +} + +bool Actor::loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool a3, bool run, bool a5, bool *isRunning) { +	return loopWalk(destination, destinationOffset, a3, run, _position, 0.0f, 24.0f, a5, isRunning, false); +} -void Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset) { +bool Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset, bool a3, bool run, bool a5, bool *isRunning) {  	int sceneObject = _vm->_scene->_set->findObject(objectName); -	if (sceneObject < 0) -		return; +	if (sceneObject < 0) { +		return true; +	}  	BoundingBox bbox; -	if (!_vm->_scene->_set->objectGetBoundingBox(sceneObject, &bbox)) -		return; +	if (!_vm->_scene->_set->objectGetBoundingBox(sceneObject, &bbox)) { +		return true; +	}  	float x0, y0, z0, x1, y1, z1;  	bbox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1); -	// debug("[%f %f] -> [%f %f %f, %f %f %f]", _position.x, _position.z, x0, y0, z0, x1, y1, z1); - -	float closest_distance = distance(_position.x, _position.z, x0, z0); -	float closest_x = x0; -	float closest_z = z0; +	float closestDistance = distance(_position.x, _position.z, x0, z0); +	float closestX = x0; +	float closestZ = z0;  	float d = distance(_position.x, _position.z, x1, z0); -	// debug("%f - %f %f %f %f", d, _position.x, _position.z, x1, z0); -	if (d < closest_distance) { -		closest_x = x1; -		closest_z = z0; -		closest_distance = d; +	if (d < closestDistance) { +		closestX = x1; +		closestZ = z0; +		closestDistance = d;  	}  	d = distance(_position.x, _position.z, x1, z1); -	// debug("%f - %f %f %f %f", d, _position.x, _position.z, x1, z0); -	if (d < closest_distance) { -		closest_x = x1; -		closest_z = z1; -		closest_distance = d; +	if (d < closestDistance) { +		closestX = x1; +		closestZ = z1; +		closestDistance = d;  	}  	d = distance(_position.x, _position.z, x0, z1); -	// debug("%f - %f %f %f %f", d, _position.x, _position.z, x1, z0); -	if (d < closest_distance) { -		closest_x = x0; -		closest_z = z1; -		closest_distance = d; +	if (d < closestDistance) { +		closestX = x0; +		closestZ = z1; +		closestDistance = d;  	} +	bool inWalkbox; +	float y = _vm->_scene->_set->getAltitudeAtXZ(closestX, closestZ, &inWalkbox); +	Vector3 destination(closestX, y, closestZ); -	// debug("%f = %f %f %f %f", closest_distance, _position.x, _position.z, closest_x, closest_z); - -	Vector3 destination(closest_x, _position.y, closest_z); +	return loopWalk(destination, destinationOffset, a3, run, _position, 0.0f, 24.0f, a5, isRunning, false); +} -	// Vector3 properDestination(-124.2592, -0.3046913, 204.0923); -	// debug("delta: %f\n", distance(destination, properDestination)); +bool Actor::loopWalkToWaypoint(int waypointId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning) { +	float x, y, z; +	_vm->_waypoints->getXYZ(waypointId, &x, &y, &z); +	Vector3 waypointPosition(x, y, z); -	loopWalkToXYZ(destination); +	return loopWalk(waypointPosition, destinationOffset, a3, run, _position, 0.0f, 24.0f, a5, isRunning, false);  }  bool Actor::tick(bool forceDraw) { @@ -299,7 +406,7 @@ bool Actor::tick(bool forceDraw) {  		_animationFrame = newFrame;  		Vector3 positionChange = _vm->_sliceAnimations->getPositionChange(_animationId); -		float facingChange = _vm->_sliceAnimations->getFacingChange(_animationId); +		float angleChange = _vm->_sliceAnimations->getFacingChange(_animationId);  		if (_id == 47) {  			positionChange.x = 0.0f; @@ -331,10 +438,10 @@ bool Actor::tick(bool forceDraw) {  				}  			}  		} else { -			if (facingChange != 0.0f) { -				int v27 = (512.0f / M_PI) * facingChange; -				if (v27 != 0) { -					this->_facing = this->_facing - v27; +			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;  					} @@ -356,9 +463,9 @@ bool Actor::tick(bool forceDraw) {  					positionChange.z = positionChange.z * this->_actorSpeed.z;  				} -				float facing = (_facing / 512.0f) * M_PI; -				float sinx = sin(facing); -				float cosx = cos(facing); +				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; @@ -397,13 +504,13 @@ bool Actor::tick(bool forceDraw) {  }  void Actor::draw() { -	Vector3 draw_position(_position.x, -_position.z, _position.y + 2.0); -	float draw_facing = M_PI - _facing * M_PI / 512.0; -	float draw_scale  = _scale; +	Vector3 drawPosition(_position.x, -_position.z, _position.y + 2.0); +	float drawAngle = M_PI - _facing * (M_PI / 512.0f); +	float drawScale = _scale;  	// TODO: Handle SHORTY mode -	_vm->_sliceRenderer->drawFrame(_animationId, _animationFrame, draw_position, draw_facing, draw_scale, _vm->_surface2, _vm->_zBuffer2); +	_vm->_sliceRenderer->drawFrame(_animationId, _animationFrame, drawPosition, drawAngle, drawScale, _vm->_surface2, _vm->_zBuffer2);  	//todo udpate screenrect  } @@ -421,16 +528,16 @@ void Actor::setSetId(int setId) {  	if (_setId > 0) {  		for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {  			if (_vm->_actors[i]->_id != _id && _vm->_actors[i]->_setId == _setId) { -				// TODO: actorScript->OtherAgentExitedThisScene( i, _id); +				// TODO: _vm->_aiScripts->OtherAgentExitedThisScene( i, _id);  			}  		}  	}  	_setId = setId; -	// TODO: actorScript->EnteredScene(_id, set); +	// TODO: _vm->_aiScripts->EnteredScene(_id, set);  	if (_setId > 0) {  		for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {  			if (_vm->_actors[i]->_id != _id && _vm->_actors[i]->_setId == _setId) { -				// TODO: actorScript->OtherAgentEnteredThisScene(i, _id); +				// TODO: _vm->_aiScripts->OtherAgentEnteredThisScene(i, _id);  			}  		}  	} @@ -474,7 +581,7 @@ void Actor::setFacing(int facing, bool halfOrSet) {  	_facing = (_facing + offset) % 1024;  } -void Actor::setBoundingBox(Vector3 position, bool retired) { +void Actor::setBoundingBox(const Vector3 &position, bool retired) {  	if (retired) {  		_bbox->setXYZ(position.x - (_retiredWidth / 2.0f),  		              position.y, @@ -510,11 +617,11 @@ void Actor::stopWalking(bool value) {  	}  	if (isWalking()) { -		_walkInfo->stop(_id, 1, _combatAnimationMode, 0); +		_walkInfo->stop(_id, true, _combatAnimationMode, 0);  	} else if (inCombat()) { -		changeAnimationMode(_combatAnimationMode, 0); +		changeAnimationMode(_combatAnimationMode, false);  	} else { -		changeAnimationMode(0, 0); +		changeAnimationMode(0, false);  	}  } @@ -563,13 +670,13 @@ void Actor::faceWaypoint(int waypointId, bool animate) {  void Actor::faceXYZ(float x, float y, float z, bool animate) {  	if (isWalking()) { -		stopWalking(0); +		stopWalking(false);  	}  	if (x == _position.x && z == _position.z) {  		return;  	} -	int heading = int(512.0f * atan2f(_position.x - x, _position.z - z) / M_PI) % 1024; +	int heading = angle_1024(_position.x, _position.z, x, z);  	faceHeading(heading, animate);  } @@ -622,7 +729,7 @@ void Actor::setImmunityToObstacles(bool isImmune) {  void Actor::modifyCurrentHP(signed int change) {  	_currentHP = MIN(MAX(_currentHP + change, 0), 100);  	if (_currentHP > 0) -		retire(0, 0, 0, -1); +		retire(false, 0, 0, -1);  }  void Actor::modifyMaxHP(signed int change) { @@ -674,7 +781,7 @@ void Actor::setHealth(int hp, int maxHp) {  	_currentHP = hp;  	_maxHP = maxHp;  	if (hp > 0) { -		retire(0, 0, 0, -1); +		retire(false, 0, 0, -1);  	}  } @@ -685,8 +792,8 @@ void Actor::combatModeOn(int a2, int a3, int otherActorId, int a5, int combatAni  	_inCombat = true;  	if (_id > 0)  		_combatInfo->combatOn(_id, a2, a3, otherActorId, a5, a9, a10, a11, ammoDamage, a13, a14); -	stopWalking(0); -	changeAnimationMode(_combatAnimationMode, 0); +	stopWalking(false); +	changeAnimationMode(_combatAnimationMode, false);  	int i;  	for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {  		Actor *otherActor = _vm->_actors[i]; @@ -700,8 +807,8 @@ void Actor::combatModeOff() {  	if (_id > 0)  		_combatInfo->combatOff();  	_inCombat = false; -	stopWalking(0); -	changeAnimationMode(0, 0); +	stopWalking(false); +	changeAnimationMode(0, false);  	int i;  	for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) {  		Actor *otherActor = _vm->_actors[i]; @@ -868,4 +975,84 @@ void Actor::countdownTimerUpdate(int timerId) {  	}  } +bool Actor::walkFindU1(const Vector3 &startPosition, const Vector3 &targetPosition, float size, Vector3 *newDestination) { +	newDestination->x = 0.0f; +	newDestination->y = 0.0f; +	newDestination->z = 0.0f; +	int facing = angle_1024(targetPosition, startPosition); +	int facing1 = 0; + +	int facing2 = facing; +	int facing3 = 0; +	while (true) { +		float cos = cos_1024(facing); +		float sin = sin_1024(facing); +		float rotatedX = size * sin + targetPosition.x; +		float rotatedZ = size * cos + targetPosition.z; + +		if (!_walkInfo->isXYZEmpty(rotatedX, targetPosition.y, rotatedZ, _id)) { +			if (_vm->_scene->_set->findWalkbox(rotatedX, rotatedZ) >= 0) { +				newDestination->x = rotatedX; +				newDestination->y = targetPosition.y; +				newDestination->z = rotatedZ; +				return true; +			} +		} else { +			facing += 20; +			if (facing > 1024) { +				facing -= 1024; +			} +			facing3 += 20; +		} + +		cos = cos_1024(facing2); +		sin = sin_1024(facing2); +		rotatedX = size * sin + targetPosition.x; +		rotatedZ = size * cos + targetPosition.z; + +		if (!_walkInfo->isXYZEmpty(rotatedX, targetPosition.y, rotatedZ, _id)) { +			if (_vm->_scene->_set->findWalkbox(rotatedX, rotatedZ) >= 0) { +				newDestination->x = rotatedX; +				newDestination->y = targetPosition.y; +				newDestination->z = rotatedZ; +				return true; +			} +		} else { +			facing2 -= 20; +			if (facing2 < 0) { +				facing2 += 1024; +			} +			facing1 += 20; +		} + +		if (facing3 > 1024 && facing1 > 1024) { +			return false; +		} +	} +} + +bool Actor::walkFindU2(Vector3 *newDestination, float targetWidth, int destinationOffset, float targetSize, const Vector3 &startPosition, const Vector3 &targetPosition) { +	newDestination->x = 0.0f; +	newDestination->y = 0.0f; +	newDestination->z = 0.0f; +	float size = destinationOffset + targetSize * 0.5f + targetWidth * 0.5f; +	float distance = (startPosition - targetPosition).length() - targetWidth * 0.5f - targetSize * 0.5f; +	if (size < distance) { +		return walkFindU1(startPosition, targetPosition, size, newDestination); +	} else { +		*newDestination = targetPosition; +		return true; +	} +} + +bool Actor::walkToU(const Vector3 &destination, float distance) { +	Vector3 out; +	bool isRunning; +	if (_walkInfo->findU1(_id, destination, distance, &out)) { +		loopWalk(out, 0, false, false, _position, 0.0f, 24.0f, false, &isRunning, false); +		return true; +	} +	return false; +} +  } // End of namespace BladeRunner diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h index 1edbea49b4..b2b52c623d 100644 --- a/engines/bladerunner/actor.h +++ b/engines/bladerunner/actor.h @@ -72,6 +72,7 @@ private:  	bool _isTargetable;  	bool _isInvisible;  	bool _isImmuneToObstacles; +	bool _inWalkLoop;  	bool _isRetired;  	bool _inCombat;  	bool _isMoving; @@ -106,7 +107,7 @@ public:  	void setup(int actorId); -	void setAtXYZ(Vector3 pos, int facing, bool setFacing = true, bool moving = false, bool retired = false); +	void setAtXYZ(const Vector3 &pos, int facing, bool setFacing = true, bool moving = false, bool retired = false);  	void setAtWaypoint(int waypointId, int angle, int unknown, bool retired);  	float getX(); @@ -123,9 +124,11 @@ public:  	void processMovement(); -	void loopWalkToXYZ(Vector3 destination); -	void loopWalkToXYZ(float x, float y, float z, int a4, int a5, int a6, int a7); -	void loopWalkToSceneObject(const char *objectName, int destinationOffset = 0); +	bool loopWalkToActor(int otherActorId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning); +	bool loopWalkToItem(int itemId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning); +	bool loopWalkToSceneObject(const char *objectName, int destinationOffset, bool a3, bool run, bool a5, bool *isRunning); +	bool loopWalkToWaypoint(int waypointId, int destinationOffset, int a3, bool run, bool a5, bool *isRunning); +	bool loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool a3, bool run, bool a5, bool *isRunning);  	bool tick(bool forceUpdate);  	void draw(); @@ -141,8 +144,9 @@ public:  	Common::Rect *getScreenRectangle() { return &_screenRectangle; }  	int getWalkbox() { return _walkboxId; }  	bool isRetired() { return _isRetired; } -	bool isTargetable() { return _isTargetable; } +	bool isTargetable() { return _isTargetable; }	  	void setTargetable(bool targetable); +	bool isImmuneToObstacles() { return _isImmuneToObstacles; }  	bool inCombat() { return _inCombat; }  	bool isMoving() { return _isMoving; }  	void setMoving(bool value) { _isMoving = value; } @@ -198,8 +202,16 @@ public:  	int soundBalance();  private:  	void setFacing(int facing, bool halfOrSet = true); -	void setBoundingBox(Vector3 position, bool retired); +	void setBoundingBox(const Vector3 &position, bool retired);  	float distanceFromView(View* view); +	 +	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 walkFindU3(int actorId, Vector3 from, int distance, Vector3 *out);  };  } // End of namespace BladeRunner diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp index ed55bd0277..717422f60d 100644 --- a/engines/bladerunner/actor_walk.cpp +++ b/engines/bladerunner/actor_walk.cpp @@ -25,14 +25,13 @@  #include "bladerunner/bladerunner.h"  #include "bladerunner/actor.h" +#include "bladerunner/obstacles.h" +#include "bladerunner/scene.h"  #include "bladerunner/scene_objects.h" +#include "bladerunner/set.h" -namespace BladeRunner { -static int angle_1024(float x1, float z1, float x2, float z2); -static int angle_1024(Vector3 &v1, Vector3 &v2); -float distance(float x1, float x2, float z1, float z2); -float distance(Vector3 &v1, Vector3 &v2); +namespace BladeRunner {  ActorWalk::ActorWalk(BladeRunnerEngine *vm) {  	_vm = vm; @@ -41,36 +40,38 @@ ActorWalk::ActorWalk(BladeRunnerEngine *vm) {  	_running =  0;  	_facing  = -1;  	_status  =  0; + +	_entries.clear();  }  ActorWalk::~ActorWalk() {  } -int ActorWalk::setup(int actorId, int run, Vector3 from, Vector3 to, int unk1, int *unk2) { +bool ActorWalk::setup(int actorId, bool run, const Vector3 &from, const Vector3 &to, bool unk1, bool *stopped) {  	Vector3 next; -	*unk2 = 0; +	*stopped = false;  	int r = nextOnPath(actorId, from, to, &next);  	if (r == 0) {  		if (actorId != 0) {  			_current = from;  			_destination = to; -			stop(actorId, false); +			stop(actorId, false, 4, 0);  		} else { -			stop(actorId, true); +			stop(actorId, true, 4, 0);  		} -		return 0; +		return false;  	}  	if (r == -1) { -		stop(actorId, true); -		*unk2 = 1; -		return 0; +		stop(actorId, true, 4, 0); +		*stopped = true; +		return false;  	} -	// TODO: Init array -	// TODO: Update screen index -	// Set actor field e8 +	resetList(); +	_vm->_sceneObjects->setMoving(actorId + SCENE_OBJECTS_ACTORS_OFFSET, true); +	_vm->_actors[actorId]->setMoving(true);  	if (_running) {  		run = true; @@ -95,17 +96,17 @@ int ActorWalk::setup(int actorId, int run, Vector3 from, Vector3 to, int unk1, i  		_running = run;  		_status = 2; -		return 1; +		return true;  	} -	stop(actorId, true); -	return 0; +	stop(actorId, true, 4, 0); +	return false;  }  bool ActorWalk::tick(int actorId, float stepDistance, bool flag) {  	if (_status == 5) {  		if (flag) { -			stop(actorId, true); +			stop(actorId, true, 4, 0);  			return true;  		} @@ -117,7 +118,7 @@ bool ActorWalk::tick(int actorId, float stepDistance, bool flag) {  	// TODO: Handle collisions?  	if (stepDistance > distance(_current, _destination)) { -		stop(actorId, true); +		stop(actorId, true, 4, 0);  		_current = _destination;  		// TODO: Update y from walkbox  		return true; @@ -127,7 +128,7 @@ bool ActorWalk::tick(int actorId, float stepDistance, bool flag) {  	_current = Vector3(  		_current.x + stepDistance * sinf(angle_rad), -		_current.y,                    // TODO: Update from walkbox +		_current.y, // TODO: Update from walkbox  		_current.z - stepDistance * cosf(angle_rad)  	); @@ -135,7 +136,7 @@ bool ActorWalk::tick(int actorId, float stepDistance, bool flag) {  }  void ActorWalk::getCurrentPosition(int actorId, Vector3 *pos, int *facing) { -	*pos    = _current; +	*pos = _current;  	*facing = _facing;  } @@ -144,14 +145,14 @@ void ActorWalk::setRunning() {  	// TODO: Set animation mode  } -void ActorWalk::stop(int actorId, bool unknown, int animationMode, int notused) { -	_vm->_sceneObjects->setMoving(actorId, 0); -	_vm->_actors[actorId]->setMoving(0); +void ActorWalk::stop(int actorId, bool unknown, int combatAnimationMode, int animationMode) { +	_vm->_sceneObjects->setMoving(actorId, false); +	_vm->_actors[actorId]->setMoving(false);  	if (_vm->_actors[actorId]->inCombat()) { -		_vm->_actors[actorId]->changeAnimationMode(animationMode, 0); +		_vm->_actors[actorId]->changeAnimationMode(combatAnimationMode, false);  	} else { -		_vm->_actors[actorId]->changeAnimationMode(notused, 0); +		_vm->_actors[actorId]->changeAnimationMode(animationMode, false);  	}  	if (unknown) { @@ -165,45 +166,111 @@ void ActorWalk::stop(int actorId, bool unknown, int animationMode, int notused)  	}  } -int ActorWalk::nextOnPath(int actorId, Vector3 from, Vector3 to, Vector3 *next) { -	if (distance(from, to) < 6.0) { -		return -1; +bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) { +	if (_vm->_scene->_set->findWalkbox(x, z) == -1) { +		return true;  	} - -	// if (_vm->_actors[actorId]->getImmunityToObstacles()) { -		*next = to; -		return 1; -	// } - -	error("TODO!"); +	if (_vm->_actors[actorId]->isImmuneToObstacles()) { +		return false; +	} +	return _vm->_sceneObjects->existsOnXZ(actorId, x, z, false, false);  } -static int angle_1024(float x1, float z1, float x2, float z2) { -	float angle_rad = atan2(x2 - x1, z1 - z2); -	int a = int(512.0 * angle_rad / M_PI); -	return (a + 1024) % 1024; -} +int ActorWalk::findU1(int actorId, const Vector3 &to, int dist, Vector3 *out) { +	float cos, sin; +	bool inWalkbox; + +	int facingFound = -1; +	float distFound = -1.0f; +	float x = 0.0f; +	float z = 0.0f; + +	out->x = 0.0f; +	out->y = 0.0f; +	out->z = 0.0f; + +	for (int facing = 0; facing < 1024; facing += 128) { +		sin = sin_1024(facing); +		cos = cos_1024(facing); +		x = to.x + sin * dist; +		z = to.z + cos * dist; +		float dist2 = distance(x, z, _vm->_actors[actorId]->getX(), _vm->_actors[actorId]->getZ()); + +		if (distFound == -1.0f || distFound > dist2) { +			distFound = dist2; +			facingFound = facing; +		} +	} -static int angle_1024(Vector3 &v1, Vector3 &v2) { -	return angle_1024(v1.x, v1.z, v2.x, v2.z); -} +	int v23 = facingFound; +	int v24 = facingFound; +	int v25 = -1024; +	while (v25 < 0) { +		sin = sin_1024(v24); +		cos = cos_1024(v24); +		x = to.x + sin * dist; +		z = to.z + cos * dist; + +		if (!_vm->_sceneObjects->existsOnXZ(actorId, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) { +			break; +		} -float distance(float x1, float z1, float x2, float z2) { -	float dx = x1 - x2; -	float dz = z1 - z2; -	float d = sqrt(dx * dx + dz * dz); +		sin = sin_1024(v23); +		cos = cos_1024(v23); +		x = to.x + sin * dist; +		z = to.z + cos * dist; -	float int_part = (int)d; -	float frac_part = d - int_part; +		if (!_vm->_sceneObjects->existsOnXZ(actorId, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) { +			break; +		} -	if (frac_part < 0.001) -		frac_part = 0.0; +		v24 -= 64; +		if (v24 < 0) { +			v24 += 1024; +		} +		v23 += 64; +		if (v23 >= 1024) { +			v23 -= 1024; +		} +		v25 += 64; +	} -	return int_part + frac_part; +	float y = _vm->_scene->_set->getAltitudeAtXZ(x, z, &inWalkbox); +	if (inWalkbox) { +		out->x = x; +		out->y = y; +		out->z = z; +		return true; +	} +	return false;  } -float distance(Vector3 &v1, Vector3 &v2) { -	return distance(v1.x, v1.z, v2.x, v2.z); +int ActorWalk::nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 *next) { +	*next = from; + +	if (distance(from, to) < 6.0) { +		return -1; +	} + +	if (_vm->_actors[actorId]->isImmuneToObstacles()) { +		*next = to; +		return 1; +	} +	if (_vm->_scene->_set->findWalkbox(to.x, to.z) == -1) { +		return 0; +	} +	if (_vm->_sceneObjects->existsOnXZ(actorId, to.x, to.z, false, false)) { +		return 0; +	} +	Vector3 next1; +	if (_vm->_obstacles->find(from, to, &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 12da69bead..6cd5850672 100644 --- a/engines/bladerunner/actor_walk.h +++ b/engines/bladerunner/actor_walk.h @@ -24,6 +24,7 @@  #define BLADERUNNER_ACTOR_WALK_H  #include "bladerunner/vector.h" +#include "common/array.h"  namespace BladeRunner { @@ -45,8 +46,7 @@ private:  	Vector3 _current;  	Vector3 _next;  	int     _facing; -	ActorWalkEntry _actors[20]; -	int     _actorsCount; +	Common::Array<ActorWalk> _entries;  	int     _field15;  	int     _status; @@ -54,7 +54,8 @@ public:  	ActorWalk(BladeRunnerEngine *vm);  	~ActorWalk(); -	int setup(int actorId, int run, Vector3 from, Vector3 to, int unk1, int *unk2); +	 +	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 tick(int actorId, float stepDistance, bool flag); @@ -62,10 +63,15 @@ public:  	bool isRunning() { return _running; }  	void setRunning(); -	void stop(int actorId, bool unknown, int animationMode = 4, int notused = 0); +	void stop(int actorId, bool unknown, int combatAnimationMode, int animationMode);  	// void setWalkingMode(int actorId, int active, int unk2 = 4, int unk3 = 0); -	int nextOnPath(int actorId, Vector3 from, Vector3 to, Vector3 *next); +	int nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 *next); + +	void resetList(); + +	bool isXYZEmpty(float x, float y, float z, int actorId); +	int findU1(int actorId, const Vector3 &to, int distance, Vector3 *out);  };  } // End of namespace BladeRunner diff --git a/engines/bladerunner/adq.cpp b/engines/bladerunner/adq.cpp index b8611ee665..ca72497b99 100644 --- a/engines/bladerunner/adq.cpp +++ b/engines/bladerunner/adq.cpp @@ -32,7 +32,7 @@  namespace BladeRunner { -ADQ::ADQEntry::ADQEntry() { +ADQEntry::ADQEntry() {  	this->_isNotPause = false;  	this->_isPause = false;  	this->_actorId = -1; diff --git a/engines/bladerunner/adq.h b/engines/bladerunner/adq.h index b0619c7650..f4e69df684 100644 --- a/engines/bladerunner/adq.h +++ b/engines/bladerunner/adq.h @@ -28,22 +28,21 @@ namespace BladeRunner {  class BladeRunnerEngine; +struct ADQEntry { +	bool _isNotPause; +	bool _isPause; +	int _actorId; +	int _sentenceId; +	int _animationMode; +	int _delay; + +	ADQEntry(); +}; +  // actor dialogue queue??  class ADQ {  	BladeRunnerEngine *_vm; -	class ADQEntry { -	public: -		bool _isNotPause; -		bool _isPause; -		int _actorId; -		int _sentenceId; -		int _animationMode; -		int _delay; - -		ADQEntry(); -	}; -  	Common::Array<ADQEntry> _entries;  	bool     _isNotPause; diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 3365bb1c09..66ed387e0d 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -37,6 +37,7 @@  #include "bladerunner/lights.h"  #include "bladerunner/mouse.h"  #include "bladerunner/outtake.h" +#include "bladerunner/obstacles.h"  #include "bladerunner/scene.h"  #include "bladerunner/scene_objects.h"  #include "bladerunner/script/init.h" @@ -73,6 +74,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst)  	_lights = new Lights(this);  	_combat = new Combat(this);  	_adq = new ADQ(this); +	_obstacles = new Obstacles(this);  	_walkSoundId = -1;  	_walkSoundVolume = 0; @@ -100,6 +102,7 @@ BladeRunnerEngine::~BladeRunnerEngine() {  	// delete[] _zBuffer1;  	// delete[] _zBuffer2; +	delete _obstacles;  	delete _adq;  	delete _combat;  	delete _lights; @@ -743,7 +746,8 @@ void BladeRunnerEngine::handleMouseClick(int x, int y) {  	}  	if (sceneObjectId == -1) { -		_actors[0]->loopWalkToXYZ(mousePosition); +		bool isRunning; +		_playerActor->loopWalkToXYZ(mousePosition, 0, false, false, false, &isRunning);  		debug("Clicked on nothing %f, %f, %f", mousePosition.x, mousePosition.y, mousePosition.z);  		return;  	} else if (sceneObjectId >= 0 && sceneObjectId <= 73) { diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 273449fcf6..d3759d6ce8 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -49,6 +49,7 @@ class GameInfo;  class Items;  class Lights;  class Mouse; +class Obstacles;  class Scene;  class SceneObjects;  class Script; @@ -65,7 +66,7 @@ public:  	bool      _gameIsRunning;  	bool      _windowIsActive;  	int       _playerLosesControlCounter; - +	  	ADQ             *_adq;  	AIScripts       *_aiScripts;  	AmbientSounds   *_ambientSounds; @@ -73,9 +74,13 @@ public:  	AudioSpeech     *_audioSpeech;  	Chapters        *_chapters;  	Clues           *_clues; +	Combat          *_combat;  	GameFlags       *_gameFlags;  	GameInfo        *_gameInfo; +	Items           *_items; +	Lights          *_lights;  	Mouse           *_mouse; +	Obstacles       *_obstacles;  	Scene           *_scene;  	SceneObjects    *_sceneObjects;  	Script          *_script; @@ -83,13 +88,9 @@ public:  	SliceAnimations *_sliceAnimations;  	SliceRenderer   *_sliceRenderer;  	View            *_view; -	int             *_gameVars; - -	Lights          *_lights;  	Waypoints       *_waypoints; -	Items           *_items; -	Combat          *_combat; - +	int             *_gameVars; +	  	TextResource    *_textActorNames;  	TextResource    *_textCrimes;  	TextResource    *_textCluetype; @@ -124,6 +125,7 @@ public:  	int _walkSoundId;  	int _walkSoundVolume;  	int _walkSoundBalance; +	int _walkingActorId;  private:  	static const int kArchiveCount = 10; diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp index 11e75e93e6..00f98d35b8 100644 --- a/engines/bladerunner/item.cpp +++ b/engines/bladerunner/item.cpp @@ -66,6 +66,11 @@ void Item::getXYZ(float *x, float *y, float *z) {  	*z = _position.z;  } +void Item::getWidthHeight(int *width, int *height) { +	*width = _width; +	*height = _height; +} +  bool Item::isTargetable() {  	return _isTargetable;  } @@ -84,7 +89,7 @@ void Item::tick(bool special) {  			} else if (_facing < 0) {  				_facing += 1024;  			} -			_angle = M_PI / 512.0f * _facing; +			_angle = _facing * (M_PI / 512.0f);  			if (_facingChange > 0) {  				_facingChange = _facingChange - 20; @@ -108,7 +113,7 @@ void Item::tick(bool special) {  void Item::setXYZ(Vector3 position) {  	_position = position;  	int halfWidth = _width / 2; -	_boundingBox.setXYZ(_position.x - halfWidth, _position.y,           _position.z - halfWidth, +	_boundingBox.setXYZ(_position.x - halfWidth, _position.y, _position.z - halfWidth,  	                    _position.x + halfWidth, _position.y + _height, _position.z + halfWidth);  	Vector3 screenPosition = _vm->_view->calculateScreenPosition(_position);  	_screenX = screenPosition.x; @@ -121,7 +126,7 @@ void Item::setup(int itemId, int setId, int animationId, Vector3 position, int f  	_setId = setId;  	_animationId = animationId;  	_facing = facing; -	_angle = M_PI / 512.0f * facing; +	_angle = facing * (M_PI / 512.0f);  	_width = width;  	_height = height;  	_isTargetable = isTargetable; diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h index bdcaea7846..0035985751 100644 --- a/engines/bladerunner/item.h +++ b/engines/bladerunner/item.h @@ -62,12 +62,16 @@ private:  public:  	Item(BladeRunnerEngine* vm);  	~Item(); - +	  	void getXYZ(float *x, float *y, float *z); +	void setXYZ(Vector3 position); +	void getWidthHeight(int * width, int * height); +  	bool isTargetable();  	void tick(bool special); -	void setXYZ(Vector3 position); +  	void setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy); +	  };  } diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp index e9cb013246..51145a3b14 100644 --- a/engines/bladerunner/items.cpp +++ b/engines/bladerunner/items.cpp @@ -44,6 +44,13 @@ void Items::getXYZ(int itemId, float* x, float* y, float* z) {  	_items[itemIndex]->getXYZ(x, y, z);  } +void Items::getWidthHeight(int itemId, int *width, int *height) { +	int itemIndex = findItem(itemId); +	assert(itemIndex != -1); + +	_items[itemIndex]->getWidthHeight(width, height); +} +  void Items::tick() {  	int setId = _vm->_scene->getSetId();  	for(int i = 0; i < (int)_items.size(); i++) { diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h index e6e1cb2500..0b5c7e09a9 100644 --- a/engines/bladerunner/items.h +++ b/engines/bladerunner/items.h @@ -40,9 +40,12 @@ public:  	~Items();  	void getXYZ(int itemId, float *x, float *y, float *z); +	void getWidthHeight(int itemId, int * width, int * height); +  	void tick();  	bool add(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool b);  	bool remove(int itemId); +	  private:  	int findItem(int itemId);  }; diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk index 3867331a36..b7c85ceeec 100644 --- a/engines/bladerunner/module.mk +++ b/engines/bladerunner/module.mk @@ -31,6 +31,7 @@ MODULE_OBJS = \  	matrix.o \  	mouse.o \  	movement_track.o \ +	obstacles.o \  	outtake.o \  	regions.o \  	scene.o \ diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp new file mode 100644 index 0000000000..3c9552d231 --- /dev/null +++ b/engines/bladerunner/obstacles.cpp @@ -0,0 +1,46 @@ +#include "bladerunner/obstacles.h" + +#include "bladerunner/bladerunner.h" + +namespace BladeRunner { + +Obstacles::Obstacles(BladeRunnerEngine* vm) { +	_vm = vm; +	_polygons  = new ObstaclesPolygon[50]; +	_polygons2 = new ObstaclesPolygon[50]; +	_unknown = new int[50]; +	clear(); +} + +Obstacles::~Obstacles() { +	delete[] _unknown; +	delete[] _polygons2; +	delete[] _polygons; +} + +void Obstacles::clear() { +	for(int i = 0; i < 50; i++) { +		_polygons[i]._isPresent = false; +		_polygons[i]._verticesCount = 0; +		for(int j = 0; j < 160; j++) { +			_polygons[i]._vertices[j].x = 0.0f; +			_polygons[i]._vertices[j].y = 0.0f; +		} +	} +	_count = 0; +	_processed = false; +} + +void Obstacles::add(float x0, float z0, float x1, float z1) { + +} + +bool Obstacles::find(const Vector3 &from, const Vector3 &to, Vector3 *next) { +	//TODO +	*next = to; +	return true; +} + +void Obstacles::process() { +} +} // End of namespace BladeRunner diff --git a/engines/bladerunner/obstacles.h b/engines/bladerunner/obstacles.h new file mode 100644 index 0000000000..2caa3cd580 --- /dev/null +++ b/engines/bladerunner/obstacles.h @@ -0,0 +1,64 @@ +/* ScummVM - Graphic Adventure Engine +* +* ScummVM is the legal property of its developers, whose names +* are too numerous to list here. Please refer to the COPYRIGHT +* file distributed with this source distribution. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +*/ + +#ifndef BLADERUNNER_OBSTACLES_H +#define BLADERUNNER_OBSTACLES_H +#include "vector.h" + +namespace BladeRunner { + +struct ObstaclesPolygon { +	bool    _isPresent; +	int     _verticesCount; +	float   _left; +	float   _bottom; +	float   _right; +	float   _top; +	Vector2 _vertices[160]; +	int     _vertexType[160]; +}; + +class BladeRunnerEngine; + +class Obstacles { +	BladeRunnerEngine *_vm; + +private: +	ObstaclesPolygon *_polygons; +	ObstaclesPolygon *_polygons2; +	int              *_unknown; +	int               _count; +	bool              _processed; + +public: +	Obstacles(BladeRunnerEngine *vm); +	~Obstacles(); + +	void clear(); +	void add(float x0, float z0, float x1, float z1); +	bool find(const Vector3 &from, const Vector3 &to, Vector3 *next); +	void process(); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp index 06563b7d51..f9a112eff5 100644 --- a/engines/bladerunner/scene.cpp +++ b/engines/bladerunner/scene.cpp @@ -236,7 +236,7 @@ void Scene::objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded,  	if (sceneLoaded) {  		_vm->_sceneObjects->setIsObstacle(objectId + 198, isObstacle);  		if(updateWalkpath) { -			_vm->_sceneObjects->updateWalkpath(); +			_vm->_sceneObjects->updateObstacles();  		}  	}  } diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp index 4c038fa9c7..59df6c12b4 100644 --- a/engines/bladerunner/scene_objects.cpp +++ b/engines/bladerunner/scene_objects.cpp @@ -22,8 +22,12 @@  #include "bladerunner/scene_objects.h" +#include "bladerunner/bladerunner.h" + +#include "bladerunner/obstacles.h"  #include "bladerunner/view.h" +  namespace BladeRunner {  SceneObjects::SceneObjects(BladeRunnerEngine *vm, View *view) { @@ -280,8 +284,18 @@ void SceneObjects::setIsTarget(int sceneObjectId, bool isTarget) {  } -void SceneObjects::updateWalkpath() { -	//TODO: implement +void SceneObjects::updateObstacles() { +	_vm->_obstacles->clear(); +	for(int i = 0; i < _count; i++) { +		int index = _sceneObjectsSortedByDistance[i]; +		SceneObject sceneObject = _sceneObjects[index]; +		if(sceneObject._isObstacle) { +			float x0, y0, z0, x1, y1, z1; +			sceneObject._boundingBox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1); +			_vm->_obstacles->add(x0, z0, x1, z1); +		} +	} +	_vm->_obstacles->process();  }  } // End of namespace BladeRunner diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h index 947ee17336..010dc43532 100644 --- a/engines/bladerunner/scene_objects.h +++ b/engines/bladerunner/scene_objects.h @@ -87,7 +87,7 @@ public:  	void setIsClickable(int sceneObjectId, bool isClickable);  	void setIsObstacle(int sceneObjectId, bool isObstacle);  	void setIsTarget(int sceneObjectId, bool isTarget); -	void updateWalkpath(); +	void updateObstacles();  private:  	int findById(int sceneObjectId); diff --git a/engines/bladerunner/script/nr03.cpp b/engines/bladerunner/script/nr03.cpp index f0d2f359b5..a4afdd36ec 100644 --- a/engines/bladerunner/script/nr03.cpp +++ b/engines/bladerunner/script/nr03.cpp @@ -305,7 +305,7 @@ void ScriptNR03::sub_40259C(int frame) {  	float z = -60.21f * s + 36.49f * c + -408.79f;  	if (Actor_Query_Goal_Number(4) == 201) { -		facing = angle * (1024.0f / (2.0f * M_PI)); +		facing = angle * (512.0f / M_PI);  		facing = facing + 144;  		if (facing < 0) {  			facing = facing + 1168; @@ -315,7 +315,7 @@ void ScriptNR03::sub_40259C(int frame) {  		}  		Actor_Set_At_XYZ(4, x, -70.19f, z, facing);  	} else { -		facing = angle * (1024.0f / (2.0f * M_PI)); +		facing = angle * (512.0f / M_PI);  		facing = facing + 400;  		if (facing < 0) {  			facing = facing + 1424; diff --git a/engines/bladerunner/script/nr05.cpp b/engines/bladerunner/script/nr05.cpp index a62052bdfd..d686bce374 100644 --- a/engines/bladerunner/script/nr05.cpp +++ b/engines/bladerunner/script/nr05.cpp @@ -205,7 +205,7 @@ void ScriptNR05::sub_401F74(int frame) {  	float x = 6.0f * s - 80.0f * c + -450.0f;  	float z = 80.0f * s + 6.0f * c + -531.0f; -	int facing = angle * (1024.0f / (2.0f * M_PI)); +	int facing = angle * (512.0f / M_PI);  	facing = facing + 765;  	if (facing < 0) {  		facing = facing + 1789; diff --git a/engines/bladerunner/script/rc01.cpp b/engines/bladerunner/script/rc01.cpp index 9d88d2dec3..d94f104403 100644 --- a/engines/bladerunner/script/rc01.cpp +++ b/engines/bladerunner/script/rc01.cpp @@ -215,7 +215,7 @@ bool ScriptRC01::ClickedOn3DObject(const char *objectName, bool a2) {  	}  	if (Object_Query_Click("HYDRANT02", objectName)) { -		if (!Loop_Actor_Walk_To_Scene_Object(0, "HYDRANT02", 60, 1, false)) { +		if (!Loop_Actor_Walk_To_Scene_Object(0, "HYDRANT02", 60, true, false)) {  			if (Actor_Clue_Query(0, 26)) {  				Actor_Says(0, 6975, 3);  			} else { @@ -230,7 +230,7 @@ bool ScriptRC01::ClickedOn3DObject(const char *objectName, bool a2) {  	}  	if (Object_Query_Click("DOOR LEFT", objectName)) { -		if (!Loop_Actor_Walk_To_Scene_Object(0, "DOOR LEFT", 48, 1, false)) { +		if (!Loop_Actor_Walk_To_Scene_Object(0, "DOOR LEFT", 48, true, false)) {  			Actor_Face_Object(0, "DOOR LEFT", true);  			if (!Actor_Clue_Query(0, 2) && Actor_Query_In_Set(23, 69) && Global_Variable_Query(1)) {  				Actor_Set_Goal_Number(23, 0); @@ -247,7 +247,7 @@ bool ScriptRC01::ClickedOn3DObject(const char *objectName, bool a2) {  	}  	if (Object_Query_Click("T-CAN01", objectName)) { -		if (!Loop_Actor_Walk_To_Scene_Object(0, "T-CAN01", 24, 1, false)) { +		if (!Loop_Actor_Walk_To_Scene_Object(0, "T-CAN01", 24, true, false)) {  			Actor_Face_Object(0, "T-CAN01", true);  			Actor_Voice_Over(1810, 99);  			Actor_Voice_Over(1820, 99); @@ -530,7 +530,7 @@ bool ScriptRC01::ClickedOnExit(int exitId) {  }  void ScriptRC01::sub_403850() { -	if (!Game_Flag_Query(186) && !Loop_Actor_Walk_To_Scene_Object(0, "BARICADE03", 36, 1, false)) { +	if (!Game_Flag_Query(186) && !Loop_Actor_Walk_To_Scene_Object(0, "BARICADE03", 36, true, false)) {  		Actor_Set_Goal_Number(23, 0);  		Actor_Face_Object(0, "BARICADE03", true);  		Loop_Actor_Walk_To_Actor(23, 0, 36, 1, false); diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp index 216428c2f8..180e8cb96e 100644 --- a/engines/bladerunner/script/script.cpp +++ b/engines/bladerunner/script/script.cpp @@ -540,48 +540,75 @@ int ScriptBase::Actor_Query_Animation_Mode(int actorId) {  	return _vm->_actors[actorId]->getAnimationMode();  } -bool ScriptBase::Loop_Actor_Walk_To_Actor(int actorId, int otherActorId, int a3, int a4, bool running) { +bool ScriptBase::Loop_Actor_Walk_To_Actor(int actorId, int otherActorId, int a3, int a4, bool run) {  	//TODO -	warning("Loop_Actor_Walk_To_Actor(%d, %d, %d, %d, %d)", actorId, otherActorId, a3, a4, running); +	warning("Loop_Actor_Walk_To_Actor(%d, %d, %d, %d, %d)", actorId, otherActorId, a3, a4, run);  	return false;  } -bool ScriptBase::Loop_Actor_Walk_To_Item(int actorId, int itemId, int a3, int a4, bool running) { +bool ScriptBase::Loop_Actor_Walk_To_Item(int actorId, int itemId, int a3, int a4, bool run) {  	//TODO -	warning("Loop_Actor_Walk_To_Item(%d, %d, %d, %d, %d)", actorId, itemId, a3, a4, running); +	warning("Loop_Actor_Walk_To_Item(%d, %d, %d, %d, %d)", actorId, itemId, a3, a4, run);  	return false;  } -bool ScriptBase::Loop_Actor_Walk_To_Scene_Object(int actorId, const char *objectName, int distance, int a4, bool running) { +bool ScriptBase::Loop_Actor_Walk_To_Scene_Object(int actorId, const char *objectName, int destinationOffset, bool a4, bool run) {  	_vm->gameWaitForActive(); -	_vm->_actors[actorId]->loopWalkToSceneObject(objectName); - -	return false; +	if(_vm->_walkingActorId == actorId) { +		run = true; +	} +	bool isRunning; +	bool result = _vm->_actors[actorId]->loopWalkToSceneObject(objectName, destinationOffset, a4, run, true, &isRunning); +	if(isRunning == 1) { +		_vm->_walkingActorId = actorId; +	} +	Global_Variable_Set(37, actorId); +	Global_Variable_Set(38, isRunning); +	return result;  } -bool ScriptBase::Loop_Actor_Walk_To_Waypoint(int actorId, int waypointId, int a3, int a4, bool running) { +bool ScriptBase::Loop_Actor_Walk_To_Waypoint(int actorId, int waypointId, int destinationOffset, int a4, bool run) {  	//TODO -	warning("Loop_Actor_Walk_To_Waypoint(%d, %d, %d, %d, %d)", actorId, waypointId, a3, a4, running); +	warning("Loop_Actor_Walk_To_Waypoint(%d, %d, %d, %d, %d)", actorId, waypointId, destinationOffset, a4, run);  	return false;  } -bool ScriptBase::Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int a4, int a5, bool running, int a7) { +bool ScriptBase::Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int destinationOffset, int a5, bool run, int a7) {  	_vm->gameWaitForActive(); -	_vm->_actors[actorId]->loopWalkToXYZ(x, y, z, a4, a5, running, 1); - -	return false; +	if(_vm->_walkingActorId == actorId) { +		if(a7) { +			_vm->_walkingActorId = -1; +		} else { +			run = true; +		} +	} +	//TODO: +	//PlayerActorIdle = 0; +	bool isRunning; +	bool result = _vm->_actors[actorId]->loopWalkToXYZ(Vector3(x, y, z), destinationOffset, a5, run, 1, &isRunning); + +//	if (PlayerActorIdle == 1) { +//		result = 1; +//		PlayerActorIdle = 0; +//	} +	if(isRunning) { +		_vm->_walkingActorId = actorId; +	} +	Global_Variable_Set(37, actorId); +	Global_Variable_Set(38, isRunning); +	return result;  } -void ScriptBase::Async_Actor_Walk_To_Waypoint(int actorId, int waypointId, int a3, int running) { +void ScriptBase::Async_Actor_Walk_To_Waypoint(int actorId, int waypointId, int destinationOffset, int run) {  	//TODO -	warning("Async_Actor_Walk_To_Waypoint(%d, %d, %d, %d)", actorId, waypointId, a3, running); +	warning("Async_Actor_Walk_To_Waypoint(%d, %d, %d, %d)", actorId, waypointId, destinationOffset, run);  } -void ScriptBase::Async_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int a5, bool running) { +void ScriptBase::Async_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int destinationOffset, bool run) {  	//TODO -	warning("Async_Actor_Walk_To_XYZ(%d, %f, %f, %f, %d, %d)", actorId, x, y, z, a5, running); +	warning("Async_Actor_Walk_To_XYZ(%d, %f, %f, %f, %d, %d)", actorId, x, y, z, destinationOffset, run);  }  void ScriptBase::Actor_Force_Stop_Walking(int actorId) { @@ -692,11 +719,11 @@ void ScriptBase::Delay(int miliseconds) {  }  void ScriptBase::Player_Loses_Control() { -		_vm->playerLosesControl(); +	_vm->playerLosesControl();  }  void ScriptBase::Player_Gains_Control() { -		_vm->playerGainsControl(); +	_vm->playerGainsControl();  }  void ScriptBase::Player_Set_Combat_Mode(bool activate) { diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h index 0e4c0e9f62..fb38fdaf91 100644 --- a/engines/bladerunner/script/script.h +++ b/engines/bladerunner/script/script.h @@ -99,12 +99,12 @@ protected:  	void Actor_Change_Animation_Mode(int actorId, int animationMode);  	int Actor_Query_Animation_Mode(int actorId);  	bool Loop_Actor_Walk_To_Actor(int actorId, int otherActorId, int a3, int a4, bool running); -	bool Loop_Actor_Walk_To_Item(int actorId, int itemId, int a3, int a4, bool running); -	bool Loop_Actor_Walk_To_Scene_Object(int actorId, const char *objectName, int distance, int a4, bool running); -	bool Loop_Actor_Walk_To_Waypoint(int actorId, int waypointId, int a3, int a4, bool running); -	bool Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int a4, int a5, bool running, int a7); -	void Async_Actor_Walk_To_Waypoint(int actorId, int waypointId, int a3, int running); -	void Async_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int a5, bool running); +	bool Loop_Actor_Walk_To_Item(int actorId, int itemId, int a3, int a4, bool run); +	bool Loop_Actor_Walk_To_Scene_Object(int actorId, const char *objectName, int distance, bool a4, bool run); +	bool Loop_Actor_Walk_To_Waypoint(int actorId, int waypointId, int a3, int a4, bool run); +	bool Loop_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int a4, int a5, bool run, int a7); +	void Async_Actor_Walk_To_Waypoint(int actorId, int waypointId, int a3, int run); +	void Async_Actor_Walk_To_XYZ(int actorId, float x, float y, float z, int a5, bool run);  	void Actor_Force_Stop_Walking(int actorId);  	bool Loop_Actor_Travel_Stairs(int actorId, int a2, int a3, int a4);  	bool Loop_Actor_Travel_Ladder(int actorId, int a2, int a3, int a4); diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp index 12db84ae24..f8a480c181 100644 --- a/engines/bladerunner/set.cpp +++ b/engines/bladerunner/set.cpp @@ -91,10 +91,10 @@ bool Set::open(const Common::String &name) {  	assert(_walkboxCount <= 95);  	for (int i = 0; i < _walkboxCount; ++i) { -		float x, y, z; +		float x, z;  		s->read(_walkboxes[i]._name, 20); -		y = s->readFloatLE(); +		_walkboxes[i]._altitude = s->readFloatLE();  		_walkboxes[i]._vertexCount = s->readUint32LE();  		assert(_walkboxes[i]._vertexCount <= 8); @@ -103,7 +103,7 @@ bool Set::open(const Common::String &name) {  			x = s->readFloatLE();  			z = s->readFloatLE(); -			_walkboxes[i]._vertices[j] = Vector3(x, y, z); +			_walkboxes[i]._vertices[j] = Vector3(x, _walkboxes[i]._altitude, z);  		}  		// debug("WALKBOX: %s", _walkboxes[i]._name); @@ -166,7 +166,8 @@ static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox) {  			if (x < lineX)  				found++;  		} - +		lastX = currentX; +		lastZ = currentZ;  	}  	return found & 1;  } diff --git a/engines/bladerunner/vector.h b/engines/bladerunner/vector.h index 070ca86190..84e4df63bb 100644 --- a/engines/bladerunner/vector.h +++ b/engines/bladerunner/vector.h @@ -108,6 +108,54 @@ inline Vector4 operator/(Vector4 a, Vector4 b) {  	return Vector4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);  } +inline +int angle_1024(float x1, float z1, float x2, float z2) +{ +	float angle_rad = atan2(x2 - x1, z1 - z2); +	int a = int(512.0 * angle_rad / M_PI); +	return (a + 1024) % 1024; +} + +inline +int angle_1024(const Vector3 &v1, const Vector3 &v2) +{ +	return angle_1024(v1.x, v1.z, v2.x, v2.z); +} + +inline +float distance(float x1, float z1, float x2, float z2) +{ +	float dx = x1 - x2; +	float dz = z1 - z2; +	float d = sqrt(dx*dx + dz*dz); + +	float int_part = (int)d; +	float frac_part = d - int_part; + +	if (frac_part < 0.001) +		frac_part = 0.0; + +	return int_part + frac_part; +} + +inline +float distance(const Vector3 &v1, const Vector3 &v2) +{ +	return distance(v1.x, v1.z, v2.x, v2.z); +} + +inline +float cos_1024(int angle1024) { +	return cos(angle1024 * (M_PI / 512.0f)); +} + +inline +float sin_1024(int angle1024) { +	return sin(angle1024 * (M_PI / 512.0f)); +} + + +  } // End of namespace BladeRunner  #endif | 
