BLADERUNNER: Added Generic Walker actors

Fixed isseue of duplicating items in world
Fixed fog issue with incorrect rendering in special occasions
Added basic debugger console
Refactored looping code for better readability
This commit is contained in:
Peter Kohaut 2018-02-25 19:31:52 +01:00
parent 842c67fc34
commit 62b75b9990
49 changed files with 2256 additions and 412 deletions

View File

@ -31,6 +31,7 @@
#include "bladerunner/chapters.h"
#include "bladerunner/combat.h"
#include "bladerunner/crimes_database.h"
#include "bladerunner/debugger.h"
#include "bladerunner/dialogue_menu.h"
#include "bladerunner/font.h"
#include "bladerunner/game_flags.h"
@ -176,9 +177,12 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
_scene = nullptr;
_aiScripts = nullptr;
for (int i = 0; i != kActorCount; ++i) {
_actors[i] = nullptr;
_actors[i] = nullptr;
}
_debugger = nullptr;
walkingReset();
_actorUpdateCounter = 0;
}
BladeRunnerEngine::~BladeRunnerEngine() {
@ -244,6 +248,8 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_sceneScript = new SceneScript(this);
_debugger = new Debugger(this);
// This is the original startup in the game
bool r;
@ -637,6 +643,9 @@ void BladeRunnerEngine::shutdown() {
// These are static objects in original game
delete _debugger;
_debugger = nullptr;
delete _zbuffer;
_zbuffer = nullptr;
@ -701,36 +710,6 @@ void BladeRunnerEngine::gameLoop() {
} while (_gameIsRunning);
}
#if BLADERUNNER_DEBUG_RENDERING
void drawBBox(Vector3 start, Vector3 end, View *view, Graphics::Surface *surface, int color) {
Vector3 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z));
Vector3 bfr = view->calculateScreenPosition(Vector3(start.x, end.y, start.z));
Vector3 bbr = view->calculateScreenPosition(Vector3(end.x, end.y, start.z));
Vector3 bbl = view->calculateScreenPosition(Vector3(end.x, start.y, start.z));
Vector3 tfl = view->calculateScreenPosition(Vector3(start.x, start.y, end.z));
Vector3 tfr = view->calculateScreenPosition(Vector3(start.x, end.y, end.z));
Vector3 tbr = view->calculateScreenPosition(Vector3(end.x, end.y, end.z));
Vector3 tbl = view->calculateScreenPosition(Vector3(end.x, start.y, end.z));
surface->drawLine(bfl.x, bfl.y, bfr.x, bfr.y, color);
surface->drawLine(bfr.x, bfr.y, bbr.x, bbr.y, color);
surface->drawLine(bbr.x, bbr.y, bbl.x, bbl.y, color);
surface->drawLine(bbl.x, bbl.y, bfl.x, bfl.y, color);
surface->drawLine(tfl.x, tfl.y, tfr.x, tfr.y, color);
surface->drawLine(tfr.x, tfr.y, tbr.x, tbr.y, color);
surface->drawLine(tbr.x, tbr.y, tbl.x, tbl.y, color);
surface->drawLine(tbl.x, tbl.y, tfl.x, tfl.y, color);
surface->drawLine(bfl.x, bfl.y, tfl.x, tfl.y, color);
surface->drawLine(bfr.x, bfr.y, tfr.x, tfr.y, color);
surface->drawLine(bbr.x, bbr.y, tbr.x, tbr.y, color);
surface->drawLine(bbl.x, bbl.y, tbl.x, tbl.y, color);
}
#endif
void BladeRunnerEngine::gameTick() {
handleEvents();
@ -814,15 +793,9 @@ void BladeRunnerEngine::gameTick() {
int setId = _scene->getSetId();
for (int i = 0, end = _gameInfo->getActorCount(); i != end; ++i) {
if (_actors[i]->getSetId() == setId) {
// TODO: remove this limitation
if (i == kActorMcCoy
|| i == kActorRunciter
|| i == kActorOfficerLeary
|| i == kActorMaggie) {
Common::Rect screenRect;
if (_actors[i]->tick(backgroundChanged, &screenRect)) {
_zbuffer->mark(screenRect);
}
Common::Rect screenRect;
if (_actors[i]->tick(backgroundChanged, &screenRect)) {
_zbuffer->mark(screenRect);
}
}
}
@ -839,8 +812,9 @@ void BladeRunnerEngine::gameTick() {
_dialogueMenu->draw(_surfaceFront);
}
// TODO: remove zbuffer draw
// _surfaceFront.copyRectToSurface(_zbuffer->getData(), 1280, 0, 0, 640, 480);
if (_debugger->_viewZBuffer) {
_surfaceFront.copyRectToSurface(_zbuffer->getData(), 1280, 0, 0, 640, 480);
}
_mouse->tick(p.x, p.y);
_mouse->draw(_surfaceFront, p.x, p.y);
@ -853,141 +827,10 @@ void BladeRunnerEngine::gameTick() {
_walkSoundId = -1;
}
#if BLADERUNNER_DEBUG_RENDERING
//draw scene objects
int count = _sceneObjects->_count;
if (count > 0) {
for (int i = 0; i < count; i++) {
SceneObjects::SceneObject *sceneObject = &_sceneObjects->_sceneObjects[_sceneObjects->_sceneObjectsSortedByDistance[i]];
const BoundingBox *bbox = sceneObject->boundingBox;
Vector3 a, b;
bbox->getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
Vector3 pos = _view->calculateScreenPosition(0.5 * (a + b));
int color;
switch (sceneObject->type) {
case kSceneObjectTypeActor:
color = 0b111110000000000;
drawBBox(a, b, _view, &_surfaceFront, color);
_mainFont->drawColor(_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors), _surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeItem:
char itemText[40];
drawBBox(a, b, _view, &_surfaceFront, color);
sprintf(itemText, "item %i", sceneObject->id - kSceneObjectOffsetItems);
_mainFont->drawColor(itemText, _surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeObject:
color = 0b011110111101111;
//if (sceneObject->_isObstacle)
// color += 0b100000000000000;
if (sceneObject->isClickable) {
color = 0b000001111100000;
}
drawBBox(a, b, _view, &_surfaceFront, color);
_mainFont->drawColor(_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects), _surfaceFront, pos.x, pos.y, color);
break;
}
_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
}
if (_debugger->_viewSceneObjects) {
_debugger->drawSceneObjects();
}
//draw regions
for (int i = 0; i < 10; i++) {
Regions::Region *region = &_scene->_regions->_regions[i];
if (!region->present) continue;
_surfaceFront.frameRect(region->rectangle, 0b000000000011111);
}
for (int i = 0; i < 10; i++) {
Regions::Region *region = &_scene->_exits->_regions[i];
if (!region->present) continue;
_surfaceFront.frameRect(region->rectangle, 0b111111111111111);
}
//draw walkboxes
for (int i = 0; i < _scene->_set->_walkboxCount; i++) {
Set::Walkbox *walkbox = &_scene->_set->_walkboxes[i];
for (int j = 0; j < walkbox->vertexCount; j++) {
Vector3 start = _view->calculateScreenPosition(walkbox->vertices[j]);
Vector3 end = _view->calculateScreenPosition(walkbox->vertices[(j + 1) % walkbox->vertexCount]);
_surfaceFront.drawLine(start.x, start.y, end.x, end.y, 0b111111111100000);
Vector3 pos = _view->calculateScreenPosition(0.5 * (start + end));
_mainFont->drawColor(walkbox->name, _surfaceFront, pos.x, pos.y, 0b111111111100000);
}
}
// draw lights
for (int i = 0; i < (int)_lights->_lights.size(); i++) {
Light *light = _lights->_lights[i];
Matrix4x3 m = light->_matrix;
m = invertMatrix(m);
//todo do this properly
Vector3 posOrigin = m * Vector3(0.0f, 0.0f, 0.0f);
float t = posOrigin.y;
posOrigin.y = posOrigin.z;
posOrigin.z = -t;
Vector3 posTarget = m * Vector3(0.0f, 0.0f, -100.0f);
t = posTarget.y;
posTarget.y = posTarget.z;
posTarget.z = -t;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
int colorR = (light->_color.r * 31.0f);
int colorG = (light->_color.g * 31.0f);
int colorB = (light->_color.b * 31.0f);
int color = (colorR << 10) + (colorG << 5) + colorB;
drawBBox(posOrigin - size, posOrigin + size, _view, &_surfaceFront, color);
Vector3 posOriginT = _view->calculateScreenPosition(posOrigin);
Vector3 posTargetT = _view->calculateScreenPosition(posTarget);
_surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color);
_mainFont->drawColor(light->_name, _surfaceFront, posOriginT.x, posOriginT.y, color);
}
//draw waypoints
for(int i = 0; i < _waypoints->_count; i++) {
Waypoints::Waypoint *waypoint = &_waypoints->_waypoints[i];
if(waypoint->setId != _scene->getSetId())
continue;
Vector3 pos = waypoint->position;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
int color = 0b111111111111111;
drawBBox(pos - size, pos + size, _view, &_surfaceFront, color);
Vector3 spos = _view->calculateScreenPosition(pos);
char waypointText[40];
sprintf(waypointText, "waypoint %i", i);
_mainFont->drawColor(waypointText, _surfaceFront, spos.x, spos.y, color);
}
#endif
#if BLADERUNNER_DEBUG_RENDERING
//draw aesc
for (uint i = 0; i < _screenEffects->_entries.size(); i++) {
ScreenEffects::Entry &entry = _screenEffects->_entries[i];
int j = 0;
for (int y = 0; y < entry.height; y++) {
for (int x = 0; x < entry.width; x++) {
Common::Rect r((entry.x + x) * 2, (entry.y + y) * 2, (entry.x + x) * 2 + 2, (entry.y + y) * 2 + 2);
int ec = entry.data[j++];
Color256 color = entry.palette[ec];
int bladeToScummVmConstant = 256 / 16;
Graphics::PixelFormat _pixelFormat = createRGB555();
int color555 = _pixelFormat.RGBToColor(
CLIP(color.r * bladeToScummVmConstant, 0, 255),
CLIP(color.g * bladeToScummVmConstant, 0, 255),
CLIP(color.b * bladeToScummVmConstant, 0, 255));
_surfaceFront.fillRect(r, color555);
}
}
}
#endif
blitToScreen(_surfaceFront);
_system->delayMillis(10);
}
@ -998,15 +841,18 @@ void BladeRunnerEngine::actorsUpdate() {
int actorCount = (int)_gameInfo->getActorCount();
int setId = _scene->getSetId();
//TODO: original game updates every non-visible characters by updating only one character in one frame
if (setId != kSetUG18 || _gameVars[kVariableChapter] != 4 || !_gameFlags->query(670) || !_aiScripts->isInsideScript()) {
for (int i = 0; i < actorCount; i++) {
Actor *actor = _actors[i];
if (actor->getSetId() == setId) {
if (actor->getSetId() == setId || i == _actorUpdateCounter) {
_aiScripts->update(i);
actor->timersUpdate();
}
}
++_actorUpdateCounter;
if (_actorUpdateCounter >= actorCount) {
_actorUpdateCounter = 0;
}
}
}
@ -1117,6 +963,12 @@ void BladeRunnerEngine::handleKeyUp(Common::Event &event) {
}
void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
if ((event.kbd.keycode == Common::KEYCODE_d) && (event.kbd.flags & Common::KBD_CTRL)) {
getDebugger()->attach();
getDebugger()->onFrame();
return;
}
//TODO:
if (!playerHasControl() /* || ActorWalkingLoop || ActorSpeaking || VqaIsPlaying */) {
return;
@ -1426,7 +1278,7 @@ void BladeRunnerEngine::handleMouseClickEmpty(int x, int y, Vector3 &scenePositi
//TODO mouse::randomize(Mouse);
if (actorId) {
if (actorId > 0) {
_aiScripts->shotAtAndMissed(actorId);
}
} else {
@ -1696,7 +1548,7 @@ Common::SeekableReadStream *BladeRunnerEngine::getResourceStream(const Common::S
}
}
debug("getResource: Resource %s not found.", name.c_str());
error("getResource: Resource %s not found", name.c_str());
return nullptr;
}
@ -1735,6 +1587,10 @@ void BladeRunnerEngine::blitToScreen(const Graphics::Surface &src) {
_system->updateScreen();
}
GUI::Debugger *BladeRunnerEngine::getDebugger() {
return _debugger;
}
void blit(const Graphics::Surface &src, Graphics::Surface &dst) {
dst.copyRectToSurface(src.getPixels(), src.pitch, 0, 0, src.w, src.h);
}

View File

@ -34,7 +34,6 @@
#include "graphics/surface.h"
//TODO: remove these when game is playable
#define BLADERUNNER_DEBUG_RENDERING 0
#define BLADERUNNER_DEBUG_CONSOLE 0
#define BLADERUNNER_DEBUG_GAME 0
@ -42,6 +41,10 @@ namespace Common {
struct Event;
}
namespace GUI {
class Debugger;
}
struct ADGameDescription;
namespace BladeRunner {
@ -57,6 +60,7 @@ class AudioSpeech;
class Chapters;
class CrimesDatabase;
class Combat;
class Debugger;
class DialogueMenu;
class Elevator;
class ESPER;
@ -161,6 +165,8 @@ public:
Common::RandomSource _rnd;
Debugger *_debugger;
bool _isWalkingInterruptible;
bool _interruptWalking;
bool _playerActorIdle;
@ -194,6 +200,8 @@ public:
int _walkingToActorId;
bool _isInsideScriptActor;
int _actorUpdateCounter;
private:
MIXArchive _archives[kArchiveCount];
@ -251,6 +259,8 @@ public:
void ISez(const char *str);
void blitToScreen(const Graphics::Surface &src);
GUI::Debugger *getDebugger();
};
static inline const Graphics::PixelFormat createRGB555() {

View File

@ -0,0 +1,344 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "bladerunner/debugger.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/boundingbox.h"
#include "bladerunner/font.h"
#include "bladerunner/game_constants.h"
#include "bladerunner/game_flags.h"
#include "bladerunner/game_info.h"
#include "bladerunner/light.h"
#include "bladerunner/lights.h"
#include "bladerunner/regions.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/settings.h"
#include "bladerunner/set.h"
#include "bladerunner/text_resource.h"
#include "bladerunner/vector.h"
#include "bladerunner/view.h"
#include "bladerunner/waypoints.h"
#include "bladerunner/zbuffer.h"
#include "common/debug.h"
#include "common/str.h"
#include "graphics/surface.h"
namespace BladeRunner {
Debugger::Debugger(BladeRunnerEngine *vm) : GUI::Debugger() {
_vm = vm;
_viewSceneObjects = false;
_viewUI = false;
_viewZBuffer = false;
registerCmd("draw", WRAP_METHOD(Debugger, cmdDraw));
registerCmd("scene", WRAP_METHOD(Debugger, cmdScene));
registerCmd("chapter", WRAP_METHOD(Debugger, cmdChapter));
registerCmd("flag", WRAP_METHOD(Debugger, cmdFlag));
registerCmd("var", WRAP_METHOD(Debugger, cmdVariable));
}
Debugger::~Debugger() {
}
bool Debugger::cmdDraw(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: %s (obj | ui | zbuf | reset)\n", argv[0]);
return true;
}
Common::String arg = argv[1];
if (arg == "obj") {
_viewSceneObjects = !_viewSceneObjects;
debugPrintf("Drawing scene objects = %i\n", _viewSceneObjects);
} else if (arg == "ui") {
_viewUI = !_viewUI;
debugPrintf("Drawing UI elements = %i\n", _viewUI);
} else if (arg == "zbuf") {
_viewZBuffer = !_viewZBuffer;
debugPrintf("Drawing Z buffer = %i\n", _viewZBuffer);
} else if (arg == "reset") {
_viewSceneObjects = false;
_viewUI = false;
_viewZBuffer = false;
debugPrintf("Drawing scene objects = %i\n", _viewSceneObjects);
debugPrintf("Drawing UI elements = %i\n", _viewUI);
debugPrintf("Drawing Z buffer = %i\n", _viewZBuffer);
}
return true;
}
bool Debugger::cmdScene(int argc, const char **argv) {
if (argc != 1 && argc != 3) {
debugPrintf("Usage: %s [<set_id> <scene_id>]\n", argv[0]);
return true;
}
if (argc == 1) {
debugPrintf("set = %i\nscene = %i\n", _vm->_scene->getSetId(), _vm->_scene->getSceneId());
return true;
}
if (argc == 3) {
int setId = atoi(argv[1]);
int sceneId = atoi(argv[2]);
_vm->_settings->setNewSetAndScene(setId, sceneId);
}
return true;
}
bool Debugger::cmdChapter(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: %s <chapter>\n", argv[0]);
return true;
}
int chapter = atoi(argv[1]);
if (chapter >= 1 && chapter <= 5) {
_vm->_settings->setChapter(chapter);
} else {
debugPrintf("Chapter must be between 1 and 5\n");
}
return true;
}
bool Debugger::cmdFlag(int argc, const char **argv) {
if (argc != 2 && argc != 3) {
debugPrintf("Usage: %s <id> [<new_value>]\n", argv[0]);
return true;
}
int flag = atoi(argv[1]);
int flagCount = _vm->_gameInfo->getFlagCount();
if (flag > 0 && flag < flagCount) {
if (argc == 3) {
int value = atoi(argv[2]);
if (value == 0) {
_vm->_gameFlags->reset(flag);
} else {
_vm->_gameFlags->set(flag);
}
}
debugPrintf("flag(%i) = %i\n", flag, _vm->_gameFlags->query(flag));
} else {
debugPrintf("Flag id must be between 0 and %i\n", flagCount - 1);
}
return true;
}
bool Debugger::cmdVariable(int argc, const char **argv) {
if (argc != 2 && argc != 3) {
debugPrintf("Usage: %s <id> [<new_value>]\n", argv[0]);
return true;
}
int variable = atoi(argv[1]);
int variableCount = _vm->_gameInfo->getGlobalVarCount();
if (variable >= 0 && variable < variableCount) {
if (argc == 3) {
_vm->_gameVars[variable] = atoi(argv[2]);
}
debugPrintf("variable(%i) = %i\n", variable, _vm->_gameVars[variable]);
} else {
debugPrintf("Variable id must be between 0 and %i\n", variableCount - 1);
}
return true;
}
void Debugger::drawBBox(Vector3 start, Vector3 end, View *view, Graphics::Surface *surface, int color) {
Vector3 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z));
Vector3 bfr = view->calculateScreenPosition(Vector3(start.x, end.y, start.z));
Vector3 bbr = view->calculateScreenPosition(Vector3(end.x, end.y, start.z));
Vector3 bbl = view->calculateScreenPosition(Vector3(end.x, start.y, start.z));
Vector3 tfl = view->calculateScreenPosition(Vector3(start.x, start.y, end.z));
Vector3 tfr = view->calculateScreenPosition(Vector3(start.x, end.y, end.z));
Vector3 tbr = view->calculateScreenPosition(Vector3(end.x, end.y, end.z));
Vector3 tbl = view->calculateScreenPosition(Vector3(end.x, start.y, end.z));
surface->drawLine(bfl.x, bfl.y, bfr.x, bfr.y, color);
surface->drawLine(bfr.x, bfr.y, bbr.x, bbr.y, color);
surface->drawLine(bbr.x, bbr.y, bbl.x, bbl.y, color);
surface->drawLine(bbl.x, bbl.y, bfl.x, bfl.y, color);
surface->drawLine(tfl.x, tfl.y, tfr.x, tfr.y, color);
surface->drawLine(tfr.x, tfr.y, tbr.x, tbr.y, color);
surface->drawLine(tbr.x, tbr.y, tbl.x, tbl.y, color);
surface->drawLine(tbl.x, tbl.y, tfl.x, tfl.y, color);
surface->drawLine(bfl.x, bfl.y, tfl.x, tfl.y, color);
surface->drawLine(bfr.x, bfr.y, tfr.x, tfr.y, color);
surface->drawLine(bbr.x, bbr.y, tbr.x, tbr.y, color);
surface->drawLine(bbl.x, bbl.y, tbl.x, tbl.y, color);
}
void Debugger::drawSceneObjects() {
//draw scene objects
int count = _vm->_sceneObjects->_count;
if (count > 0) {
for (int i = 0; i < count; i++) {
SceneObjects::SceneObject *sceneObject = &_vm->_sceneObjects->_sceneObjects[_vm->_sceneObjects->_sceneObjectsSortedByDistance[i]];
const BoundingBox *bbox = sceneObject->boundingBox;
Vector3 a, b;
bbox->getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b));
int color;
switch (sceneObject->type) {
case kSceneObjectTypeUnknown:
break;
case kSceneObjectTypeActor:
color = 0x7C00; // 11111 00000 00000;
drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color);
_vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
_vm->_mainFont->drawColor(_vm->_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors), _vm->_surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeItem:
color = 0x03E0; // 00000 11111 00000
char itemText[40];
drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color);
sprintf(itemText, "item %i", sceneObject->id - kSceneObjectOffsetItems);
_vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
_vm->_mainFont->drawColor(itemText, _vm->_surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeObject:
color = 0x3DEF; //01111 01111 01111;
//if (sceneObject->_isObstacle)
// color += 0b100000000000000;
if (sceneObject->isClickable) {
color = 0x03E0; // 00000 11111 00000;
}
drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color);
_vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
_vm->_mainFont->drawColor(_vm->_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects), _vm->_surfaceFront, pos.x, pos.y, color);
break;
}
}
}
//draw regions
for (int i = 0; i < 10; i++) {
Regions::Region *region = &_vm->_scene->_regions->_regions[i];
if (!region->present) continue;
_vm->_surfaceFront.frameRect(region->rectangle, 0x001F); // 00000 00000 11111
}
for (int i = 0; i < 10; i++) {
Regions::Region *region = &_vm->_scene->_exits->_regions[i];
if (!region->present) continue;
_vm->_surfaceFront.frameRect(region->rectangle, 0x7FFF); // 11111 11111 11111
}
//draw walkboxes
for (int i = 0; i < _vm->_scene->_set->_walkboxCount; i++) {
Set::Walkbox *walkbox = &_vm->_scene->_set->_walkboxes[i];
for (int j = 0; j < walkbox->vertexCount; j++) {
Vector3 start = _vm->_view->calculateScreenPosition(walkbox->vertices[j]);
Vector3 end = _vm->_view->calculateScreenPosition(walkbox->vertices[(j + 1) % walkbox->vertexCount]);
_vm->_surfaceFront.drawLine(start.x, start.y, end.x, end.y, 0x7FE0); // 11111 11111 00000
Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (start + end));
_vm->_mainFont->drawColor(walkbox->name, _vm->_surfaceFront, pos.x, pos.y, 0x7FE0); // 11111 11111 00000
}
}
// draw lights
for (int i = 0; i < (int)_vm->_lights->_lights.size(); i++) {
Light *light = _vm->_lights->_lights[i];
Matrix4x3 m = light->_matrix;
m = invertMatrix(m);
//todo do this properly
Vector3 posOrigin = m * Vector3(0.0f, 0.0f, 0.0f);
float t = posOrigin.y;
posOrigin.y = posOrigin.z;
posOrigin.z = -t;
Vector3 posTarget = m * Vector3(0.0f, 0.0f, -100.0f);
t = posTarget.y;
posTarget.y = posTarget.z;
posTarget.z = -t;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
int colorR = (light->_color.r * 31.0f);
int colorG = (light->_color.g * 31.0f);
int colorB = (light->_color.b * 31.0f);
int color = (colorR << 10) + (colorG << 5) + colorB;
drawBBox(posOrigin - size, posOrigin + size, _vm->_view, &_vm->_surfaceFront, color);
Vector3 posOriginT = _vm->_view->calculateScreenPosition(posOrigin);
Vector3 posTargetT = _vm->_view->calculateScreenPosition(posTarget);
_vm->_surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color);
_vm->_mainFont->drawColor(light->_name, _vm->_surfaceFront, posOriginT.x, posOriginT.y, color);
}
//draw waypoints
for(int i = 0; i < _vm->_waypoints->_count; i++) {
Waypoints::Waypoint *waypoint = &_vm->_waypoints->_waypoints[i];
if(waypoint->setId != _vm->_scene->getSetId())
continue;
Vector3 pos = waypoint->position;
Vector3 size = Vector3(5.0f, 5.0f, 5.0f);
int color = 0x7FFF; // 11111 11111 11111
drawBBox(pos - size, pos + size, _vm->_view, &_vm->_surfaceFront, color);
Vector3 spos = _vm->_view->calculateScreenPosition(pos);
char waypointText[40];
sprintf(waypointText, "waypoint %i", i);
_vm->_mainFont->drawColor(waypointText, _vm->_surfaceFront, spos.x, spos.y, color);
}
#if 0
//draw aesc
for (uint i = 0; i < _screenEffects->_entries.size(); i++) {
ScreenEffects::Entry &entry = _screenEffects->_entries[i];
int j = 0;
for (int y = 0; y < entry.height; y++) {
for (int x = 0; x < entry.width; x++) {
Common::Rect r((entry.x + x) * 2, (entry.y + y) * 2, (entry.x + x) * 2 + 2, (entry.y + y) * 2 + 2);
int ec = entry.data[j++];
Color256 color = entry.palette[ec];
int bladeToScummVmConstant = 256 / 16;
Graphics::PixelFormat _pixelFormat = createRGB555();
int color555 = _pixelFormat.RGBToColor(
CLIP(color.r * bladeToScummVmConstant, 0, 255),
CLIP(color.g * bladeToScummVmConstant, 0, 255),
CLIP(color.b * bladeToScummVmConstant, 0, 255));
_surfaceFront.fillRect(r, color555);
}
}
}
#endif
}
} // End of namespace BladeRunner

