aboutsummaryrefslogtreecommitdiff
path: root/engines/draci
diff options
context:
space:
mode:
authorRobert Špalek2009-11-22 05:10:31 +0000
committerRobert Špalek2009-11-22 05:10:31 +0000
commit0ee8f879fa718a7507f1b22108b7d173edd7bdb5 (patch)
tree40538b56c5dbcbab83d5ba3201414e85340de7ba /engines/draci
parent509444cc9135e7d0bf7212ce01a1d61f8dcf0680 (diff)
downloadscummvm-rg350-0ee8f879fa718a7507f1b22108b7d173edd7bdb5.tar.gz
scummvm-rg350-0ee8f879fa718a7507f1b22108b7d173edd7bdb5.tar.bz2
scummvm-rg350-0ee8f879fa718a7507f1b22108b7d173edd7bdb5.zip
Fix positioning of one-time hero animations.
With the previous code, the position of the animation was doubled (due to counting the position twice, the second time being a relative shift), which put it mostly outside the screen. This is because one-time hero animations are actually stored using absolute coordinates. svn-id: r46057
Diffstat (limited to 'engines/draci')
-rw-r--r--engines/draci/animation.cpp2
-rw-r--r--engines/draci/animation.h3
-rw-r--r--engines/draci/game.cpp28
-rw-r--r--engines/draci/script.cpp32
4 files changed, 38 insertions, 27 deletions
diff --git a/engines/draci/animation.cpp b/engines/draci/animation.cpp
index dc14c7bb0d..4012719add 100644
--- a/engines/draci/animation.cpp
+++ b/engines/draci/animation.cpp
@@ -43,6 +43,7 @@ Animation::Animation(DraciEngine *vm, int id, uint z, bool playing) : _vm(vm) {
_currentFrame = 0;
_hasChangedFrame = true;
_callback = &Animation::doNothing;
+ _isRelative = false;
}
Animation::~Animation() {
@@ -556,6 +557,7 @@ Animation *AnimationManager::load(uint animNum) {
insert(anim, true);
anim->setLooping(cyclic);
+ anim->setIsRelative(relative);
for (uint i = 0; i < numFrames; ++i) {
uint spriteNum = animationReader.readUint16LE() - 1;
diff --git a/engines/draci/animation.h b/engines/draci/animation.h
index b669d53272..6f070cf9a7 100644
--- a/engines/draci/animation.h
+++ b/engines/draci/animation.h
@@ -94,6 +94,8 @@ public:
bool isLooping() const { return _looping; }
void setLooping(bool looping);
+ void setIsRelative(bool value) { _isRelative = value; }
+ bool isRelative() const { return _isRelative; }
void setRelative(int relx, int rely);
int getRelativeX() const { return _displacement.relX; }
int getRelativeY() const { return _displacement.relY; }
@@ -147,6 +149,7 @@ private:
bool _hasChangedFrame;
Displacement _displacement;
+ bool _isRelative;
uint _tick;
bool _playing;
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index a170cc2948..1862ceb22d 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -1290,16 +1290,24 @@ void Game::positionAnimAsHero(Animation *anim) {
_persons[kDragonObject]._x = _hero.x;
_persons[kDragonObject]._y = p.y;
- // Set the per-animation scaling factor
- anim->setScaleFactors(scale, scale);
-
- anim->setRelative(p.x, p.y);
-
- // Clear the animation's shift so that the real sprite stays at place
- // regardless of what the current phase is. If the animation starts
- // from the beginning, the shift is already [0,0], but if it is in the
- // middle, it may be different.
- anim->clearShift();
+ if (anim->isRelative()) {
+ // Set the per-animation scaling factor and relative position
+ anim->setScaleFactors(scale, scale);
+ anim->setRelative(p.x, p.y);
+
+ // Clear the animation's shift so that the real sprite stays at place
+ // regardless of what the current phase is. If the animation starts
+ // from the beginning, the shift is already [0,0], but if it is in the
+ // middle, it may be different.
+ anim->clearShift();
+
+ // Otherwise this dragon animation is used at exactly one place
+ // in the game (such as jumping into the secret entrance),
+ // which can is recognized by it using absolute coordinates.
+ // Bypass our animation positioning system, otherwise there two
+ // shifts will get summed and the animation will be placed
+ // outside the screen.
+ }
}
void Game::positionHeroAsAnim(Animation *anim) {
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index df632dc0d7..6adef11778 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -338,8 +338,7 @@ int Script::funcActPhase(int objID) const {
const GameObject *obj = _vm->_game->getObject(objID);
- bool visible = (obj->_location == _vm->_game->getRoomNum() && obj->_visible);
-
+ const bool visible = (obj->_location == _vm->_game->getRoomNum() && obj->_visible);
if (objID == kDragonObject || visible) {
const int i = obj->playingAnim();
if (i >= 0) {
@@ -421,16 +420,15 @@ void Script::start(const Common::Array<int> &params) {
objID, obj->_title.c_str(), animID);
}
Animation *anim = obj->_anim[index];
-
- if (objID == kDragonObject)
- _vm->_game->positionAnimAsHero(anim);
-
anim->registerCallback(&Animation::stop);
- bool visible = (obj->_location == _vm->_game->getRoomNum() && obj->_visible);
-
- if (objID == kDragonObject || visible) {
- obj->playAnim(index);
+ if (objID == kDragonObject) {
+ _vm->_game->playHeroAnimation(index);
+ } else {
+ const bool visible = (obj->_location == _vm->_game->getRoomNum() && obj->_visible);
+ if (visible) {
+ obj->playAnim(index);
+ }
}
}
@@ -452,15 +450,15 @@ void Script::startPlay(const Common::Array<int> &params) {
objID, obj->_title.c_str(), animID);
}
Animation *anim = obj->_anim[index];
-
- if (objID == kDragonObject)
- _vm->_game->positionAnimAsHero(anim);
-
anim->registerCallback(&Animation::exitGameLoop);
- bool visible = (obj->_location == _vm->_game->getRoomNum() && obj->_visible);
- if (objID == kDragonObject || visible) {
- obj->playAnim(index);
+ if (objID == kDragonObject) {
+ _vm->_game->playHeroAnimation(index);
+ } else {
+ const bool visible = (obj->_location == _vm->_game->getRoomNum() && obj->_visible);
+ if (visible) {
+ obj->playAnim(index);
+ }
}
// Runs an inner loop until the animation ends.