aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPeter Kohaut2016-10-04 02:21:08 +0200
committerPeter Kohaut2016-10-04 18:15:57 +0200
commit6547c35e15252fd24f260ebd6b8f01d9edd01aa2 (patch)
tree89fec132f3325fed022c4f7bd7fd003942604352 /engines
parent281c19ab036f387a99192594aa645e696009f40b (diff)
downloadscummvm-rg350-6547c35e15252fd24f260ebd6b8f01d9edd01aa2.tar.gz
scummvm-rg350-6547c35e15252fd24f260ebd6b8f01d9edd01aa2.tar.bz2
scummvm-rg350-6547c35e15252fd24f260ebd6b8f01d9edd01aa2.zip
BLADERUNNER: trying to figure out walking, added structures for obstacles used for pathfinding, fixed bug in searching for walkboxes
Diffstat (limited to 'engines')
-rw-r--r--engines/bladerunner/actor.cpp337
-rw-r--r--engines/bladerunner/actor.h24
-rw-r--r--engines/bladerunner/actor_walk.cpp181
-rw-r--r--engines/bladerunner/actor_walk.h16
-rw-r--r--engines/bladerunner/adq.cpp2
-rw-r--r--engines/bladerunner/adq.h23
-rw-r--r--engines/bladerunner/bladerunner.cpp6
-rw-r--r--engines/bladerunner/bladerunner.h16
-rw-r--r--engines/bladerunner/item.cpp11
-rw-r--r--engines/bladerunner/item.h8
-rw-r--r--engines/bladerunner/items.cpp7
-rw-r--r--engines/bladerunner/items.h3
-rw-r--r--engines/bladerunner/module.mk1
-rw-r--r--engines/bladerunner/obstacles.cpp46
-rw-r--r--engines/bladerunner/obstacles.h64
-rw-r--r--engines/bladerunner/scene.cpp2
-rw-r--r--engines/bladerunner/scene_objects.cpp18
-rw-r--r--engines/bladerunner/scene_objects.h2
-rw-r--r--engines/bladerunner/script/nr03.cpp4
-rw-r--r--engines/bladerunner/script/nr05.cpp2
-rw-r--r--engines/bladerunner/script/rc01.cpp8
-rw-r--r--engines/bladerunner/script/script.cpp67
-rw-r--r--engines/bladerunner/script/script.h12
-rw-r--r--engines/bladerunner/set.cpp9
-rw-r--r--engines/bladerunner/vector.h48
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