View File

@ -0,0 +1,63 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef BLADERUNNER_DEBUGGER_H
#define BLADERUNNER_DEBUGGER_H
#include "bladerunner/vector.h"
#include "gui/debugger.h"
namespace Graphics {
struct Surface;
}
namespace BladeRunner {
class BladeRunnerEngine;
class View;
class Debugger : public GUI::Debugger{
BladeRunnerEngine *_vm;
public:
bool _viewSceneObjects;
bool _viewUI;
bool _viewZBuffer;
Debugger(BladeRunnerEngine *vm);
~Debugger();
bool cmdDraw(int argc, const char **argv);
bool cmdScene(int argc, const char **argv);
bool cmdChapter(int argc, const char **argv);
bool cmdFlag(int argc, const char **argv);
bool cmdVariable(int argc, const char **argv);
void drawBBox(Vector3 start, Vector3 end, View *view, Graphics::Surface *surface, int color);
void drawSceneObjects();
void drawZBuffer();
};
} // End of namespace BladeRunner
#endif

View File

@ -118,13 +118,13 @@ void FogCone::read(Common::ReadStream *stream, int frameCount) {
void FogCone::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) {
*coeficient = 0.0f;
Vector3 positionT = this->_matrix * position;
Vector3 viewPositionT = this->_matrix * viewPosition;
Vector3 positionT = _matrix * position;
Vector3 viewPositionT = _matrix * viewPosition;
Vector3 vectorT = (viewPositionT - positionT).normalize();
float v67 = - positionT.x * vectorT.x - positionT.y * vectorT.y - positionT.z * vectorT.z;
float v66 = - (positionT.z * positionT.z) - (positionT.y * positionT.y) - (positionT.x * positionT.x) + (v67 * v67) + (this->_parameter1 * this->_parameter1);
float v66 = - (positionT.z * positionT.z) - (positionT.y * positionT.y) - (positionT.x * positionT.x) + (v67 * v67) + (_parameter1 * _parameter1);
if (v66 >= 0.0f) {
float v24 = sqrt(v66);
@ -132,8 +132,8 @@ void FogCone::calculateCoeficient(Vector3 position, Vector3 viewPosition, float
Vector3 v29 = positionT + (v67 - v24) * vectorT;
Vector3 v36 = positionT + (v67 + v24) * vectorT;
Vector3 v39 = this->_inverted * v29;
Vector3 v42 = this->_inverted * v36;
Vector3 v39 = _inverted * v29;
Vector3 v42 = _inverted * v36;
float v74 = (v39 - position).length();
float v76 = (v42 - position).length();
@ -164,8 +164,8 @@ void FogSphere::read(Common::ReadStream *stream, int frameCount) {
void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) {
*coeficient = 0.0f;
Vector3 positionT = this->_matrix * position;
Vector3 viewPositionT = this->_matrix * viewPosition;
Vector3 positionT = _matrix * position;
Vector3 viewPositionT = _matrix * viewPosition;
Vector3 v158 = Vector3::cross(positionT, viewPositionT);
@ -176,12 +176,12 @@ void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, floa
}
float v173 = sqrt(1.0f - v167.z * v167.z);
if (v173 > cos(this->_parameter1)) {
if (v173 > cos(_parameter1)) {
Vector3 v37 = Vector3(v167.y, -v167.x, 0.0f).normalize();
float v41 = 1.0f / v173 / v173 - 1.0f;
float v42 = sqrt(v41);
float v43 = tan(this->_parameter1);
float v43 = tan(_parameter1);
float v44 = sqrt(v43 * v43 - v41);
Vector3 v45 = v44 * v37;
@ -271,10 +271,10 @@ void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, floa
}
Vector3 v139 = positionT + (v88 * vector);
Vector3 v142 = this->_inverted * v139;
Vector3 v142 = _inverted * v139;
Vector3 v148 = positionT + (v114 * vector);
Vector3 v151 = this->_inverted * v148;
Vector3 v151 = _inverted * v148;
*coeficient = (v151 - v142).length();
}
@ -292,102 +292,102 @@ void FogBox::read(Common::ReadStream *stream, int frameCount) {
}
void FogBox::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) {
Vector3 v159 = this->_matrix * position;
Vector3 v146 = v159;
Vector3 v156 = this->_matrix * viewPosition;
Vector3 v153 = v156;
Vector3 v150 = v156 - v159;
Vector3 positionT = _matrix * position;
Vector3 viewPositionT = _matrix * viewPosition;
float v149 = this->_parameter1 * 0.5f;
if (v159.x < -v149) {
if (v156.x < -v149) {
Vector3 positionTadj = positionT;
Vector3 viewPositionTadj = viewPositionT;
Vector3 direction = viewPositionT - positionT;
float parameter1half = _parameter1 * 0.5f;
if (positionT.x < -parameter1half) {
if (viewPositionT.x < -parameter1half) {
*coeficient = 0.0f;
return;
}
float v28 = (-v159.x - v149) / v150.x;
Vector3 v29 = v28 * v150;
v146 = v159 + v29;
} else {
if (v156.x < -v149) {
float v19 = (-v156.x - v149) / v150.x;
Vector3 v20 = v19 * v150;
v153 = v156 + v20;
}
}
if (v149 < v146.x) {
if (v149 < v153.x) {
return;
}
float v48 = (v149 - v146.x) / v150.x;
Vector3 v49 = v48 * v150;
v146 = v146 + v49;
} else {
if (v149 < v153.x) {
float v40 = (v149 - v153.x) / v150.x;
Vector3 v41 = v40 * v150;
v153 = v153 + v41;
}
}
float v162 = this->_parameter2 * 0.5f;
if (v146.y < -v162) {
if (v153.y < -v162) {
return;
}
float v71 = (-v146.y - v162) / v150.y;
Vector3 v72 = v71 * v150;
v146 = v146 + v72;
} else {
if (v153.y < -v162) {
float v62 = (-v153.y - v162) / v150.y;
Vector3 v63 = v62 * v150;
v153 = v153 + v63;
}
}
if (v162 < v146.y) {
if (v162 < v153.y) {
return;
}
float v91 = (v162 - v146.y) / v150.y;
Vector3 v92 = v91 * v150;
v146 = v146 + v92;
} else {
if (v162 < v153.y) {
float v83 = (v162 - v153.y) / v150.y;
Vector3 v84 = v83 * v150;
v153 = v153 + v84;
}
float v28 = (-positionT.x - parameter1half) / direction.x;
Vector3 v29 = v28 * direction;
positionTadj = positionT + v29;
} else if (viewPositionT.x < -parameter1half) {
float v19 = (-viewPositionT.x - parameter1half) / direction.x;
Vector3 v20 = v19 * direction;
viewPositionTadj = viewPositionT + v20;
}
if (0.0f <= v146.z) {
if (0.0f > v153.z) {
float v103 = -v153.z / v150.z;
Vector3 v104 = v103 * v150;
v153 = v153 + v104;
}
} else {
if (0.0f > v153.z) {
if (parameter1half < positionTadj.x) {
if (parameter1half < viewPositionTadj.x) {
*coeficient = 0.0f;
return;
}
float v111 = -v146.z / v150.z;
Vector3 v112 = v111 * v150;
v146 = v146 + v112;
float v48 = (parameter1half - positionTadj.x) / direction.x;
Vector3 v49 = v48 * direction;
positionTadj = positionTadj + v49;
} else if (parameter1half < viewPositionTadj.x) {
float v40 = (parameter1half - viewPositionTadj.x) / direction.x;
Vector3 v41 = v40 * direction;
viewPositionTadj = viewPositionTadj + v41;
}
if (v146.z <= this->_parameter3) {
if (v153.z > this->_parameter3) {
float v124 = (this->_parameter3 - v153.z) / v150.z;
Vector3 v125 = v124 * v150;
v153 = v153 + v125;
}
} else {
if (v153.z <= this->_parameter3) {
float v132 = (this->_parameter3 - v146.z) / v150.z;
Vector3 v133 = v132 * v150;
v146 = v146 + v133;
float parameter2half = _parameter2 * 0.5f;
if (positionTadj.y < -parameter2half) {
if (viewPositionTadj.y < -parameter2half) {
*coeficient = 0.0f;
return;
}
float v71 = (-positionTadj.y - parameter2half) / direction.y;
Vector3 v72 = v71 * direction;
positionTadj = positionTadj + v72;
} else if (viewPositionTadj.y < -parameter2half) {
float v62 = (-viewPositionTadj.y - parameter2half) / direction.y;
Vector3 v63 = v62 * direction;
viewPositionTadj = viewPositionTadj + v63;
}
Vector3 v137 = this->_inverted * v146;
Vector3 v140 = this->_inverted * v153;
if (parameter2half < positionTadj.y) {
if (parameter2half < viewPositionTadj.y) {
*coeficient = 0.0f;
return;
}
float v91 = (parameter2half - positionTadj.y) / direction.y;
Vector3 v92 = v91 * direction;
positionTadj = positionTadj + v92;
} else if (parameter2half < viewPositionTadj.y) {
float v83 = (parameter2half - viewPositionTadj.y) / direction.y;
Vector3 v84 = v83 * direction;
viewPositionTadj = viewPositionTadj + v84;
}
if (0.0f > positionTadj.z) {
if (0.0f > viewPositionTadj.z) {
*coeficient = 0.0f;
return;
}
float v111 = -positionTadj.z / direction.z;
Vector3 v112 = v111 * direction;
positionTadj = positionTadj + v112;
} else if (0.0f > viewPositionTadj.z) {
float v103 = -viewPositionTadj.z / direction.z;
Vector3 v104 = v103 * direction;
viewPositionTadj = viewPositionTadj + v104;
}
if (positionTadj.z > _parameter3) {
if (viewPositionTadj.z > _parameter3) {
*coeficient = 0.0f;
return;
}
float v132 = (_parameter3 - positionTadj.z) / direction.z;
Vector3 v133 = v132 * direction;
positionTadj = positionTadj + v133;
} else if (viewPositionTadj.z > _parameter3) {
float v124 = (_parameter3 - viewPositionTadj.z) / direction.z;
Vector3 v125 = v124 * direction;
viewPositionTadj = viewPositionTadj + v125;
}
Vector3 v137 = _inverted * positionTadj;
Vector3 v140 = _inverted * viewPositionTadj;
Vector3 v143 = v140 - v137;
*coeficient = v143.length();

View File

@ -488,6 +488,7 @@ enum Flags {
kFlagDirectorsCut = 378,
KFlagMcCoyAndOfficerLearyTalking = 392,
KFlagMcCoyAndOfficerLearyArtMetaphor = 397,
kFlagGenericWalkerWaiting = 443,
kFlagMaggieIsHurt = 461,
kFlagKIAPrivacyAddon = 487,
kFlagKIAPrivacyAddonIntro = 599,
@ -503,6 +504,9 @@ enum Flags {
enum Variables {
kVariableChapter = 1,
kVariableChinyen = 2,
kVariableGenericWalkerAModel = 32,
kVariableGenericWalkerBModel = 33,
kVariableGenericWalkerCModel = 34,
kVariableWalkLoopActor = 37,
kVariableWalkLoopRun = 38,
kVariableAffectionTowards = 45, // 0 none, 1 steele, 2 dektora, 3 lucy
@ -568,9 +572,10 @@ enum AnimationModes {
};
enum SceneLoopMode {
kSceneLoopModeNone = -1,
kSceneLoopModeLoseControl = 0,
kSceneLoopModeChangeSet = 1,
kSceneLoopMode2 = 2,
kSceneLoopModeOnce = 2,
kSceneLoopModeSpinner = 3
};

View File

@ -74,11 +74,11 @@ bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position,
int itemIndex = findItem(itemId);
if (itemIndex == -1) {
itemIndex = _items.size();
_items.push_back(new Item(_vm));
}
Item *item = new Item(_vm);
Item *item = _items[itemIndex];
item->setup(itemId, setId, animationId, position, facing, height, width, isTargetFlag, isVisible, isPoliceMazeEnemy);
_items.push_back(item);
if (addToSetFlag && setId == _vm->_scene->getSetId()) {
return _vm->_sceneObjects->addItem(itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, isTargetFlag, isVisible);
@ -87,12 +87,12 @@ bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position,
}
bool Items::addToSet(int setId) {
int itemCount = _vm->_items->_items.size();
int itemCount = _items.size();
if (itemCount == 0) {
return true;
}
for (int i = 0; i < itemCount; i++) {
Item *item = _vm->_items->_items[i];
Item *item = _items[i];
if (item->_setId == setId) {
_vm->_sceneObjects->addItem(item->_itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, item->isTarget(), item->_isVisible);
}
@ -112,7 +112,9 @@ bool Items::remove(int itemId) {
if (_items[itemIndex]->_setId == _vm->_scene->getSetId()) {
_vm->_sceneObjects->remove(itemId + kSceneObjectOffsetItems);
}
_items.remove_at(itemIndex);
delete _items.remove_at(itemIndex);
return true;
}

View File

@ -29,7 +29,7 @@
#include "common/stream.h"
namespace Common{
class ReadStream;
class ReadStream;
}
namespace BladeRunner {
@ -37,9 +37,7 @@ namespace BladeRunner {
class Lights;
class Light {
#if BLADERUNNER_DEBUG_RENDERING
friend class BladeRunnerEngine;
#endif
friend class Debugger;
friend class Lights;
friend class SliceRenderer;

View File

@ -32,7 +32,7 @@
namespace BladeRunner {
class Lights {
friend class BladeRunnerEngine;
friend class Debugger;
friend class SliceRendererLights;
BladeRunnerEngine *_vm;

View File

@ -18,6 +18,7 @@ MODULE_OBJS = \
chapters.o \
combat.o \
crimes_database.o \
debugger.o \
decompress_lcw.o \
decompress_lzo.o \
detection.o \
@ -49,6 +50,9 @@ MODULE_OBJS = \
script/vk_script.o \
script/esper_script.o \
script/ai_script.o \
script/ai/generic_walker_a.o \
script/ai/generic_walker_b.o \
script/ai/generic_walker_c.o \
script/ai/leon.o \
script/ai/maggie.o \
script/ai/mccoy.o \

View File

@ -108,8 +108,10 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int timeF
}
_current.name = trackName;
if (timePlay > 0) {
_vm->getTimerManager()->removeTimerProc(timerCallbackFadeOut);
_vm->getTimerManager()->installTimerProc(timerCallbackFadeOut, timePlay * 1000 * 1000, this, "BladeRunnerMusicFadeoutTimer");
} else if (timeFadeOut > 0) {
_vm->getTimerManager()->removeTimerProc(timerCallbackFadeOut);
_vm->getTimerManager()->installTimerProc(timerCallbackFadeOut, (_stream->getLength() - timeFadeOut * 1000) * 1000, this, "BladeRunnerMusicFadeoutTimer");
}
_isPlaying = true;

View File

@ -31,9 +31,7 @@
namespace BladeRunner {
class Regions {
#if BLADERUNNER_DEBUG_RENDERING
friend class BladeRunnerEngine;
#endif
friend class Debugger;
struct Region {
Common::Rect rectangle;

View File

@ -52,7 +52,7 @@ Scene::Scene(BladeRunnerEngine *vm)
_defaultLoopSet(false),
_specialLoopMode(kSceneLoopModeLoseControl),
_specialLoop(0),
_specialLoopAtEnd(false),
_defaultLoopPreloadedSet(false),
// _introFinished(false),
_nextSetId(-1),
_nextSceneId(-1),
@ -92,8 +92,8 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
_vm->_overlays->removeAll();
_defaultLoop = 0;
_defaultLoopSet = false;
_specialLoopAtEnd = false;
_specialLoopMode = -1;
_defaultLoopPreloadedSet = false;
_specialLoopMode = kSceneLoopModeNone;
_specialLoop = -1;
_frame = -1;
}
@ -139,10 +139,10 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
return false;
}
if (_specialLoop == -1) {
if (_specialLoopMode == kSceneLoopModeNone) {
_vqaPlayer->setLoop(_defaultLoop, -1, kLoopSetModeImmediate, nullptr, nullptr);
_defaultLoopSet = true;
_specialLoopAtEnd = false;
_defaultLoopPreloadedSet = false;
}
_vm->_scene->advanceFrame();
@ -162,8 +162,8 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) {
i + kSceneObjectOffsetActors,
actor->getBoundingBox(),
actor->getScreenRectangle(),
1,
0,
true,
false,
actor->isTarget(),
actor->isRetired());
}
@ -216,21 +216,24 @@ int Scene::advanceFrame() {
_vqaPlayer->updateScreenEffects(_vm->_screenEffects);
_vqaPlayer->updateLights(_vm->_lights);
}
if (_specialLoopMode && _specialLoopMode != kSceneLoopMode2 && _specialLoopMode != kSceneLoopModeSpinner) {
if (_specialLoopMode == kSceneLoopModeChangeSet) {
if (frame == -3) { // TODO: when will this happen? bad data in/eof of vqa
_vm->_settings->setNewSetAndScene(_nextSetId, _nextSceneId);
_vm->playerGainsControl();
if (_specialLoopMode == kSceneLoopModeLoseControl || _specialLoopMode == kSceneLoopModeOnce || _specialLoopMode == kSceneLoopModeSpinner) {
if (!_defaultLoopSet) {
_vqaPlayer->setLoop(_defaultLoop, -1, kLoopSetModeEnqueue, &Scene::loopEndedStatic, this);
_defaultLoopSet = true;
if (_specialLoopMode == kSceneLoopModeLoseControl) {
_vm->playerLosesControl();
}
} else if (!_specialLoopAtEnd) {
_vqaPlayer->setLoop(_defaultLoop + 1, -1, kLoopSetModeJustStart, &Scene::loopEndedStatic, this);
_specialLoopAtEnd = true;
}
} else if (!_defaultLoopSet) {
_vqaPlayer->setLoop(_defaultLoop, -1, kLoopSetModeEnqueue, &Scene::loopEndedStatic, this);
_defaultLoopSet = true;
if (_specialLoopMode == kSceneLoopModeLoseControl) {
_vm->playerLosesControl();
} else if (_specialLoopMode == kSceneLoopModeChangeSet) {
if (frame == -3) { // EOF
_vm->_settings->setNewSetAndScene(_nextSetId, _nextSceneId);
_vm->playerGainsControl();
}
} else if (_specialLoopMode == kSceneLoopModeNone) {
if (!_defaultLoopPreloadedSet) {
_vqaPlayer->setLoop(_defaultLoop + 1, -1, kLoopSetModeJustStart, &Scene::loopEndedStatic, this);
_defaultLoopPreloadedSet = true;
}
}
@ -270,7 +273,7 @@ void Scene::loopStartSpecial(int specialLoopMode, int loopId, bool immediately)
_nextSceneId = _vm->_settings->getNewScene();
}
if (immediately) {
_specialLoopAtEnd = true;
_defaultLoopPreloadedSet = true;
loopEnded(0, _specialLoop);
}
}
@ -326,31 +329,31 @@ const char *Scene::objectGetName(int objectId) {
}
void Scene::loopEnded(int frame, int loopId) {
if (_specialLoopMode && _specialLoopMode != kSceneLoopMode2 && _specialLoopMode != kSceneLoopModeSpinner) {
if (_specialLoopMode == kSceneLoopModeChangeSet) {
if (_specialLoopMode == kSceneLoopModeLoseControl || _specialLoopMode == kSceneLoopModeOnce || _specialLoopMode == kSceneLoopModeSpinner) {
if (_defaultLoopPreloadedSet) {
_vqaPlayer->setLoop(_defaultLoop, -1, kLoopSetModeEnqueue, &Scene::loopEndedStatic, this);
_defaultLoopSet = true;
_specialLoopAtEnd = false;
_vm->playerLosesControl();
_defaultLoopPreloadedSet = false;
if (_specialLoopMode == kSceneLoopModeLoseControl) {
_vm->playerLosesControl();
}
} else {
if (_specialLoopMode == kSceneLoopModeLoseControl) {
_vm->playerGainsControl();
_playerWalkedIn = true;
}
if (_specialLoopMode == kSceneLoopModeSpinner) {
_vm->_spinner->open();
}
_specialLoopMode = kSceneLoopModeNone;
_specialLoop = -1;
_vqaPlayer->setLoop(_defaultLoop + 1, -1, kLoopSetModeJustStart, nullptr, nullptr);
_defaultLoopPreloadedSet = true;
}
} else if (_specialLoopAtEnd) {
_vqaPlayer->setLoop(_defaultLoop, -1, kLoopSetModeEnqueue, &Scene::loopEndedStatic, this);
} else if (_specialLoopMode == kSceneLoopModeChangeSet) {
_defaultLoopSet = true;
_specialLoopAtEnd = false;
if (_specialLoopMode == kSceneLoopModeLoseControl) {
_vm->playerLosesControl();
}
} else {
if (_specialLoopMode == kSceneLoopModeLoseControl) {
_vm->playerGainsControl();
_playerWalkedIn = true;
}
if (_specialLoopMode == kSceneLoopModeSpinner) {
_vm->_spinner->open();
}
_specialLoopMode = -1;
_specialLoop = -1;
_vqaPlayer->setLoop(_defaultLoop + 1, -1, kLoopSetModeJustStart, nullptr, nullptr);
_specialLoopAtEnd = true;
_defaultLoopPreloadedSet = false;
_vm->playerLosesControl();
}
}

View File

@ -42,9 +42,9 @@ class Scene {
int _defaultLoop;
bool _defaultLoopSet;
bool _defaultLoopPreloadedSet;
int _specialLoopMode;
int _specialLoop;
bool _specialLoopAtEnd;
// int _introFinished;
int _nextSetId;
int _nextSceneId;

View File

@ -58,6 +58,8 @@ void SceneObjects::clear() {
_sceneObjects[i].isTarget = false;
_sceneObjects[i].isMoving = false;
_sceneObjects[i].isRetired = false;
_sceneObjectsSortedByDistance[i] = -1;
}
_count = 0;
}

View File

@ -40,9 +40,8 @@ enum SceneObjectType {
};
class SceneObjects {
#if BLADERUNNER_DEBUG_RENDERING
friend class BladeRunnerEngine;
#endif
friend class Debugger;
static const int kSceneObjectCount = 115;
struct SceneObject {

View File

@ -0,0 +1,113 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptGenericWalkerA::AIScriptGenericWalkerA(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptGenericWalkerA::Initialize() {
_animationStateNext = 0;
_animationNext = 0;
_animationFrame = 0;
_animationState = 0;
}
bool AIScriptGenericWalkerA::Update() {
return false;
}
void AIScriptGenericWalkerA::TimerExpired(int timer) {
}
void AIScriptGenericWalkerA::CompletedMovementTrack() {
}
void AIScriptGenericWalkerA::ReceivedClue(int clueId, int fromActorId) {
}
void AIScriptGenericWalkerA::ClickedByPlayer() {
}
void AIScriptGenericWalkerA::EnteredScene(int sceneId) {
}
void AIScriptGenericWalkerA::OtherAgentEnteredThisScene(int otherActorId) {
}
void AIScriptGenericWalkerA::OtherAgentExitedThisScene(int otherActorId) {
}
void AIScriptGenericWalkerA::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
}
void AIScriptGenericWalkerA::ShotAtAndMissed() {
}
bool AIScriptGenericWalkerA::ShotAtAndHit() {
return false;
}
void AIScriptGenericWalkerA::Retired(int byActorId) {
}
int AIScriptGenericWalkerA::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerA::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptGenericWalkerA::UpdateAnimation(int *animation, int *frame) {
*animation = 0;
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerA::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptGenericWalkerA::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerA::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerA::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerA::FledCombat() {}
} // End of namespace BladeRunner

View File

@ -0,0 +1,483 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kGenericWalkerAStates {
kGenericWalkerAStatesIdle = 0,
kGenericWalkerAStatesWalk = 1,
kGenericWalkerAStatesDie = 2,
kGenericWalkerAStatesGun = 3
};
AIScriptGenericWalkerA::AIScriptGenericWalkerA(BladeRunnerEngine *vm) : AIScriptBase(vm) {
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
}
void AIScriptGenericWalkerA::Initialize() {
_animationState = kGenericWalkerAStatesIdle;
_animationFrame = 0;
_animationStateNext = 0;
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
Actor_Set_Goal_Number(kActorGenwalkerA, 0);
}
bool AIScriptGenericWalkerA::Update() {
switch (Actor_Query_Goal_Number(kActorGenwalkerA)) {
case 0:
if (prepareWalker()) {
return true;
}
break;
case 1:
if (deltaX != 0.0f || deltaZ != 0.0f) {
movingUpdate();
}
break;
case 200:
Actor_Face_Actor(kActorGenwalkerA, kActorMcCoy, true);
break;
}
return false;
}
void AIScriptGenericWalkerA::TimerExpired(int timer) {
if (timer == 2) {
AI_Countdown_Timer_Reset(kActorGenwalkerA, 2);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
return;// true;
}
//return false;
}
void AIScriptGenericWalkerA::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorGenwalkerA) > 0) {
Actor_Set_Goal_Number(kActorGenwalkerA, 0);
if (!Game_Flag_Query(kFlagGenericWalkerWaiting)) {
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerA, 2);
AI_Countdown_Timer_Start(kActorGenwalkerA, 2, Random_Query(6, 10));
}
// return true;
}
// return false;
}
void AIScriptGenericWalkerA::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGenericWalkerA::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGenwalkerA, true);
if (Actor_Query_Goal_Number(kActorGenwalkerA) == 200) {
Actor_Says(kActorMcCoy, 5290, 18);
} else {
switch (Random_Query(1, 10)) {
case 1:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 2:
Actor_Says(kActorMcCoy, 755, 3);
break;
case 3:
Actor_Says(kActorMcCoy, 940, 3);
break;
case 4:
Actor_Says(kActorMcCoy, 4560, 3);
break;
case 5:
Actor_Says(kActorMcCoy, 4870, 3);
break;
case 6:
Actor_Says(kActorMcCoy, 5125, 3);
break;
case 7:
Actor_Says(kActorMcCoy, 8450, 3);
break;
case 8:
Actor_Says(kActorMcCoy, 1085, 3);
break;
case 9:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 10:
Actor_Says(kActorMcCoy, 7415, 3);
break;
}
}
//return false;
}
void AIScriptGenericWalkerA::EnteredScene(int sceneId) {
//return false;
}
void AIScriptGenericWalkerA::OtherAgentEnteredThisScene(int otherActorId) {
//return false;
}
void AIScriptGenericWalkerA::OtherAgentExitedThisScene(int otherActorId) {
if (Actor_Query_Goal_Number(kActorGenwalkerA) && otherActorId == kActorMcCoy) {
Actor_Set_Goal_Number(kActorGenwalkerA, 0);
}
//return false;
}
void AIScriptGenericWalkerA::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
//return false;
}
void AIScriptGenericWalkerA::ShotAtAndMissed() {
//return false;
}
bool AIScriptGenericWalkerA::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorGenwalkerA)) {
AI_Movement_Track_Flush(kActorGenwalkerA);
_animationState = kGenericWalkerAStatesDie;
_animationFrame = 0;
Sound_Play(203, 100, 0, 0, 50);
movingStart();
return true;
}
return false;
}
void AIScriptGenericWalkerA::Retired(int byActorId) {
//return false;
}
int AIScriptGenericWalkerA::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerA::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 0) {
AI_Movement_Track_Flush(kActorGenwalkerA);
Actor_Put_In_Set(kActorGenwalkerA, kSetFreeSlotH);
Global_Variable_Set(kVariableGenericWalkerAModel, -1);
return false;
} else if (newGoalNumber == 1) {
return true;
} else if (newGoalNumber == 200) {
Actor_Put_In_Set(kActorGenwalkerA, kSetRC04);
Actor_Set_At_XYZ(kActorGenwalkerA, 0.0, 36.0, -172.0, 491);
Actor_Change_Animation_Mode(kActorGenwalkerA, kAnimationModeCombatIdle);
return true;
}
return false;
}
bool AIScriptGenericWalkerA::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kGenericWalkerAStatesIdle:
switch (Global_Variable_Query(kVariableGenericWalkerAModel)) {
case 0:
*animation = 426;
break;
case 1:
*animation = 430;
break;
case 2:
*animation = 437;
break;
case 3:
*animation = 431;
break;
case 4:
*animation = 427;
break;
case 5:
*animation = 433;
break;
}
_animationFrame = 0;
break;
case kGenericWalkerAStatesWalk:
switch (Global_Variable_Query(kVariableGenericWalkerAModel)){
case 0:
*animation = 424;
break;
case 1:
*animation = 428;
break;
case 2:
*animation = 436;
break;
case 3:
*animation = 429;
break;
case 4:
*animation = 425;
break;
case 5:
*animation = 432;
break;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kGenericWalkerAStatesDie:
*animation = 874;
++_animationFrame;
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(874))
{
_animationFrame = 0;
Actor_Set_Goal_Number(kActorGenwalkerA, 0);
_animationState = kGenericWalkerAStatesIdle;
deltaX = 0.0f;
deltaZ = 0.0f;
}
break;
case kGenericWalkerAStatesGun:
*animation = 440;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(440)) {
_animationFrame = 0;
}
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerA::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = kGenericWalkerAStatesIdle;
_animationFrame = 0;
break;
case kAnimationModeWalk:
_animationState = kGenericWalkerAStatesWalk;
_animationFrame = 0;
break;
case kAnimationModeCombatIdle:
_animationState = kGenericWalkerAStatesGun;
_animationFrame = 0;
break;
}
return true;
}
void AIScriptGenericWalkerA::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerA::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerA::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerA::FledCombat() {
//return false;
}
void AIScriptGenericWalkerA::movingStart() {
float mccoyX, mccoyY, mccoyZ;
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorMcCoy, &mccoyX, &mccoyY, &mccoyZ);
Actor_Query_XYZ(kActorGenwalkerA, &walkerX, &walkerY, &walkerZ);
deltaX = walkerX - mccoyX;
deltaZ = walkerZ - mccoyZ;
float dist = sqrt(deltaX * deltaX + deltaZ * deltaZ);
if (dist == 0.0f) {
deltaZ = 0.0f;
deltaX = 0.0f;
} else {
deltaX *= 10.0f / dist;
deltaZ *= 10.0f / dist;
}
}
void AIScriptGenericWalkerA::movingUpdate() {
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorGenwalkerA, &walkerX, &walkerY, &walkerZ);
int facing = Actor_Query_Facing_1024(kActorGenwalkerA);
walkerX += deltaX;
walkerZ += deltaZ;
deltaX = deltaX * 0.97f;
deltaZ = deltaZ * 0.97f;
Actor_Set_At_XYZ(kActorGenwalkerA, walkerX, walkerY, walkerZ, facing);
}
bool AIScriptGenericWalkerA::prepareWalker() {
if (Game_Flag_Query(kFlagGenericWalkerWaiting) || Global_Variable_Query(35) < 0 || !preparePath()) {
return false;
}
int model = 0;
do {
if (isInside) {
model = Random_Query(3, 5);
} else {
model = Random_Query(0, 5);
}
}
while (model == Global_Variable_Query(kVariableGenericWalkerBModel) || model == Global_Variable_Query(kVariableGenericWalkerCModel));
Global_Variable_Set(kVariableGenericWalkerAModel, model);
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerA, 2);
AI_Countdown_Timer_Start(kActorGenwalkerA, 2, Random_Query(4, 12));
Actor_Set_Goal_Number(kActorGenwalkerA, 1);
return true;
}
bool AIScriptGenericWalkerA::preparePath() {
AI_Movement_Track_Flush(kActorGenwalkerA);
int set = Player_Query_Current_Set();
if (set == kSetAR01_AR02) {
isInside = false;
int waypointStart = Random_Query(155, 158);
int waypointEnd = 0;
AI_Movement_Track_Append(kActorGenwalkerA, waypointStart, 0);
do {
waypointEnd = Random_Query(155, 158);
} while (waypointEnd == waypointStart);
if ((waypointStart == 155 || waypointStart == 156) && (waypointEnd == 157 || waypointEnd == 158)) {
AI_Movement_Track_Append(kActorGenwalkerA, 159, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 160, 0);
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerA, 161, Random_Query(15, 30), 904);
}
} else if ((waypointEnd == 155 || waypointEnd == 156) && (waypointStart == 157 || waypointStart == 158)) {
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerA, 161, Random_Query(15, 30), 904);
}
AI_Movement_Track_Append(kActorGenwalkerA, 160, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 159, 0);
} else if ((waypointStart == 155 && waypointEnd == 156) || (waypointStart == 156 && waypointEnd == 155)) {
AI_Movement_Track_Append(kActorGenwalkerA, 159, 0);
}
AI_Movement_Track_Append(kActorGenwalkerA, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerA);
return true;
}
if (set == kSetCT01_CT12) {
isInside = false;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 54, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerA, 56, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 53, 1);
}
AI_Movement_Track_Append(kActorGenwalkerA, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerA);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 53, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerA, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 54, 1);
}
AI_Movement_Track_Append(kActorGenwalkerA, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerA);
}
return true;
}
if (set == kSetHC01_HC02_HC03_HC04) {
isInside = true;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 164, 0);
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
}
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 164, 0);
} else {
if (Random_Query(0, 1)) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerA, 166, 0, 30);
}
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 164, 0);
}
}
AI_Movement_Track_Repeat(kActorGenwalkerA);
return true;
}
if (set == kSetRC03) {
isInside = false;
int waypointStart = 0;
int waypointEnd = 0;
do {
waypointStart = Random_Query(167, 171);
} while (waypointEnd == 168 || waypointEnd == 169);
do {
waypointEnd = Random_Query(167, 171);
} while (waypointEnd == waypointStart || waypointEnd == 168 || waypointEnd == 169);
AI_Movement_Track_Append(kActorGenwalkerA, waypointStart, 0);
if (waypointStart == 170) {
AI_Movement_Track_Append(kActorGenwalkerA, 169, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 168, 0);
} else if (waypointEnd == 170) {
AI_Movement_Track_Append(kActorGenwalkerA, 168, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 169, 0);
}
AI_Movement_Track_Append(kActorGenwalkerA, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerA);
return true;
}
return false;
}
} // End of namespace BladeRunner

