diff options
-rw-r--r-- | engines/gob/aniobject.cpp | 30 | ||||
-rw-r--r-- | engines/gob/aniobject.h | 5 | ||||
-rw-r--r-- | engines/gob/minigames/geisha/diving.cpp | 54 | ||||
-rw-r--r-- | engines/gob/minigames/geisha/diving.h | 5 | ||||
-rw-r--r-- | engines/gob/minigames/geisha/evilfish.cpp | 17 | ||||
-rw-r--r-- | engines/gob/minigames/geisha/evilfish.h | 6 | ||||
-rw-r--r-- | engines/gob/minigames/geisha/oko.cpp | 10 | ||||
-rw-r--r-- | engines/gob/minigames/geisha/oko.h | 4 |
8 files changed, 106 insertions, 25 deletions
diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index a01fe43672..0ca850d1fb 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -111,6 +111,36 @@ void ANIObject::getFrameSize(int16 &width, int16 &height) const { height = animation.frameAreas[_frame].bottom - animation.frameAreas[_frame].top + 1; } +bool ANIObject::isIn(int16 x, int16 y) const { + if (!isVisible()) + return false; + + int16 frameX, frameY, frameWidth, frameHeight; + getFramePosition(frameX, frameY); + getFrameSize(frameWidth, frameHeight); + + if ((x < frameX) || (y < frameY)) + return false; + if ((x > (frameX + frameWidth)) || (y > (frameY + frameHeight))) + return false; + + return true; +} + +bool ANIObject::isIn(const ANIObject &obj) const { + if (!isVisible() || !obj.isVisible()) + return false; + + int16 frameX, frameY, frameWidth, frameHeight; + getFramePosition(frameX, frameY); + getFrameSize(frameWidth, frameHeight); + + return obj.isIn(frameX , frameY ) || + obj.isIn(frameX + frameWidth - 1, frameY ) || + obj.isIn(frameX , frameY + frameHeight - 1) || + obj.isIn(frameX + frameWidth - 1, frameY + frameHeight - 1); +} + void ANIObject::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index 28103007a6..e3fe301400 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -69,6 +69,11 @@ public: /** Return the current frame size. */ void getFrameSize(int16 &width, int16 &height) const; + /** Are there coordinates within the animation sprite? */ + bool isIn(int16 x, int16 y) const; + /** Is this object within the animation sprite? */ + bool isIn(const ANIObject &obj) const; + /** Set the animation number. */ void setAnimation(uint16 animation); diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp index 0a43f96be9..fb906ce346 100644 --- a/engines/gob/minigames/geisha/diving.cpp +++ b/engines/gob/minigames/geisha/diving.cpp @@ -66,8 +66,8 @@ Diving::Diving(GobEngine *vm) : _vm(vm), _background(0), _blackPearl = new Surface(11, 8, 1); - _airMeter = new Meter(4 , 195, 38, 2, 5, 7, 38, Meter::kFillToLeft); - _healthMeter = new Meter(276, 195, 38, 2, 6, 7, 38, Meter::kFillToLeft); + _airMeter = new Meter(3 , 195, 40, 2, 5, 7, 40, Meter::kFillToLeft); + _healthMeter = new Meter(275, 195, 40, 2, 6, 7, 4, Meter::kFillToLeft); for (uint i = 0; i < kEvilFishCount; i++) _evilFish[i].evilFish = 0; @@ -108,6 +108,8 @@ bool Diving::play(uint16 playerCount, bool hasPearlLocation) { while (!_vm->shouldQuit()) { checkShots(); + checkOkoHurt(); + updateAirMeter(); updateEvilFish(); updateDecorFish(); @@ -132,13 +134,7 @@ bool Diving::play(uint16 playerCount, bool hasPearlLocation) { if (mouseButtons == kMouseButtonsLeft) shoot(mouseX, mouseY); - if (key == kKeyDown) { - _oko->sink(); - if ((_oko->getState() == Oko::kStatePick) && (_oko->getFrame() == 0)) - getPearl(); - - } else if (key == kKeyUp) - _oko->raise(); + handleOko(key); if ((_whitePearlCount >= 20) || (_blackPearlCount >= 2)) break; @@ -251,6 +247,7 @@ void Diving::init() { _healthMeter->setValue(38); _airCycle = 0; + _hurtGracePeriod = 0; } void Diving::deinit() { @@ -682,6 +679,45 @@ void Diving::checkShots() { } } +void Diving::handleOko(int16 key) { + if (key == kKeyDown) { + _oko->sink(); + + if ((_oko->getState() == Oko::kStatePick) && (_oko->getFrame() == 0)) + getPearl(); + + } else if (key == kKeyUp) + _oko->raise(); +} + +void Diving::checkOkoHurt() { + if (_oko->getState() != Oko::kStateSwim) + return; + + // Oko dies if the health reaches 0 + if (_healthMeter->getValue() == 0) + _oko->die(); + + // Give Oko a grace period after being hurt + if (_hurtGracePeriod > 0) { + _hurtGracePeriod--; + return; + } + + // Check for a fish/Oko-collision + for (uint i = 0; i < kEvilFishCount; i++) { + EvilFish &evilFish = *_evilFish[i].evilFish; + + if (!evilFish.isDead() && evilFish.isIn(*_oko)) { + _oko->hurt(); + _healthMeter->decrease(); + + _hurtGracePeriod = 10; + break; + } + } +} + } // End of namespace Geisha } // End of namespace Gob diff --git a/engines/gob/minigames/geisha/diving.h b/engines/gob/minigames/geisha/diving.h index 2915e85a93..5db1b8199a 100644 --- a/engines/gob/minigames/geisha/diving.h +++ b/engines/gob/minigames/geisha/diving.h @@ -137,6 +137,7 @@ private: Meter *_healthMeter; uint8 _airCycle; + uint8 _hurtGracePeriod; uint8 _currentShot; @@ -174,6 +175,10 @@ private: void shoot(int16 mouseX, int16 mouseY); void checkShots(); + + void handleOko(int16 key); + + void checkOkoHurt(); }; } // End of namespace Geisha diff --git a/engines/gob/minigames/geisha/evilfish.cpp b/engines/gob/minigames/geisha/evilfish.cpp index e9503f4aed..c7ef9d5622 100644 --- a/engines/gob/minigames/geisha/evilfish.cpp +++ b/engines/gob/minigames/geisha/evilfish.cpp @@ -39,19 +39,6 @@ EvilFish::EvilFish(const ANIFile &ani, uint16 screenWidth, EvilFish::~EvilFish() { } -bool EvilFish::isIn(int16 x, int16 y) const { - int16 frameX, frameY, frameWidth, frameHeight; - getFramePosition(frameX, frameY); - getFrameSize(frameWidth, frameHeight); - - if ((x < frameX) || (y < frameY)) - return false; - if ((x > (frameX + frameWidth)) || (y > (frameY + frameHeight))) - return false; - - return true; -} - void EvilFish::enter(Direction from, int16 y) { _shouldLeave = false; @@ -184,6 +171,10 @@ void EvilFish::mutate(uint16 animSwimLeft, uint16 animSwimRight, } } +bool EvilFish::isDead() { + return !isVisible() || (_state == kStateNone) || (_state == kStateDie); +} + } // End of namespace Geisha } // End of namespace Gob diff --git a/engines/gob/minigames/geisha/evilfish.h b/engines/gob/minigames/geisha/evilfish.h index 223645f47f..81efb676e2 100644 --- a/engines/gob/minigames/geisha/evilfish.h +++ b/engines/gob/minigames/geisha/evilfish.h @@ -42,9 +42,6 @@ public: uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie); ~EvilFish(); - /** Are there coordinates within the fish's sprite? */ - bool isIn(int16 x, int16 y) const; - /** Enter from this direction / screen edge. */ void enter(Direction from, int16 y); /** Leave the screen in the current direction. */ @@ -60,6 +57,9 @@ public: void mutate(uint16 animSwimLeft, uint16 animSwimRight, uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie); + /** Is the fish dead? */ + bool isDead(); + private: enum State { kStateNone, diff --git a/engines/gob/minigames/geisha/oko.cpp b/engines/gob/minigames/geisha/oko.cpp index c9d4d1f43f..1e90b1f8bf 100644 --- a/engines/gob/minigames/geisha/oko.cpp +++ b/engines/gob/minigames/geisha/oko.cpp @@ -35,6 +35,7 @@ enum kOkoAnimation { kOkoAnimationRaise = 7, kOkoAnimationBreathe = 2, kOkoAnimationPick = 3, + kOkoAnimationHurt = 4, kOkoAnimationDie0 = 17, kOkoAnimationDie1 = 18, kOkoAnimationDie2 = 19 @@ -80,6 +81,7 @@ void Oko::advance() { _sound->blasterPlay(_breathe, 1, 0); case kStateSink: case kStateRaise: + case kStateHurt: if (wasLastFrame) { setAnimation(kOkoAnimationSwim); setPosition(kOkoPositionX, kLevelPositionX[_level]); @@ -135,6 +137,14 @@ void Oko::raise() { _level--; } +void Oko::hurt() { + if (_state != kStateSwim) + return; + + setAnimation(kOkoAnimationHurt); + _state = kStateHurt; +} + void Oko::die() { if (_state != kStateSwim) return; diff --git a/engines/gob/minigames/geisha/oko.h b/engines/gob/minigames/geisha/oko.h index d5d18c16b3..7fe0001393 100644 --- a/engines/gob/minigames/geisha/oko.h +++ b/engines/gob/minigames/geisha/oko.h @@ -42,6 +42,7 @@ public: kStateRaise, kStateBreathe, kStatePick, + kStateHurt, kStateDead }; @@ -56,6 +57,9 @@ public: /** Oko should raise a level. */ void raise(); + /** Oko should get hurt. */ + void hurt(); + /** Oko should die. */ void die(); |