aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPeter Kohaut2018-03-17 16:40:33 +0100
committerPeter Kohaut2018-03-17 16:42:25 +0100
commit19d9e4cec818980a75772a204c96774afbd2b17e (patch)
treeaaf4ae3f0322c0a75418451b50c8e09b424c0a7f /engines
parentb2727018344535789c96b0e9c95c741d0dd054c5 (diff)
downloadscummvm-rg350-19d9e4cec818980a75772a204c96774afbd2b17e.tar.gz
scummvm-rg350-19d9e4cec818980a75772a204c96774afbd2b17e.tar.bz2
scummvm-rg350-19d9e4cec818980a75772a204c96774afbd2b17e.zip
BLADERUNNER: Added combat
Math cleanup Fixed obstacle detection
Diffstat (limited to 'engines')
-rw-r--r--engines/bladerunner/actor.cpp61
-rw-r--r--engines/bladerunner/actor.h59
-rw-r--r--engines/bladerunner/actor_combat.cpp605
-rw-r--r--engines/bladerunner/actor_combat.h74
-rw-r--r--engines/bladerunner/bladerunner.cpp32
-rw-r--r--engines/bladerunner/combat.cpp103
-rw-r--r--engines/bladerunner/combat.h31
-rw-r--r--engines/bladerunner/debugger.cpp43
-rw-r--r--engines/bladerunner/game_constants.h19
-rw-r--r--engines/bladerunner/matrix.h4
-rw-r--r--engines/bladerunner/scene_objects.cpp14
-rw-r--r--engines/bladerunner/scene_objects.h2
-rw-r--r--engines/bladerunner/script/ai/clovis.cpp12
-rw-r--r--engines/bladerunner/script/ai/dektora.cpp10
-rw-r--r--engines/bladerunner/script/ai/gaff.cpp2
-rw-r--r--engines/bladerunner/script/ai/gordo.cpp2
-rw-r--r--engines/bladerunner/script/ai/guzza.cpp2
-rw-r--r--engines/bladerunner/script/ai/leon.cpp2
-rw-r--r--engines/bladerunner/script/ai/lucy.cpp6
-rw-r--r--engines/bladerunner/script/ai/mccoy.cpp24
-rw-r--r--engines/bladerunner/script/ai/mutant1.cpp15
-rw-r--r--engines/bladerunner/script/ai/mutant2.cpp12
-rw-r--r--engines/bladerunner/script/ai/mutant3.cpp12
-rw-r--r--engines/bladerunner/script/ai/officer_leary.cpp2
-rw-r--r--engines/bladerunner/script/ai/sadik.cpp5
-rw-r--r--engines/bladerunner/script/ai/steele.cpp2
-rw-r--r--engines/bladerunner/script/ai/taffy_patron.cpp6
-rw-r--r--engines/bladerunner/script/ai/zuben.cpp4
-rw-r--r--engines/bladerunner/script/ai_script.cpp12
-rw-r--r--engines/bladerunner/script/ai_script.h1
-rw-r--r--engines/bladerunner/script/scene/ct07.cpp2
-rw-r--r--engines/bladerunner/script/scene/hf01.cpp12
-rw-r--r--engines/bladerunner/script/scene/hf03.cpp4
-rw-r--r--engines/bladerunner/script/scene/hf05.cpp16
-rw-r--r--engines/bladerunner/script/scene/hf06.cpp13
-rw-r--r--engines/bladerunner/script/scene/hf07.cpp8
-rw-r--r--engines/bladerunner/script/scene/kp05.cpp2
-rw-r--r--engines/bladerunner/script/scene/ma04.cpp4
-rw-r--r--engines/bladerunner/script/scene/nr01.cpp2
-rw-r--r--engines/bladerunner/script/scene/nr11.cpp6
-rw-r--r--engines/bladerunner/script/scene/ug05.cpp4
-rw-r--r--engines/bladerunner/script/scene/ug18.cpp3
-rw-r--r--engines/bladerunner/script/script.cpp50
-rw-r--r--engines/bladerunner/script/script.h6
-rw-r--r--engines/bladerunner/slice_renderer.cpp134
-rw-r--r--engines/bladerunner/slice_renderer.h2
-rw-r--r--engines/bladerunner/view.cpp19
47 files changed, 1153 insertions, 312 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index d4c4eeaee3..177734fe37 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -22,11 +22,11 @@
#include "bladerunner/actor.h"
-#include "bladerunner/bladerunner.h"
#include "bladerunner/actor_clues.h"
#include "bladerunner/actor_combat.h"
#include "bladerunner/actor_walk.h"
#include "bladerunner/audio_speech.h"
+#include "bladerunner/bladerunner.h"
#include "bladerunner/boundingbox.h"
#include "bladerunner/game_info.h"
#include "bladerunner/items.h"
@@ -671,6 +671,12 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) {
return isVisible;
}
+void Actor::tickCombat() {
+ if (_id != kActorMcCoy && !_isRetired && _inCombat) {
+ _combatInfo->tick();
+ }
+}
+
bool Actor::draw(Common::Rect *screenRect) {
Vector3 drawPosition(_position.x, -_position.z, _position.y + 2.0);
float drawAngle = M_PI - _facing * (M_PI / 512.0f);
@@ -904,16 +910,6 @@ void Actor::setImmunityToObstacles(bool isImmune) {
_isImmuneToObstacles = isImmune;
}
-void Actor::modifyCurrentHP(signed int change) {
- _currentHP = CLIP(_currentHP + change, 0, 100);
- if (_currentHP > 0)
- retire(false, 0, 0, -1);
-}
-
-void Actor::modifyMaxHP(signed int change) {
- _maxHP = CLIP(_maxHP + change, 0, 100);
-}
-
void Actor::modifyCombatAggressiveness(signed int change) {
_combatAggressiveness = CLIP(_combatAggressiveness + change, 0, 100);
}
@@ -955,6 +951,13 @@ void Actor::setTarget(bool target) {
_isTarget = target;
}
+void Actor::setCurrentHP(int hp) {
+ _currentHP = hp;
+ if (hp > 0) {
+ retire(false, 0, 0, -1);
+ }
+}
+
void Actor::setHealth(int hp, int maxHp) {
_currentHP = hp;
_maxHP = maxHp;
@@ -963,13 +966,25 @@ void Actor::setHealth(int hp, int maxHp) {
}
}
-void Actor::combatModeOn(int a2, int a3, int otherActorId, int a5, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int a9, int a10, int a11, int ammoDamage, int a13, int a14) {
+void Actor::modifyCurrentHP(signed int change) {
+ _currentHP = CLIP(_currentHP + change, 0, 100);
+ if (_currentHP > 0) {
+ retire(false, 0, 0, -1);
+ }
+}
+
+void Actor::modifyMaxHP(signed int change) {
+ _maxHP = CLIP(_maxHP + change, 0, 100);
+}
+
+
+void Actor::combatModeOn(int initialState, bool rangedAttack, int enemyId, int waypointType, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool a14) {
_animationModeCombatIdle = animationModeCombatIdle;
_animationModeCombatWalk = animationModeCombatWalk;
_animationModeCombatRun = animationModeCombatRun;
_inCombat = true;
if (_id != kActorMcCoy) {
- _combatInfo->combatOn(_id, a2, a3, otherActorId, a5, a9, a10, a11, ammoDamage, a13, a14);
+ _combatInfo->combatOn(_id, initialState, rangedAttack, enemyId, waypointType, fleeRatio, coverRatio, actionRatio, damage, range, a14);
}
stopWalking(false);
changeAnimationMode(_animationModeCombatIdle, false);
@@ -1002,6 +1017,16 @@ float Actor::distanceFromActor(int otherActorId) {
return (_position - _vm->_actors[otherActorId]->_position).length();
}
+int Actor::angleTo(const Vector3 &target) const {
+ int angle = angle_1024(_position.x, _position.z, target.x, target.z) - _facing;
+ if (angle < -512) {
+ angle += 1024;
+ } else if (angle > 512) {
+ angle -= 1024;
+ }
+ return angle;
+}
+
float Actor::getX() const {
return _position.x;
}
@@ -1014,10 +1039,8 @@ float Actor::getZ() const {
return _position.z;
}
-void Actor::getXYZ(float *x, float *y, float *z) const {
- *x = _position.x;
- *y = _position.y;
- *z = _position.z;
+Vector3 Actor::getXYZ() const {
+ return _position;
}
int Actor::getFacing() const {
@@ -1112,8 +1135,8 @@ int Actor::soundBalance() const {
return 35.0f * (CLIP(screenPosition.x / 640.0f, 0.0f, 1.0f) * 2.0f - 1.0f);
}
-bool Actor::isObstacleBetween(float targetX, float targetZ) {
- return _vm->_sceneObjects->isObstacleBetween(_position.x, _position.z, targetX, targetZ, _position.y, -1);
+bool Actor::isObstacleBetween(const Vector3 &target) {
+ return _vm->_sceneObjects->isObstacleBetween(_position, target, -1);
}
int Actor::findTargetUnderMouse(BladeRunnerEngine *vm, int mouseX, int mouseY) {
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index af0c14e367..ace90554b7 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -39,18 +39,17 @@ class MovementTrack;
class View;
class Actor {
- friend class ScriptBase;
- friend class KIA;
-
BladeRunnerEngine *_vm;
-private:
+public:
BoundingBox *_bbox;
Common::Rect _screenRectangle;
MovementTrack *_movementTrack;
ActorWalk *_walkInfo;
ActorCombat *_combatInfo;
+ ActorClues *_clues;
+private:
int _honesty;
int _intelligence;
int _stability;
@@ -61,8 +60,6 @@ private:
int _currentHP;
int _maxHP;
- ActorClues *_clues;
-
int _id;
int _setId;
Vector3 _position;
@@ -124,7 +121,7 @@ public:
float getX() const;
float getY() const;
float getZ() const;
- void getXYZ(float *x, float *y, float *z) const;
+ Vector3 getXYZ() const;
int getFacing() const;
int getAnimationMode() const;
@@ -157,6 +154,7 @@ public:
void run();
bool tick(bool forceUpdate, Common::Rect *screenRect);
+ void tickCombat();
bool draw(Common::Rect *screenRect);
int getSetId() const;
@@ -164,13 +162,16 @@ public:
BoundingBox *getBoundingBox() const { return _bbox; }
Common::Rect *getScreenRectangle() { return &_screenRectangle; }
int getWalkbox() const { return _walkboxId; }
+
bool isRetired() const { return _isRetired; }
- bool isTarget() const { return _isTarget; }
+ bool isTarget() const { return true;/*return _isTarget; */}
void setTarget(bool targetable);
bool isImmuneToObstacles() const { return _isImmuneToObstacles; }
bool inCombat() const { return _inCombat; }
+
bool isMoving() const { return _isMoving; }
void setMoving(bool value) { _isMoving = value; }
+
bool inWalkLoop() const { return _inWalkLoop; }
bool isWalking() const;
bool isRunning() const;
@@ -184,33 +185,51 @@ public:
void faceXYZ(const Vector3 &pos, bool animate);
void faceCurrentCamera(bool animate);
void faceHeading(int heading, bool animate);
- void modifyFriendlinessToOther(int otherActorId, signed int change);
+ void setFacing(int facing, bool halfOrSet = true);
+
+ int getCurrentHP() const { return _currentHP; }
+ int getMaxHP() const { return _maxHP; }
+ void setCurrentHP(int hp);
+ void setHealth(int hp, int maxHp);
+ void modifyCurrentHP(signed int change);
+ void modifyMaxHP(signed int change);
+
+ int getFriendlinessToOther(int otherActorId) const { return _friendlinessToOther[otherActorId]; }
void setFriendlinessToOther(int otherActorId, int friendliness);
+ void modifyFriendlinessToOther(int otherActorId, signed int change);
+
+ int getHonesty() const { return _honesty; }
void setHonesty(int honesty);
+ void modifyHonesty(signed int change);
+
+ int getIntelligence() const { return _intelligence; }
void setIntelligence(int intelligence);
+ void modifyIntelligence(signed int change);
+
+ int getStability() const { return _stability; }
void setStability(int stability);
+ void modifyStability(signed int change);
+
+ int getCombatAggressiveness() const { return _combatAggressiveness; }
void setCombatAggressiveness(int combatAggressiveness);
+ void modifyCombatAggressiveness(signed int change);
+
void setInvisible(bool isInvisible);
void setImmunityToObstacles(bool isImmune);
- void modifyCurrentHP(signed int change);
- void modifyMaxHP(signed int change);
- void modifyCombatAggressiveness(signed int change);
- void modifyHonesty(signed int change);
- void modifyIntelligence(signed int change);
- void modifyStability(signed int change);
+
void setFlagDamageAnimIfMoving(bool value);
- bool getFlagDamageAnimIfMoving() const;
- void setHealth(int hp, int maxHp);
+ bool getFlagDamageAnimIfMoving() const;
void retire(bool isRetired, int width, int height, int retiredByActorId);
- void combatModeOn(int a2, int a3, int a4, int a5, int combatAnimationMode, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14);
+ void combatModeOn(int initialState, bool rangedAttack, int enemyId, int waypointType, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool a14);
void combatModeOff();
void setGoal(int goalNumber);
int getGoal() const;
float distanceFromActor(int otherActorId);
+ int angleTo(const Vector3 &target) const;
void speechPlay(int sentenceId, bool voiceOver);
void speechStop();
@@ -225,11 +244,11 @@ public:
int soundVolume() const;
int soundBalance() const;
- bool isObstacleBetween(float targetX, float targetZ);
+ bool isObstacleBetween(const Vector3 &target);
static int findTargetUnderMouse(BladeRunnerEngine *vm, int mouseX, int mouseY);
+
private:
- void setFacing(int facing, bool halfOrSet = true);
void setBoundingBox(const Vector3 &position, bool retired);
float distanceFromView(View *view) const;
diff --git a/engines/bladerunner/actor_combat.cpp b/engines/bladerunner/actor_combat.cpp
index 4bd8d17c67..47d1c2d3a0 100644
--- a/engines/bladerunner/actor_combat.cpp
+++ b/engines/bladerunner/actor_combat.cpp
@@ -22,25 +22,624 @@
#include "bladerunner/actor_combat.h"
+#include "bladerunner/actor.h"
+#include "bladerunner/audio_speech.h"
+#include "bladerunner/bladerunner.h"
+#include "bladerunner/combat.h"
+#include "bladerunner/game_constants.h"
+#include "bladerunner/game_info.h"
+#include "bladerunner/movement_track.h"
+#include "bladerunner/scene.h"
+#include "bladerunner/scene_objects.h"
+#include "bladerunner/script/ai_script.h"
+#include "bladerunner/set.h"
+#include "bladerunner/settings.h"
+
namespace BladeRunner {
ActorCombat::ActorCombat(BladeRunnerEngine *vm) {
_vm = vm;
+ reset();
}
ActorCombat::~ActorCombat() {
}
-void ActorCombat::hitAttempt() {
+void ActorCombat::setup() {
+ reset();
}
-void ActorCombat::combatOn(int actorId, int a3, int a4, int otherActorId, int a6, int a7, int a8, int a9, int ammoDamage, int a11, int a12) {
+void ActorCombat::combatOn(int actorId, int initialState, bool rangedAttack, int enemyId, int waypointType, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool a12) {
+ _actorId = actorId;
+ _state = initialState;
+ _rangedAttack = rangedAttack;
+ _enemyId = enemyId;
+ _waypointType = waypointType;
+ _damage = damage;
+ _fleeRatioConst = fleeRatio;
+ _coverRatioConst = coverRatio;
+ _actionRatioConst = actionRatio;
+ _fleeRatio = fleeRatio;
+ _coverRatio = coverRatio;
+ _actionRatio = actionRatio;
+ _active = true;
+ if (rangedAttack == 1) {
+ _range = range;
+ } else {
+ _range = 300;
+ }
+ field_3C = a12;
+
+ Actor *actor = _vm->_actors[_actorId];
+
+ _actorPosition = actor->getXYZ();
+ _enemyPosition = _vm->_actors[_enemyId]->getXYZ();
+
+ actor->_movementTrack->flush();
+ actor->stopWalking(false);
+
+ if (_enemyId == kActorMcCoy) {
+ actor->setTarget(true);
+ }
+
+ _actorHp = actor->getCurrentHP();
+
+ _coversWaypointCount = 0;
+ for (int i = 0; i < (int)_vm->_gameInfo->getCoverWaypointCount(); ++i) {
+ if (_vm->_combat->_coverWaypoints[i].type == waypointType && _vm->_combat->_coverWaypoints[i].setId == actor->getSetId()) {
+ ++_coversWaypointCount;
+ }
+ }
+ if (_coversWaypointCount == 0) {
+ _coverRatioConst = 0;
+ _coverRatio = 0;
+ }
+
+ _fleeWaypointsCount = 0;
+ for (int i = 0; i < (int)_vm->_gameInfo->getFleeWaypointCount(); ++i) {
+ if (_vm->_combat->_fleeWaypoints[i].type == waypointType && _vm->_combat->_fleeWaypoints[i].setId == actor->getSetId()) {
+ ++_fleeWaypointsCount;
+ }
+ }
+ if (_fleeWaypointsCount == 0) {
+ _fleeRatioConst = 0;
+ _fleeRatio = 0;
+ }
}
void ActorCombat::combatOff() {
+ _active = false;
+ reset();
}
-void ActorCombat::setup() {
+void ActorCombat::tick() {
+ static int processingCounter = 0;
+
+ if (!_active || processingCounter > 0) {
+ return;
+ }
+
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ if (actor->getSetId() != enemy->getSetId()) {
+ actor->combatModeOff();
+ return;
+ }
+
+ ++processingCounter;
+
+ _actorPosition = actor->getXYZ();
+ _enemyPosition = enemy->getXYZ();
+
+ if (_actionRatioConst >= 0) {
+ _actionRatio = _actionRatioConst;
+ } else {
+ _actionRatio = calculateActionRatio();
+ }
+
+ if (_vm->_combat->findCoverWaypoint(_waypointType, _actorId, _enemyId) != -1) {
+ if (_coverRatioConst >= 0) {
+ _coverRatio = _coverRatioConst;
+ } else {
+ _coverRatio = calculateCoverRatio();
+ }
+ } else {
+ _coverRatio = 0;
+ }
+
+ if (_fleeRatioConst >= 0) {
+ _fleeRatio = _fleeRatioConst;
+ } else {
+ _fleeRatio = calculateFleeRatio();
+ }
+
+ float dist = actor->distanceFromActor(_enemyId);
+ int oldState = _state;
+
+ if (_actionRatio < _fleeRatio || _actionRatio < _coverRatio) {
+ if (_coverRatio >= _fleeRatio && _coverRatio >= _actionRatio) {
+ _state = kActorCombatStateCover;
+ } else {
+ _state = kActorCombatStateFlee;
+ }
+ } else {
+ if (_rangedAttack) {
+ if (dist > _range) {
+ _state = kActorCombatStateApproachRangedAttack;
+ } else {
+ if (actor->isObstacleBetween(_enemyPosition)) {
+ _state = kActorCombatStateUncover;
+ } else {
+ _state = kActorCombatStateRangedAttack;
+ }
+ }
+ } else {
+ if (dist > 36.0f) {
+ _state = kActorCombatStateApproachCloseAttack;
+ } else {
+ _state = kActorCombatStateCloseAttack;
+ }
+ }
+ }
+
+ if (enemy->isRetired()) {
+ _state = kActorCombatStateIdle;
+ }
+
+ if (actor->getAnimationMode() == kAnimationModeHit || actor->getAnimationMode() == kAnimationModeCombatHit) {
+ _state = kActorCombatStateIdle;
+ } else {
+ if (_state != oldState) {
+ actor->stopWalking(false);
+ }
+ }
+ switch (_state) {
+ case kActorCombatStateCover:
+ cover();
+ break;
+ case kActorCombatStateApproachCloseAttack:
+ approachToCloseAttack();
+ break;
+ case kActorCombatStateUncover:
+ uncover();
+ break;
+ case kActorCombatStateAim:
+ aim();
+ break;
+ case kActorCombatStateRangedAttack:
+ rangedAttack();
+ break;
+ case kActorCombatStateCloseAttack:
+ closeAttack();
+ break;
+ case kActorCombatStateFlee:
+ flee();
+ break;
+ case kActorCombatStateApproachRangedAttack:
+ approachToRangedAttack();
+ break;
+ }
+ --processingCounter;
+}
+
+void ActorCombat::hitAttempt() {
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ if (_enemyId == kActorMcCoy && !_vm->playerHasControl() && field_3C == 0) {
+ return;
+ }
+
+ if (actor->isRetired()) {
+ return;
+ }
+
+ int aggressiveness = 0;
+ if (_rangedAttack) {
+ aggressiveness = _rangedAttack == 1 ? getaggressivenessRangedAttack() : 0;
+ } else {
+ aggressiveness = getaggressivenessCloseAttack();
+ }
+
+ if (aggressiveness == 0) {
+ return;
+ }
+
+ int random = _vm->_rnd.getRandomNumberRng(1, 100);
+
+ if (random <= aggressiveness) {
+ if (enemy->isWalking()) {
+ enemy->stopWalking(true);
+ }
+
+ int sentenceId = _vm->_rnd.getRandomNumberRng(0, 1) ? 9000 : 9005;
+ if (enemy->inCombat()) {
+ enemy->changeAnimationMode(22, false);
+ } else {
+ enemy->changeAnimationMode(21, false);
+ }
+
+ int damage = 0;
+ if (_rangedAttack) {
+ damage = getDamageRangedAttack(random, aggressiveness);
+ } else {
+ damage = getDamageCloseAttack(random, aggressiveness);
+ }
+
+ int enemyHp = MAX(enemy->getCurrentHP() - damage, 0);
+ enemy->setCurrentHP(enemyHp);
+
+ if (enemyHp <= 0) {
+ if (!enemy->isRetired()) {
+ if (enemy->inCombat()) {
+ enemy->changeAnimationMode(49, false);
+ } else {
+ enemy->changeAnimationMode(48, false);
+ }
+ sentenceId = 9020;
+ }
+ enemy->retire(true, 6, 3, _actorId);
+ }
+
+ if (_enemyId == kActorMcCoy) {
+ sentenceId += 900;
+ }
+
+ _vm->_audioSpeech->playSpeechLine(_enemyId, sentenceId, 75, enemy->soundBalance(), 99);
+ }
+}
+
+void ActorCombat::reset() {
+ _active = false;
+ _actorId = -1;
+ _state = -1;
+ _rangedAttack = -1;
+ _enemyId = -1;
+ _waypointType = -1;
+ _damage = 0;
+ _fleeRatio = -1;
+ _coverRatio = -1;
+ _actionRatio = -1;
+ _fleeRatioConst = -1;
+ _coverRatioConst = -1;
+ _actionRatioConst = -1;
+ _actorHp = 0;
+ _range = 300;
+ field_3C = 0;
+ _actorPosition = Vector3(0.0f, 0.0f, 0.0f);
+ _enemyPosition = Vector3(0.0f, 0.0f, 0.0f);
+ _coversWaypointCount = 0;
+ _fleeWaypointsCount = 0;
+ _fleeingTowards = -1;
+}
+
+void ActorCombat::cover() {
+ Actor *actor = _vm->_actors[_actorId];
+
+ if (actor->isWalking()) {
+ return;
+ }
+
+ if (actor->isObstacleBetween(_enemyPosition)) {
+ faceEnemy();
+ return;
+ }
+
+ int coverWaypointId = _vm->_combat->findCoverWaypoint(_waypointType, _actorId, _enemyId);
+ if (coverWaypointId == -1) {
+ _state = kActorCombatStateIdle;
+ } else {
+ actor->asyncWalkToXYZ(_vm->_combat->_coverWaypoints[coverWaypointId].position, 0, true, 0);
+ }
+}
+
+void ActorCombat::approachToCloseAttack() {
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ float dist = actor->distanceFromActor(_enemyId);
+ if (dist > 36.0f) {
+ if (!actor->isWalking() || enemy->isWalking()) {
+ Vector3 target;
+ if (findClosestPositionToEnemy(target)) {
+ actor->asyncWalkToXYZ(target, 0, dist >= 240.0f, 0);
+ } else {
+ _state = kActorCombatStateCover;
+ }
+ }
+ } else {
+ if (actor->isWalking()) {
+ actor->stopWalking(false);
+ }
+ faceEnemy();
+ _state = kActorCombatStateCloseAttack;
+ }
+}
+
+void ActorCombat::approachToRangedAttack() {
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ float dist = actor->distanceFromActor(_enemyId);
+ if (dist > _range) {
+ if (!actor->isWalking() || enemy->isWalking()) {
+ Vector3 target;
+ if (findClosestPositionToEnemy(target)) {
+ actor->asyncWalkToXYZ(target, 0, dist >= 240.0f, 0);
+ } else {
+ _state = kActorCombatStateCover;
+ }
+ }
+ } else {
+ if (actor->isWalking()) {
+ actor->stopWalking(false);
+ }
+ faceEnemy();
+ _state = kActorCombatStateRangedAttack;
+ }
+}
+
+void ActorCombat::uncover() {
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ if (actor->isObstacleBetween(_enemyPosition)) {
+ actor->asyncWalkToXYZ(enemy->getXYZ(), 16, false, 0);
+ } else {
+ if (actor->isWalking()) {
+ actor->stopWalking(false);
+ }
+ faceEnemy();
+ }
+}
+
+void ActorCombat::aim() {
+ Actor *actor = _vm->_actors[_actorId];
+
+ if (actor->isObstacleBetween(_enemyPosition)) {
+ if (actor->getAnimationMode() != kAnimationModeCombatIdle) {
+ actor->changeAnimationMode(kAnimationModeCombatIdle, false);
+ }
+ } else {
+ faceEnemy();
+ if (actor->getAnimationMode() != kAnimationModeCombatAim) {
+ actor->changeAnimationMode(kAnimationModeCombatAim, false);
+ }
+ }
+}
+
+void ActorCombat::rangedAttack() {
+ Actor *actor = _vm->_actors[_actorId];
+
+ if (actor->isObstacleBetween(_enemyPosition) || (actor->distanceFromActor(_enemyId) > _range)) {
+ _state = kActorCombatStateApproachRangedAttack;
+ } else {
+ faceEnemy();
+ if (actor->getAnimationMode() != kAnimationModeCombatAttack) {
+ if (_enemyId != kActorMcCoy || _vm->playerHasControl() || field_3C != 0) {
+ actor->changeAnimationMode(kAnimationModeCombatAttack, false);
+ }
+ }
+ }
+}
+
+void ActorCombat::closeAttack() {
+ Actor *actor = _vm->_actors[_actorId];
+
+ if (actor->isObstacleBetween(_enemyPosition) || (actor->distanceFromActor(_enemyId) > 36.0f)) {
+ _state = kActorCombatStateApproachCloseAttack;
+ } else {
+ faceEnemy();
+ if (actor->getAnimationMode() != kAnimationModeCombatAttack) {
+ if (_enemyId != kActorMcCoy || _vm->playerHasControl() || field_3C != 0) {
+ actor->changeAnimationMode(kAnimationModeCombatAttack, false);
+ }
+ }
+ }
+}
+
+void ActorCombat::flee() {
+ Actor *actor = _vm->_actors[_actorId];
+
+ if (_fleeingTowards != -1 && actor->isWalking()) {
+ Vector3 fleeWaypointPosition = _vm->_combat->_fleeWaypoints[_fleeingTowards].position;
+ if (distance(_actorPosition, fleeWaypointPosition) <= 12.0f) {
+ _vm->_aiScripts->fledCombat(_actorId/*, _enemyId*/);
+ actor->setSetId(kSetFreeSlotG);
+ actor->combatModeOff();
+ _fleeingTowards = -1;
+ }
+ } else {
+ int fleeWaypointId = _vm->_combat->findFleeWaypoint(actor->getSetId(), _enemyId, _actorPosition);
+ if (fleeWaypointId == -1) {
+ _state = kActorCombatStateIdle;
+ } else {
+ Vector3 fleeWaypointPosition = _vm->_combat->_fleeWaypoints[fleeWaypointId].position;
+ actor->asyncWalkToXYZ(fleeWaypointPosition, 0, true, 0);
+ _fleeingTowards = fleeWaypointId;
+ }
+ }
+}
+
+void ActorCombat::faceEnemy() {
+ _vm->_actors[_actorId]->setFacing(angle_1024(_actorPosition.x, _actorPosition.z, _enemyPosition.x, _enemyPosition.z), false);
+}
+
+int ActorCombat::getaggressivenessCloseAttack() const{
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ float distance = actor->distanceFromActor(_enemyId);
+
+ if (distance > 36.0f) {
+ return 0;
+ }
+
+ int aggressiveness = 0;
+ if (enemy->isRunning()) {
+ aggressiveness = 11;
+ } else if (enemy->isMoving()) {
+ aggressiveness = 22;
+ } else {
+ aggressiveness = 33;
+ }
+
+ aggressiveness += actor->getCombatAggressiveness() / 3;
+
+ int angle = abs(actor->angleTo(_enemyPosition));
+
+ if (angle > 128) {
+ return false;
+ }
+
+ return aggressiveness + (abs(angle - 128) / 3.7f);
+}
+
+int ActorCombat::getaggressivenessRangedAttack() const {
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ if (actor->isObstacleBetween(_enemyPosition)) {
+ return 0;
+ }
+
+ float distance = MIN(actor->distanceFromActor(_enemyId), 900.0f);
+
+ int aggressiveness = 0;
+ if (enemy->isRunning()) {
+ aggressiveness = 10;
+ } else if (enemy->isMoving()) {
+ aggressiveness = 20;
+ } else {
+ aggressiveness = 30;
+ }
+
+ aggressiveness += actor->getCombatAggressiveness() / 5;
+ return aggressiveness + abs((distance / 30) - 30) + actor->getIntelligence() / 5;
+}
+
+int ActorCombat::getDamageCloseAttack(int min, int max) const {
+ if (_enemyId == kActorMcCoy && _vm->_settings->getDifficulty() == 0) {
+ return _damage / 2;
+ }
+ if (_enemyId == kActorMcCoy && _vm->_settings->getDifficulty() == 2) {
+ return _damage;
+ }
+ return ((MIN(max - min, 30) * 100.0f / 60.0f) + 50) * _damage / 100;
+}
+
+int ActorCombat::getDamageRangedAttack(int min, int max) const {
+ if (_enemyId == kActorMcCoy && _vm->_settings->getDifficulty() == 0) {
+ return _damage / 2;
+ }
+ if (_enemyId == kActorMcCoy && _vm->_settings->getDifficulty() == 2) {
+ return _damage;
+ }
+ return ((MIN(max - min, 30) * 100.0f / 60.0f) + 50) * _damage / 100;
+}
+
+int ActorCombat::calculateActionRatio() const {
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ int aggressivenessFactor = actor->getCombatAggressiveness();
+ int actorHpFactor = actor->getCurrentHP();
+ int enemyHpFactor = 100 - enemy->getCurrentHP();
+ int combatFactor = enemy->inCombat() ? 0 : 100;
+ int angleFactor = (100 * abs(enemy->angleTo(_actorPosition))) / 512;
+ int distanceFactor = 2 * (50 - MAX(actor->distanceFromActor(_enemyId) / 12.0f, 50.0f));
+
+ if (_rangedAttack) {
+ return
+ angleFactor * 0.25f +
+ combatFactor * 0.05f +
+ enemyHpFactor * 0.20f +
+ actorHpFactor * 0.10f +
+ aggressivenessFactor * 0.40f;
+ } else {
+ return
+ distanceFactor * 0.20f +
+ angleFactor * 0.10f +
+ combatFactor * 0.10f +
+ enemyHpFactor * 0.15f +
+ actorHpFactor * 0.15f +
+ aggressivenessFactor * 0.30f;
+ }
+}
+
+int ActorCombat::calculateCoverRatio() const {
+ if (_coversWaypointCount == 0) {
+ return 0;
+ }
+
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ int angleFactor = 100 - (100 * abs(enemy->angleTo(_actorPosition))) / 512;
+ int actorHpFactor = 100 - actor->getCurrentHP();
+ int enemyHpFactor = enemy->getCurrentHP();
+ int aggressivenessFactor = 100 - actor->getCombatAggressiveness();
+ int distanceFactor = 2 * MAX(actor->distanceFromActor(_enemyId) / 12.0f, 50.0f);
+
+ if (_rangedAttack) {
+ return
+ angleFactor * 0.40f +
+ enemyHpFactor * 0.05f +
+ actorHpFactor * 0.15f +
+ aggressivenessFactor * 0.50f;
+ } else {
+ return
+ distanceFactor * 0.25f +
+ angleFactor * 0.20f +
+ enemyHpFactor * 0.05f +
+ actorHpFactor * 0.10f +
+ aggressivenessFactor * 0.50f;
+ }
+}
+
+int ActorCombat::calculateFleeRatio() const {
+ if (_fleeWaypointsCount == 0) {
+ return 0;
+ }
+
+ Actor *actor = _vm->_actors[_actorId];
+ Actor *enemy = _vm->_actors[_enemyId];
+
+ int aggressivenessFactor = 100 - actor->getCombatAggressiveness();
+ int actorHpFactor = 100 - actor->getCurrentHP();
+ int combatFactor = enemy->inCombat() ? 100 : 0;
+
+ return
+ combatFactor * 0.2f +
+ actorHpFactor * 0.4f +
+ aggressivenessFactor * 0.4f;
+}
+
+bool ActorCombat::findClosestPositionToEnemy(Vector3 &output) const {
+ output = Vector3();
+
+ Vector3 offsets[] = {
+ Vector3( 0.0f, 0.0f, -28.0f),
+ Vector3( 28.0f, 0.0f, 0.0f),
+ Vector3( 0.0f, 0.0f, 28.0f),
+ Vector3(-28.0f, 0.0f, 0.0f)
+ };
+
+ float min = -1.0f;
+
+ for (int i = 0; i < 4; ++i) {
+ Vector3 test = _enemyPosition + offsets[i];
+ float dist = distance(_actorPosition, test);
+ if ( min == -1.0f || dist < min) {
+ if (!_vm->_sceneObjects->existsOnXZ(_actorId, test.x, test.z, true, true) && _vm->_scene->_set->findWalkbox(test.x, test.z) >= 0) {
+ output = test;
+ min = dist;
+ }
+ }
+ }
+
+ return min >= 0.0f;
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/actor_combat.h b/engines/bladerunner/actor_combat.h
index b7ec93533d..2c6ea8ac8e 100644
--- a/engines/bladerunner/actor_combat.h
+++ b/engines/bladerunner/actor_combat.h
@@ -32,27 +32,27 @@ class BladeRunnerEngine;
class ActorCombat {
BladeRunnerEngine *_vm;
-// int _actorId;
-// int _combatOn;
-// int _field2;
-// int _field3;
-// int _otherActorId;
-// int _field5;
-// int _field6;
-// int _field7;
-// int _field8;
-// int _field9;
-// int _field10;
-// int _field11;
-// int _field12;
-// int _actorHp;
-// int _field14;
-// int _field15;
- Vector3 actorPosition;
- Vector3 otherActorPosition;
-// int _availableCoversCount;
-// int _availableFleeWaypointsCount;
-// int _field24;
+ int _actorId;
+ bool _active;
+ int _state;
+ int _rangedAttack;
+ int _enemyId;
+ int _waypointType;
+ int _damage;
+ int _fleeRatio;
+ int _coverRatio;
+ int _actionRatio;
+ int _fleeRatioConst;
+ int _coverRatioConst;
+ int _actionRatioConst;
+ int _actorHp;
+ int _range;
+ int field_3C;
+ Vector3 _actorPosition;
+ Vector3 _enemyPosition;
+ int _coversWaypointCount;
+ int _fleeWaypointsCount;
+ int _fleeingTowards;
public:
ActorCombat(BladeRunnerEngine *vm);
@@ -60,10 +60,38 @@ public:
void setup();
+ void combatOn(int actorId, int initialState, bool rangedAttack, int enemyId, int waypointType, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool a12);
+ void combatOff();
+
+ void tick();
+
void hitAttempt();
- void combatOn(int actorId, int a3, int a4, int otherActorId, int a6, int a7, int a8, int a9, int a10, int a11, int a12);
- void combatOff();
+private:
+ void reset();
+
+ void cover();
+ void approachToCloseAttack();
+ void approachToRangedAttack();
+ void uncover();
+ void aim();
+ void rangedAttack();
+ void closeAttack();
+ void flee();
+
+ void faceEnemy();
+
+ int getaggressivenessCloseAttack() const;
+ int getaggressivenessRangedAttack() const;
+
+ int getDamageCloseAttack(int min, int max) const;
+ int getDamageRangedAttack(int min, int max) const;
+
+ int calculateActionRatio() const;
+ int calculateCoverRatio() const;
+ int calculateFleeRatio() const;
+
+ bool findClosestPositionToEnemy(Vector3 &output) const;
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index ea663b53bc..43f67ea92d 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -224,7 +224,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_screenEffects = new ScreenEffects(this, 0x8000);
- _combat = new Combat(this);
// TODO: end credits
@@ -265,8 +264,11 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
return false;
r = _gameInfo->open("GAMEINFO.DAT");
- if (!r)
+ if (!r) {
return false;
+ }
+
+ _combat = new Combat(this);
// TODO: Create datetime - not used
@@ -751,8 +753,10 @@ void BladeRunnerEngine::gameTick() {
_sceneScript->playerWalkedIn();
}
bool inDialogueMenu = _dialogueMenu->isVisible();
- if (!inDialogueMenu) {
- // TODO: actors combat-tick
+ if (!inDialogueMenu) {
+ for (int i = 0; i < (int)_gameInfo->getActorCount(); ++i) {
+ _actors[i]->tickCombat();
+ }
}
// TODO: Gun range announcements
@@ -769,9 +773,6 @@ void BladeRunnerEngine::gameTick() {
(void)backgroundChanged;
blit(_surfaceBack, _surfaceFront);
- // TODO: remove zbuffer draw
- // _surfaceFront.copyRectToSurface(_zbuffer->getData(), 1280, 0, 0, 640, 480);
-
_overlays->tick();
if (!inDialogueMenu) {
@@ -1226,7 +1227,7 @@ void BladeRunnerEngine::handleMouseClick3DObject(int objectId, bool buttonDown,
}
_playerActor->stopWalking(false);
_playerActor->faceObject(objectName, false);
- _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatAttack, false);
_settings->decreaseAmmo();
_audioPlayer->playAud(_gameInfo->getSfxTrack(_combat->getHitSound()), 100, 0, 0, 90, 0);
@@ -1267,7 +1268,7 @@ void BladeRunnerEngine::handleMouseClickEmpty(int x, int y, Vector3 &scenePositi
} else {
_playerActor->faceItem(itemId, false);
}
- _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatAttack, false);
_settings->decreaseAmmo();
_audioPlayer->playAud(_gameInfo->getSfxTrack(_combat->getMissSound()), 100, 0, 0, 90, 0);
@@ -1362,7 +1363,7 @@ void BladeRunnerEngine::handleMouseClickItem(int itemId, bool buttonDown) {
_playerActor->stopWalking(false);
_playerActor->faceItem(itemId, false);
- _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatAttack, false);
_settings->decreaseAmmo();
_audioPlayer->playAud(_gameInfo->getSfxTrack(_combat->getHitSound()), 100, 0, 0, 90, 0);
@@ -1422,18 +1423,17 @@ void BladeRunnerEngine::handleMouseClickActor(int actorId, bool mainButton, bool
}
}
} else {
- if (!_combat->isActive() || actorId == kActorMcCoy || !_actors[actorId]->isTarget() || _actors[actorId]->isRetired() /*|| _mouse->isRandomized()*/) {
+ Actor *actor = _actors[actorId];
+
+ if (!_combat->isActive() || actorId == kActorMcCoy || !actor->isTarget() || actor->isRetired() /*|| _mouse->isRandomized()*/) {
return;
}
_playerActor->stopWalking(false);
_playerActor->faceActor(actorId, false);
- _playerActor->changeAnimationMode(kAnimationModeCombatShoot, false);
+ _playerActor->changeAnimationMode(kAnimationModeCombatAttack, false);
_settings->decreaseAmmo();
- float targetX = _actors[actorId]->getX();
- float targetZ = _actors[actorId]->getZ();
-
- bool missed = _playerActor->isObstacleBetween(targetX, targetZ);
+ bool missed = _playerActor->isObstacleBetween(actor->getXYZ());
_audioPlayer->playAud(_gameInfo->getSfxTrack(missed ? _combat->getMissSound() : _combat->getHitSound()), 100, 0, 0, 90, 0);
diff --git a/engines/bladerunner/combat.cpp b/engines/bladerunner/combat.cpp
index c371f7bedd..ef7a589456 100644
--- a/engines/bladerunner/combat.cpp
+++ b/engines/bladerunner/combat.cpp
@@ -22,10 +22,13 @@
#include "bladerunner/combat.h"
-
#include "bladerunner/actor.h"
+#include "bladerunner/audio_speech.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_constants.h"
+#include "bladerunner/game_info.h"
+#include "bladerunner/movement_track.h"
+#include "bladerunner/scene_objects.h"
#include "bladerunner/settings.h"
namespace BladeRunner {
@@ -33,6 +36,9 @@ namespace BladeRunner {
Combat::Combat(BladeRunnerEngine *vm) {
_vm = vm;
+ _coverWaypoints.resize(_vm->_gameInfo->getCoverWaypointCount());
+ _fleeWaypoints.resize(_vm->_gameInfo->getFleeWaypointCount());
+
reset();
}
@@ -55,7 +61,7 @@ void Combat::reset() {
void Combat::activate() {
if(_enabled) {
- _vm->_playerActor->combatModeOn(-1, -1, -1, -1, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, _vm->_combat->_ammoDamage[_vm->_settings->getAmmoType()], 0, 0);
+ _vm->_playerActor->combatModeOn(-1, true, -1, -1, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, _vm->_combat->_ammoDamage[_vm->_settings->getAmmoType()], 0, false);
_active = true;
}
}
@@ -97,16 +103,105 @@ void Combat::setMissSound(int ammoType, int column, int soundId) {
_missSoundId[ammoType * 3 + column] = soundId;
}
-int Combat::getHitSound() {
+int Combat::getHitSound() const {
return _hitSoundId[3 * _vm->_settings->getAmmoType() + _vm->_rnd.getRandomNumber(2)];
}
-int Combat::getMissSound() {
+int Combat::getMissSound() const {
return _hitSoundId[3 * _vm->_settings->getAmmoType() + _vm->_rnd.getRandomNumber(2)];
}
void Combat::shoot(int actorId, Vector3 &to, int screenX) {
+ Actor *actor = _vm->_actors[actorId];
+
+ if (actor->isRetired()) {
+ return;
+ }
+
+ int sentenceId = -1;
+
+ /*
+ Distance from center as a percentage:
+ screenX - abs(right + left) / 2
+ distanceFromCenter = 100 * -------------------------------
+ abs(right - left) / 2
+ */
+ Common::Rect *rect = actor->getScreenRectangle();
+ int distanceFromCenter = CLIP(100 * (screenX - abs((rect->right + rect->left) / 2)) / abs((rect->right - rect->left) / 2), 0, 100);
+
+ int damage = (100 - distanceFromCenter) * _ammoDamage[_vm->_settings->getAmmoType()] / 100;
+ int hp = MAX(actor->getCurrentHP() - damage, 0);
+
+ actor->setCurrentHP(hp);
+
+ bool setDamageAnimation = true;
+ if (actor->isWalking() == 1 && !actor->getFlagDamageAnimIfMoving()) {
+ setDamageAnimation = false;
+ }
+ if (actor->_movementTrack->hasNext() && !actor->_movementTrack->isPaused()) {
+ setDamageAnimation = false;
+ }
+ if (setDamageAnimation) {
+ if (actor->isWalking()) {
+ actor->stopWalking(false);
+ }
+ if (actor->getAnimationMode() != kAnimationModeHit && actor->getAnimationMode() != kAnimationModeCombatHit) {
+ actor->changeAnimationMode(kAnimationModeHit, false);
+ sentenceId = _vm->_rnd.getRandomNumberRng(0, 1) ? 9000 : 9005;
+ }
+ }
+
+ if (hp <= 0) {
+ actor->setTarget(false);
+ if (actor->inCombat()) {
+ actor->combatModeOff();
+ }
+ actor->stopWalking(false);
+ actor->changeAnimationMode(48, false);
+ actor->retire(true, 72, 36, kActorMcCoy);
+ actor->setAtXYZ(actor->getXYZ(), actor->getFacing(), true, false, true);
+ _vm->_sceneObjects->setRetired(actorId + kSceneObjectOffsetActors, true);
+ sentenceId = 9020;
+ }
+
+ if (sentenceId >= 0 && actor->inCombat()) {
+ _vm->_audioSpeech->playSpeechLine(actorId, sentenceId, 75, 0, 99);
+ }
+}
+
+int Combat::findFleeWaypoint(int setId, int enemyId, const Vector3& position) const {
+ float min = -1.0f;
+ int result = -1;
+ for (int i = 0; i < (int)_fleeWaypoints.size(); ++i) {
+ if (setId == _fleeWaypoints[i].setId) {
+ float dist = distance(position, _fleeWaypoints[i].position);
+ if (result == -1 || dist < min) {
+ result = i;
+ min = dist;
+ }
+ }
+ }
+ return result;
+}
+
+int Combat::findCoverWaypoint(int waypointType, int actorId, int enemyId) const {
+ Actor *actor = _vm->_actors[actorId];
+ Actor *enemy = _vm->_actors[enemyId];
+ int result = -1;
+ float min = -1.0f;
+ for (int i = 0; i < (int)_coverWaypoints.size(); ++i) {
+ if (waypointType == _coverWaypoints[i].type && actor->getSetId() == _coverWaypoints[i].setId) {
+ if (_vm->_sceneObjects->isObstacleBetween(_coverWaypoints[i].position, enemy->getXYZ(), enemyId)) {
+ float dist = distance(_coverWaypoints[i].position, actor->getXYZ());
+ if (result == -1 || dist < min) {
+ result = i;
+ min = dist;
+ }
+ }
+ }
+ }
+ return result;
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/combat.h b/engines/bladerunner/combat.h
index 21989dac52..ab289cca5c 100644
--- a/engines/bladerunner/combat.h
+++ b/engines/bladerunner/combat.h
@@ -23,9 +23,11 @@
#ifndef BLADERUNNER_COMBAT_H
#define BLADERUNNER_COMBAT_H
-namespace BladeRunner {
+#include "bladerunner/vector.h"
+
+#include "common/array.h"
-class Vector3;
+namespace BladeRunner {
class BladeRunnerEngine;
@@ -44,6 +46,24 @@ class Combat {
public:
int _ammoDamage[3];
+ struct CoverWaypoint {
+ int type;
+ int setId;
+ int sceneId;
+ Vector3 position;
+ };
+
+ struct FleeWaypoint {
+ int type;
+ int setId;
+ int sceneId;
+ Vector3 position;
+ int field7;
+ };
+
+ Common::Array<CoverWaypoint> _coverWaypoints;
+ Common::Array<FleeWaypoint> _fleeWaypoints;
+
public:
Combat(BladeRunnerEngine *vm);
~Combat();
@@ -60,10 +80,13 @@ public:
void setHitSound(int ammoType, int column, int soundId);
void setMissSound(int ammoType, int column, int soundId);
- int getHitSound();
- int getMissSound();
+ int getHitSound() const;
+ int getMissSound() const;
void shoot(int actorId, Vector3 &to, int screenX);
+
+ int findFleeWaypoint(int setId, int enemyId, const Vector3& position) const;
+ int findCoverWaypoint(int waypointType, int actorId, int enemyId) const;
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index 5539082187..2c9b7e6f74 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/actor.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/boundingbox.h"
+#include "bladerunner/combat.h"
#include "bladerunner/font.h"
#include "bladerunner/game_constants.h"
#include "bladerunner/game_flags.h"
@@ -271,8 +272,7 @@ bool Debugger::cmdPosition(int argc, const char **argv) {
return true;
}
- Vector3 position;
- otherActor->getXYZ(&position.x, &position.y, &position.z);
+ Vector3 position = otherActor->getXYZ();
actor->setSetId(otherActor->getSetId());
actor->setAtXYZ(position, otherActor->getFacing());
return true;
@@ -481,12 +481,13 @@ void Debugger::drawSceneObjects() {
}
//draw waypoints
- for(int i = 0; i < _vm->_waypoints->_count; i++) {
+ for (int i = 0; i < _vm->_waypoints->_count; i++) {
Waypoints::Waypoint *waypoint = &_vm->_waypoints->_waypoints[i];
- if(waypoint->setId != _vm->_scene->getSetId())
+ if(waypoint->setId != _vm->_scene->getSetId()) {
continue;
+ }
Vector3 pos = waypoint->position;
- Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
+ Vector3 size = Vector3(3.0f, 3.0f, 3.0f);
int color = 0x7FFF; // 11111 11111 11111
drawBBox(pos - size, pos + size, _vm->_view, &_vm->_surfaceFront, color);
Vector3 spos = _vm->_view->calculateScreenPosition(pos);
@@ -495,6 +496,38 @@ void Debugger::drawSceneObjects() {
_vm->_mainFont->drawColor(waypointText, _vm->_surfaceFront, spos.x, spos.y, color);
}
+ //draw combat cover waypoints
+ for (int i = 0; i < (int)_vm->_combat->_coverWaypoints.size(); i++) {
+ Combat::CoverWaypoint *cover = &_vm->_combat->_coverWaypoints[i];
+ if (cover->setId != _vm->_scene->getSetId()) {
+ continue;
+ }
+ Vector3 pos = cover->position;
+ Vector3 size = Vector3(3.0f, 3.0f, 3.0f);
+ int color = 0x7C1F; // 11111 00000 11111
+ drawBBox(pos - size, pos + size, _vm->_view, &_vm->_surfaceFront, color);
+ Vector3 spos = _vm->_view->calculateScreenPosition(pos);
+ char coverText[40];
+ sprintf(coverText, "cover %i", i);
+ _vm->_mainFont->drawColor(coverText, _vm->_surfaceFront, spos.x, spos.y, color);
+ }
+
+ //draw combat flee waypoints
+ for (int i = 0; i < (int)_vm->_combat->_fleeWaypoints.size(); i++) {
+ Combat::FleeWaypoint *flee = &_vm->_combat->_fleeWaypoints[i];
+ if (flee->setId != _vm->_scene->getSetId()) {
+ continue;
+ }
+ Vector3 pos = flee->position;
+ Vector3 size = Vector3(3.0f, 3.0f, 3.0f);
+ int color = 0x03FF; // 00000 11111 11111
+ drawBBox(pos - size, pos + size, _vm->_view, &_vm->_surfaceFront, color);
+ Vector3 spos = _vm->_view->calculateScreenPosition(pos);
+ char fleeText[40];
+ sprintf(fleeText, "flee %i", i);
+ _vm->_mainFont->drawColor(fleeText, _vm->_surfaceFront, spos.x, spos.y, color);
+ }
+
#if 0
//draw aesc
for (uint i = 0; i < _screenEffects->_entries.size(); i++) {
diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h
index af4728aaad..4aa72c1bc6 100644
--- a/engines/bladerunner/game_constants.h
+++ b/engines/bladerunner/game_constants.h
@@ -597,14 +597,17 @@ enum AnimationModes {
kAnimationModeTalk = 3,
kAnimationModeCombatIdle = 4,
kAnimationModeCombatAim = 5,
- kAnimationModeCombatShoot = 6,
+ kAnimationModeCombatAttack = 6,
kAnimationModeCombatWalk = 7,
kAnimationModeCombatRun = 8,
+ kAnimationModeHit = 21,
+ kAnimationModeCombatHit = 22,
kAnimationModeWalkUp = 44,
kAnimationModeWalkDown = 45,
kAnimationModeCombatWalkUp = 46,
kAnimationModeCombatWalkDown = 47,
- kAnimationModeDie = 48, // TODO: check
+ kAnimationModeDie = 48,
+ kAnimationModeCombatDie = 49,
kAnimationModeFeeding = 52,
kAnimationModeSit = 53, // TODO: check
kAnimationModeClimbUp = 64,
@@ -871,6 +874,18 @@ enum SceneObjectOffset {
kSceneObjectOffsetObjects = 198
};
+enum ActorCombatStates {
+ kActorCombatStateIdle = 0,
+ kActorCombatStateCover = 1,
+ kActorCombatStateApproachCloseAttack = 2,
+ kActorCombatStateUncover = 3,
+ kActorCombatStateAim = 4,
+ kActorCombatStateRangedAttack = 5,
+ kActorCombatStateCloseAttack = 6,
+ kActorCombatStateFlee = 7,
+ kActorCombatStateApproachRangedAttack = 8
+};
+
} // End of namespace BladeRunner
#endif
diff --git a/engines/bladerunner/matrix.h b/engines/bladerunner/matrix.h
index 5343eb6b8e..d5922b403f 100644
--- a/engines/bladerunner/matrix.h
+++ b/engines/bladerunner/matrix.h
@@ -57,8 +57,8 @@ inline Matrix3x2 operator*(const Matrix3x2 &a, const Matrix3x2 &b) {
inline Matrix3x2 operator+(const Matrix3x2 &a, Vector2 b) {
Matrix3x2 t(a);
- t(0,2) += b.x;
- t(1,2) += b.y;
+ t(0, 2) += b.x;
+ t(1, 2) += b.y;
return t;
}
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index 87320a3fa4..148cde827c 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -255,7 +255,7 @@ bool SceneObjects::isBetween(float sourceX, float sourceZ, float targetX, float
|| lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ2), Vector2(objectX1, objectZ1), &intersection);
}
-bool SceneObjects::isObstacleBetween(float sourceX, float sourceZ, float targetX, float targetZ, float altitude, int exceptSceneObjectId) const {
+bool SceneObjects::isObstacleBetween(const Vector3 &source, const Vector3 &target, int exceptSceneObjectId) const {
for (int i = 0; i < _count; ++i) {
const SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]];
@@ -264,9 +264,9 @@ bool SceneObjects::isObstacleBetween(float sourceX, float sourceZ, float targetX
}
float objectX1, objectY1, objectZ1, objectX2, objectY2, objectZ2;
- _sceneObjects[i].boundingBox->getXYZ(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2);
+ sceneObject->boundingBox->getXYZ(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2);
- if (84.0f <= objectY1 - altitude || 72.0f >= objectY2 - altitude) {
+ if (84.0f <= objectY1 - source.y || 72.0f >= objectY2 - source.y) {
continue;
}
@@ -279,10 +279,10 @@ bool SceneObjects::isObstacleBetween(float sourceX, float sourceZ, float targetX
objectZ2 = objectZ2 - zAdjustement;
Vector2 intersection;
- if (lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ1), Vector2(objectX2, objectZ1), &intersection)
- || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX2, objectZ1), Vector2(objectX2, objectZ2), &intersection)
- || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX2, objectZ2), Vector2(objectX1, objectZ2), &intersection)
- || lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ2), Vector2(objectX1, objectZ1), &intersection)) {
+ if (lineIntersection(Vector2(source.x, source.z), Vector2(target.x, target.z), Vector2(objectX1, objectZ1), Vector2(objectX2, objectZ1), &intersection)
+ || lineIntersection(Vector2(source.x, source.z), Vector2(target.x, target.z), Vector2(objectX2, objectZ1), Vector2(objectX2, objectZ2), &intersection)
+ || lineIntersection(Vector2(source.x, source.z), Vector2(target.x, target.z), Vector2(objectX2, objectZ2), Vector2(objectX1, objectZ2), &intersection)
+ || lineIntersection(Vector2(source.x, source.z), Vector2(target.x, target.z), Vector2(objectX1, objectZ2), Vector2(objectX1, objectZ1), &intersection)) {
return true;
}
}
diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h
index dbd61b6dc5..de31eae88d 100644
--- a/engines/bladerunner/scene_objects.h
+++ b/engines/bladerunner/scene_objects.h
@@ -80,7 +80,7 @@ public:
void setMoving(int sceneObjectId, bool isMoving);
void setRetired(int sceneObjectId, bool isRetired);
bool isBetween(float sourceX, float sourceZ, float targetX, float targetZ, int sceneObjectId) const;
- bool isObstacleBetween(float sourceX, float sourceZ, float targetX, float targetZ, float altitude, int exceptSceneObjectId) const;
+ bool isObstacleBetween(const Vector3 &source, const Vector3 &target, int exceptSceneObjectId) const;
void setIsClickable(int sceneObjectId, bool isClickable);
void setIsObstacle(int sceneObjectId, bool isObstacle);
void setIsTarget(int sceneObjectId, bool isTarget);
diff --git a/engines/bladerunner/script/ai/clovis.cpp b/engines/bladerunner/script/ai/clovis.cpp
index 9c8976e02d..e55fdb9468 100644
--- a/engines/bladerunner/script/ai/clovis.cpp
+++ b/engines/bladerunner/script/ai/clovis.cpp
@@ -440,22 +440,22 @@ bool AIScriptClovis::GoalChanged(int currentGoalNumber, int newGoalNumber) {
Global_Variable_Decrement(51, 1);
}
if (Global_Variable_Query(kVariableChapter) == 5 && Actor_Query_In_Set(kActorDektora, kSetKP07)) {
- Non_Player_Actor_Combat_Mode_On(kActorDektora, 0, 0, 0, 19, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorDektora, kActorCombatStateIdle, false, kActorMcCoy, 19, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
if (Global_Variable_Query(kVariableChapter) == 5 && Actor_Query_In_Set(kActorZuben, kSetKP07)) {
- Non_Player_Actor_Combat_Mode_On(kActorZuben, 0, 0, 0, 19, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorZuben, kActorCombatStateIdle, false, kActorMcCoy, 19, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
if (Global_Variable_Query(kVariableChapter) == 5 && Actor_Query_In_Set(kActorSadik, kSetKP07)) {
- Non_Player_Actor_Combat_Mode_On(kActorSadik, 0, 1, 0, 19, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSadik, kActorCombatStateIdle, true, kActorMcCoy, 19, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
if (Global_Variable_Query(kVariableChapter) == 5 && Actor_Query_In_Set(kActorIzo, kSetKP07)) {
- Non_Player_Actor_Combat_Mode_On(kActorIzo, 0, 0, 0, 19, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorIzo, kActorCombatStateIdle, false, kActorMcCoy, 19, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
if (Global_Variable_Query(kVariableChapter) == 5 && Actor_Query_In_Set(kActorGordo, kSetKP07)) {
- Non_Player_Actor_Combat_Mode_On(kActorGordo, 0, 1, 0, 19, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorGordo, kActorCombatStateIdle, true, kActorMcCoy, 19, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
if (Global_Variable_Query(kVariableChapter) == 5 && Actor_Query_In_Set(kActorClovis, kSetKP07)) {
- Non_Player_Actor_Combat_Mode_On(kActorClovis, 0, 0, 0, 19, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorClovis, kActorCombatStateIdle, false, kActorMcCoy, 19, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
return true;
diff --git a/engines/bladerunner/script/ai/dektora.cpp b/engines/bladerunner/script/ai/dektora.cpp
index 905c3d16da..28bdf3c83d 100644
--- a/engines/bladerunner/script/ai/dektora.cpp
+++ b/engines/bladerunner/script/ai/dektora.cpp
@@ -280,7 +280,7 @@ void AIScriptDektora::Retired(int byActorId) {
}
if (byActorId == kActorSteele && Actor_Query_In_Set(kActorSteele, kSetHF06) && Actor_Query_In_Set(kActorMcCoy, kSetHF06)) {
- Non_Player_Actor_Combat_Mode_On(kActorSteele, 3, 1, 0, 15, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, kActorMcCoy, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
if (Actor_Query_In_Set(kActorDektora, kSetKP07)) {
@@ -290,8 +290,8 @@ void AIScriptDektora::Retired(int byActorId) {
if (!Global_Variable_Query(51)) {
Player_Loses_Control();
Delay(2000);
- Player_Set_Combat_Mode(0);
- Loop_Actor_Walk_To_XYZ(0, -12.0, -41.580002, 72.0, 0, 1, 0, 0);
+ Player_Set_Combat_Mode(false);
+ Loop_Actor_Walk_To_XYZ(kActorMcCoy, -12.0f, -41.58f, 72.0f, 0, true, false, 0);
Ambient_Sounds_Remove_All_Non_Looping_Sounds(1);
Ambient_Sounds_Remove_All_Looping_Sounds(1);
Game_Flag_Set(579);
@@ -1095,11 +1095,11 @@ void AIScriptDektora::checkCombat() {
&& Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorDektora) != 450) {
if (Global_Variable_Query(kVariableAffectionTowards) == 2) {
- Global_Variable_Set(45, 0);
+ Global_Variable_Set(kVariableAffectionTowards, 0);
}
Actor_Set_Goal_Number(kActorDektora, 450);
- Non_Player_Actor_Combat_Mode_On(kActorDektora, 0, 0, kActorMcCoy, 4, 4, 7, 8, 0, -1, -1, 20, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorDektora, kActorCombatStateIdle, false, kActorMcCoy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, -1, -1, 20, 300, false);
}
}
diff --git a/engines/bladerunner/script/ai/gaff.cpp b/engines/bladerunner/script/ai/gaff.cpp
index c26f0d907f..c5e629cab0 100644
--- a/engines/bladerunner/script/ai/gaff.cpp
+++ b/engines/bladerunner/script/ai/gaff.cpp
@@ -287,7 +287,7 @@ bool AIScriptGaff::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return true;
case 303:
Actor_Face_Actor(kActorGaff, kActorMcCoy, 1);
- Actor_Change_Animation_Mode(kActorGaff, kAnimationModeCombatShoot);
+ Actor_Change_Animation_Mode(kActorGaff, kAnimationModeCombatAttack);
Sound_Play(27, 100, 0, 0, 50);
Actor_Change_Animation_Mode(kActorMcCoy, 48);
Actor_Retired_Here(kActorMcCoy, 12, 12, 1, -1);
diff --git a/engines/bladerunner/script/ai/gordo.cpp b/engines/bladerunner/script/ai/gordo.cpp
index fd64112897..c44497176a 100644
--- a/engines/bladerunner/script/ai/gordo.cpp
+++ b/engines/bladerunner/script/ai/gordo.cpp
@@ -1157,7 +1157,7 @@ bool AIScriptGordo::ChangeAnimationMode(int mode) {
break;
}
break;
- case kAnimationModeCombatShoot:
+ case kAnimationModeCombatAttack:
_animationState = 18;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai/guzza.cpp b/engines/bladerunner/script/ai/guzza.cpp
index 0f99fa8a46..5a4459535e 100644
--- a/engines/bladerunner/script/ai/guzza.cpp
+++ b/engines/bladerunner/script/ai/guzza.cpp
@@ -728,7 +728,7 @@ bool AIScriptGuzza::ChangeAnimationMode(int mode) {
_animationFrame = 0;
}
break;
- case kAnimationModeCombatShoot:
+ case kAnimationModeCombatAttack:
_animationState = 31;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai/leon.cpp b/engines/bladerunner/script/ai/leon.cpp
index fad9da3cfb..fdcb538f0a 100644
--- a/engines/bladerunner/script/ai/leon.cpp
+++ b/engines/bladerunner/script/ai/leon.cpp
@@ -386,7 +386,7 @@ bool AIScriptLeon::ChangeAnimationMode(int mode) {
_animationFrame = 0;
var_45EDAC = 0;
break;
- case kAnimationModeCombatShoot:
+ case kAnimationModeCombatAttack:
_animationState = 10;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai/lucy.cpp b/engines/bladerunner/script/ai/lucy.cpp
index aebeac7322..464f228179 100644
--- a/engines/bladerunner/script/ai/lucy.cpp
+++ b/engines/bladerunner/script/ai/lucy.cpp
@@ -227,7 +227,7 @@ void AIScriptLucy::Retired(int byActorId) {
if ((byActorId == kActorSteele || byActorId == kActorMcCoy)
&& Actor_Query_In_Set(kActorSteele, kSetHF06)
&& Actor_Query_In_Set(kActorMcCoy, kSetHF06)) {
- Non_Player_Actor_Combat_Mode_On(kActorSteele, 3, 1, 0, 15, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, kActorMcCoy, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
if (Query_Difficulty_Level() && byActorId == kActorMcCoy && Game_Flag_Query(46)) {
Global_Variable_Increment(2, 200);
@@ -861,10 +861,10 @@ void AIScriptLucy::checkCombat() {
&& Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorLucy) != 450) {
if (Global_Variable_Query(kVariableAffectionTowards) == 3) {
- Global_Variable_Set(45, 0);
+ Global_Variable_Set(kVariableAffectionTowards, 0);
}
Actor_Set_Goal_Number(kActorLucy, 450);
- Non_Player_Actor_Combat_Mode_On(kActorLucy, 0, 0, 0, 4, 0, 1, 2, -1, 0, 0, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorLucy, kActorCombatStateIdle, false, kActorMcCoy, 4, kAnimationModeIdle, kAnimationModeWalk, kAnimationModeRun, -1, 0, 0, 10, 300, false);
}
}
diff --git a/engines/bladerunner/script/ai/mccoy.cpp b/engines/bladerunner/script/ai/mccoy.cpp
index 554de0cd80..56b54ac0eb 100644
--- a/engines/bladerunner/script/ai/mccoy.cpp
+++ b/engines/bladerunner/script/ai/mccoy.cpp
@@ -242,22 +242,22 @@ bool AIScriptMcCoy::ShotAtAndHit() {
void AIScriptMcCoy::Retired(int byActorId) {
if (byActorId == kActorSteele && Actor_Query_In_Set(kActorSteele, kSetHF06)) {
if (Actor_Query_In_Set(kActorDektora, kSetHF06) && Actor_Query_Goal_Number(kActorDektora) != 599) {
- Non_Player_Actor_Combat_Mode_On(kActorSteele, 3, 1, kActorDektora, 15, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, kActorDektora, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
} else if (Actor_Query_In_Set(kActorLucy, kSetHF06) && Actor_Query_Goal_Number(kActorLucy) != 599) {
- Non_Player_Actor_Combat_Mode_On(kActorSteele, 3, 1, kActorLucy, 15, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, kActorLucy, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
}
if (Actor_Query_In_Set(kActorMcCoy, kSetHF05) && Actor_Query_In_Set(kActorOfficerLeary, kSetHF05) && Actor_Query_In_Set(kActorDektora, kSetHF05) && Actor_Query_Goal_Number(kActorDektora) != 599) {
- Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, 3, 1, kActorDektora, 4, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, kActorCombatStateUncover, true, kActorDektora, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
if (Actor_Query_In_Set(kActorMcCoy, kSetHF05) && Actor_Query_In_Set(kActorOfficerGrayford, kSetHF05) && Actor_Query_In_Set(kActorDektora, kSetHF05) && Actor_Query_Goal_Number(kActorDektora) != 599) {
- Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, 3, 1, kActorDektora, 4, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, kActorCombatStateUncover, true, kActorDektora, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
if (Actor_Query_In_Set(kActorMcCoy, kSetHF05) && Actor_Query_In_Set(kActorOfficerLeary, kSetHF05) && Actor_Query_In_Set(kActorLucy, kSetHF05) && Actor_Query_Goal_Number(kActorLucy) != 599) {
- Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, 3, 1, kActorLucy, 4, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, kActorCombatStateUncover, true, kActorLucy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
if (Actor_Query_In_Set(kActorMcCoy, kSetHF05) && Actor_Query_In_Set(kActorOfficerGrayford, kSetHF05) && Actor_Query_In_Set(kActorLucy, kSetHF05) && Actor_Query_Goal_Number(kActorLucy) != 599) {
- Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, 3, 1, kActorLucy, 4, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, kActorCombatStateUncover, true, kActorLucy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
}
@@ -307,7 +307,7 @@ bool AIScriptMcCoy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return true;
case 230:
dword_45A0FC = Actor_Query_Goal_Number(kActorSteele) == 215;
- Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeCombatShoot);
+ Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeCombatAttack);
return true;
case 220:
Actor_Change_Animation_Mode(kActorMcCoy, 75);
@@ -412,7 +412,7 @@ bool AIScriptMcCoy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 400:
Actor_Set_Health(kActorMcCoy, 50, 50);
Game_Flag_Set(373);
- v5 = Global_Variable_Query(45);
+ v5 = Global_Variable_Query(kVariableAffectionTowards);
if (v5 == 1) {
Actor_Modify_Friendliness_To_Other(kActorSteele, kActorMcCoy, 3);
} else if (v5 == 2) {
@@ -428,14 +428,14 @@ bool AIScriptMcCoy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (Actor_Query_Friendliness_To_Other(kActorSteele, kActorMcCoy) < Actor_Query_Friendliness_To_Other(kActorClovis, kActorMcCoy)) {
Game_Flag_Set(653);
}
- v7 = Global_Variable_Query(45);
+ v7 = Global_Variable_Query(kVariableAffectionTowards);
if (v7 == 1) {
if (Game_Flag_Query(653)) {
- Global_Variable_Set(45, 0);
+ Global_Variable_Set(kVariableAffectionTowards, 0);
}
} else if (v7 == 2 || v7 == 3) {
if (!Game_Flag_Query(653)) {
- Global_Variable_Set(45, 0);
+ Global_Variable_Set(kVariableAffectionTowards, 0);
}
}
if (!Game_Flag_Query(653)) {
@@ -1382,7 +1382,7 @@ bool AIScriptMcCoy::ChangeAnimationMode(int mode) {
break;
}
break;
- case kAnimationModeCombatShoot:
+ case kAnimationModeCombatAttack:
_animationState = 21;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai/mutant1.cpp b/engines/bladerunner/script/ai/mutant1.cpp
index 9ecaf9d80e..eb1c0562af 100644
--- a/engines/bladerunner/script/ai/mutant1.cpp
+++ b/engines/bladerunner/script/ai/mutant1.cpp
@@ -83,7 +83,7 @@ bool AIScriptMutant1::Update() {
case 410:
if (Actor_Query_Which_Set_In(kActorMutant1) != Player_Query_Current_Set()) {
- Non_Player_Actor_Combat_Mode_Off(70);
+ Non_Player_Actor_Combat_Mode_Off(kActorMutant1);
Actor_Set_Goal_Number(kActorMutant1, 403);
}
break;
@@ -326,28 +326,23 @@ bool AIScriptMutant1::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 410:
switch (Actor_Query_Which_Set_In(kActorMutant1)) {
case kSetUG01:
- Non_Player_Actor_Combat_Mode_On(kActorMutant1, 0, 0, 0, 11, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 11, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG04:
case kSetUG05:
case kSetUG06:
- Non_Player_Actor_Combat_Mode_On(kActorMutant1, 0, 0, 0, 10, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 10, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG07:
- Non_Player_Actor_Combat_Mode_On(kActorMutant1, 0, 0, 0, 12, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 12, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG10:
- Non_Player_Actor_Combat_Mode_On(kActorMutant1, 0, 0, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
- break;
-
case kSetUG12:
- Non_Player_Actor_Combat_Mode_On(kActorMutant1, 0, 0, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
- break;
case kSetUG14:
- Non_Player_Actor_Combat_Mode_On(kActorMutant1, 0, 0, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 14, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
}
return true;
diff --git a/engines/bladerunner/script/ai/mutant2.cpp b/engines/bladerunner/script/ai/mutant2.cpp
index 6a51c710dd..6317311088 100644
--- a/engines/bladerunner/script/ai/mutant2.cpp
+++ b/engines/bladerunner/script/ai/mutant2.cpp
@@ -305,25 +305,19 @@ bool AIScriptMutant2::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 410:
switch (Actor_Query_Which_Set_In(kActorMutant2)) {
case kSetUG01:
- Non_Player_Actor_Combat_Mode_On(kActorMutant2, 0, 0, 0, 11, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant2, kActorCombatStateIdle, false, kActorMcCoy, 11, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG04:
case kSetUG05:
case kSetUG06:
- Non_Player_Actor_Combat_Mode_On(kActorMutant2, 0, 0, 0, 10, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant2, kActorCombatStateIdle, false, kActorMcCoy, 10, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG10:
- Non_Player_Actor_Combat_Mode_On(kActorMutant2, 0, 0, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
- break;
-
case kSetUG12:
- Non_Player_Actor_Combat_Mode_On(kActorMutant2, 0, 0, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
- break;
-
case kSetUG14:
- Non_Player_Actor_Combat_Mode_On(kActorMutant2, 0, 0, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant2, kActorCombatStateIdle, false, kActorMcCoy, 14, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
}
return true;
diff --git a/engines/bladerunner/script/ai/mutant3.cpp b/engines/bladerunner/script/ai/mutant3.cpp
index 76a9a0edff..db161d8d5a 100644
--- a/engines/bladerunner/script/ai/mutant3.cpp
+++ b/engines/bladerunner/script/ai/mutant3.cpp
@@ -316,24 +316,19 @@ bool AIScriptMutant3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 410:
switch (Actor_Query_Which_Set_In(kActorMutant3)) {
case kSetUG01:
- Non_Player_Actor_Combat_Mode_On(kActorMutant3, 0, 1, 0, 11, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant3, kActorCombatStateIdle, false, kActorMcCoy, 11, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG04:
case kSetUG05:
case kSetUG06:
- Non_Player_Actor_Combat_Mode_On(kActorMutant3, 0, 1, 0, 10, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant3, kActorCombatStateIdle, false, kActorMcCoy, 10, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG10:
- Non_Player_Actor_Combat_Mode_On(kActorMutant3, 0, 1, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
- break;
case kSetUG12:
- Non_Player_Actor_Combat_Mode_On(kActorMutant3, 0, 1, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
- break;
-
case kSetUG14:
- Non_Player_Actor_Combat_Mode_On(kActorMutant3, 0, 1, 0, 14, 4, 7, 8, -1, -1, -1, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorMutant3, kActorCombatStateIdle, false, kActorMcCoy, 14, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
}
break;
@@ -342,6 +337,7 @@ bool AIScriptMutant3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 39, 100);
AI_Movement_Track_Repeat(kActorMutant3);
+ break;
case 599:
AI_Movement_Track_Flush(kActorMutant3);
diff --git a/engines/bladerunner/script/ai/officer_leary.cpp b/engines/bladerunner/script/ai/officer_leary.cpp
index b18ba0869f..0adbe7c1c0 100644
--- a/engines/bladerunner/script/ai/officer_leary.cpp
+++ b/engines/bladerunner/script/ai/officer_leary.cpp
@@ -979,7 +979,7 @@ bool AIScriptOfficerLeary::ChangeAnimationMode(int mode) {
break;
}
break;
- case kAnimationModeCombatShoot:
+ case kAnimationModeCombatAttack:
_animationState = 24;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai/sadik.cpp b/engines/bladerunner/script/ai/sadik.cpp
index b6abc8dab8..9fdb889b6c 100644
--- a/engines/bladerunner/script/ai/sadik.cpp
+++ b/engines/bladerunner/script/ai/sadik.cpp
@@ -356,7 +356,7 @@ bool AIScriptSadik::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 413:
Loop_Actor_Walk_To_XYZ(kActorSadik, -1062.0f, 0.0f, 219.0f, 0, 0, 1, 0);
Actor_Set_Targetable(kActorSadik, 1);
- Non_Player_Actor_Combat_Mode_On(kActorSadik, 0, 1, 0, 9, 4, 7, 8, 0, -1, -1, 15, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSadik, kActorCombatStateIdle, true, kActorMcCoy, 9, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, -1, -1, 15, 300, false);
Actor_Set_Goal_Number(kActorSadik, 450);
return true;
@@ -412,7 +412,7 @@ bool AIScriptSadik::GoalChanged(int currentGoalNumber, int newGoalNumber) {
case 418:
Game_Flag_Reset(653);
Actor_Set_Goal_Number(kActorClovis, 518);
- Non_Player_Actor_Combat_Mode_On(kActorSadik, 0, 1, 0, 9, 4, 7, 8, 0, -1, -1, 15, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSadik, kActorCombatStateIdle, true, kActorMcCoy, 9, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, -1, -1, 15, 300, false);
return true;
case 419:
@@ -999,6 +999,7 @@ bool AIScriptSadik::ChangeAnimationMode(int mode) {
_animationState = 33;
_animationFrame = 0;
}
+ break;
case 63:
if (Actor_Query_Goal_Number(kActorSadik) != 105 && Actor_Query_Goal_Number(kActorSadik) != 106) {
diff --git a/engines/bladerunner/script/ai/steele.cpp b/engines/bladerunner/script/ai/steele.cpp
index e51a14a8ca..ff2afa1ec3 100644
--- a/engines/bladerunner/script/ai/steele.cpp
+++ b/engines/bladerunner/script/ai/steele.cpp
@@ -419,7 +419,7 @@ bool AIScriptSteele::ShotAtAndHit() {
Actor_Set_Goal_Number(kActorSteele, 271);
if (/* !a1 && */ Actor_Query_In_Set(kActorSteele, kSetHF06))
- Non_Player_Actor_Combat_Mode_On(1, 3, 1, 0, 15, 4, 7, 8, 0, 0, 100, 25, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, kActorMcCoy, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
return false;
}
diff --git a/engines/bladerunner/script/ai/taffy_patron.cpp b/engines/bladerunner/script/ai/taffy_patron.cpp
index c7fa3a7165..0bf6861d12 100644
--- a/engines/bladerunner/script/ai/taffy_patron.cpp
+++ b/engines/bladerunner/script/ai/taffy_patron.cpp
@@ -95,13 +95,13 @@ bool AIScriptTaffyPatron::GoalChanged(int currentGoalNumber, int newGoalNumber)
case 250:
Actor_Put_In_Set(kActorTaffyPatron, kSetNR01);
- Actor_Set_At_XYZ(kActorTaffyPatron, -170.39999, 23.68, -850.0, 324);
- Async_Actor_Walk_To_XYZ(kActorTaffyPatron, -390.0, 31.549999, -429.0, 24, 1);
+ Actor_Set_At_XYZ(kActorTaffyPatron, -170.4f, 23.68f, -850.0f, 324);
+ Async_Actor_Walk_To_XYZ(kActorTaffyPatron, -390.0f, 31.55f, -429.0f, 24, 1);
return true;
case 255:
Actor_Put_In_Set(kActorTaffyPatron, kSetNR01);
- Actor_Set_At_XYZ(kActorTaffyPatron, -170.39999, 23.68, -850.0, 324);
+ Actor_Set_At_XYZ(kActorTaffyPatron, -170.4f, 23.68f, -850.0f, 324);
Actor_Change_Animation_Mode(kActorTaffyPatron, 48);
return true;
diff --git a/engines/bladerunner/script/ai/zuben.cpp b/engines/bladerunner/script/ai/zuben.cpp
index 9fe6aa2f10..58cea9d39d 100644
--- a/engines/bladerunner/script/ai/zuben.cpp
+++ b/engines/bladerunner/script/ai/zuben.cpp
@@ -152,7 +152,7 @@ void AIScriptZuben::CompletedMovementTrack() {
Set_Enter(kSetCT06, kSceneCT06);
}
if (Actor_Query_Goal_Number(kActorZuben) == 21) {
- Non_Player_Actor_Combat_Mode_On(kActorZuben, 0, 0, kActorMcCoy, 6, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 15, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorZuben, kActorCombatStateIdle, false, kActorMcCoy, 6, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 15, 300, false);
}
int goal = Actor_Query_Goal_Number(kActorZuben);
if (goal == 200) {
@@ -977,7 +977,7 @@ bool AIScriptZuben::ChangeAnimationMode(int mode) {
break;
}
break;
- case kAnimationModeCombatShoot:
+ case kAnimationModeCombatAttack:
_animationState = 8;
_animationFrame = 0;
break;
diff --git a/engines/bladerunner/script/ai_script.cpp b/engines/bladerunner/script/ai_script.cpp
index 98ad4c152f..aa8c14c6fc 100644
--- a/engines/bladerunner/script/ai_script.cpp
+++ b/engines/bladerunner/script/ai_script.cpp
@@ -329,4 +329,16 @@ void AIScripts::changeAnimationMode(int actor, int mode) {
_inScriptCounter--;
}
+void AIScripts::fledCombat(int actor) {
+ if (actor >= _actorCount) {
+ return;
+ }
+
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->FledCombat();
+ }
+ _inScriptCounter--;
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/ai_script.h b/engines/bladerunner/script/ai_script.h
index edbb198040..d746dce631 100644
--- a/engines/bladerunner/script/ai_script.h
+++ b/engines/bladerunner/script/ai_script.h
@@ -535,6 +535,7 @@ public:
bool reachedMovementTrackWaypoint(int actor, int waypointId);
void updateAnimation(int actor, int *animation, int *frame);
void changeAnimationMode(int actor, int mode);
+ void fledCombat(int actor);
bool isInsideScript() const { return _inScriptCounter > 0; }
diff --git a/engines/bladerunner/script/scene/ct07.cpp b/engines/bladerunner/script/scene/ct07.cpp
index 2eb7805c44..ebbe604b65 100644
--- a/engines/bladerunner/script/scene/ct07.cpp
+++ b/engines/bladerunner/script/scene/ct07.cpp
@@ -89,7 +89,7 @@ void SceneScriptCT07::ActorChangedGoal(int actorId, int newGoal, int oldGoal, bo
void SceneScriptCT07::PlayerWalkedIn() {
Player_Gains_Control();
- Non_Player_Actor_Combat_Mode_On(kActorZuben, 0, 0, kActorMcCoy, 2, 4, 7, 8, 0, 0, 100, 15, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorZuben, kActorCombatStateIdle, false, kActorMcCoy, 2, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 15, 300, false);
Game_Flag_Set(516);
Actor_Face_Actor(kActorMcCoy, kActorZuben, true);
}
diff --git a/engines/bladerunner/script/scene/hf01.cpp b/engines/bladerunner/script/scene/hf01.cpp
index ce36b91e31..d75c381f35 100644
--- a/engines/bladerunner/script/scene/hf01.cpp
+++ b/engines/bladerunner/script/scene/hf01.cpp
@@ -90,9 +90,9 @@ bool SceneScriptHF01::ClickedOn3DObject(const char *objectName, bool a2) {
bool SceneScriptHF01::ClickedOnActor(int actorId) {
int v1;
- if (Global_Variable_Query(45) == 2) {
+ if (Global_Variable_Query(kVariableAffectionTowards) == 2) {
v1 = kActorDektora;
- } else if (Global_Variable_Query(45) == 3) {
+ } else if (Global_Variable_Query(kVariableAffectionTowards) == 3) {
v1 = kActorLucy;
} else {
v1 = -1;
@@ -295,15 +295,15 @@ void SceneScriptHF01::PlayerWalkedIn() {
Actor_Set_At_XYZ(kActorOfficerLeary, 8.2f, 8.0f, -346.67f, 1021);
Actor_Put_In_Set(kActorOfficerGrayford, 37);
Actor_Set_At_XYZ(kActorOfficerGrayford, 51.21f, 8.0f, -540.78f, 796);
- Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, 3, 1, kActorMcCoy, 4, 4, 7, 8, 0, 0, 0, 100, 300, 0);
- Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, 3, 1, kActorMcCoy, 4, 4, 7, 8, 0, 0, 0, 100, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, kActorCombatStateUncover, true, kActorMcCoy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 0, 100, 300, false);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, kActorCombatStateUncover, true, kActorMcCoy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 0, 100, 300, false);
}
if (!Game_Flag_Query(165) && Actor_Query_Goal_Number(kActorCrazylegs) != 2) {
- if (Actor_Clue_Query(kActorMcCoy, kCluePhoneCallLucy1) && Global_Variable_Query(45) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
+ if (Actor_Clue_Query(kActorMcCoy, kCluePhoneCallLucy1) && Global_Variable_Query(kVariableAffectionTowards) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
Actor_Put_In_Set(kActorLucy, 37);
Actor_Set_At_XYZ(kActorLucy, -5.0f, 8.0f, -622.0f, 419);
Actor_Set_Targetable(kActorLucy, true);
- } else if (Actor_Clue_Query(kActorMcCoy, kCluePhoneCallDektora1) && Global_Variable_Query(45) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
+ } else if (Actor_Clue_Query(kActorMcCoy, kCluePhoneCallDektora1) && Global_Variable_Query(kVariableAffectionTowards) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
Actor_Put_In_Set(kActorDektora, 37);
Actor_Set_At_XYZ(kActorDektora, -5.0f, 8.0f, -622.0f, 419);
Actor_Set_Targetable(kActorDektora, true);
diff --git a/engines/bladerunner/script/scene/hf03.cpp b/engines/bladerunner/script/scene/hf03.cpp
index 09bf589bb7..e3b01df4f8 100644
--- a/engines/bladerunner/script/scene/hf03.cpp
+++ b/engines/bladerunner/script/scene/hf03.cpp
@@ -96,8 +96,8 @@ void SceneScriptHF03::sub_401C80() {
Actor_Says(kActorLucy, 210, 13);
Actor_Says(kActorMcCoy, 1655, 15);
Actor_Modify_Friendliness_To_Other(kActorLucy, kActorMcCoy, Random_Query(9, 10));
- if (Actor_Query_Friendliness_To_Other(kActorLucy, kActorMcCoy) > 59 && !Global_Variable_Query(45)) {
- Global_Variable_Set(45, 3);
+ if (Actor_Query_Friendliness_To_Other(kActorLucy, kActorMcCoy) > 59 && Global_Variable_Query(kVariableAffectionTowards) == 0) {
+ Global_Variable_Set(kVariableAffectionTowards, 3);
Actor_Says(kActorLucy, 940, 14);
Actor_Says(kActorMcCoy, 6780, 11);
Actor_Says(kActorLucy, 950, 12);
diff --git a/engines/bladerunner/script/scene/hf05.cpp b/engines/bladerunner/script/scene/hf05.cpp
index ff497ebbe8..a620d3aa15 100644
--- a/engines/bladerunner/script/scene/hf05.cpp
+++ b/engines/bladerunner/script/scene/hf05.cpp
@@ -483,10 +483,10 @@ void SceneScriptHF05::sub_403738() {
}
int SceneScriptHF05::sub_404858() {
- if (Global_Variable_Query(45) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
+ if (Global_Variable_Query(kVariableAffectionTowards) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
return kActorDektora;
}
- if (Global_Variable_Query(45) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
+ if (Global_Variable_Query(kVariableAffectionTowards) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
return kActorLucy;
}
return -1;
@@ -494,15 +494,15 @@ int SceneScriptHF05::sub_404858() {
void SceneScriptHF05::sub_4042E4() {
Actor_Force_Stop_Walking(kActorMcCoy);
- Actor_Put_In_Set(kActorOfficerLeary, 41);
- Actor_Set_At_XYZ(kActorOfficerLeary, 430.39999f, 40.630001f, -258.17999f, 300);
- Actor_Put_In_Set(kActorOfficerGrayford, 41);
- Actor_Set_At_XYZ(kActorOfficerGrayford, 526.40002f, 37.18f, -138.17999f, 300);
+ Actor_Put_In_Set(kActorOfficerLeary, kSetHF05);
+ Actor_Set_At_XYZ(kActorOfficerLeary, 430.4f, 40.63f, -258.18f, 300);
+ Actor_Put_In_Set(kActorOfficerGrayford, kSetHF05);
+ Actor_Set_At_XYZ(kActorOfficerGrayford, 526.4f, 37.18f, -138.18f, 300);
ADQ_Flush();
ADQ_Add(kActorOfficerGrayford, 260, -1);
Player_Loses_Control();
- Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, 3, 1, kActorMcCoy, 4, 4, 7, 8, 0, 0, 100, 100, 1200, 1);
- return Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, 3, 1, kActorMcCoy, 4, 4, 7, 8, 0, 0, 100, 100, 300, 1);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerLeary, kActorCombatStateUncover, true, kActorMcCoy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 100, 1200, true);
+ Non_Player_Actor_Combat_Mode_On(kActorOfficerGrayford, kActorCombatStateUncover, true, kActorMcCoy, 4, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 100, 300, true);
}
void SceneScriptHF05::sub_403F0C() {
diff --git a/engines/bladerunner/script/scene/hf06.cpp b/engines/bladerunner/script/scene/hf06.cpp
index 7a41c9eda2..49ea1d81d2 100644
--- a/engines/bladerunner/script/scene/hf06.cpp
+++ b/engines/bladerunner/script/scene/hf06.cpp
@@ -180,12 +180,13 @@ void SceneScriptHF06::ActorChangedGoal(int actorId, int newGoal, int oldGoal, bo
void SceneScriptHF06::PlayerWalkedIn() {
if (Game_Flag_Query(662)) {
- int actorId;
- if (Global_Variable_Query(45) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
+ int actorId = -1;
+ if (Global_Variable_Query(kVariableAffectionTowards) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
actorId = kActorLucy;
- } else {
- actorId = Global_Variable_Query(45) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599 ? kActorDektora : -1;
- }
+ } else if (Global_Variable_Query(kVariableAffectionTowards) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
+ actorId = kActorDektora;
+ }
+
if (actorId != -1) {
Actor_Put_In_Set(actorId, 42);
if (Game_Flag_Query(559)) {
@@ -267,7 +268,7 @@ void SceneScriptHF06::sub_401EF4() {
Sound_Play(562, 50, 0, 0, 50);
Game_Flag_Set(559);
Scene_Exits_Disable();
- Non_Player_Actor_Combat_Mode_On(kActorSteele, 3, 1, actorId, 15, 4, 7, 8, 0, 0, 100, 10, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, actorId, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 10, 300, false);
}
void SceneScriptHF06::sub_4023E0() {
diff --git a/engines/bladerunner/script/scene/hf07.cpp b/engines/bladerunner/script/scene/hf07.cpp
index e9fe2f05fd..b653cfd08a 100644
--- a/engines/bladerunner/script/scene/hf07.cpp
+++ b/engines/bladerunner/script/scene/hf07.cpp
@@ -142,11 +142,11 @@ void SceneScriptHF07::DialogueQueueFlushed(int a1) {
}
int SceneScriptHF07::sub_401864() {
- if (Global_Variable_Query(45) == 2 && Actor_Query_Goal_Number(3) != 599) {
- return 3;
+ if (Global_Variable_Query(kVariableAffectionTowards) == 2 && Actor_Query_Goal_Number(3) != 599) {
+ return kActorDektora;
}
- if (Global_Variable_Query(45) == 3 && Actor_Query_Goal_Number(6) != 599) {
- return 6;
+ if (Global_Variable_Query(kVariableAffectionTowards) == 3 && Actor_Query_Goal_Number(6) != 599) {
+ return kActorLucy;
}
return -1;
}
diff --git a/engines/bladerunner/script/scene/kp05.cpp b/engines/bladerunner/script/scene/kp05.cpp
index 9b080aceb0..99fa6c33fa 100644
--- a/engines/bladerunner/script/scene/kp05.cpp
+++ b/engines/bladerunner/script/scene/kp05.cpp
@@ -158,7 +158,7 @@ void SceneScriptKP05::PlayerWalkedIn() {
Actor_Says(kActorMcCoy, 2220, 3);
Actor_Says(kActorSteele, 620, 15);
Actor_Says(kActorSteele, 630, 17);
- Non_Player_Actor_Combat_Mode_On(kActorSteele, 0, 1, kActorMcCoy, 9, 4, 7, 8, 0, -1, -1, 20, 240, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateIdle, true, kActorMcCoy, 9, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, -1, -1, 20, 240, false);
}
}
diff --git a/engines/bladerunner/script/scene/ma04.cpp b/engines/bladerunner/script/scene/ma04.cpp
index 5f1b41e998..ead9f1946d 100644
--- a/engines/bladerunner/script/scene/ma04.cpp
+++ b/engines/bladerunner/script/scene/ma04.cpp
@@ -176,9 +176,9 @@ bool SceneScriptMA04::ClickedOn2DRegion(int region) {
Overlay_Remove("MA04OVER");
Delay(500);
if (Game_Flag_Query(653)) {
- if (Global_Variable_Query(45) == 2) {
+ if (Global_Variable_Query(kVariableAffectionTowards) == 2) {
phoneCallWithDektora();
- } else if (Global_Variable_Query(45) == 3) {
+ } else if (Global_Variable_Query(kVariableAffectionTowards) == 3) {
phoneCallWithLucy();
} else {
phoneCallWithClovis();
diff --git a/engines/bladerunner/script/scene/nr01.cpp b/engines/bladerunner/script/scene/nr01.cpp
index 171cea52d8..fd7c9911d0 100644
--- a/engines/bladerunner/script/scene/nr01.cpp
+++ b/engines/bladerunner/script/scene/nr01.cpp
@@ -384,7 +384,7 @@ void SceneScriptNR01::PlayerWalkedIn() {
if (Actor_Query_Goal_Number(kActorGordo) == 230) {
Scene_Exits_Disable();
Actor_Set_Goal_Number(kActorGordo, 231);
- Non_Player_Actor_Combat_Mode_On(kActorGordo, 0, 1, kActorMcCoy, 3, 4, 7, 8, -1, -1, -1, 20, 300, 0);
+ Non_Player_Actor_Combat_Mode_On(kActorGordo, kActorCombatStateIdle, true, kActorMcCoy, 3, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 20, 300, false);
}
} else if (Game_Flag_Query(545)) {
Game_Flag_Reset(545);
diff --git a/engines/bladerunner/script/scene/nr11.cpp b/engines/bladerunner/script/scene/nr11.cpp
index 95ef4b7d84..5c4f4c141c 100644
--- a/engines/bladerunner/script/scene/nr11.cpp
+++ b/engines/bladerunner/script/scene/nr11.cpp
@@ -140,7 +140,7 @@ bool SceneScriptNR11::ClickedOn3DObject(const char *objectName, bool a2) {
} else {
Actor_Says(kActorMcCoy, 3840, 18);
Delay(1000);
- if (Actor_Query_Friendliness_To_Other(kActorDektora, kActorMcCoy) > 59 && !Global_Variable_Query(45)) {
+ if (Actor_Query_Friendliness_To_Other(kActorDektora, kActorMcCoy) > 59 && Global_Variable_Query(kVariableAffectionTowards) == 0) {
Music_Play(21, 35, 0, 3, -1, 0, 0);
}
Loop_Actor_Walk_To_XYZ(kActorDektora, -135.0f, 0.33f, -267.0f, 0, 0, false, 0);
@@ -164,8 +164,8 @@ bool SceneScriptNR11::ClickedOn3DObject(const char *objectName, bool a2) {
Actor_Says(kActorMcCoy, 3870, 3);
Actor_Says(kActorDektora, 1070, 14);
Actor_Modify_Friendliness_To_Other(kActorDektora, kActorMcCoy, 5);
- if (Actor_Query_Friendliness_To_Other(kActorDektora, kActorMcCoy) > 55 && !Global_Variable_Query(45)) {
- Global_Variable_Set(45, 2);
+ if (Actor_Query_Friendliness_To_Other(kActorDektora, kActorMcCoy) > 55 && Global_Variable_Query(kVariableAffectionTowards) == 0) {
+ Global_Variable_Set(kVariableAffectionTowards, 2);
Actor_Says(kActorDektora, 1130, 17);
Actor_Says(kActorMcCoy, 6365, 12);
Actor_Says(kActorDektora, 1140, 14);
diff --git a/engines/bladerunner/script/scene/ug05.cpp b/engines/bladerunner/script/scene/ug05.cpp
index c3996dca37..3348ebbfb6 100644
--- a/engines/bladerunner/script/scene/ug05.cpp
+++ b/engines/bladerunner/script/scene/ug05.cpp
@@ -222,10 +222,10 @@ void SceneScriptUG05::DialogueQueueFlushed(int a1) {
}
int SceneScriptUG05::sub_4021B0() {
- if (Global_Variable_Query(45) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
+ if (Global_Variable_Query(kVariableAffectionTowards) == 2 && Actor_Query_Goal_Number(kActorDektora) != 599) {
return kActorDektora;
}
- if (Global_Variable_Query(45) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
+ if (Global_Variable_Query(kVariableAffectionTowards) == 3 && Actor_Query_Goal_Number(kActorLucy) != 599) {
return kActorLucy;
}
return -1;
diff --git a/engines/bladerunner/script/scene/ug18.cpp b/engines/bladerunner/script/scene/ug18.cpp
index cafe42654a..c20c58cc72 100644
--- a/engines/bladerunner/script/scene/ug18.cpp
+++ b/engines/bladerunner/script/scene/ug18.cpp
@@ -323,9 +323,8 @@ void SceneScriptUG18::sub_402734() {
}
void SceneScriptUG18::sub_402DE8() {
-
if (Player_Query_Agenda()) {
- if (Global_Variable_Query(45) > 1 || Player_Query_Agenda() == 2) {
+ if (Global_Variable_Query(kVariableAffectionTowards) > 1 || Player_Query_Agenda() == 2) {
sub_403114();
} else {
sub_402F8C();
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index 2aca6db9d3..ff2a840a28 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -130,7 +130,7 @@ void ScriptBase::Actor_Face_Heading(int actorId, int heading, bool animate) {
}
int ScriptBase::Actor_Query_Friendliness_To_Other(int actorId, int otherActorId) {
- return _vm->_actors[actorId]->_friendlinessToOther[otherActorId];
+ return _vm->_actors[actorId]->getFriendlinessToOther(otherActorId);
}
void ScriptBase::Actor_Modify_Friendliness_To_Other(int actorId, int otherActorId, signed int change) {
@@ -158,27 +158,27 @@ void ScriptBase::Actor_Set_Combat_Aggressiveness(int actorId, int combatAggressi
}
int ScriptBase::Actor_Query_Current_HP(int actorId) {
- return _vm->_actors[actorId]->_currentHP;
+ return _vm->_actors[actorId]->getCurrentHP();
}
int ScriptBase::Actor_Query_Max_HP(int actorId) {
- return _vm->_actors[actorId]->_maxHP;
+ return _vm->_actors[actorId]->getMaxHP();
}
int ScriptBase::Actor_Query_Combat_Aggressiveness(int actorId) {
- return _vm->_actors[actorId]->_combatAggressiveness;
+ return _vm->_actors[actorId]->getCombatAggressiveness();
}
int ScriptBase::Actor_Query_Honesty(int actorId) {
- return _vm->_actors[actorId]->_honesty;
+ return _vm->_actors[actorId]->getHonesty();
}
int ScriptBase::Actor_Query_Intelligence(int actorId) {
- return _vm->_actors[actorId]->_intelligence;
+ return _vm->_actors[actorId]->getIntelligence();
}
int ScriptBase::Actor_Query_Stability(int actorId) {
- return _vm->_actors[actorId]->_stability;
+ return _vm->_actors[actorId]->getStability();
}
void ScriptBase::Actor_Modify_Current_HP(int actorId, signed int change) {
@@ -218,8 +218,8 @@ void ScriptBase::Actor_Combat_AI_Hit_Attempt(int actorId) {
_vm->_actors[actorId]->_combatInfo->hitAttempt();
}
-void ScriptBase::Non_Player_Actor_Combat_Mode_On(int actorId, int a2, int a3, int otherActorId, int a5, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int a9, int a10, int a11, int a12, int a13, int a14) {
- _vm->_actors[actorId]->combatModeOn(a2, a3, otherActorId, a5, animationModeCombatIdle, animationModeCombatWalk, animationModeCombatRun, a9, a10, a11, a12, a13, a14);
+void ScriptBase::Non_Player_Actor_Combat_Mode_On(int actorId, int initialState, bool rangedAttack, int enemyId, int waypointType, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool a14) {
+ _vm->_actors[actorId]->combatModeOn(initialState, rangedAttack, enemyId, waypointType, animationModeCombatIdle, animationModeCombatWalk, animationModeCombatRun, fleeRatio, coverRatio, actionRatio, damage, range, a14);
}
void ScriptBase::Non_Player_Actor_Combat_Mode_Off(int actorId) {
@@ -723,8 +723,9 @@ int ScriptBase::Animation_Skip_To_Frame() {
void ScriptBase::Delay(int miliseconds) {
Player_Loses_Control();
int endTime = _vm->getTotalPlayTime() + miliseconds;
- while ((int)_vm->getTotalPlayTime() < endTime)
+ while ((int)_vm->getTotalPlayTime() < endTime) {
_vm->gameTick();
+ }
Player_Gains_Control();
}
@@ -1075,14 +1076,27 @@ float ScriptBase::World_Waypoint_Query_Z(int waypointId) {
return _vm->_waypoints->getZ(waypointId);
}
-void ScriptBase::Combat_Cover_Waypoint_Set_Data(int combatCoverId, int type, int setId, int sceneId, float x, float y, float z) {
- //TODO
- warning("Combat_Cover_Waypoint_Set_Data(%d, %d, %d, %d, %f, %f, %f)", combatCoverId, type, setId, sceneId, x, y, z);
+void ScriptBase::Combat_Cover_Waypoint_Set_Data(int coverWaypointId, int type, int setId, int sceneId, float x, float y, float z) {
+ assert(coverWaypointId < (int)_vm->_combat->_coverWaypoints.size());
+
+ _vm->_combat->_coverWaypoints[coverWaypointId].type = type;
+ _vm->_combat->_coverWaypoints[coverWaypointId].setId = setId;
+ _vm->_combat->_coverWaypoints[coverWaypointId].sceneId = sceneId;
+ _vm->_combat->_coverWaypoints[coverWaypointId].position.x = x;
+ _vm->_combat->_coverWaypoints[coverWaypointId].position.y = y;
+ _vm->_combat->_coverWaypoints[coverWaypointId].position.z = z;
}
-void ScriptBase::Combat_Flee_Waypoint_Set_Data(int combatFleeWaypointId, int type, int setId, int sceneId, float x, float y, float z, int a8) {
- //TODO
- warning("Combat_Cover_Waypoint_Set_Data(%d, %d, %d, %d, %f, %f, %f, %d)", combatFleeWaypointId, type, setId, sceneId, x, y, z, a8);
+void ScriptBase::Combat_Flee_Waypoint_Set_Data(int fleeWaypointId, int type, int setId, int sceneId, float x, float y, float z, int a8) {
+ assert(fleeWaypointId < (int)_vm->_combat->_fleeWaypoints.size());
+
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].type = type;
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].setId = setId;
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].sceneId = sceneId;
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].position.x = x;
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].position.y = y;
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].position.z = z;
+ _vm->_combat->_fleeWaypoints[fleeWaypointId].field7 = a8;
}
void ScriptBase::Police_Maze_Target_Track_Add(int itemId, float startX, float startY, float startZ, float endX, float endY, float endZ, int steps, signed int data[], bool a10) {
@@ -1221,10 +1235,8 @@ bool ScriptBase::Query_System_Currently_Loading_Game() {
void ScriptBase::Actor_Retired_Here(int actorId, int width, int height, int retired, int retiredByActorId) {
Actor *actor = _vm->_actors[actorId];
- Vector3 actorPosition;
- actor->getXYZ(&actorPosition.x, &actorPosition.y, &actorPosition.z);
actor->retire(retired, width, height, retiredByActorId);
- actor->setAtXYZ(actorPosition, actor->getFacing(), true, false, true);
+ actor->setAtXYZ(actor->getXYZ(), actor->getFacing(), true, false, true);
_vm->_sceneObjects->setRetired(actorId + kSceneObjectOffsetActors, true);
}
diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h
index 7faf3886b2..9df231a1c3 100644
--- a/engines/bladerunner/script/script.h
+++ b/engines/bladerunner/script/script.h
@@ -78,7 +78,7 @@ protected:
void Actor_Set_Flag_Damage_Anim_If_Moving(int actorId, bool value);
bool Actor_Query_Flag_Damage_Anim_If_Moving(int actorId);
void Actor_Combat_AI_Hit_Attempt(int actorId);
- void Non_Player_Actor_Combat_Mode_On(int actorId, int a2, int a3, int otherActorId, int a5, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int a9, int a10, int a11, int a12, int a13, int a14);
+ void Non_Player_Actor_Combat_Mode_On(int actorId, int initialState, bool rangedAttack, int enemyId, int waypointType, int animationModeCombatIdle, int animationModeCombatWalk, int animationModeCombatRun, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool a14);
void Non_Player_Actor_Combat_Mode_Off(int actorId);
void Actor_Set_Health(int actorId, int hp, int maxHp);
void Actor_Set_Targetable(int actorId, bool targetable);
@@ -205,8 +205,8 @@ protected:
float World_Waypoint_Query_X(int waypointId);
float World_Waypoint_Query_Y(int waypointId);
float World_Waypoint_Query_Z(int waypointId);
- void Combat_Cover_Waypoint_Set_Data(int combatCoverId, int a2, int setId, int a4, float x, float y, float z);
- void Combat_Flee_Waypoint_Set_Data(int combatFleeWaypointId, int a2, int setId, int a4, float x, float y, float z, int a8);
+ void Combat_Cover_Waypoint_Set_Data(int coverWaypointId, int a2, int setId, int a4, float x, float y, float z);
+ void Combat_Flee_Waypoint_Set_Data(int fleeWaypointId, int a2, int setId, int a4, float x, float y, float z, int a8);
void Police_Maze_Target_Track_Add(int itemId, float startX, float startY, float startZ, float endX, float endY, float endZ, int steps, signed int data[], bool a10);
// Police_Maze_Query_Score
// Police_Maze_Zero_Score
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
index 15633f6581..31da697c20 100644
--- a/engines/bladerunner/slice_renderer.cpp
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -122,7 +122,7 @@ Matrix3x2 SliceRenderer::calculateFacingRotationMatrix() {
float s = sinf(dir);
float c = cosf(dir);
- Matrix3x2 mRotation( c, -s, 0.0f,
+ Matrix3x2 mRotation(c, -s, 0.0f,
s, c, 0.0f);
Matrix3x2 mView(_view->_sliceViewMatrix(0,0), _view->_sliceViewMatrix(0,1), 0.0f,
@@ -164,29 +164,20 @@ void SliceRenderer::calculateBoundingRect() {
Matrix3x2 mScale(_frameScale.x, 0.0f, 0.0f,
0.0f, _frameScale.y, 0.0f);
- _modelMatrix = mProjection * (facingRotation * (mOffset * mScale));
+ _mvpMatrix = mProjection * (facingRotation * (mOffset * mScale));
Vector4 startScreenVector(
- _view->_viewportPosition.x + top.x / top.z * _view->_viewportPosition.z,
- _view->_viewportPosition.y + top.y / top.z * _view->_viewportPosition.z,
+ _view->_viewportPosition.x + (top.x / top.z) * _view->_viewportPosition.z,
+ _view->_viewportPosition.y + (top.y / top.z) * _view->_viewportPosition.z,
1.0f / top.z,
_frameSliceCount * (1.0f / top.z));
Vector4 endScreenVector(
- _view->_viewportPosition.x + bottom.x / bottom.z * _view->_viewportPosition.z,
- _view->_viewportPosition.y + bottom.y / bottom.z * _view->_viewportPosition.z,
+ _view->_viewportPosition.x + (bottom.x / bottom.z) * _view->_viewportPosition.z,
+ _view->_viewportPosition.y + (bottom.y / bottom.z) * _view->_viewportPosition.z,
1.0f / bottom.z,
0.0f);
- _startScreenVector.x = startScreenVector.x;
- _startScreenVector.y = startScreenVector.y;
- _startScreenVector.z = startScreenVector.z;
- _endScreenVector.x = endScreenVector.x;
- _endScreenVector.y = endScreenVector.y;
- _endScreenVector.z = endScreenVector.z;
- _startSlice = startScreenVector.w;
- _endSlice = endScreenVector.w;
-
Vector4 delta = endScreenVector - startScreenVector;
if (delta.y == 0.0f) {
@@ -197,60 +188,68 @@ void SliceRenderer::calculateBoundingRect() {
* Calculate min and max Y
*/
- float screenMinY = 0.0f;
- float screenMaxY = 479.0f;
+ float screenTop = 0.0f;
+ float screenBottom = 479.0f;
- if (startScreenVector.y < screenMinY) {
- if (endScreenVector.y < screenMinY)
+ if (startScreenVector.y < screenTop) {
+ if (endScreenVector.y < screenTop) {
return;
-
- float f = (screenMinY - startScreenVector.y) / delta.y;
+ }
+ float f = (screenTop - startScreenVector.y) / delta.y;
startScreenVector = startScreenVector + f * delta;
- } else if (startScreenVector.y > screenMaxY) {
- if (endScreenVector.y >= screenMaxY)
+ } else if (startScreenVector.y > screenBottom) {
+ if (endScreenVector.y >= screenBottom) {
return;
-
- float f = (screenMaxY - startScreenVector.y) / delta.y;
+ }
+ float f = (screenBottom - startScreenVector.y) / delta.y;
startScreenVector = startScreenVector + f * delta;
}
- if (endScreenVector.y < screenMinY) {
- float f = (screenMinY - endScreenVector.y) / delta.y;
+ if (endScreenVector.y < screenTop) {
+ float f = (screenTop - endScreenVector.y) / delta.y;
endScreenVector = endScreenVector + f * delta;
- } else if (endScreenVector.y > screenMaxY) {
- float f = (screenMaxY - endScreenVector.y) / delta.y;
+ } else if (endScreenVector.y > screenBottom) {
+ float f = (screenBottom - endScreenVector.y) / delta.y;
endScreenVector = endScreenVector + f * delta;
}
- int bbox_min_y = (int)MIN(startScreenVector.y, endScreenVector.y);
- int bbox_max_y = (int)MAX(startScreenVector.y, endScreenVector.y) + 1;
+ _screenRectangle.top = (int)MIN(startScreenVector.y, endScreenVector.y);
+ _screenRectangle.bottom = (int)MAX(startScreenVector.y, endScreenVector.y) + 1;
/*
* Calculate min and max X
*/
- Matrix3x2 mB6 = _modelMatrix + Vector2(startScreenVector.x, 25.5f / startScreenVector.z);
- Matrix3x2 mC2 = _modelMatrix + Vector2(endScreenVector.x, 25.5f / endScreenVector.z);
+ Matrix3x2 mStart(
+ 1.0f, 0.0f, startScreenVector.x,
+ 0.0f, 1.0f, 25.5f / startScreenVector.z
+ );
- float min_x = 640.0f;
- float max_x = 0.0f;
+ Matrix3x2 mEnd(
+ 1.0f, 0.0f, endScreenVector.x,
+ 0.0f, 1.0f, 25.5f / endScreenVector.z
+ );
- for (float i = 0.0f; i <= 256.0f; i += 255.0f) {
- for (float j = 0.0f; j <= 256.0f; j += 255.0f) {
- Vector2 v1 = mB6 * Vector2(i, j);
+ Matrix3x2 mStartMVP = mStart * _mvpMatrix;
+ Matrix3x2 mEndMVP = mEnd * _mvpMatrix;
- min_x = MIN(min_x, v1.x);
- max_x = MAX(max_x, v1.x);
+ float minX = 640.0f;
+ float maxX = 0.0f;
- Vector2 v2 = mC2 * Vector2(i, j);
+ for (float i = 0.0f; i <= 256.0f; i += 255.0f) {
+ for (float j = 0.0f; j <= 256.0f; j += 255.0f) {
+ Vector2 v1 = mStartMVP * Vector2(i, j);
+ minX = MIN(minX, v1.x);
+ maxX = MAX(maxX, v1.x);
- min_x = MIN(min_x, v2.x);
- max_x = MAX(max_x, v2.x);
+ Vector2 v2 = mEndMVP * Vector2(i, j);
+ minX = MIN(minX, v2.x);
+ maxX = MAX(maxX, v2.x);
}
}
- int bbox_min_x = CLIP((int)min_x, 0, 640);
- int bbox_max_x = CLIP((int)max_x + 1, 0, 640);
+ _screenRectangle.left = CLIP((int)minX, 0, 640);
+ _screenRectangle.right = CLIP((int)maxX + 1, 0, 640);
_startScreenVector.x = startScreenVector.x;
_startScreenVector.y = startScreenVector.y;
@@ -260,11 +259,6 @@ void SliceRenderer::calculateBoundingRect() {
_endScreenVector.z = endScreenVector.z;
_startSlice = startScreenVector.w;
_endSlice = endScreenVector.w;
-
- _screenRectangle.left = bbox_min_x;
- _screenRectangle.right = bbox_max_x;
- _screenRectangle.top = bbox_min_y;
- _screenRectangle.bottom = bbox_max_y;
}
void SliceRenderer::loadFrame(int animation, int frame) {
@@ -285,7 +279,8 @@ void SliceRenderer::loadFrame(int animation, int frame) {
}
struct SliceLineIterator {
- int _sliceMatrix[2][3];
+ // int _sliceMatrix[2][3];
+ Matrix3x2 _sliceMatrix;
int _startY;
int _endY;
@@ -316,8 +311,9 @@ void SliceLineIterator::setup(
float size = endScreenY - startScreenY;
- if (size <= 0.0f || startScreenZ <= 0.0f)
+ if (size <= 0.0f || startScreenZ <= 0.0f) {
_currentY = _endY + 1;
+ }
_currentZ = startScreenZ;
_stepZ = (endScreenZ - startScreenZ) / size;
@@ -328,7 +324,7 @@ void SliceLineIterator::setup(
_currentX = startScreenX;
_stepX = (endScreenX - startScreenX) / size;
- _field_38 = (int)((25.5f / size) * (1.0f / endScreenZ - 1.0f / startScreenZ) * 64.0);
+ _field_38 = (int)((25.5f / size) * (1.0f / endScreenZ - 1.0f / startScreenZ) * 64.0f);
_currentY = _startY;
float offsetX = _currentX;
@@ -342,9 +338,7 @@ void SliceLineIterator::setup(
m = scale_matrix * (translate_matrix * m);
- for (int r = 0; r != 2; ++r)
- for (int c = 0; c != 3; ++c)
- _sliceMatrix[r][c] = m(r, c);
+ _sliceMatrix = m;
}
float SliceLineIterator::line() {
@@ -364,8 +358,8 @@ void SliceLineIterator::advance() {
_currentSlice += _stepSlice;
_currentX += _stepX;
_currentY += 1;
- _sliceMatrix[0][2] += (int)(65536.0f * _stepX);
- _sliceMatrix[1][2] += _field_38;
+ _sliceMatrix._m[0][2] += (int)(65536.0f * _stepX);
+ _sliceMatrix._m[1][2] += _field_38;
}
static void setupLookupTable(int t[256], int inc) {
@@ -393,7 +387,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
_endScreenVector.x, _endScreenVector.y, _endScreenVector.z,
_startScreenVector.x, _startScreenVector.y, _startScreenVector.z,
_endSlice, _startSlice,
- _modelMatrix
+ _mvpMatrix
);
SliceRendererLights sliceRendererLights = SliceRendererLights(_lights);
@@ -424,12 +418,12 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos
_setEffectColor.g = setEffectColor.g * 31.0f * 65536.0f;
_setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f;
- setupLookupTable(_m11lookup, sliceLineIterator._sliceMatrix[0][0]);
- setupLookupTable(_m12lookup, sliceLineIterator._sliceMatrix[0][1]);
- _m13 = sliceLineIterator._sliceMatrix[0][2];
- setupLookupTable(_m21lookup, sliceLineIterator._sliceMatrix[1][0]);
- setupLookupTable(_m22lookup, sliceLineIterator._sliceMatrix[1][1]);
- _m23 = sliceLineIterator._sliceMatrix[1][2];
+ setupLookupTable(_m12lookup, sliceLineIterator._sliceMatrix(0, 1));
+ setupLookupTable(_m11lookup, sliceLineIterator._sliceMatrix(0, 0));
+ _m13 = sliceLineIterator._sliceMatrix(0, 2);
+ setupLookupTable(_m21lookup, sliceLineIterator._sliceMatrix(1, 0));
+ setupLookupTable(_m22lookup, sliceLineIterator._sliceMatrix(1, 1));
+ _m23 = sliceLineIterator._sliceMatrix(1, 2);
if (_animationsShadowEnabled[_animation]) {
float coeficientShadow;
@@ -545,8 +539,9 @@ void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screen
}
void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr, int y) {
- if (slice < 0 || (uint32)slice >= _frameSliceCount)
+ if (slice < 0 || (uint32)slice >= _frameSliceCount) {
return;
+ }
SliceAnimations::Palette &palette = _vm->_sliceAnimations->getPalette(_framePaletteIndex);
@@ -714,7 +709,12 @@ void SliceRenderer::drawShadowPolygon(int transparency, Graphics::Surface &surfa
yMax = CLIP(yMax, 0, 480);
yMin = CLIP(yMin, 0, 480);
- int ditheringFactor[] = { 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5 };
+ int ditheringFactor[] = {
+ 0, 8, 2, 10,
+ 12, 4, 14, 6,
+ 3, 11, 1, 9,
+ 15, 7, 13, 5
+ };
for (int y = yMin; y < yMax; ++y) {
int xMin = CLIP(polygonLeft[y], 0, 640);
diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h
index d2de61e279..2e3617162c 100644
--- a/engines/bladerunner/slice_renderer.h
+++ b/engines/bladerunner/slice_renderer.h
@@ -67,7 +67,7 @@ class SliceRenderer {
uint32 _framePaletteIndex;
uint32 _frameSliceCount;
- Matrix3x2 _modelMatrix;
+ Matrix3x2 _mvpMatrix;
Vector3 _startScreenVector;
Vector3 _endScreenVector;
float _startSlice;
diff --git a/engines/bladerunner/view.cpp b/engines/bladerunner/view.cpp
index d304b92bb1..72c070ecc0 100644
--- a/engines/bladerunner/view.cpp
+++ b/engines/bladerunner/view.cpp
@@ -31,8 +31,9 @@ bool View::readVqa(Common::ReadStream *stream) {
_frame = stream->readUint32LE();
float d[12];
- for (int i = 0; i != 12; ++i)
+ for (int i = 0; i != 12; ++i) {
d[i] = stream->readFloatLE();
+ }
_frameViewMatrix = Matrix4x3(d);
@@ -54,17 +55,11 @@ void View::setFovX(float fovX) {
}
void View::calculateSliceViewMatrix() {
- Matrix4x3 m = _frameViewMatrix;
-
- m = m * rotationMatrixX(float(M_PI) / 2.0f);
-
- Matrix4x3 a(-1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f);
-
- m = a * m;
-
- _sliceViewMatrix = m;
+ Matrix4x3 mRotation = rotationMatrixX(float(M_PI) / 2.0f);
+ Matrix4x3 mInvert(-1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f);
+ _sliceViewMatrix = mInvert * (_frameViewMatrix * mRotation);
}
void View::calculateCameraPosition() {