View File

@ -0,0 +1,458 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kGenericWalkerBStates {
kGenericWalkerBStatesIdle = 0,
kGenericWalkerBStatesWalk = 1,
kGenericWalkerBStatesDie = 2
};
AIScriptGenericWalkerB::AIScriptGenericWalkerB(BladeRunnerEngine *vm) : AIScriptBase(vm) {
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
}
void AIScriptGenericWalkerB::Initialize() {
_animationState = kGenericWalkerBStatesIdle;
_animationFrame = 0;
_animationStateNext = 0;
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
Actor_Set_Goal_Number(kActorGenwalkerB, 0);
}
bool AIScriptGenericWalkerB::Update() {
switch (Actor_Query_Goal_Number(kActorGenwalkerB)) {
case 0:
if (prepareWalker()) {
return true;
}
break;
case 1:
if (deltaX != 0.0f || deltaZ != 0.0f) {
movingUpdate();
}
break;
}
return false;
}
void AIScriptGenericWalkerB::TimerExpired(int timer) {
if (timer == 2) {
AI_Countdown_Timer_Reset(kActorGenwalkerB, 2);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
return;// true;
}
//return false;
}
void AIScriptGenericWalkerB::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorGenwalkerB) > 0) {
Actor_Set_Goal_Number(kActorGenwalkerB, 0);
if (!Game_Flag_Query(kFlagGenericWalkerWaiting)) {
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerB, 2);
AI_Countdown_Timer_Start(kActorGenwalkerB, 2, Random_Query(6, 10));
}
// return true;
}
// return false;
}
void AIScriptGenericWalkerB::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGenericWalkerB::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGenwalkerB, true);
switch (Random_Query(1, 10)) {
case 1:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 2:
Actor_Says(kActorMcCoy, 755, 3);
break;
case 3:
Actor_Says(kActorMcCoy, 940, 3);
break;
case 4:
Actor_Says(kActorMcCoy, 4560, 3);
break;
case 5:
Actor_Says(kActorMcCoy, 4870, 3);
break;
case 6:
Actor_Says(kActorMcCoy, 5125, 3);
break;
case 7:
Actor_Says(kActorMcCoy, 8450, 3);
break;
case 8:
Actor_Says(kActorMcCoy, 1085, 3);
break;
case 9:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 10:
Actor_Says(kActorMcCoy, 7415, 3);
break;
}
//return false;
}
void AIScriptGenericWalkerB::EnteredScene(int sceneId) {
//return false;
}
void AIScriptGenericWalkerB::OtherAgentEnteredThisScene(int otherActorId) {
//return false;
}
void AIScriptGenericWalkerB::OtherAgentExitedThisScene(int otherActorId) {
if (Actor_Query_Goal_Number(kActorGenwalkerB) && otherActorId == kActorMcCoy) {
Actor_Set_Goal_Number(kActorGenwalkerB, 0);
}
//return false;
}
void AIScriptGenericWalkerB::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
//return false;
}
void AIScriptGenericWalkerB::ShotAtAndMissed() {
//return false;
}
bool AIScriptGenericWalkerB::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorGenwalkerB)) {
AI_Movement_Track_Flush(kActorGenwalkerB);
_animationState = kGenericWalkerBStatesDie;
_animationFrame = 0;
Sound_Play(203, 100, 0, 0, 50);
movingStart();
return true;
}
return false;
}
void AIScriptGenericWalkerB::Retired(int byActorId) {
//return false;
}
int AIScriptGenericWalkerB::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerB::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 0) {
AI_Movement_Track_Flush(kActorGenwalkerB);
Actor_Put_In_Set(kActorGenwalkerB, kSetFreeSlotH);
Global_Variable_Set(kVariableGenericWalkerBModel, -1);
return false;
} else if (newGoalNumber == 1) {
return true;
}
return false;
}
bool AIScriptGenericWalkerB::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kGenericWalkerBStatesIdle:
switch (Global_Variable_Query(kVariableGenericWalkerBModel)) {
case 0:
*animation = 426;
break;
case 1:
*animation = 430;
break;
case 2:
*animation = 437;
break;
case 3:
*animation = 431;
break;
case 4:
*animation = 427;
break;
case 5:
*animation = 433;
break;
}
_animationFrame = 0;
break;
case kGenericWalkerBStatesWalk:
switch (Global_Variable_Query(kVariableGenericWalkerBModel)){
case 0:
*animation = 424;
break;
case 1:
*animation = 428;
break;
case 2:
*animation = 436;
break;
case 3:
*animation = 429;
break;
case 4:
*animation = 425;
break;
case 5:
*animation = 432;
break;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kGenericWalkerBStatesDie:
*animation = 874;
++_animationFrame;
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(874))
{
_animationFrame = 0;
Actor_Set_Goal_Number(kActorGenwalkerB, 0);
_animationState = kGenericWalkerBStatesIdle;
deltaX = 0.0f;
deltaZ = 0.0f;
}
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerB::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = kGenericWalkerBStatesIdle;
_animationFrame = 0;
break;
case kAnimationModeWalk:
_animationState = kGenericWalkerBStatesWalk;
_animationFrame = 0;
break;
}
return true;
}
void AIScriptGenericWalkerB::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerB::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerB::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerB::FledCombat() {
//return false;
}
void AIScriptGenericWalkerB::movingStart() {
float mccoyX, mccoyY, mccoyZ;
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorMcCoy, &mccoyX, &mccoyY, &mccoyZ);
Actor_Query_XYZ(kActorGenwalkerB, &walkerX, &walkerY, &walkerZ);
deltaX = walkerX - mccoyX;
deltaZ = walkerZ - mccoyZ;
float dist = sqrt(deltaX * deltaX + deltaZ * deltaZ);
if (dist == 0.0f) {
deltaZ = 0.0f;
deltaX = 0.0f;
} else {
deltaX *= 10.0f / dist;
deltaZ *= 10.0f / dist;
}
}
void AIScriptGenericWalkerB::movingUpdate() {
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorGenwalkerB, &walkerX, &walkerY, &walkerZ);
int facing = Actor_Query_Facing_1024(kActorGenwalkerB);
walkerX += deltaX;
walkerZ += deltaZ;
deltaX = deltaX * 0.97f;
deltaZ = deltaZ * 0.97f;
Actor_Set_At_XYZ(kActorGenwalkerB, walkerX, walkerY, walkerZ, facing);
}
bool AIScriptGenericWalkerB::prepareWalker() {
if (Game_Flag_Query(kFlagGenericWalkerWaiting) || Global_Variable_Query(35) < 0 || !preparePath()) {
return false;
}
int model = 0;
do {
if (isInside) {
model = Random_Query(3, 5);
} else {
model = Random_Query(0, 5);
}
}
while (model == Global_Variable_Query(kVariableGenericWalkerAModel) || model == Global_Variable_Query(kVariableGenericWalkerCModel));
Global_Variable_Set(kVariableGenericWalkerBModel, model);
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerB, 2);
AI_Countdown_Timer_Start(kActorGenwalkerB, 2, Random_Query(4, 12));
Actor_Set_Goal_Number(kActorGenwalkerB, 1);
return true;
}
bool AIScriptGenericWalkerB::preparePath() {
AI_Movement_Track_Flush(kActorGenwalkerB);
int set = Player_Query_Current_Set();
if (set == kSetAR01_AR02) {
isInside = false;
int waypointStart = Random_Query(155, 158);
int waypointEnd = 0;
AI_Movement_Track_Append(kActorGenwalkerB, waypointStart, 0);
do {
waypointEnd = Random_Query(155, 158);
} while (waypointEnd == waypointStart);
if ((waypointStart == 155 || waypointStart == 156) && (waypointEnd == 157 || waypointEnd == 158)) {
AI_Movement_Track_Append(kActorGenwalkerB, 159, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 160, 0);
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerB, 161, Random_Query(15, 30), 904);
}
} else if ((waypointEnd == 155 || waypointEnd == 156) && (waypointStart == 157 || waypointStart == 158)) {
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerB, 161, Random_Query(15, 30), 904);
}
AI_Movement_Track_Append(kActorGenwalkerB, 160, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 159, 0);
} else if ((waypointStart == 155 && waypointEnd == 156) || (waypointStart == 156 && waypointEnd == 155)) {
AI_Movement_Track_Append(kActorGenwalkerB, 159, 0);
}
AI_Movement_Track_Append(kActorGenwalkerB, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerB);
return true;
}
if (set == kSetCT01_CT12) {
isInside = false;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 54, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerB, 56, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 53, 1);
}
AI_Movement_Track_Append(kActorGenwalkerB, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerB);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 53, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerB, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 54, 1);
}
AI_Movement_Track_Append(kActorGenwalkerB, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerB);
}
return true;
}
if (set == kSetHC01_HC02_HC03_HC04) {
isInside = true;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
}
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
}
}
AI_Movement_Track_Repeat(kActorGenwalkerB);
return true;
}
if (set == kSetRC03) {
isInside = false;
int waypointStart = 0;
int waypointEnd = 0;
do {
waypointStart = Random_Query(167, 171);
} while (waypointEnd == 168 || waypointEnd == 169);
do {
waypointEnd = Random_Query(167, 171);
} while (waypointEnd == waypointStart || waypointEnd == 168 || waypointEnd == 169);
AI_Movement_Track_Append(kActorGenwalkerB, waypointStart, 0);
if (waypointStart == 170) {
AI_Movement_Track_Append(kActorGenwalkerB, 169, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 168, 0);
} else if (waypointEnd == 170) {
AI_Movement_Track_Append(kActorGenwalkerB, 168, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 169, 0);
}
AI_Movement_Track_Append(kActorGenwalkerB, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerB);
return true;
}
return false;
}
} // End of namespace BladeRunner

