#include #include "Bonus.h" #include "Gameplay.h" #include "constant.h" extern void go(int *x, int *y, int step, int xMax, int yMax, direction way); Bonus::Bonus(Gameplay *desiredGame, bool desiredDud) : game(desiredGame), goUp(false), goLeft(false), goRight(false), goDown(false), dud(desiredDud) { const int homeX = game->getLevelPointer()->getBonusStartX() * tileSize; const int homeY = game->getLevelPointer()->getBonusStartY() * tileSize; int endX = homeX; int endY = homeY; for (vector::iterator i = game->getLevelPointer()->bonusRouteBegin(); i != game->getLevelPointer()->bonusRouteEnd(); i++) go(&endX, &endY, tileSize, boardW * tileSize, boardH * tileSize, *i); const int homeXDiff = game->getPlayerPointer()->getX() - homeX; const int homeYDiff = game->getPlayerPointer()->getY() - homeY; const int endXDiff = game->getPlayerPointer()->getX() - endX; const int endYDiff = game->getPlayerPointer()->getY() - endY; const int absHomeXDiff = homeXDiff < 0 ? -homeXDiff : homeXDiff; const int absHomeYDiff = homeYDiff < 0 ? -homeYDiff : homeYDiff; const int absEndXDiff = endXDiff < 0 ? -endXDiff : endXDiff; const int absEndYDiff = endYDiff < 0 ? -endYDiff : endYDiff; const int distanceToHome = (absHomeXDiff < (boardW * tileSize) - absHomeXDiff ? absHomeXDiff : (boardW * tileSize) - absHomeXDiff) + (absHomeYDiff < (boardH * tileSize) - absHomeYDiff ? absHomeYDiff : (boardH * tileSize) - absHomeYDiff); const int distanceToEnd = (absEndXDiff < (boardW * tileSize) - absEndXDiff ? absEndXDiff : (boardW * tileSize) - absEndXDiff) + (absEndYDiff < (boardH * tileSize) - absEndYDiff ? absEndYDiff : (boardH * tileSize) - absEndYDiff); backwards = distanceToHome == distanceToEnd ? rand() % 2 : distanceToHome < distanceToEnd; if (backwards) { x = endX; y = endY; position = game->getLevelPointer()->getBonusRouteSize() * tileSize + tileSize; } else { x = homeX; y = homeY; position = -tileSize; } if (y == 0) { y = -tileSize; goDown = true; } if (x == 0) { x = -tileSize; goRight = true; } if (x == boardW * tileSize - tileSize) { x = boardW * tileSize; goLeft = true; } if (y == boardH * tileSize - tileSize) { y = boardH * tileSize; goUp = true; } } int Bonus::getX() { return x; } int Bonus::getY() { return y; } bool Bonus::getDud() { return dud; } void Bonus::move() { if (!dud) { if (position % tileSize == 0) if (backwards ? position == -tileSize : position == game->getLevelPointer()->getBonusRouteSize() * tileSize + tileSize) dud = true; else if (backwards ? position == 0 : position == game->getLevelPointer()->getBonusRouteSize() * tileSize) { goUp = y == 0; goLeft = x == 0; goRight = x == boardW * tileSize - tileSize; goDown = y == boardH * tileSize - tileSize; } else if (backwards ? position < game->getLevelPointer()->getBonusRouteSize() * tileSize + tileSize : position > -tileSize) { int bonusRouteIndex = position / tileSize; if (backwards) bonusRouteIndex--; const direction way = backwards ? otherWay[game->getLevelPointer()->getBonusDirection(bonusRouteIndex)] : game->getLevelPointer()->getBonusDirection(bonusRouteIndex); goUp = way == up; goLeft = way == left; goRight = way == right; goDown = way == down; } if (goUp) y -= bonusStep; if (goLeft) x -= bonusStep; if (goRight) x += bonusStep; if (goDown) y += bonusStep; if (backwards) position -= bonusStep; else position += bonusStep; } } void Bonus::remove() { dud = true; } void Bonus::draw(BITMAP *canvas, BITMAP *source) { if (!dud) { int showX = x + halfTileSize - bonusSize / 2; int showY = y + halfTileSize - bonusSize / 2; const int xWave = fixtoi(fixsin(itofix(((y + tileSize) % tileSize) * 256 / tileSize)) * bonusWaveAmplitude); const int yWave = fixtoi(fixsin(itofix(((x + tileSize) % tileSize) * 256 / tileSize)) * bonusWaveAmplitude); if (goUp && goLeft || goRight && goDown) { showX += (int)(xWave * oneOverRootTwo); showY -= (int)(yWave * oneOverRootTwo); } else if (goLeft && goDown || goRight && goUp) { showX += (int)(xWave * oneOverRootTwo); showY += (int)(yWave * oneOverRootTwo); } else if (goUp || goDown) showX += xWave; else if (goLeft || goRight) showY += yWave; if (gfx_capabilities & GFX_HW_VRAM_BLIT_MASKED) masked_blit(source, canvas, bonusDisplayX, bonusDisplayY, showX, showY, bonusSize, bonusSize); else draw_rle_sprite(canvas, game->getRleBonus(), showX, showY); } }