From 19d9e4cec818980a75772a204c96774afbd2b17e Mon Sep 17 00:00:00 2001 From: Peter Kohaut Date: Sat, 17 Mar 2018 16:40:33 +0100 Subject: [PATCH] BLADERUNNER: Added combat Math cleanup Fixed obstacle detection --- engines/bladerunner/actor.cpp | 61 +- engines/bladerunner/actor.h | 59 +- engines/bladerunner/actor_combat.cpp | 605 +++++++++++++++++- engines/bladerunner/actor_combat.h | 74 ++- engines/bladerunner/bladerunner.cpp | 32 +- engines/bladerunner/combat.cpp | 103 ++- engines/bladerunner/combat.h | 31 +- engines/bladerunner/debugger.cpp | 43 +- engines/bladerunner/game_constants.h | 19 +- engines/bladerunner/matrix.h | 4 +- engines/bladerunner/scene_objects.cpp | 14 +- engines/bladerunner/scene_objects.h | 2 +- engines/bladerunner/script/ai/clovis.cpp | 12 +- engines/bladerunner/script/ai/dektora.cpp | 10 +- engines/bladerunner/script/ai/gaff.cpp | 2 +- engines/bladerunner/script/ai/gordo.cpp | 2 +- engines/bladerunner/script/ai/guzza.cpp | 2 +- engines/bladerunner/script/ai/leon.cpp | 2 +- engines/bladerunner/script/ai/lucy.cpp | 6 +- engines/bladerunner/script/ai/mccoy.cpp | 24 +- engines/bladerunner/script/ai/mutant1.cpp | 15 +- engines/bladerunner/script/ai/mutant2.cpp | 12 +- engines/bladerunner/script/ai/mutant3.cpp | 12 +- .../bladerunner/script/ai/officer_leary.cpp | 2 +- engines/bladerunner/script/ai/sadik.cpp | 5 +- engines/bladerunner/script/ai/steele.cpp | 2 +- .../bladerunner/script/ai/taffy_patron.cpp | 6 +- engines/bladerunner/script/ai/zuben.cpp | 4 +- engines/bladerunner/script/ai_script.cpp | 12 + engines/bladerunner/script/ai_script.h | 1 + engines/bladerunner/script/scene/ct07.cpp | 2 +- engines/bladerunner/script/scene/hf01.cpp | 12 +- engines/bladerunner/script/scene/hf03.cpp | 4 +- engines/bladerunner/script/scene/hf05.cpp | 16 +- engines/bladerunner/script/scene/hf06.cpp | 13 +- engines/bladerunner/script/scene/hf07.cpp | 8 +- engines/bladerunner/script/scene/kp05.cpp | 2 +- engines/bladerunner/script/scene/ma04.cpp | 4 +- engines/bladerunner/script/scene/nr01.cpp | 2 +- engines/bladerunner/script/scene/nr11.cpp | 6 +- engines/bladerunner/script/scene/ug05.cpp | 4 +- engines/bladerunner/script/scene/ug18.cpp | 3 +- engines/bladerunner/script/script.cpp | 50 +- engines/bladerunner/script/script.h | 6 +- engines/bladerunner/slice_renderer.cpp | 134 ++-- engines/bladerunner/slice_renderer.h | 2 +- engines/bladerunner/view.cpp | 19 +- 47 files changed, 1153 insertions(+), 312 deletions(-) diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index d4c4eeaee342..177734fe37f1 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 af0c14e36705..ace90554b743 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 @@ class Actor { int _currentHP; int _maxHP; - ActorClues *_clues; - int _id; int _setId; Vector3 _position; @@ -124,7 +121,7 @@ class Actor { 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 @@ class Actor { void run(); bool tick(bool forceUpdate, Common::Rect *screenRect); + void tickCombat(); bool draw(Common::Rect *screenRect); int getSetId() const; @@ -164,13 +162,16 @@ class Actor { 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 @@ class Actor { 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 @@ class Actor { 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 4bd8d17c672b..47d1c2d3a0f4 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 b7ec93533dfa..2c6ea8ac8eb3 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 @@ class ActorCombat { 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 ea663b53bcd1..43f67ea92dde 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 c371f7beddd4..ef7a58945603 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 21989dac52a3..ab289cca5cad 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 _coverWaypoints; + Common::Array _fleeWaypoints; + public: Combat(BladeRunnerEngine *vm); ~Combat(); @@ -60,10 +80,13 @@ class Combat { 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 5539082187e2..2c9b7e6f747b 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 af4728aaadef..4aa72c1bc6ba 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 5343eb6b8e02..d5922b403f61 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 87320a3fa431..148cde827c76 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 dbd61b6dc504..de31eae88d05 100644 --- a/engines/bladerunner/scene_objects.h +++ b/engines/bladerunner/scene_objects.h @@ -80,7 +80,7 @@ class SceneObjects { 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 9c8976e02dea..e55fdb946880 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 905c3d16dab8..28bdf3c83d09 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 c26f0d907f6c..c5e629cab08e 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 fd64112897a0..c44497176a88 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 0f99fa8a46a8..5a4459535eb6 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 fad9da3cfb4d..fdcb538f0a92 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 aebeac7322aa..464f22817967 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 554de0cd80db..56b54ac0eb87 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 9ecaf9d80e68..eb1c0562afbc 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 6a51c710dd99..6317311088d3 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 76a9a0edff12..db161d8d5a13 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 b18ba0869fb6..0adbe7c1c067 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 b6abc8dab864..9fdb889b6c4b 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 e51a14a8caa0..ff2afa1ec346 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 c7fa3a71653a..0bf6861d121c 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 9fe6aa2f10db..58cea9d39d1a 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 98ad4c152f86..aa8c14c6fcce 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 edbb19804004..d746dce63134 100644 --- a/engines/bladerunner/script/ai_script.h +++ b/engines/bladerunner/script/ai_script.h @@ -535,6 +535,7 @@ class AIScripts { 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 2eb7805c447c..ebbe604b65ad 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 ce36b91e3101..d75c381f3522 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 09bf589bb7d2..e3b01df4f890 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 ff497ebbe82d..a620d3aa153d 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 7a41c9eda281..49ea1d81d2f0 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 e9fe2f05fdd0..b653cfd08a47 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 9b080aceb093..99fa6c33fa22 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 5f1b41e998e9..ead9f1946dd2 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 171cea52d894..fd7c9911d05f 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 95ef4b7d8474..5c4f4c141cb7 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 c3996dca37a7..3348ebbfb607 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 cafe42654ae0..c20c58cc725a 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 2aca6db9d35a..ff2a840a28bb 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 7faf3886b275..9df231a1c365 100644 --- a/engines/bladerunner/script/script.h +++ b/engines/bladerunner/script/script.h @@ -78,7 +78,7 @@ class ScriptBase { 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 @@ class ScriptBase { 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 15633f65818a..31da697c206a 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 d2de61e279e7..2e3617162c35 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 d304b92bb169..72c070ecc0ec 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() {