aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/actor.cpp
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/bladerunner/actor.cpp
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/bladerunner/actor.cpp')
-rw-r--r--engines/bladerunner/actor.cpp337
1 files changed, 262 insertions, 75 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