/* 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 3 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, see . * */ #include "darkseed/darkseed.h" #include "darkseed/animation.h" namespace Darkseed { void Animation::setupOtherNspAnimation(int nspAnimIdx, int animId) { assert(nspAnimIdx < 20); _player->_playerIsChangingDirection = false; _nsp_sprite_scaling_y_position = 0; _scaleSequence = false; _animIndexTbl[nspAnimIdx] = 0; if (_player->_animations.getTotalAnim() > nspAnimIdx) { _spriteAnimCountdownTimer[nspAnimIdx] = _player->_animations.getAnimAt(nspAnimIdx)._frameDuration[0]; _player->_frameIdx = _player->_animations.getAnimAt(nspAnimIdx)._frameNo[0]; } else { _spriteAnimCountdownTimer[nspAnimIdx] = 0; _player->_frameIdx = 0; } _isPlayingAnimation_maybe = true; _otherNspAnimationType_maybe = animId; g_engine->_player->_flipSprite = false; _objRestarted = false; if (_otherNspAnimationType_maybe < 2) { return; } // TODO big switch here to init the different animation types. switch (_otherNspAnimationType_maybe) { case 2: _player->_position.x = 188; _player->_position.y = 94; break; case 3: if (g_engine->_currentDay == 3) { g_engine->_sound->playMusic(MusicId::kDth); g_engine->playSound(0,6,-1); } _scaleSequence = true; break; case 4: case 14: case 15: case 18: case 21: case 22: case 24: case 25: case 65: _scaleSequence = true; break; case 6: // stairs _nsp_sprite_scaling_y_position = 0xbe; _scaleSequence = true; break; case 7: // stairs down _nsp_sprite_scaling_y_position = 0xbe; _scaleSequence = true; _player->_walkTarget.x -= 60; break; case 8: _player->_position.x = 249; _player->_position.y = 92; break; case 16: _player->_position.x = 324; _player->_position.y = 50; break; case 19: case 23: _scaleSequence = true; _player->_frameIdx = 24; break; case 20: _spriteAnimCountdownTimer[3] = 3; break; case 26 : _player->_position.x = 324; _player->_position.y = 135; break; case 27 : _player->_position.x = 397; _player->_position.y = 84; break; case 28 : _player->_position.x = 397; _player->_position.y = 77; break; case 39: case 47: _scaleSequence = true; _player->_frameIdx = g_engine->_room->_locationSprites.getAnimAt(nspAnimIdx)._frameNo[0]; break; case 41 : case 42 : _player->_position.x = 432; _player->_position.y = 78; break; case 44: case 46: g_engine->playSound(30, 5, -1); break; case 53 : case 54 : _player->_position.x = 308; _player->_position.y = 160; break; case 55 : _player->_position.x = 150; _player->_position.y = 104; break; case 56 : _player->_position.x = 142; _player->_position.y = 104; break; case 57: case 58: g_engine->playSound(48, 5, -1); break; case 63: _player->_position.x = 249; _player->_position.y = 92; g_engine->_phoneStatus = 1; break; default: break; } } void Animation::updateAnimation() { int currentRoomNumber = g_engine->_room->_roomNumber; switch (_otherNspAnimationType_maybe) { case 0: break; case 1: // sleep wake anim advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->_position.x = 0xdf; _player->_position.y = 0xbe; _player->_walkTarget.x = 0xdf; _player->_walkTarget.y = 0xbe; _player->updateSprite(); } break; case 2: // shower advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->_position.x = 218; _player->_position.y = 198; _player->_direction = 2; _player->updateSprite(); _player->_walkTarget.x = 218; _player->_walkTarget.y = 198; _objectVar[52] = 0; g_engine->_sound->stopSfx(); } break; case 3: advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { if (g_engine->_room->isGiger()) { stuffPlayer(); } else { if (g_engine->_room->isOutside() && g_engine->_currentTimeInSeconds > 61200) { g_engine->_room->restorePalette(); } g_engine->gotoNextMorning(); g_engine->playDayChangeCutscene(); } } break; case 4: case 21: case 22: // dig up grave advanceAnimationFrame(0); if (_player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]] % 5 == 3 && _player->_animations.getAnimAt(0)._frameDuration[_animIndexTbl[0]] == _spriteAnimCountdownTimer[0]) { g_engine->playSound(14, 5, -1); } if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _isPlayingAnimation_maybe = false; _objectVar[52] = 1; if (_otherNspAnimationType_maybe == 21 && _objectVar[151] != 0) { if (_objectVar[87] == 0) { _objectVar[88] = 1; _objectVar[87] = 1; g_engine->_console->printTosText(581); g_engine->_inventory.addItem(29); } else { g_engine->_console->printTosText(582); } } else { _objectVar[88] = 1; g_engine->_console->printTosText(580); } } break; case 5: // goto sleep animation _player->_position.x = 135; _player->_position.y = 91; advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { g_engine->gotoNextMorning(); // TODO there might be some extra logic required from original function _player->_position.x = 242; _player->_position.y = 187; g_engine->playDayChangeCutscene(); } _player->_position.x = 242; _player->_position.y = 187; break; case 6: // stairs up if (currentRoomNumber == 6) { advanceAnimationFrame(1); } else { advanceAnimationFrame(2); } if (_frameAdvanced && ((currentRoomNumber == 6 && _animIndexTbl[1] == 1) || (currentRoomNumber == 5 && _animIndexTbl[2] == 1))) { // FUN_1208_0dacg_engine->_sound_related(0xd,CONCAT11(uVar4,5)); g_engine->playSound(4, 5, -1); } if (!_objRestarted) { if (currentRoomNumber == 6) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { _player->_frameIdx = _player->_animations.getAnimAt(2)._frameNo[_animIndexTbl[2]]; } } else { if (currentRoomNumber == 6) { g_engine->_previousRoomNumber = 6; g_engine->changeToRoom(5); } if (_player->_isAutoWalkingToBed) { _player->setPlayerTowardsBedroom(); } } break; case 7: // stairs down if (currentRoomNumber == 5) { advanceAnimationFrame(3); if (_frameAdvanced && _animIndexTbl[3] == 1) { // FUN_1208_0dacg_engine->_sound_related(0xd,CONCAT11(extraout_AH_05,5)); g_engine->playSound(4, 5, -1); } if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(3)._frameNo[_animIndexTbl[3]]; } else { g_engine->_previousRoomNumber = 5; g_engine->changeToRoom(6); } } else { advanceAnimationFrame(0); if (_frameAdvanced && _animIndexTbl[0] == 1) { // FUN_1208_0dacg_engine->_sound_related(0xd,CONCAT11(extraout_AH_05,5)); g_engine->playSound(4, 5, -1); } if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } } break; case 8: //phone call case 63: if (_otherNspAnimationType_maybe == 8) { advanceAnimationFrame(0); } else { advanceAnimationFrame(2); if (g_engine->_phoneStatus == 1) { g_engine->_phoneStatus = 2; } } if (!_objRestarted) { if (_otherNspAnimationType_maybe == 8) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->_frameIdx = _player->_animations.getAnimAt(2)._frameNo[_animIndexTbl[2]]; } } else { if (_otherNspAnimationType_maybe == 63) { g_engine->_console->printTosText(44); setupOtherNspAnimation(1, 64); } else { _objectVar.setObjectRunningCode(47, 0); if (g_engine->_currentDay == 1) { g_engine->_console->printTosText(904); _objectVar[47] = 1; _objectVar[46] = 1; } else { _objectVar[51] = 2; _objectVar[47] = 1; g_engine->_console->printTosText(922); } g_engine->waitForSpeech(); setupOtherNspAnimation(1, 9); } } break; case 9: // hang up phone case 64: advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { _player->_position.x = 300; _player->_position.y = 183; _player->_walkTarget.x = 300; _player->_walkTarget.y = 183; _player->_direction = 3; _player->updateSprite(); } break; case 11: advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { _player->_position.x = 175; _player->_position.y = 200; _player->_walkTarget.x = 175; _player->_walkTarget.y = 200; _player->updateSprite(); if (_player->_isAutoWalkingToBed) { _player->setPlayerTowardsBedroom(); } } break; case 12: // rt ladder climb up advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->_position.x = 360; _player->_position.y = 238; _player->_walkTarget.x = 360; _player->_walkTarget.y = 238; _player->_direction = 3; g_engine->changeToRoom(2); } break; case 13: advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { _player->_position.x = 450; _player->_position.y = 217; _player->_walkTarget.x = 450; _player->_walkTarget.y = 217; _player->_direction = 3; _player->updateSprite(); } break; case 16: // climb down rope advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->_position.x = 336; _player->_position.y = 195; _player->_walkTarget.x = 336; _player->_walkTarget.y = 195; _player->_direction = 1; _player->updateSprite(); } break; case 17: // open trunk with crowbar advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } if (_animIndexTbl[0] == 5 && _frameAdvanced) { g_engine->playSound(31, 5, -1); g_engine->_console->printTosText(666); if (_objectVar[42] == 0) { _objectVar[42] = 1; } else { _objectVar[42] = 3; } } break; case 18: // push trunk advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } if (_player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]] == 3 && _frameAdvanced) { g_engine->_console->printTosText(_objectVar[22] + 662); _objectVar[22] = _objectVar[22] + 1; if (_objectVar[22] == 3) { g_engine->_room->loadRoom61AWalkableLocations(); } } break; case 19: // pickup book from library _player->_frameIdx = 24; if (_objRestarted) { _isPlayingAnimation_maybe = true; _objectVar[46] = 2; libAnim(true); } break; case 20: // receive card from delbert advanceAnimationFrame(3); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(3)._frameNo[_animIndexTbl[3]]; } else { g_engine->_inventory.addItem(18); } break; case 23: _player->_frameIdx = 24; if (_objRestarted != 0) { _isPlayingAnimation_maybe = false; _objectVar[99] = 1; g_engine->_console->printTosText(468); } break; case 10: // climb ladder left advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(61); } break; case 14: case 15: case 24: case 25: // Open doors advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->updateSprite(); if (_otherNspAnimationType_maybe == 14) { if (_objectVar.getObjectRunningCode(140) == 0 || g_engine->_room->_roomNumber != 6) { g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; int newRoomNumber; if (g_engine->_room->_roomNumber == 6) { if (_player->_isAutoWalkingToBed && _objectVar[137] == 2) { wonGame(); return; } newRoomNumber = 10; } else if (g_engine->_room->_roomNumber == 10) { newRoomNumber = 6; } else if (g_engine->_room->_roomNumber == 11) { if (_player->_position.x < 250) { newRoomNumber = 15; } else { newRoomNumber = 16; } } else { newRoomNumber = 17; } g_engine->changeToRoom(newRoomNumber); } else { _objectVar.setObjectRunningCode(140, 0); g_engine->getPackageObj(g_engine->_currentDay); } } if (_otherNspAnimationType_maybe == 25) { g_engine->_previousRoomNumber = 33; g_engine->changeToRoom(34); } } break; case 26: // climb up rope. advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(13); } break; case 27: // enter mirror from normal world advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(38); } break; case 28: // step out of mirror normal world advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { _player->_position.x = 418; _player->_position.y = 170; _player->_direction = 3; _player->updateSprite(); _player->_walkTarget = _player->_position; } break; case 30: case 31: { int animIdx = _otherNspAnimationType_maybe - 30; advanceAnimationFrame(animIdx); if (_isPlayingAnimation_maybe) { _player->_frameIdx = _player->_animations.getAnimAt(animIdx)._frameNo[_animIndexTbl[animIdx]]; } if (_objRestarted && _otherNspAnimationType_maybe == 30) { setupOtherNspAnimation(1, 31); } break; } case 32: case 33: case 34: { // Take medicine from cabinet _objectVar[112] = 1; int animIdx = _otherNspAnimationType_maybe - 30; advanceAnimationFrame(animIdx); if (_frameAdvanced) { if (_otherNspAnimationType_maybe == 33) { if (_animIndexTbl[animIdx] == 12) { g_engine->playSound(35, 5, -1); // water } } else if (_otherNspAnimationType_maybe == 32) { if (_animIndexTbl[animIdx] == 1 || _animIndexTbl[animIdx] == 18) { g_engine->playSound(34, 5, -1); // open / close cabinet } } } if (_isPlayingAnimation_maybe) { _player->_frameIdx = _player->_animations.getAnimAt(animIdx)._frameNo[_animIndexTbl[animIdx]]; } if (_objRestarted && (_otherNspAnimationType_maybe == 32 || _otherNspAnimationType_maybe == 33)) { setupOtherNspAnimation(_otherNspAnimationType_maybe - 29, _otherNspAnimationType_maybe + 1); } break; } case 35: // pay shopkeeper advanceAnimationFrame(6); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(6)._frameNo[_animIndexTbl[6]]; } else { _objectVar[8]++; if (_objectVar[8] > 2) { g_engine->_inventory.removeItem(8); } _objectVar[138]++; g_engine->_console->printTosText(927); } break; case 36: case 37: // smash mirror advanceAnimationFrame(_otherNspAnimationType_maybe - 36); _player->_frameIdx = _player->_animations.getAnimAt(_otherNspAnimationType_maybe - 36)._frameNo[_animIndexTbl[_otherNspAnimationType_maybe - 36]]; if (_frameAdvanced && _otherNspAnimationType_maybe == 36 && _player->_frameIdx == 4) { g_engine->playSound(28, 5, -1); } if (_objRestarted) { if (_otherNspAnimationType_maybe == 36) { setupOtherNspAnimation(1, 37); } else { _objectVar[137] = 2; _player->_isAutoWalkingToBed = true; _player->setPlayerTowardsBedroom(); } } break; case 38: advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { stuffPlayer(); } break; case 39: // Arrest Mike. g_engine->_room->advanceFrame(1); if (!_objRestarted) { _player->_frameIdx = g_engine->_room->_locationSprites.getAnimAt(1)._frameNo[g_engine->_room->_locObjFrame[1]]; } else { g_engine->throwmikeinjail(); } break; case 40: // give Delbert's card to cop. advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { g_engine->_console->printTosText(61); g_engine->_console->draw(); g_engine->_screen->updateScreen(); g_engine->waitxticks(60); g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; _player->_position.x = 240; _player->_position.y = 200; _player->updateSprite(); _isPlayingAnimation_maybe = false; g_engine->changeToRoom(15, true); g_engine->_inventory.removeItem(41); g_engine->_inventory.removeItem(18); _objectVar.setMoveObjectRoom(41, 255); } break; case 41: advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(7); } break; case 42: // step out of mirror giger world advanceAnimationFrame(1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(1)._frameNo[_animIndexTbl[1]]; } else { _player->_position.x = 456; _player->_position.y = 173; _player->_direction = 3; _player->updateSprite(); _player->_walkTarget = _player->_position; } break; case 43: case 44: case 45: case 46: { // pull lever int iVar4 = 0; if ((_otherNspAnimationType_maybe == 44) || (_otherNspAnimationType_maybe == 46)) { iVar4 = 1; } advanceAnimationFrame(iVar4); _player->_frameIdx = _player->_animations.getAnimAt(iVar4)._frameNo[_animIndexTbl[iVar4]]; // _HeroSpr = (uint) * (byte *)((int)&DAT_1060_7eb8 + *(int *)((int)&_ObjFrame + iVar4 * 2) + iVar4 * 202); if (_frameAdvanced && _animIndexTbl[iVar4] == 3) { // TODO should we add this conditionally? This logic was missing from the original game. I assume they just forgot to add the sfx. g_engine->playSound(8, 5, -1); // pull lever sound. } if (!_objRestarted || (_otherNspAnimationType_maybe != 46 && _otherNspAnimationType_maybe != 44)) { if (_otherNspAnimationType_maybe == 45) { _objectVar[117] = 1; } else if (_objRestarted) { if ((_objectVar[71] == 2) && (_objectVar[44] != 0)) { g_engine->_console->printTosText(896); _objectVar[57] = 1; } else { g_engine->_console->printTosText(897); } } } else { g_engine->_sound->playMusic(MusicId::kDth); g_engine->playSound(0, 6, -1); stuffPlayer(); } break; } case 47: g_engine->_room->mikeStickThrowAnim(); break; case 48: case 49: case 50: case 51: case 52: // open/close cupboards, oven advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { if (_otherNspAnimationType_maybe == 52) { _objectVar[108] = (_objectVar[108] == 0) ? 1 : 0; } else { _objectVar[56 + _otherNspAnimationType_maybe] = _objectVar[56 + _otherNspAnimationType_maybe] == 0 ? 1 : 0; } g_engine->playSound(42, 5, -1); } break; case 53: case 54: case 55: case 56: { int stairsIdx = (_otherNspAnimationType_maybe - 53) & 1; advanceAnimationFrame(stairsIdx); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(stairsIdx)._frameNo[_animIndexTbl[stairsIdx]]; } else { switch (_otherNspAnimationType_maybe) { case 53: g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(6); break; case 54: _player->_position.x = 322; _player->_position.y = 220; _player->_walkTarget = _player->_position; _player->_direction = 2; _player->updateSprite(); break; case 55: g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(15); break; case 56: _player->_position.x = 162; _player->_position.y = 206; _player->_walkTarget = _player->_position; _player->_direction = 2; _player->updateSprite(); break; default: break; } } if (_otherNspAnimationType_maybe == 55 && _frameAdvanced && _animIndexTbl[stairsIdx] == 4) { // FUN_1208_0dacg_engine->_sound_related(0xd,CONCAT11(extraout_AH_05,5)); g_engine->playSound(1, 5, -1); //open door to police station } break; } case 57: case 58: advanceAnimationFrame((_otherNspAnimationType_maybe - 57) & 1); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else if (_otherNspAnimationType_maybe == 57) { g_engine->_previousRoomNumber = g_engine->_room->_roomNumber; g_engine->changeToRoom(g_engine->_room->_roomNumber == 41 ? 44 : 41); } else { _player->_direction = 2; } break; case 59: // use shard on mirror advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->_direction = 1; _player->updateSprite(); } if (_frameAdvanced && _player->_frameIdx == 3) { g_engine->playSound(26, 5, -1); } break; case 60: // turn on alien computer g_engine->_room->advanceFrame(0); if (!_objRestarted) { _player->_frameIdx = g_engine->_room->_locationSprites.getAnimAt(0)._frameNo[g_engine->_room->_locObjFrame[0]]; } else { _isPlayingAnimation_maybe = false; _objectVar[187] = 1; } break; case 61: // turn off alien computer g_engine->_room->advanceFrame(1); if (!_objRestarted) { _player->_frameIdx = g_engine->_room->_locationSprites.getAnimAt(1)._frameNo[g_engine->_room->_locObjFrame[1]]; } else { _isPlayingAnimation_maybe = false; } _objectVar[187] = 0; break; case 62: // bang cup against bars advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { bool bVar5 = _objectVar.getMoveObjectRoom(18) == 250; if (!bVar5) { if (g_engine->_inventory.hasObject(18)) { bVar5 = true; } } if (bVar5) { _isPlayingAnimation_maybe = false; _objectVar.setObjectRunningCode(53, 1); _player->loadAnimations("copcard.nsp"); _animIndexTbl[0] = 0; _spriteAnimCountdownTimer[0] = 3; _objectVar[1] = 2000; } else { g_engine->_console->addI18NText(kI18N_TheCopsIgnoreYourDemandsText); } } if (_frameAdvanced && _player->_frameIdx == 1) { g_engine->playSound(22, 5, -1); } break; case 65: advanceAnimationFrame(0); if (!_objRestarted) { _player->_frameIdx = _player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]; } else { _player->updateSprite(); } break; default: error("Unhandled animation type! %d", _otherNspAnimationType_maybe); } } void Animation::advanceAnimationFrame(int nspAminIdx) { if (!_scaleSequence) { g_engine->_scaledWalkSpeed_maybe = 1000; } else { g_engine->_room->calculateScaledSpriteDimensions(10, 10, _player->_position.y); } _objRestarted = false; _frameAdvanced = false; const Obt &anim = _player->_animations.getAnimAt(nspAminIdx); _spriteAnimCountdownTimer[nspAminIdx] = _spriteAnimCountdownTimer[nspAminIdx] - 1; if (_spriteAnimCountdownTimer[nspAminIdx] < 1) { _frameAdvanced = true; _animIndexTbl[nspAminIdx] = _animIndexTbl[nspAminIdx] + 1; _player->_position.x += ((int16)anim._deltaX[_animIndexTbl[nspAminIdx]] * g_engine->_scaledWalkSpeed_maybe) / 1000; _player->_position.y += ((int16)anim._deltaY[_animIndexTbl[nspAminIdx]] * g_engine->_scaledWalkSpeed_maybe) / 1000; if (_animIndexTbl[nspAminIdx] == anim._numFrames) { _animIndexTbl[nspAminIdx] = 0; _objRestarted = true; _isPlayingAnimation_maybe = false; _player->_walkTarget.x = _player->_position.x; _player->_walkTarget.y = _player->_position.y; _player->updateSprite(); } _spriteAnimCountdownTimer[nspAminIdx] = anim._frameDuration[_animIndexTbl[nspAminIdx]]; } } static constexpr uint8 dcopList[100] = { 0, 1, 2, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 2, 1, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 2, 1, 2, 1, 2, 3, 2, 1, 0, 1, 2, 1, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 2, 1, 2, 1, 2, 3, 2, 1, 0, 1, 2, 1, 2, 1, 2, 3, 2, 1 }; void Animation::dCopAnim() { _player->loadAnimations("dcopb.nsp"); g_engine->showFullscreenPic("dcopb.pic"); _animIndexTbl[0] = 0; _spriteAnimCountdownTimer[0] = _player->_animations.getAnimAt(0)._frameDuration[0]; g_engine->_sprites.clearSpriteDrawList(); g_engine->_console->printTosText(923); uint8 lipsIdx = 0; while (g_engine->_sound->isPlayingSpeech()) { g_engine->_sprites.clearSpriteDrawList(); g_engine->drawFullscreenPic(); advanceAnimationFrame(0); const Sprite &dcopSprite = _player->_animations.getSpriteAt(dcopList[lipsIdx]); g_engine->_sprites.addSpriteToDrawList(310, 180, &dcopSprite, 255, dcopSprite._width, dcopSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_console->draw(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); lipsIdx++; if (lipsIdx == 100) { lipsIdx = 0; } for (int i = 0; i < 6; i++) { g_engine->wait(); } } g_engine->removeFullscreenPic(); } static constexpr uint8 sargoList[100] = { 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 2, 3, 4, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 4, 3, 2, 1, 1, 2, 3, 4, 3, 2, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 1, 2, 1, 0, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 3, 2, 1, 1 }; void Animation::sargoAnim() { g_engine->_cursor.showCursor(false); _player->loadAnimations("sargo.nsp"); g_engine->showFullscreenPic("sargo.pic"); _animIndexTbl[0] = 0; _spriteAnimCountdownTimer[0] = _player->_animations.getAnimAt(0)._frameDuration[0]; g_engine->_console->printTosText(916); uint8 dialogIdx = 79; uint8 lipsIdx = 0; while (g_engine->_sound->isPlayingSpeech() || dialogIdx < 81) { g_engine->_sprites.clearSpriteDrawList(); g_engine->drawFullscreenPic(); advanceAnimationFrame(0); const Sprite &sargoSprite = _player->_animations.getSpriteAt(sargoList[lipsIdx]); g_engine->_sprites.addSpriteToDrawList(334, 160, &sargoSprite, 255, sargoSprite._width, sargoSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_console->draw(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); lipsIdx++; if (lipsIdx == 100) { lipsIdx = 0; } if (!g_engine->_sound->isPlayingSpeech()) { dialogIdx++; if (dialogIdx == 80) { g_engine->_console->printTosText(917); } } g_engine->waitxticks(1); } g_engine->removeFullscreenPic(); g_engine->_cursor.showCursor(true); } void Animation::gancAnim() { g_engine->_cursor.showCursor(false); _player->loadAnimations("ganc.nsp"); g_engine->showFullscreenPic("ganc.pic"); _animIndexTbl[0] = 0; _spriteAnimCountdownTimer[0] = _player->_animations.getAnimAt(0)._frameDuration[0]; g_engine->_sound->playMusic(MusicId::kDth); g_engine->playSound(0, 6, -1); g_engine->_console->printTosText(0); g_engine->_console->draw(); while (!_objRestarted) { g_engine->_sprites.clearSpriteDrawList(); g_engine->drawFullscreenPic(); advanceAnimationFrame(0); const Sprite &sargoSprite = _player->_animations.getSpriteAt(_player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]); g_engine->_sprites.addSpriteToDrawList(303, 122, &sargoSprite, 255, sargoSprite._width, sargoSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); g_system->delayMillis(20); } g_engine->removeFullscreenPic(); g_engine->_cursor.showCursor(true); stuffPlayer(); } static constexpr uint8 keeperList[250] = { 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 10, 11, 11, 12, 12, 11, 12, 12, 13, 12, 12, 12, 13, 13, 12, 13, 12, 11, 12, 13, 12, 11, 10, 11, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 11, 12, 12, 13, 12, 12, 12, 13, 13, 12, 13, 12, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 10, 11, 11, 12, 12, 11, 12, 12, 13, 12, 12, 12, 13, 13, 12, 13, 12, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 10, 10, 11, 11, 12, 12, 11, 12, 12, 13, 12, 12, 12, 13, 13, 12, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 12, 12, 13, 10, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void Animation::keeperAdmin() { g_engine->_cursor.showCursor(false); _player->loadAnimations("keeper.nsp"); g_engine->showFullscreenPic("keeper.pic"); _animIndexTbl[0] = 0; _spriteAnimCountdownTimer[0] = _player->_animations.getAnimAt(0)._frameDuration[0]; g_engine->_console->printTosText(913); uint8 dialogIdx = 73; uint8 lipsIdx = 0; while (g_engine->_sound->isPlayingSpeech() || dialogIdx < 76) { g_engine->_sprites.clearSpriteDrawList(); g_engine->drawFullscreenPic(); advanceAnimationFrame(0); const Sprite &keeperSprite = _player->_animations.getSpriteAt(keeperList[lipsIdx]); g_engine->_sprites.addSpriteToDrawList(254, 117, &keeperSprite, 255, keeperSprite._width, keeperSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_console->draw(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); lipsIdx++; if (lipsIdx == 250) { lipsIdx = 0; } if (!g_engine->_sound->isPlayingSpeech()) { dialogIdx++; if (dialogIdx == 74) { g_engine->_console->printTosText(914); } else if (dialogIdx == 75) { g_engine->_console->printTosText(915); } } g_engine->waitxticks(1); } g_engine->removeFullscreenPic(); g_engine->_cursor.showCursor(true); } void Animation::stuffPlayer() { g_engine->_cursor.showCursor(false); _player->loadAnimations("labparts.nsp"); g_engine->showFullscreenPic("lab.pic"); const Sprite &alienSprite = _player->_animations.getSpriteAt(8); bool updateCounter = false; int counter = 0; while (counter < 8) { g_engine->_sprites.clearSpriteDrawList(); g_engine->drawFullscreenPic(); const Sprite &mikeSprite = _player->_animations.getSpriteAt(counter); g_engine->_sprites.addSpriteToDrawList(103, 93, &mikeSprite, 255, mikeSprite._width, mikeSprite._height, false); g_engine->_sprites.addSpriteToDrawList(226, 100, &alienSprite, 255, alienSprite._width, alienSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_console->draw(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); updateCounter = !updateCounter; if (updateCounter) { counter++; } g_engine->waitxticks(1); } g_engine->waitxticks(3); g_engine->removeFullscreenPic(); g_engine->_sprites.clearSpriteDrawList(); g_engine->_cursor.showCursor(true); g_engine->_cutscene.play('Z'); g_engine->_sound->stopMusic(); } void Animation::runDrekethSequence() { bool updateCounter = false; int counter = 0; if (!g_engine->isCdVersion()) { g_engine->_sound->playMusic(MusicId::kDth); } g_engine->_console->printTosText(2); g_engine->_console->draw(); while (counter < 6) { g_engine->_sprites.clearSpriteDrawList(); const Sprite &drekethBaseSprite = g_engine->_room->_locationSprites.getSpriteAt(15); const Sprite &openingAnimation = g_engine->_room->_locationSprites.getSpriteAt(counter); g_engine->_sprites.addSpriteToDrawList(346, 133, &drekethBaseSprite, 255, drekethBaseSprite._width, drekethBaseSprite._height, false); g_engine->_sprites.addSpriteToDrawList(395, 133, &openingAnimation, 255, openingAnimation._width, openingAnimation._height, false); adddrekbutt(); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); updateCounter = !updateCounter; if (updateCounter) { counter++; } g_engine->waitxticks(1); } while (counter < 9) { g_engine->_sprites.clearSpriteDrawList(); const Sprite &grabMikeSprite = g_engine->_room->_locationSprites.getSpriteAt(counter); g_engine->_sprites.addSpriteToDrawList(346, 133, &grabMikeSprite, 255, grabMikeSprite._width, grabMikeSprite._height, false); adddrekbutt(); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); updateCounter = !updateCounter; if (updateCounter) { counter++; if (counter == 7) { g_engine->playSound(19, 5, -1); } } g_engine->waitxticks(1); } while (counter < 13) { g_engine->_sprites.clearSpriteDrawList(); const Sprite &drekethBaseSprite = g_engine->_room->_locationSprites.getSpriteAt(14); const Sprite &closingAnimation = g_engine->_room->_locationSprites.getSpriteAt(counter); g_engine->_sprites.addSpriteToDrawList(346, 175, &drekethBaseSprite, 255, drekethBaseSprite._width, drekethBaseSprite._height, false); g_engine->_sprites.addSpriteToDrawList(346, 133, &closingAnimation, 255, closingAnimation._width, closingAnimation._height, false); adddrekbutt(); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); updateCounter = !updateCounter; if (updateCounter) { counter++; } g_engine->waitxticks(1); } stuffPlayer(); } void Animation::adddrekbutt() { const Sprite &drekButt = g_engine->_room->_locationSprites.getSpriteAt(16); g_engine->_sprites.addSpriteToDrawList(466, 133, &drekButt, 255, drekButt._width, drekButt._height, false); } static constexpr uint8 libList[100] = { 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6, 7, 6, 7, 8, 7, 6, 5, 6, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6, 7, 6, 7, 8, 7, 6, 5, 6, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6, 5, 6, 7, 6, 7, 8, 7, 6, 5, 6, 7, 6, 7, 8, 7, 6, 5, 6, 5, 6, 5, 6, 7, 6, 7, 8, 7, 6, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6 }; void Animation::libAnim(bool pickingUpReservedBook) { _player->loadAnimations("libparts.nsp"); g_engine->showFullscreenPic("libinlib.pic"); g_engine->_console->printTosText(pickingUpReservedBook ? 928 : 924); _spriteAnimCountdownTimer[0] = _player->_animations.getAnimAt(0)._frameDuration[0]; uint8 lipsIdx = 0; while (g_engine->_sound->isPlayingSpeech()) { g_engine->_sprites.clearSpriteDrawList(); g_engine->_frame.draw(); g_engine->drawFullscreenPic(); g_engine->_console->draw(); advanceAnimationFrame(0); const Sprite &eyesSprite = _player->_animations.getSpriteAt(_player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]); g_engine->_sprites.addSpriteToDrawList(255, 114, &eyesSprite, 255, eyesSprite._width, eyesSprite._height, false); advanceAnimationFrame(1); const Sprite &mouthSprite = _player->_animations.getSpriteAt(libList[lipsIdx]); g_engine->_sprites.addSpriteToDrawList(255, 154, &mouthSprite, 255, mouthSprite._width, mouthSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); lipsIdx++; if (lipsIdx == 100) { lipsIdx = 0; } for (int i = 0; i < 6; i++) { g_engine->wait(); } } g_engine->removeFullscreenPic(); if (pickingUpReservedBook) { _objectVar[49] = 1; _objectVar[62] = 0; g_engine->_cutscene.play('G'); } } void Animation::wonGame() { _player->loadAnimations("libparts.nsp"); g_engine->_room->loadLocationSprites("libmorph.nsp"); g_engine->showFullscreenPic("lib_babe.pic"); g_engine->_cursor.showCursor(false); g_engine->_console->printTosText(925); _animIndexTbl[0] = 0; _spriteAnimCountdownTimer[0] = _player->_animations.getAnimAt(0)._frameDuration[0]; int counter = 68; uint8 lipsIdx = 0; while (counter < 70) { g_engine->_sprites.clearSpriteDrawList(); g_engine->drawFullscreenPic(); g_engine->_console->draw(); if (!g_engine->_sound->isPlayingSpeech()) { counter++; if (counter == 69) { g_engine->_console->printTosText(926); } } g_engine->_animation->advanceAnimationFrame(0); const Sprite &eyesSprite = _player->_animations.getSpriteAt(_player->_animations.getAnimAt(0)._frameNo[_animIndexTbl[0]]); g_engine->_sprites.addSpriteToDrawList(255, 114, &eyesSprite, 255, eyesSprite._width, eyesSprite._height, false); g_engine->_animation->advanceAnimationFrame(1); const Sprite &mouthSprite = _player->_animations.getSpriteAt(libList[lipsIdx]); g_engine->_sprites.addSpriteToDrawList(255, 154, &mouthSprite, 255, mouthSprite._width, mouthSprite._height, false); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); lipsIdx++; if (lipsIdx == 100) { lipsIdx = 0; } g_system->delayMillis(50); } _objRestarted = false; while (!_objRestarted) { g_engine->_sprites.clearSpriteDrawList(); g_engine->_room->advanceFrame(0); const Sprite &headMorph = g_engine->_room->_locationSprites.getSpriteAt(g_engine->_room->_locationSprites.getAnimAt(0)._frameNo[g_engine->_room->_locObjFrame[0]]); g_engine->_sprites.addSpriteToDrawList(227, 50, &headMorph, 255, headMorph._width, headMorph._height, false); g_engine->_sprites.drawSprites(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); g_system->delayMillis(30); } g_engine->_console->printTosText(918); g_engine->_sound->playMusic(MusicId::kVictory, false); g_engine->showFullscreenPic("wonpic.pic"); g_engine->_console->draw(); g_engine->_screen->makeAllDirty(); g_engine->_screen->update(); while (g_engine->_sound->isPlayingMusic() && !g_engine->shouldQuit()) { g_engine->waitxticks(1); } g_engine->_cutscene.play('Z'); } } // End of namespace Darkseed