diff options
author | Peter Kohaut | 2018-02-25 19:31:52 +0100 |
---|---|---|
committer | Peter Kohaut | 2018-02-25 22:38:52 +0100 |
commit | 62b75b99908f9cf1ea60bd4dfa415395e80d5c78 (patch) | |
tree | 91f2b2b058252ea4c7d7fe8e8e4a7d71850d7099 /engines | |
parent | 842c67fc34fdc1ff932c8cf70c768e6ad8157038 (diff) | |
download | scummvm-rg350-62b75b99908f9cf1ea60bd4dfa415395e80d5c78.tar.gz scummvm-rg350-62b75b99908f9cf1ea60bd4dfa415395e80d5c78.tar.bz2 scummvm-rg350-62b75b99908f9cf1ea60bd4dfa415395e80d5c78.zip |
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
Diffstat (limited to 'engines')
49 files changed, 2248 insertions, 404 deletions
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 [<set_id> <scene_id>]\n", argv[0]); + return true; + } + + if (argc == 1) { + debugPrintf("set = %i\nscene = %i\n", _vm->_scene->getSetId(), _vm->_scene->getSceneId()); + return true; + } + + if (argc == 3) { + int setId = atoi(argv[1]); + int sceneId = atoi(argv[2]); + _vm->_settings->setNewSetAndScene(setId, sceneId); + } + + return true; +} + +bool Debugger::cmdChapter(int argc, const char **argv) { + if (argc != 2) { + debugPrintf("Usage: %s <chapter>\n", argv[0]); + return true; + } + + int chapter = atoi(argv[1]); + if (chapter >= 1 && chapter <= 5) { + _vm->_settings->setChapter(chapter); + } else { + debugPrintf("Chapter must be between 1 and 5\n"); + } + + return true; +} + +bool Debugger::cmdFlag(int argc, const char **argv) { + if (argc != 2 && argc != 3) { + debugPrintf("Usage: %s <id> [<new_value>]\n", argv[0]); + return true; + } + + int flag = atoi(argv[1]); + int flagCount = _vm->_gameInfo->getFlagCount(); + if (flag > 0 && flag < flagCount) { + if (argc == 3) { + int value = atoi(argv[2]); + if (value == 0) { + _vm->_gameFlags->reset(flag); + } else { + _vm->_gameFlags->set(flag); + } + } + debugPrintf("flag(%i) = %i\n", flag, _vm->_gameFlags->query(flag)); + } else { + debugPrintf("Flag id must be between 0 and %i\n", flagCount - 1); + } + + return true; +} + +bool Debugger::cmdVariable(int argc, const char **argv) { + if (argc != 2 && argc != 3) { + debugPrintf("Usage: %s <id> [<new_value>]\n", argv[0]); + return true; + } + + int variable = atoi(argv[1]); + int variableCount = _vm->_gameInfo->getGlobalVarCount(); + if (variable >= 0 && variable < variableCount) { + if (argc == 3) { + _vm->_gameVars[variable] = atoi(argv[2]); + } + debugPrintf("variable(%i) = %i\n", variable, _vm->_gameVars[variable]); + } else { + debugPrintf("Variable id must be between 0 and %i\n", variableCount - 1); + } + return true; +} + +void Debugger::drawBBox(Vector3 start, Vector3 end, View *view, Graphics::Surface *surface, int color) { + Vector3 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z)); + Vector3 bfr = view->calculateScreenPosition(Vector3(start.x, end.y, start.z)); + Vector3 bbr = view->calculateScreenPosition(Vector3(end.x, end.y, start.z)); + Vector3 bbl = view->calculateScreenPosition(Vector3(end.x, start.y, start.z)); + + Vector3 tfl = view->calculateScreenPosition(Vector3(start.x, start.y, end.z)); + Vector3 tfr = view->calculateScreenPosition(Vector3(start.x, end.y, end.z)); + Vector3 tbr = view->calculateScreenPosition(Vector3(end.x, end.y, end.z)); + Vector3 tbl = view->calculateScreenPosition(Vector3(end.x, start.y, end.z)); + + surface->drawLine(bfl.x, bfl.y, bfr.x, bfr.y, color); + surface->drawLine(bfr.x, bfr.y, bbr.x, bbr.y, color); + surface->drawLine(bbr.x, bbr.y, bbl.x, bbl.y, color); + surface->drawLine(bbl.x, bbl.y, bfl.x, bfl.y, color); + + surface->drawLine(tfl.x, tfl.y, tfr.x, tfr.y, color); + surface->drawLine(tfr.x, tfr.y, tbr.x, tbr.y, color); + surface->drawLine(tbr.x, tbr.y, tbl.x, tbl.y, color); + surface->drawLine(tbl.x, tbl.y, tfl.x, tfl.y, color); + + surface->drawLine(bfl.x, bfl.y, tfl.x, tfl.y, color); + surface->drawLine(bfr.x, bfr.y, tfr.x, tfr.y, color); + surface->drawLine(bbr.x, bbr.y, tbr.x, tbr.y, color); + surface->drawLine(bbl.x, bbl.y, tbl.x, tbl.y, color); +} + +void Debugger::drawSceneObjects() { + //draw scene objects + int count = _vm->_sceneObjects->_count; + if (count > 0) { + for (int i = 0; i < count; i++) { + SceneObjects::SceneObject *sceneObject = &_vm->_sceneObjects->_sceneObjects[_vm->_sceneObjects->_sceneObjectsSortedByDistance[i]]; + + const BoundingBox *bbox = sceneObject->boundingBox; + Vector3 a, b; + bbox->getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z); + Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b)); + int color; + + switch (sceneObject->type) { + case kSceneObjectTypeUnknown: + break; + case kSceneObjectTypeActor: + color = 0x7C00; // 11111 00000 00000; + drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color); + _vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color); + _vm->_mainFont->drawColor(_vm->_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors), _vm->_surfaceFront, pos.x, pos.y, color); + break; + case kSceneObjectTypeItem: + color = 0x03E0; // 00000 11111 00000 + char itemText[40]; + drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color); + sprintf(itemText, "item %i", sceneObject->id - kSceneObjectOffsetItems); + _vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color); + _vm->_mainFont->drawColor(itemText, _vm->_surfaceFront, pos.x, pos.y, color); + break; + case kSceneObjectTypeObject: + color = 0x3DEF; //01111 01111 01111; + //if (sceneObject->_isObstacle) + // color += 0b100000000000000; + if (sceneObject->isClickable) { + color = 0x03E0; // 00000 11111 00000; + } + drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color); + _vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color); + _vm->_mainFont->drawColor(_vm->_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects), _vm->_surfaceFront, pos.x, pos.y, color); + break; + } + } + } + + //draw regions + for (int i = 0; i < 10; i++) { + Regions::Region *region = &_vm->_scene->_regions->_regions[i]; + if (!region->present) continue; + _vm->_surfaceFront.frameRect(region->rectangle, 0x001F); // 00000 00000 11111 + } + + for (int i = 0; i < 10; i++) { + Regions::Region *region = &_vm->_scene->_exits->_regions[i]; + if (!region->present) continue; + _vm->_surfaceFront.frameRect(region->rectangle, 0x7FFF); // 11111 11111 11111 + } + + //draw walkboxes + for (int i = 0; i < _vm->_scene->_set->_walkboxCount; i++) { + Set::Walkbox *walkbox = &_vm->_scene->_set->_walkboxes[i]; + + for (int j = 0; j < walkbox->vertexCount; j++) { + Vector3 start = _vm->_view->calculateScreenPosition(walkbox->vertices[j]); + Vector3 end = _vm->_view->calculateScreenPosition(walkbox->vertices[(j + 1) % walkbox->vertexCount]); + _vm->_surfaceFront.drawLine(start.x, start.y, end.x, end.y, 0x7FE0); // 11111 11111 00000 + Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (start + end)); + _vm->_mainFont->drawColor(walkbox->name, _vm->_surfaceFront, pos.x, pos.y, 0x7FE0); // 11111 11111 00000 + } + } + + // draw lights + for (int i = 0; i < (int)_vm->_lights->_lights.size(); i++) { + Light *light = _vm->_lights->_lights[i]; + Matrix4x3 m = light->_matrix; + m = invertMatrix(m); + //todo do this properly + Vector3 posOrigin = m * Vector3(0.0f, 0.0f, 0.0f); + float t = posOrigin.y; + posOrigin.y = posOrigin.z; + posOrigin.z = -t; + + Vector3 posTarget = m * Vector3(0.0f, 0.0f, -100.0f); + t = posTarget.y; + posTarget.y = posTarget.z; + posTarget.z = -t; + + Vector3 size = Vector3(5.0f, 5.0f, 5.0f); + int colorR = (light->_color.r * 31.0f); + int colorG = (light->_color.g * 31.0f); + int colorB = (light->_color.b * 31.0f); + int color = (colorR << 10) + (colorG << 5) + colorB; + + drawBBox(posOrigin - size, posOrigin + size, _vm->_view, &_vm->_surfaceFront, color); + + Vector3 posOriginT = _vm->_view->calculateScreenPosition(posOrigin); + Vector3 posTargetT = _vm->_view->calculateScreenPosition(posTarget); + _vm->_surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color); + _vm->_mainFont->drawColor(light->_name, _vm->_surfaceFront, posOriginT.x, posOriginT.y, color); + } + + //draw waypoints + for(int i = 0; i < _vm->_waypoints->_count; i++) { + Waypoints::Waypoint *waypoint = &_vm->_waypoints->_waypoints[i]; + if(waypoint->setId != _vm->_scene->getSetId()) + continue; + Vector3 pos = waypoint->position; + Vector3 size = Vector3(5.0f, 5.0f, 5.0f); + int color = 0x7FFF; // 11111 11111 11111 + drawBBox(pos - size, pos + size, _vm->_view, &_vm->_surfaceFront, color); + Vector3 spos = _vm->_view->calculateScreenPosition(pos); + char waypointText[40]; + sprintf(waypointText, "waypoint %i", i); + _vm->_mainFont->drawColor(waypointText, _vm->_surfaceFront, spos.x, spos.y, color); + } + +#if 0 + //draw aesc + for (uint i = 0; i < _screenEffects->_entries.size(); i++) { + ScreenEffects::Entry &entry = _screenEffects->_entries[i]; + int j = 0; + for (int y = 0; y < entry.height; y++) { + for (int x = 0; x < entry.width; x++) { + Common::Rect r((entry.x + x) * 2, (entry.y + y) * 2, (entry.x + x) * 2 + 2, (entry.y + y) * 2 + 2); + + int ec = entry.data[j++]; + Color256 color = entry.palette[ec]; + int bladeToScummVmConstant = 256 / 16; + + Graphics::PixelFormat _pixelFormat = createRGB555(); + int color555 = _pixelFormat.RGBToColor( + CLIP(color.r * bladeToScummVmConstant, 0, 255), + CLIP(color.g * bladeToScummVmConstant, 0, 255), + CLIP(color.b * bladeToScummVmConstant, 0, 255)); + _surfaceFront.fillRect(r, color555); + } + } + } +#endif +} + +} // End of namespace BladeRunner 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; |