View File

@ -0,0 +1,462 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kGenericWalkerCStates {
kGenericWalkerCStatesIdle = 0,
kGenericWalkerCStatesWalk = 1,
kGenericWalkerCStatesDie = 2,
kGenericWalkerCStatesGun = 3
};
AIScriptGenericWalkerC::AIScriptGenericWalkerC(BladeRunnerEngine *vm) : AIScriptBase(vm) {
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
}
void AIScriptGenericWalkerC::Initialize() {
_animationState = kGenericWalkerCStatesIdle;
_animationFrame = 0;
_animationStateNext = 0;
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
Actor_Set_Goal_Number(kActorGenwalkerC, 0);
}
bool AIScriptGenericWalkerC::Update() {
switch (Actor_Query_Goal_Number(kActorGenwalkerC)) {
case 0:
if (prepareWalker()) {
return true;
}
break;
case 1:
if (deltaX != 0.0f || deltaZ != 0.0f) {
movingUpdate();
}
break;
}
return false;
}
void AIScriptGenericWalkerC::TimerExpired(int timer) {
if (timer == 2) {
AI_Countdown_Timer_Reset(kActorGenwalkerC, 2);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
return;// true;
}
//return false;
}
void AIScriptGenericWalkerC::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorGenwalkerC) > 0) {
Actor_Set_Goal_Number(kActorGenwalkerC, 0);
if (!Game_Flag_Query(kFlagGenericWalkerWaiting)) {
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerC, 2);
AI_Countdown_Timer_Start(kActorGenwalkerC, 2, Random_Query(6, 10));
}
// return true;
}
// return false;
}
void AIScriptGenericWalkerC::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGenericWalkerC::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGenwalkerC, true);
switch (Random_Query(1, 10)) {
case 1:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 2:
Actor_Says(kActorMcCoy, 755, 3);
break;
case 3:
Actor_Says(kActorMcCoy, 940, 3);
break;
case 4:
Actor_Says(kActorMcCoy, 4560, 3);
break;
case 5:
Actor_Says(kActorMcCoy, 4870, 3);
break;
case 6:
Actor_Says(kActorMcCoy, 5125, 3);
break;
case 7:
Actor_Says(kActorMcCoy, 8450, 3);
break;
case 8:
Actor_Says(kActorMcCoy, 1085, 3);
break;
case 9:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 10:
Actor_Says(kActorMcCoy, 7415, 3);
break;
}
//return false;
}
void AIScriptGenericWalkerC::EnteredScene(int sceneId) {
//return false;
}
void AIScriptGenericWalkerC::OtherAgentEnteredThisScene(int otherActorId) {
//return false;
}
void AIScriptGenericWalkerC::OtherAgentExitedThisScene(int otherActorId) {
if (Actor_Query_Goal_Number(kActorGenwalkerC) && otherActorId == kActorMcCoy) {
Actor_Set_Goal_Number(kActorGenwalkerC, 0);
}
//return false;
}
void AIScriptGenericWalkerC::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
//return false;
}
void AIScriptGenericWalkerC::ShotAtAndMissed() {
//return false;
}
bool AIScriptGenericWalkerC::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorGenwalkerC)) {
AI_Movement_Track_Flush(kActorGenwalkerC);
_animationState = kGenericWalkerCStatesDie;
_animationFrame = 0;
Sound_Play(203, 100, 0, 0, 50);
movingStart();
return true;
}
return false;
}
void AIScriptGenericWalkerC::Retired(int byActorId) {
//return false;
}
int AIScriptGenericWalkerC::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerC::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 0) {
AI_Movement_Track_Flush(kActorGenwalkerC);
Actor_Put_In_Set(kActorGenwalkerC, kSetFreeSlotH);
Global_Variable_Set(kVariableGenericWalkerCModel, -1);
return false;
} else if (newGoalNumber == 1) {
return true;
}
return false;
}
bool AIScriptGenericWalkerC::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kGenericWalkerCStatesIdle:
switch (Global_Variable_Query(kVariableGenericWalkerCModel)) {
case 0:
*animation = 426;
break;
case 1:
*animation = 430;
break;
case 2:
*animation = 437;
break;
case 3:
*animation = 431;
break;
case 4:
*animation = 427;
break;
case 5:
*animation = 433;
break;
}
_animationFrame = 0;
break;
case kGenericWalkerCStatesWalk:
switch (Global_Variable_Query(kVariableGenericWalkerCModel)){
case 0:
*animation = 424;
break;
case 1:
*animation = 428;
break;
case 2:
*animation = 436;
break;
case 3:
*animation = 429;
break;
case 4:
*animation = 425;
break;
case 5:
*animation = 432;
break;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kGenericWalkerCStatesDie:
*animation = 874;
++_animationFrame;
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(874))
{
_animationFrame = 0;
Actor_Set_Goal_Number(kActorGenwalkerC, 0);
_animationState = kGenericWalkerCStatesIdle;
deltaX = 0.0f;
deltaZ = 0.0f;
}
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerC::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = kGenericWalkerCStatesIdle;
_animationFrame = 0;
break;
case kAnimationModeWalk:
_animationState = kGenericWalkerCStatesWalk;
_animationFrame = 0;
break;
}
return true;
}
void AIScriptGenericWalkerC::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerC::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerC::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerC::FledCombat() {
//return false;
}
void AIScriptGenericWalkerC::movingStart() {
float mccoyX, mccoyY, mccoyZ;
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorMcCoy, &mccoyX, &mccoyY, &mccoyZ);
Actor_Query_XYZ(kActorGenwalkerC, &walkerX, &walkerY, &walkerZ);
deltaX = walkerX - mccoyX;
deltaZ = walkerZ - mccoyZ;
float dist = sqrt(deltaX * deltaX + deltaZ * deltaZ);
if (dist == 0.0f) {
deltaZ = 0.0f;
deltaX = 0.0f;
} else {
deltaX *= 10.0f / dist;
deltaZ *= 10.0f / dist;
}
}
void AIScriptGenericWalkerC::movingUpdate() {
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorGenwalkerC, &walkerX, &walkerY, &walkerZ);
int facing = Actor_Query_Facing_1024(kActorGenwalkerC);
walkerX += deltaX;
walkerZ += deltaZ;
deltaX = deltaX * 0.97f;
deltaZ = deltaZ * 0.97f;
Actor_Set_At_XYZ(kActorGenwalkerC, walkerX, walkerY, walkerZ, facing);
}
bool AIScriptGenericWalkerC::prepareWalker() {
if (Game_Flag_Query(kFlagGenericWalkerWaiting) || Global_Variable_Query(35) < 2 || !preparePath()) {
return false;
}
int model = 0;
do {
if (isInside) {
model = Random_Query(3, 5);
} else {
model = Random_Query(0, 5);
}
}
// Here is probably bug in original code, because it not using kVariableGenericWalkerBModel but kVariableGenericWalkerCModel
while (model == Global_Variable_Query(kVariableGenericWalkerAModel) || model == Global_Variable_Query(kVariableGenericWalkerBModel));
Global_Variable_Set(kVariableGenericWalkerCModel, model);
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerC, 2);
AI_Countdown_Timer_Start(kActorGenwalkerC, 2, Random_Query(4, 12));
Actor_Set_Goal_Number(kActorGenwalkerC, 1);
return true;
}
bool AIScriptGenericWalkerC::preparePath() {
AI_Movement_Track_Flush(kActorGenwalkerC);
int set = Player_Query_Current_Set();
if (set == kSetAR01_AR02) {
isInside = false;
int waypointStart = Random_Query(155, 158);
int waypointEnd = 0;
AI_Movement_Track_Append(kActorGenwalkerC, waypointStart, 0);
do {
waypointEnd = Random_Query(155, 158);
} while (waypointEnd == waypointStart);
if ((waypointStart == 155 || waypointStart == 156) && (waypointEnd == 157 || waypointEnd == 158)) {
AI_Movement_Track_Append(kActorGenwalkerC, 159, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 160, 0);
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerC, 161, Random_Query(15, 30), 904);
}
} else if ((waypointEnd == 155 || waypointEnd == 156) && (waypointStart == 157 || waypointStart == 158)) {
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerC, 161, Random_Query(15, 30), 904);
}
AI_Movement_Track_Append(kActorGenwalkerC, 160, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 159, 0);
} else if ((waypointStart == 155 && waypointEnd == 156) || (waypointStart == 156 && waypointEnd == 155)) {
AI_Movement_Track_Append(kActorGenwalkerC, 159, 0);
}
AI_Movement_Track_Append(kActorGenwalkerC, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerC);
return true;
}
if (set == kSetCT01_CT12) {
isInside = false;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 54, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerC, 56, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 53, 1);
}
AI_Movement_Track_Append(kActorGenwalkerC, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerC);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 53, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerC, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 54, 1);
}
AI_Movement_Track_Append(kActorGenwalkerC, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerC);
}
return true;
}
if (set == kSetHC01_HC02_HC03_HC04) {
isInside = true;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
}
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
} else {
if (Random_Query(0, 1)) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerC, 166, 0, 30);
}
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
}
}
AI_Movement_Track_Repeat(kActorGenwalkerC);
return true;
}
if (set == kSetRC03) {
isInside = false;
int waypointStart = 0;
int waypointEnd = 0;
do {
waypointStart = Random_Query(167, 171);
} while (waypointEnd == 168 || waypointEnd == 169);
do {
waypointEnd = Random_Query(167, 171);
} while (waypointEnd == waypointStart || waypointEnd == 168 || waypointEnd == 169);
AI_Movement_Track_Append(kActorGenwalkerC, waypointStart, 0);
if (waypointStart == 170) {
AI_Movement_Track_Append(kActorGenwalkerC, 169, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 168, 0);
} else if (waypointEnd == 170) {
AI_Movement_Track_Append(kActorGenwalkerC, 168, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 169, 0);
}
AI_Movement_Track_Append(kActorGenwalkerC, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerC);
return true;
}
return false;
}
} // End of namespace BladeRunner

