From 62b75b99908f9cf1ea60bd4dfa415395e80d5c78 Mon Sep 17 00:00:00 2001 From: Peter Kohaut Date: Sun, 25 Feb 2018 19:31:52 +0100 Subject: 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 --- engines/bladerunner/bladerunner.cpp | 214 ++------- engines/bladerunner/bladerunner.h | 12 +- engines/bladerunner/debugger.cpp | 344 +++++++++++++++ engines/bladerunner/debugger.h | 63 +++ engines/bladerunner/fog.cpp | 174 ++++---- engines/bladerunner/game_constants.h | 7 +- engines/bladerunner/items.cpp | 12 +- engines/bladerunner/light.h | 6 +- engines/bladerunner/lights.h | 2 +- engines/bladerunner/module.mk | 4 + engines/bladerunner/music.cpp | 2 + engines/bladerunner/regions.h | 4 +- engines/bladerunner/scene.cpp | 89 ++-- engines/bladerunner/scene.h | 2 +- engines/bladerunner/scene_objects.cpp | 2 + engines/bladerunner/scene_objects.h | 5 +- engines/bladerunner/script/ai/_template.cpp | 113 +++++ engines/bladerunner/script/ai/generic_walker_a.cpp | 483 +++++++++++++++++++++ engines/bladerunner/script/ai/generic_walker_b.cpp | 458 +++++++++++++++++++ engines/bladerunner/script/ai/generic_walker_c.cpp | 462 ++++++++++++++++++++ engines/bladerunner/script/ai/mccoy.cpp | 2 +- engines/bladerunner/script/ai_script.cpp | 16 +- engines/bladerunner/script/ai_script.h | 33 ++ engines/bladerunner/script/init_script.cpp | 4 +- engines/bladerunner/script/scene/bb02.cpp | 2 +- engines/bladerunner/script/scene/ct02.cpp | 8 +- engines/bladerunner/script/scene/ct12.cpp | 2 +- engines/bladerunner/script/scene/dr04.cpp | 4 +- engines/bladerunner/script/scene/hc03.cpp | 4 +- engines/bladerunner/script/scene/hf04.cpp | 4 +- engines/bladerunner/script/scene/hf05.cpp | 2 +- engines/bladerunner/script/scene/hf06.cpp | 2 +- engines/bladerunner/script/scene/kp03.cpp | 8 +- engines/bladerunner/script/scene/ma05.cpp | 2 +- engines/bladerunner/script/scene/ma06.cpp | 2 +- engines/bladerunner/script/scene/nr08.cpp | 2 +- engines/bladerunner/script/scene/nr10.cpp | 2 +- engines/bladerunner/script/scene/nr11.cpp | 4 +- engines/bladerunner/script/scene/rc01.cpp | 8 +- engines/bladerunner/script/scene/tb07.cpp | 2 +- engines/bladerunner/script/scene/ug01.cpp | 2 +- engines/bladerunner/script/scene/ug10.cpp | 6 +- engines/bladerunner/script/scene/ug13.cpp | 4 +- engines/bladerunner/script/scene/ug15.cpp | 2 +- engines/bladerunner/script/script.cpp | 2 +- engines/bladerunner/set.h | 4 +- engines/bladerunner/ui/esper.cpp | 46 +- engines/bladerunner/ui/ui_image_picker.cpp | 10 +- engines/bladerunner/waypoints.h | 5 +- 49 files changed, 2248 insertions(+), 404 deletions(-) create mode 100644 engines/bladerunner/debugger.cpp create mode 100644 engines/bladerunner/debugger.h create mode 100644 engines/bladerunner/script/ai/_template.cpp create mode 100644 engines/bladerunner/script/ai/generic_walker_a.cpp create mode 100644 engines/bladerunner/script/ai/generic_walker_b.cpp create mode 100644 engines/bladerunner/script/ai/generic_walker_c.cpp diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 7a24f8da06..87f3528fdf 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -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); - } - } - - //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); + if (_debugger->_viewSceneObjects) { + _debugger->drawSceneObjects(); } - //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); } diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 373974f238..88f4cf7197 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -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() { diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp new file mode 100644 index 0000000000..94fb7c538c --- /dev/null +++ b/engines/bladerunner/debugger.cpp @@ -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 [ ]\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 \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 []\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 []\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 diff --git a/engines/bladerunner/debugger.h b/engines/bladerunner/debugger.h new file mode 100644 index 0000000000..47b06d26f8 --- /dev/null +++ b/engines/bladerunner/debugger.h @@ -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 diff --git a/engines/bladerunner/fog.cpp b/engines/bladerunner/fog.cpp index 2befaf3e95..fff27b0558 100644 --- a/engines/bladerunner/fog.cpp +++ b/engines/bladerunner/fog.cpp @@ -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; - - float v149 = this->_parameter1 * 0.5f; - if (v159.x < -v149) { - if (v156.x < -v149) { + Vector3 positionT = _matrix * position; + Vector3 viewPositionT = _matrix * viewPosition; + + 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; - } + 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 (v149 < v146.x) { - if (v149 < v153.x) { + + if (parameter1half < positionTadj.x) { + if (parameter1half < viewPositionTadj.x) { + *coeficient = 0.0f; 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 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; } - float v162 = this->_parameter2 * 0.5f; - if (v146.y < -v162) { - if (v153.y < -v162) { + + float parameter2half = _parameter2 * 0.5f; + if (positionTadj.y < -parameter2half) { + if (viewPositionTadj.y < -parameter2half) { + *coeficient = 0.0f; 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; - } + 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; } - if (v162 < v146.y) { - if (v162 < v153.y) { + + if (parameter2half < positionTadj.y) { + if (parameter2half < viewPositionTadj.y) { + *coeficient = 0.0f; 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 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 <= 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 (0.0f > positionTadj.z) { + if (0.0f > viewPositionTadj.z) { + *coeficient = 0.0f; return; } - float v111 = -v146.z / v150.z; - Vector3 v112 = v111 * v150; - v146 = v146 + v112; + 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 (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; + 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 = this->_inverted * v146; - Vector3 v140 = this->_inverted * v153; + Vector3 v137 = _inverted * positionTadj; + Vector3 v140 = _inverted * viewPositionTadj; Vector3 v143 = v140 - v137; *coeficient = v143.length(); diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h index 032c40cfe1..edc8807b7e 100644 --- a/engines/bladerunner/game_constants.h +++ b/engines/bladerunner/game_constants.h @@ -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 }; diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp index 6360d4a3e8..9d9efd6a38 100644 --- a/engines/bladerunner/items.cpp +++ b/engines/bladerunner/items.cpp @@ -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; } diff --git a/engines/bladerunner/light.h b/engines/bladerunner/light.h index 8ad86368ea..1ef9f3082c 100644 --- a/engines/bladerunner/light.h +++ b/engines/bladerunner/light.h @@ -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; diff --git a/engines/bladerunner/lights.h b/engines/bladerunner/lights.h index ee89fbb5be..376b860234 100644 --- a/engines/bladerunner/lights.h +++ b/engines/bladerunner/lights.h @@ -32,7 +32,7 @@ namespace BladeRunner { class Lights { - friend class BladeRunnerEngine; + friend class Debugger; friend class SliceRendererLights; BladeRunnerEngine *_vm; diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk index eefae18c50..4a929a495a 100644 --- a/engines/bladerunner/module.mk +++ b/engines/bladerunner/module.mk @@ -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 \ diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp index 88fb3e0b55..818d412ba9 100644 --- a/engines/bladerunner/music.cpp +++ b/engines/bladerunner/music.cpp @@ -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; diff --git a/engines/bladerunner/regions.h b/engines/bladerunner/regions.h index 4501f0030c..9868f46ac0 100644 --- a/engines/bladerunner/regions.h +++ b/engines/bladerunner/regions.h @@ -31,9 +31,7 @@ namespace BladeRunner { class Regions { -#if BLADERUNNER_DEBUG_RENDERING - friend class BladeRunnerEngine; -#endif + friend class Debugger; struct Region { Common::Rect rectangle; diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp index c327e80fa7..0a4877e45a 100644 --- a/engines/bladerunner/scene.cpp +++ b/engines/bladerunner/scene.cpp @@ -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(); } } diff --git a/engines/bladerunner/scene.h b/engines/bladerunner/scene.h index 0220bd0098..e0d017556b 100644 --- a/engines/bladerunner/scene.h +++ b/engines/bladerunner/scene.h @@ -42,9 +42,9 @@ class Scene { int _defaultLoop; bool _defaultLoopSet; + bool _defaultLoopPreloadedSet; int _specialLoopMode; int _specialLoop; - bool _specialLoopAtEnd; // int _introFinished; int _nextSetId; int _nextSceneId; diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp index 79c3e0b3af..64cb04f40c 100644 --- a/engines/bladerunner/scene_objects.cpp +++ b/engines/bladerunner/scene_objects.cpp @@ -58,6 +58,8 @@ void SceneObjects::clear() { _sceneObjects[i].isTarget = false; _sceneObjects[i].isMoving = false; _sceneObjects[i].isRetired = false; + + _sceneObjectsSortedByDistance[i] = -1; } _count = 0; } diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h index f0a78da106..dbd61b6dc5 100644 --- a/engines/bladerunner/scene_objects.h +++ b/engines/bladerunner/scene_objects.h @@ -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 { diff --git a/engines/bladerunner/script/ai/_template.cpp b/engines/bladerunner/script/ai/_template.cpp new file mode 100644 index 0000000000..af7c685a72 --- /dev/null +++ b/engines/bladerunner/script/ai/_template.cpp @@ -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 diff --git a/engines/bladerunner/script/ai/generic_walker_a.cpp b/engines/bladerunner/script/ai/generic_walker_a.cpp new file mode 100644 index 0000000000..4bb5b14b47 --- /dev/null +++ b/engines/bladerunner/script/ai/generic_walker_a.cpp @@ -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 diff --git a/engines/bladerunner/script/ai/generic_walker_b.cpp b/engines/bladerunner/script/ai/generic_walker_b.cpp new file mode 100644 index 0000000000..a2ff58113f --- /dev/null +++ b/engines/bladerunner/script/ai/generic_walker_b.cpp @@ -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 diff --git a/engines/bladerunner/script/ai/generic_walker_c.cpp b/engines/bladerunner/script/ai/generic_walker_c.cpp new file mode 100644 index 0000000000..0f86c239ad --- /dev/null +++ b/engines/bladerunner/script/ai/generic_walker_c.cpp @@ -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 diff --git a/engines/bladerunner/script/ai/mccoy.cpp b/engines/bladerunner/script/ai/mccoy.cpp index b38e328fe0..f86a328373 100644 --- a/engines/bladerunner/script/ai/mccoy.cpp +++ b/engines/bladerunner/script/ai/mccoy.cpp @@ -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) { diff --git a/engines/bladerunner/script/ai_script.cpp b/engines/bladerunner/script/ai_script.cpp index 7b211aaa4c..4c03d61d66 100644 --- a/engines/bladerunner/script/ai_script.cpp +++ b/engines/bladerunner/script/ai_script.cpp @@ -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; } } diff --git a/engines/bladerunner/script/ai_script.h b/engines/bladerunner/script/ai_script.h index 066de29445..8577682463 100644 --- a/engines/bladerunner/script/ai_script.h +++ b/engines/bladerunner/script/ai_script.h @@ -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 diff --git a/engines/bladerunner/script/init_script.cpp b/engines/bladerunner/script/init_script.cpp index 2c0b530118..fcb8968e31 100644 --- a/engines/bladerunner/script/init_script.cpp +++ b/engines/bladerunner/script/init_script.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/bb02.cpp b/engines/bladerunner/script/scene/bb02.cpp index a507f4dd67..fed5ee9c0f 100644 --- a/engines/bladerunner/script/scene/bb02.cpp +++ b/engines/bladerunner/script/scene/bb02.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/ct02.cpp b/engines/bladerunner/script/scene/ct02.cpp index e94e0ba719..499ad13695 100644 --- a/engines/bladerunner/script/scene/ct02.cpp +++ b/engines/bladerunner/script/scene/ct02.cpp @@ -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; } diff --git a/engines/bladerunner/script/scene/ct12.cpp b/engines/bladerunner/script/scene/ct12.cpp index e8d3a5b804..5acf2fe898 100644 --- a/engines/bladerunner/script/scene/ct12.cpp +++ b/engines/bladerunner/script/scene/ct12.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/dr04.cpp b/engines/bladerunner/script/scene/dr04.cpp index 81302e4e3f..937fd105b2 100644 --- a/engines/bladerunner/script/scene/dr04.cpp +++ b/engines/bladerunner/script/scene/dr04.cpp @@ -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) { diff --git a/engines/bladerunner/script/scene/hc03.cpp b/engines/bladerunner/script/scene/hc03.cpp index 092fcca70b..7b89fc6652 100644 --- a/engines/bladerunner/script/scene/hc03.cpp +++ b/engines/bladerunner/script/scene/hc03.cpp @@ -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); } } diff --git a/engines/bladerunner/script/scene/hf04.cpp b/engines/bladerunner/script/scene/hf04.cpp index 09a849c781..192d0e92a1 100644 --- a/engines/bladerunner/script/scene/hf04.cpp +++ b/engines/bladerunner/script/scene/hf04.cpp @@ -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; } diff --git a/engines/bladerunner/script/scene/hf05.cpp b/engines/bladerunner/script/scene/hf05.cpp index e98bc8c805..ff497ebbe8 100644 --- a/engines/bladerunner/script/scene/hf05.cpp +++ b/engines/bladerunner/script/scene/hf05.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/hf06.cpp b/engines/bladerunner/script/scene/hf06.cpp index f06e099406..7a41c9eda2 100644 --- a/engines/bladerunner/script/scene/hf06.cpp +++ b/engines/bladerunner/script/scene/hf06.cpp @@ -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(); diff --git a/engines/bladerunner/script/scene/kp03.cpp b/engines/bladerunner/script/scene/kp03.cpp index bb8c005240..cb96e8bfe3 100644 --- a/engines/bladerunner/script/scene/kp03.cpp +++ b/engines/bladerunner/script/scene/kp03.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/ma05.cpp b/engines/bladerunner/script/scene/ma05.cpp index 519f43e30b..a10086168c 100644 --- a/engines/bladerunner/script/scene/ma05.cpp +++ b/engines/bladerunner/script/scene/ma05.cpp @@ -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)) { diff --git a/engines/bladerunner/script/scene/ma06.cpp b/engines/bladerunner/script/scene/ma06.cpp index 3f385271e8..cf69ded5f3 100644 --- a/engines/bladerunner/script/scene/ma06.cpp +++ b/engines/bladerunner/script/scene/ma06.cpp @@ -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) { diff --git a/engines/bladerunner/script/scene/nr08.cpp b/engines/bladerunner/script/scene/nr08.cpp index ef54702191..9af74908eb 100644 --- a/engines/bladerunner/script/scene/nr08.cpp +++ b/engines/bladerunner/script/scene/nr08.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/nr10.cpp b/engines/bladerunner/script/scene/nr10.cpp index c3f7bd85a7..f580463187 100644 --- a/engines/bladerunner/script/scene/nr10.cpp +++ b/engines/bladerunner/script/scene/nr10.cpp @@ -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; diff --git a/engines/bladerunner/script/scene/nr11.cpp b/engines/bladerunner/script/scene/nr11.cpp index 20a1706704..95ef4b7d84 100644 --- a/engines/bladerunner/script/scene/nr11.cpp +++ b/engines/bladerunner/script/scene/nr11.cpp @@ -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) { diff --git a/engines/bladerunner/script/scene/rc01.cpp b/engines/bladerunner/script/scene/rc01.cpp index 11eb28ee86..83d12d0f39 100644 --- a/engines/bladerunner/script/scene/rc01.cpp +++ b/engines/bladerunner/script/scene/rc01.cpp @@ -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)) { diff --git a/engines/bladerunner/script/scene/tb07.cpp b/engines/bladerunner/script/scene/tb07.cpp index 21041fdd72..b45bc1e794 100644 --- a/engines/bladerunner/script/scene/tb07.cpp +++ b/engines/bladerunner/script/scene/tb07.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/ug01.cpp b/engines/bladerunner/script/scene/ug01.cpp index 8c60aabd38..138f962cfc 100644 --- a/engines/bladerunner/script/scene/ug01.cpp +++ b/engines/bladerunner/script/scene/ug01.cpp @@ -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); diff --git a/engines/bladerunner/script/scene/ug10.cpp b/engines/bladerunner/script/scene/ug10.cpp index 123693d8ef..bca6765e8f 100644 --- a/engines/bladerunner/script/scene/ug10.cpp +++ b/engines/bladerunner/script/scene/ug10.cpp @@ -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(); diff --git a/engines/bladerunner/script/scene/ug13.cpp b/engines/bladerunner/script/scene/ug13.cpp index 09e33e8b1e..cdfa8ad806 100644 --- a/engines/bladerunner/script/scene/ug13.cpp +++ b/engines/bladerunner/script/scene/ug13.cpp @@ -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; diff --git a/engines/bladerunner/script/scene/ug15.cpp b/engines/bladerunner/script/scene/ug15.cpp index 760e9c42f8..8477e5b46f 100644 --- a/engines/bladerunner/script/scene/ug15.cpp +++ b/engines/bladerunner/script/scene/ug15.cpp @@ -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) { diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp index f88f330e2f..b7b6e477d8 100644 --- a/engines/bladerunner/script/script.cpp +++ b/engines/bladerunner/script/script.cpp @@ -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); diff --git a/engines/bladerunner/set.h b/engines/bladerunner/set.h index a6779d4225..a6e7e9f3df 100644 --- a/engines/bladerunner/set.h +++ b/engines/bladerunner/set.h @@ -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]; diff --git a/engines/bladerunner/ui/esper.cpp b/engines/bladerunner/ui/esper.cpp index 79b8f5d3ac..181ef0f5d1 100644 --- a/engines/bladerunner/ui/esper.cpp +++ b/engines/bladerunner/ui/esper.cpp @@ -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(); diff --git a/engines/bladerunner/ui/ui_image_picker.cpp b/engines/bladerunner/ui/ui_image_picker.cpp index 5cee12fef8..0e00bf0484 100644 --- a/engines/bladerunner/ui/ui_image_picker.cpp +++ b/engines/bladerunner/ui/ui_image_picker.cpp @@ -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); + } } } diff --git a/engines/bladerunner/waypoints.h b/engines/bladerunner/waypoints.h index 9977b71243..826f8f5a94 100644 --- a/engines/bladerunner/waypoints.h +++ b/engines/bladerunner/waypoints.h @@ -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; -- cgit v1.2.3