Files
scummvm-cursorfix/engines/mutationofjb/tasks/objectanimationtask.cpp
2026-02-02 04:50:13 +01:00

154 lines
4.8 KiB
C++

/* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "mutationofjb/tasks/objectanimationtask.h"
#include "mutationofjb/tasks/taskmanager.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/room.h"
namespace MutationOfJB {
static const int TICK_MILLIS = 100;
// TODO: Respect currentScene._delay.
ObjectAnimationTask::ObjectAnimationTask() : _timer(TICK_MILLIS) {
}
void ObjectAnimationTask::start() {
setState(RUNNING);
_timer.start();
}
void ObjectAnimationTask::update() {
_timer.update();
if (_timer.isFinished()) {
_timer.start();
updateObjects();
}
}
void ObjectAnimationTask::updateObjects() {
Scene *const scene = getTaskManager()->getGame().getGameData().getCurrentScene();
if (!scene) {
return;
}
for (uint8 i = 1; i <= scene->getNoObjects(); ++i) {
Object *const object = scene->getObject(i);
// Skip if object animation not active.
if (!object->_active)
continue;
// Number of frames must be higher than 1.
if (object->_numFrames <= 1)
continue;
const uint8 currentAnimOffset = object->_currentFrame - object->_firstFrame;
const bool randomized = object->_randomFrame != 0;
const bool belowRandomFrame = currentAnimOffset < (object->_randomFrame - 1);
uint8 maxAnimOffset = object->_numFrames - 1;
if (randomized && belowRandomFrame) {
maxAnimOffset = object->_randomFrame - 2;
}
uint8 nextAnimationOffset = currentAnimOffset + 1;
if (currentAnimOffset == maxAnimOffset) {
if (randomized && object->_jumpChance != 0 && getTaskManager()->getGame().getRandomSource().getRandomNumber(object->_jumpChance) == 0)
nextAnimationOffset = object->_randomFrame - 1;
else
nextAnimationOffset = 0;
}
object->_currentFrame = nextAnimationOffset + object->_firstFrame;
const bool drawObject = handleHardcodedAnimation(object);
if (drawObject) {
getTaskManager()->getGame().getRoom().drawObject(i);
}
}
}
bool ObjectAnimationTask::handleHardcodedAnimation(Object *const object) {
GameData &gameData = getTaskManager()->getGame().getGameData();
Scene *const scene = gameData.getCurrentScene();
const bool carnivalScene = gameData._currentScene == 30 && !gameData._partB;
const bool tavernScene = gameData._currentScene == 8 && gameData._partB;
if (carnivalScene) {
// This alternates between the two burglars' talking animations.
// Each burglar gets to talk for a varying amount of time since
// the switch occurs when his random frame is reached.
if (object->_WX == 1 && object->_currentFrame == 79) {
object->_currentFrame = 68;
object->_active = 0;
scene->getObject(6)->_active = 1;
scene->getObject(7)->_active = 0;
scene->getObject(8)->_active = 1;
return false;
} else if (object->_WX == 2 && object->_currentFrame == 91) {
object->_currentFrame = 80;
object->_active = 0;
scene->getObject(5)->_active = 1;
scene->getObject(7)->_active = 1;
scene->getObject(8)->_active = 0;
return false;
}
// The following makes sure you can't interact with the glass
// while the scientist is drinking from it.
if (scene->getObject(4)->_currentFrame > 52 && scene->getObject(4)->_active) {
scene->getStatic(9)->_active = 0; // disable scientist's glass
} else {
scene->getStatic(9)->_active = 1; // enable scientist's glass
}
if (!scene->getObject(4)->_active) {
scene->getStatic(9)->_active = 0; // disable scientist's glass
}
} else if (tavernScene) {
// Similarly to the carnival burglars, this alternates between
// the talking animations of the two soldiers in the tavern.
//
// At some point the script disables their conversation
// by nulling their _WX registers.
if (object->_WX == 3 && object->_currentFrame == 46) {
object->_currentFrame = 30;
object->_active = 0;
scene->getObject(3)->_active = 1;
return false;
} else if (object->_WX == 4 && object->_currentFrame == 63) {
object->_currentFrame = 47;
object->_active = 0;
scene->getObject(2)->_active = 1;
return false;
}
}
return true;
}
}