View File

@ -1699,7 +1699,7 @@ void AIScriptMcCoy::sub_4054F0() {
if ((z < 220.0f) && (-210.0f < x) && (-70.0f > x)) {
Game_Flag_Set(682);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
Actor_Set_Goal_Number(kActorMcCoy, 390);
Actor_Query_XYZ(kActorFreeSlotA, &x, &y, &z);
if (-200.0 < x && -62.0f > x) {

View File

@ -44,6 +44,9 @@ AIScripts::AIScripts(BladeRunnerEngine *vm, int actorCount) {
_AIScripts[kActorOfficerLeary] = new AIScriptOfficerLeary(_vm);
_AIScripts[kActorLeon] = new AIScriptLeon(_vm);
_AIScripts[kActorMaggie] = new AIScriptMaggie(_vm);
_AIScripts[kActorGenwalkerA] = new AIScriptGenericWalkerA(_vm);
_AIScripts[kActorGenwalkerB] = new AIScriptGenericWalkerB(_vm);
_AIScripts[kActorGenwalkerC] = new AIScriptGenericWalkerC(_vm);
}
AIScripts::~AIScripts() {
@ -64,13 +67,14 @@ void AIScripts::initialize(int actor) {
void AIScripts::update(int actor) {
assert(actor < _actorCount);
if (this->_actorUpdating[actor] != 1) {
this->_actorUpdating[actor] = true;
++this->_inScriptCounter;
if (_AIScripts[actor])
if (!_actorUpdating[actor]) {
_actorUpdating[actor] = true;
++_inScriptCounter;
if (_AIScripts[actor]) {
_AIScripts[actor]->Update();
--this->_inScriptCounter;
this->_actorUpdating[actor] = false;
}
--_inScriptCounter;
_actorUpdating[actor] = false;
}
}

View File

@ -156,6 +156,39 @@ DECLARE_SCRIPT(Maggie)
float sub_44B200(int actorId, float x, float y, float z);
END_SCRIPT
DECLARE_SCRIPT(GenericWalkerA)
bool isInside;
float deltaX;
float deltaZ;
void movingStart();
void movingUpdate();
bool prepareWalker();
bool preparePath();
END_SCRIPT
DECLARE_SCRIPT(GenericWalkerB)
bool isInside;
float deltaX;
float deltaZ;
void movingStart();
void movingUpdate();
bool prepareWalker();
bool preparePath();
END_SCRIPT
DECLARE_SCRIPT(GenericWalkerC)
bool isInside;
float deltaX;
float deltaZ;
void movingStart();
void movingUpdate();
bool prepareWalker();
bool preparePath();
END_SCRIPT
#undef DECLARE_SCRIPT
#undef END_SCRIPT

View File

@ -59,8 +59,8 @@ void InitScript::Init_Globals() {
Global_Variable_Set(i, 0);
Global_Variable_Set(35, 2);
Global_Variable_Set(1, 1);
Global_Variable_Set(2, 100);
Global_Variable_Set(kVariableChapter, 1);
Global_Variable_Set(kVariableChinyen, 100);
Set_Score(0, 0);
Set_Score(1, 64);

View File

@ -100,7 +100,7 @@ bool SceneScriptBB02::ClickedOnExit(int exitId) {
if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, -12.0f, -415.06f, -27.0f, 0, 1, false, 0)) {
Player_Loses_Control();
if (!Game_Flag_Query(493)) {
Scene_Loop_Start_Special(kSceneLoopMode2, 0, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 0, true);
}
Game_Flag_Set(332);
Game_Flag_Reset(493);

View File

@ -152,7 +152,7 @@ void SceneScriptCT02::sub_401ACC() {
Actor_Set_Goal_Number(kActorZuben, 8);
Game_Flag_Set(293);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
}
break;
case 280:
@ -165,7 +165,7 @@ void SceneScriptCT02::sub_401ACC() {
Actor_Set_Goal_Number(kActorZuben, 8);
Game_Flag_Set(293);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
}
break;
case 290:
@ -181,7 +181,7 @@ void SceneScriptCT02::sub_401ACC() {
Actor_Set_Goal_Number(kActorZuben, 8);
Game_Flag_Set(293);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
}
break;
case 300:
@ -192,7 +192,7 @@ void SceneScriptCT02::sub_401ACC() {
Actor_Set_Goal_Number(kActorZuben, 8);
Game_Flag_Set(293);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
}
break;
}

View File

@ -271,7 +271,7 @@ void SceneScriptCT12::PlayerWalkedIn() {
}
void SceneScriptCT12::PlayerWalkedOut() {
Game_Flag_Reset(443);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
if (Game_Flag_Query(433)) {
Game_Flag_Reset(176);
Game_Flag_Set(259);

View File

@ -184,7 +184,7 @@ void SceneScriptDR04::SceneFrameAdvanced(int frame) {
Game_Flag_Reset(515);
Game_Flag_Reset(271);
Scene_Loop_Set_Default(1);
Scene_Loop_Start_Special(kSceneLoopMode2, 6, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 6, true);
Music_Stop(4);
Actor_Set_Goal_Number(kActorMoraji, 99);
} else {
@ -192,7 +192,7 @@ void SceneScriptDR04::SceneFrameAdvanced(int frame) {
Game_Flag_Reset(271);
Game_Flag_Set(272);
Scene_Loop_Set_Default(1);
Scene_Loop_Start_Special(kSceneLoopMode2, 6, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 6, true);
Item_Remove_From_World(78);
}
switch (frame) {

View File

@ -100,7 +100,7 @@ bool SceneScriptHC03::ClickedOnItem(int itemId, bool a2) {
if (itemId == 121) {
if (a2) {
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
Game_Flag_Set(403);
Item_Remove_From_World(121);
Unobstacle_Object("GPscisGate", true);
@ -146,7 +146,7 @@ bool SceneScriptHC03::ClickedOnExit(int exitId) {
Set_Enter(75, kSceneUG02);
} else {
Scene_Loop_Set_Default(6);
Scene_Loop_Start_Special(kSceneLoopMode2, 5, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 5, true);
Game_Flag_Set(388);
}
}

View File

@ -108,14 +108,14 @@ void SceneScriptHF04::SceneFrameAdvanced(int frame) {
if (Game_Flag_Query(585)) {
Game_Flag_Reset(585);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
//return true;
return;
}
if (Game_Flag_Query(586)) {
Game_Flag_Reset(586);
Scene_Loop_Set_Default(0);
Scene_Loop_Start_Special(kSceneLoopMode2, 5, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 5, true);
//return true;
return;
}

View File

@ -92,7 +92,7 @@ bool SceneScriptHF05::ClickedOn3DObject(const char *objectName, bool a2) {
Actor_Face_Heading(kActorMcCoy, 0, false);
Actor_Change_Animation_Mode(kActorMcCoy, 23);
Scene_Loop_Set_Default(5);
Scene_Loop_Start_Special(kSceneLoopMode2, 4, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 4, true);
if (sub_4048C0()) {
if (sub_4048C0() == 3) {
Actor_Face_Heading(kActorDektora, 0, false);

View File

@ -263,7 +263,7 @@ void SceneScriptHF06::sub_401EF4() {
Actor_Change_Animation_Mode(kActorSteele, 6);
Delay(500);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
Sound_Play(562, 50, 0, 0, 50);
Game_Flag_Set(559);
Scene_Exits_Disable();

View File

@ -69,7 +69,7 @@ bool SceneScriptKP03::ClickedOn3DObject(const char *objectName, bool a2) {
if (Object_Query_Click("BRACK MID", objectName) && !Game_Flag_Query(422)) {
if (a2) {
Scene_Loop_Set_Default(5);
Scene_Loop_Start_Special(kSceneLoopMode2, 4, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 4, true);
Actor_Change_Animation_Mode(kActorMcCoy, 39);
Actor_Retired_Here(kActorMcCoy, 72, 18, 1, -1);
Game_Flag_Set(422);
@ -90,7 +90,7 @@ bool SceneScriptKP03::ClickedOn3DObject(const char *objectName, bool a2) {
Game_Flag_Set(484);
Game_Flag_Reset(421);
Scene_Loop_Set_Default(7);
Scene_Loop_Start_Special(kSceneLoopMode2, 0, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 0, false);
Actor_Voice_Over(1110, kActorVoiceOver);
Actor_Voice_Over(1120, kActorVoiceOver);
} else {
@ -178,7 +178,7 @@ void SceneScriptKP03::SceneFrameAdvanced(int frame) {
}
if (v1 != -1) {
Scene_Loop_Set_Default(5);
Scene_Loop_Start_Special(kSceneLoopMode2, 4, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 4, true);
Game_Flag_Set(422);
Game_Flag_Reset(421);
Unclickable_Object("BRACK MID");
@ -244,7 +244,7 @@ void SceneScriptKP03::sub_401E54() {
Game_Flag_Set(484);
Game_Flag_Reset(421);
Scene_Loop_Set_Default(7);
Scene_Loop_Start_Special(kSceneLoopMode2, 7, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 7, false);
Actor_Set_Goal_Number(kActorSteele, 413);
Actor_Says(kActorMcCoy, 2195, 14);
Ambient_Sounds_Play_Sound(151, 40, -60, -60, 0);

View File

@ -117,7 +117,7 @@ void SceneScriptMA05::PlayerWalkedIn() {
Music_Play(2, 52, 0, 2, -1, 0, 0);
if ((Random_Query(0, 4) == 1 || (Game_Flag_Query(kFlagChapter1Ending) && !Game_Flag_Query(kFlagChapter1Ended))) && Global_Variable_Query(kVariableChapter) == 1) {
Scene_Loop_Set_Default(kMA05LoopMain);
Scene_Loop_Start_Special(kSceneLoopMode2, kMA05LoopSpinner, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, kMA05LoopSpinner, true);
Sound_Play(69, 100, 0, 0, 50);
}
if (Game_Flag_Query(kFlagChapter1Ending) && !Game_Flag_Query(kFlagChapter1Ended)) {

View File

@ -134,7 +134,7 @@ void SceneScriptMA06::activateElevator() {
Player_Gains_Control();
int floor = Elevator_Activate(kElevatorMA);
Player_Loses_Control();
Scene_Loop_Start_Special(kSceneLoopMode2, 1, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, kMA06LoopMain, true);
if (floor > 1) {
Game_Flag_Set(kFlagMA06toMA07);
} else if (floor == 1) {

View File

@ -150,7 +150,7 @@ void SceneScriptNR08::SceneFrameAdvanced(int frame) {
Game_Flag_Set(636);
Scene_Exits_Disable();
Scene_Loop_Set_Default(1);
Scene_Loop_Start_Special(kSceneLoopMode2, 3, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 3, true);
}
if (frame == 95) {
Actor_Put_In_Set(kActorDektora, 91);

View File

@ -71,7 +71,7 @@ bool SceneScriptNR10::ClickedOn3DObject(const char *objectName, bool a2) {
Ambient_Sounds_Remove_Looping_Sound(452, true);
Sound_Play(453, 52, 0, 0, 50);
Scene_Loop_Set_Default(0);
Scene_Loop_Start_Special(kSceneLoopMode2, 0, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 0, true);
Un_Combat_Target_Object("BOX18");
Scene_Exits_Enable();
return true;

View File

@ -122,7 +122,7 @@ bool SceneScriptNR11::ClickedOn3DObject(const char *objectName, bool a2) {
}
Actor_Set_Goal_Number(kActorMcCoy, 230);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
} else if (Actor_Query_Goal_Number(kActorDektora) == 250) {
if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, 24.0f, 0.33f, 0.0f, 0, 1, false, 0)) {
Actor_Face_XYZ(kActorMcCoy, -180.0f, 0.0f, -170.0f, true);
@ -260,7 +260,7 @@ void SceneScriptNR11::SceneFrameAdvanced(int frame) {
}
Actor_Set_Goal_Number(kActorMcCoy, 230);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
Game_Flag_Reset(635);
} else {
if (frame < 61 || frame > 120) {

View File

@ -50,12 +50,12 @@ void SceneScriptRC01::InitializeScene() {
#if BLADERUNNER_DEBUG_GAME
//TODO: not part of game, remove
Game_Flag_Set(kFlagIntroPlayed); // force skip intro
Game_Flag_Set(kFlagRC02toRC01); // no landing
Game_Flag_Set(kFlagRC02toRC01); // no landing
// Game_Flag_Set(kFlagRC01PoliceDone);
// Game_Flag_Set(kFlagKIAPrivacyAddon);
// Game_Flag_Set(kFlagZubenRetired);
// Game_Flag_Set(kFlagSpinnerToMA01);
// Set_Enter(kSetMA02_MA04, kSceneMA02);
// Set_Enter(kSetMA02_MA04, kSceneMA04);
// Spinner_Set_Selectable_Destination_Flag(0, true);
// Spinner_Set_Selectable_Destination_Flag(1, true);
@ -70,6 +70,10 @@ void SceneScriptRC01::InitializeScene() {
// ESPER_Flag_To_Activate();
// Voight_Kampff_Activate(kActorLucy, 50);
// Global_Variable_Set(kVariableChapter, 2);
// Chapter_Enter(2, kSetRC03, kSceneRC03);
#endif
if (!Game_Flag_Query(kFlagIntroPlayed)) {

View File

@ -254,7 +254,7 @@ void SceneScriptTB07::sub_401B0C() {
Actor_Set_At_XYZ(kActorTyrell, 68.0f, 12.0f, 288.0f, 0);
Actor_Change_Animation_Mode(kActorTyrell, 0);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, false);
Actor_Start_Speech_Sample(kActorTyrell, 0);
Loop_Actor_Walk_To_XYZ(kActorTyrell, 44.0f, 12.0f, 176.0f, 0, 0, false, 0);
Actor_Face_Actor(kActorTyrell, kActorMcCoy, true);

View File

@ -80,7 +80,7 @@ bool SceneScriptUG01::ClickedOn3DObject(const char *objectName, bool a2) {
if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, -9.0f, -50.13f, -148.0f, 0, 1, false, 0) && !Game_Flag_Query(324)) {
Actor_Says(kActorMcCoy, 8525, 13);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
Game_Flag_Set(324);
} else {
Actor_Says(kActorMcCoy, 8525, 13);

View File

@ -74,7 +74,7 @@ void SceneScriptUG10::SceneLoaded() {
Obstacle_Object("SLUICEGATE_LEVER", true);
if (Global_Variable_Query(kVariableChapter) == 4 && !Game_Flag_Query(474) && Game_Flag_Query(172) && !Game_Flag_Query(693)) {
Scene_Loop_Set_Default(1);
Scene_Loop_Start_Special(kSceneLoopMode2, 6, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 6, true);
Game_Flag_Set(693);
//return true;
}
@ -158,13 +158,13 @@ bool SceneScriptUG10::ClickedOn2DRegion(int region) {
} else if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, 4.98f, 0.38f, 83.15f, 0, 1, false, 0)) {
if (Game_Flag_Query(474)) {
Scene_Loop_Set_Default(1);
Scene_Loop_Start_Special(kSceneLoopMode2, 0, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 0, false);
Game_Flag_Reset(474);
Obstacle_Object("BOX01 BRIDGE", true);
Player_Loses_Control();
} else {
Scene_Loop_Set_Default(4);
Scene_Loop_Start_Special(kSceneLoopMode2, 3, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 3, false);
Game_Flag_Set(474);
Unobstacle_Object("BOX01 BRIDGE", true);
Player_Loses_Control();

View File

@ -87,13 +87,13 @@ bool SceneScriptUG13::ClickedOn3DObject(const char *objectName, bool a2) {
Actor_Face_Object(kActorMcCoy, "BOLLARD", true);
if (Game_Flag_Query(431)) {
Scene_Loop_Set_Default(1);
Scene_Loop_Start_Special(kSceneLoopMode2, 0, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 0, false);
Game_Flag_Reset(431);
Game_Flag_Set(436);
return true;
} else {
Scene_Loop_Set_Default(4);
Scene_Loop_Start_Special(kSceneLoopMode2, 3, false);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 3, false);
Game_Flag_Set(431);
Scene_Exit_Remove(0);
return true;

View File

@ -168,7 +168,7 @@ void SceneScriptUG15::SceneFrameAdvanced(int frame) {
Game_Flag_Set(724);
Game_Flag_Set(682);
Scene_Loop_Set_Default(3);
Scene_Loop_Start_Special(kSceneLoopMode2, 2, true);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 2, true);
Actor_Set_Goal_Number(kActorMcCoy, 390);
Actor_Query_XYZ(kActorFreeSlotA, &x, &y, &z);
if (-200.0f < x && -62.0f > x) {

View File

@ -848,7 +848,7 @@ void ScriptBase::Scene_Loop_Set_Default(int loopId) {
}
void ScriptBase::Scene_Loop_Start_Special(int sceneLoopMode, int loopId, bool immediately) {
if (sceneLoopMode == kSceneLoopModeChangeSet) {
if (sceneLoopMode == kSceneLoopModeOnce) {
immediately = true;
}
_vm->_scene->loopStartSpecial(sceneLoopMode, loopId, immediately);

View File

@ -37,9 +37,7 @@ class SetEffects;
class SceneObjects;
class Set {
#if BLADERUNNER_DEBUG_RENDERING
friend class BladeRunnerEngine;
#endif
friend class Debugger;
struct Object {
char name[20];

View File

@ -26,6 +26,7 @@
#include "bladerunner/ambient_sounds.h"
#include "bladerunner/audio_player.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/debugger.h"
#include "bladerunner/decompress_lcw.h"
#include "bladerunner/font.h"
#include "bladerunner/game_info.h"
@ -577,30 +578,31 @@ void ESPER::draw(Graphics::Surface &surface) {
if (_isDrawingSelection) {
drawSelection(surface, true, 1);
}
#if BLADERUNNER_DEBUG_RENDERING
for (int i = 0; i < kRegionCount; ++i) {
if (_regions[i].isPresent) {
surface.frameRect(
Common::Rect(
viewportXToScreenX(_regions[i].rectInner.left),
viewportYToScreenY(_regions[i].rectInner.top),
viewportXToScreenX(_regions[i].rectInner.right),
viewportYToScreenY(_regions[i].rectInner.bottom)
),
0x7FE0
);
surface.frameRect(
Common::Rect(
viewportXToScreenX(_regions[i].rectOuter.left),
viewportYToScreenY(_regions[i].rectOuter.top),
viewportXToScreenX(_regions[i].rectOuter.right),
viewportYToScreenY(_regions[i].rectOuter.bottom)
),
0x7FE0
);
if (_vm->_debugger->_viewUI) {
for (int i = 0; i < kRegionCount; ++i) {
if (_regions[i].isPresent) {
surface.frameRect(
Common::Rect(
viewportXToScreenX(_regions[i].rectInner.left),
viewportYToScreenY(_regions[i].rectInner.top),
viewportXToScreenX(_regions[i].rectInner.right),
viewportYToScreenY(_regions[i].rectInner.bottom)
),
0x7FE0
);
surface.frameRect(
Common::Rect(
viewportXToScreenX(_regions[i].rectOuter.left),
viewportYToScreenY(_regions[i].rectOuter.top),
viewportXToScreenX(_regions[i].rectOuter.right),
viewportYToScreenY(_regions[i].rectOuter.bottom)
),
0x7FE0
);
}
}
}
#endif
break;
case kEsperPhotoStateScrolling:
scrollUpdate();

View File

@ -23,6 +23,7 @@
#include "bladerunner/ui/ui_image_picker.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/debugger.h"
#include "bladerunner/font.h"
#include "bladerunner/mouse.h"
#include "bladerunner/shape.h"
@ -212,10 +213,11 @@ void UIImagePicker::draw(Graphics::Surface &surface) {
img.shapeUp->draw(surface, img.rect.left, img.rect.top);
}
}
#if BLADERUNNER_DEBUG_RENDERING
surface.frameRect(img.rect, 0x7fff);
_vm->_mainFont->drawColor(Common::String::format("%d", i), surface, (img.rect.left + img.rect.right) / 2, (img.rect.top + img.rect.bottom) / 2, 0x7fff);
#endif
if (_vm->_debugger->_viewUI) {
surface.frameRect(img.rect, 0x7fff);
_vm->_mainFont->drawColor(Common::String::format("%d", i), surface, (img.rect.left + img.rect.right) / 2, (img.rect.top + img.rect.bottom) / 2, 0x7fff);
}
}
}

View File

@ -31,9 +31,8 @@
namespace BladeRunner {
class Waypoints {
#if BLADERUNNER_DEBUG_RENDERING
friend class BladeRunnerEngine;
#endif
friend class Debugger;
struct Waypoint {
int setId;
Vector3 position;