diff options
Diffstat (limited to 'engines/hdb/ai-bots.cpp')
-rw-r--r-- | engines/hdb/ai-bots.cpp | 457 |
1 files changed, 282 insertions, 175 deletions
diff --git a/engines/hdb/ai-bots.cpp b/engines/hdb/ai-bots.cpp index 482ae87e63..cf7a799348 100644 --- a/engines/hdb/ai-bots.cpp +++ b/engines/hdb/ai-bots.cpp @@ -78,7 +78,7 @@ void aiOmniBotAction(AIEntity *e) { // Shoot player ? if (onEvenTile(e->x, e->y) && g_hdb->getActionMode()) { int xv = 0, yv = 0, result; - int shoot = 0; + bool shoot = false; // FIXME: Is reloading Player required here? p = g_hdb->_ai->getPlayer(); @@ -91,25 +91,25 @@ void aiOmniBotAction(AIEntity *e) { switch (e->dir) { case DIR_UP: if (p->x == e->x && p->y < e->y) { - shoot = 1; + shoot = true; yv = -1; } break; case DIR_DOWN: if (p->x == e->x && p->y > e->y) { - shoot = 1; + shoot = true; yv = 1; } break; case DIR_LEFT: if (p->x < e->x && p->y == e->y) { - shoot = 1; + shoot = true; xv = -1; } break; case DIR_RIGHT: if (p->x > e->x && p->y == e->y) { - shoot = 1; + shoot = true; xv = 1; } break; @@ -118,10 +118,10 @@ void aiOmniBotAction(AIEntity *e) { break; } - // If shoot = 1, take the shot + // If shoot = true, take the shot // (1) Check we're not shooting into a solid tile // (2) Check we're not shooting into an Entity unless it's the player - AIEntity *hit = g_hdb->_ai->legalMoveOverWater(e->tileX+xv, e->tileY + yv, e->level, &result); + AIEntity *hit = g_hdb->_ai->legalMoveOverWater(e->tileX + xv, e->tileY + yv, e->level, &result); if (shoot && !hit && result) { AIEntity *omni = g_hdb->_ai->spawn(AI_OMNIBOT_MISSILE, e->dir, e->tileX + xv, e->tileY + yv, NULL, NULL, NULL, DIR_NONE, e->level, 0, 0, 1); omni->xVel = xv * kPlayerMoveSpeed * 2; @@ -298,17 +298,16 @@ void aiShockBotAction(AIEntity *e) { } void aiShockBotShock(AIEntity *e, int mx, int my) { - int offX[8] = { -1, 0, 1, 1, 1, 0, -1, -1 }; - int offY[8] = { -1, -1, -1, 0, 1, 1, 1, 0 }; + static const int offX[8] = { -1, 0, 1, 1, 1, 0, -1, -1 }; + static const int offY[8] = { -1, -1, -1, 0, 1, 1, 1, 0 }; // Only on a exact tile boundary do we change the shocked tiles // Start at top left and go around if (g_hdb->_map->getMapBGTileFlags(e->tileX, e->tileY) & kFlagMetal) e->special1Gfx[e->animFrame]->drawMasked(e->tileX * kTileWidth - mx, e->tileY * kTileHeight - my); - uint32 flags; for (int i = 0; i < 8; i++) { - flags = g_hdb->_map->getMapBGTileFlags(e->tileX + offX[i], e->tileY + offY[i]); + uint32 flags = g_hdb->_map->getMapBGTileFlags(e->tileX + offX[i], e->tileY + offY[i]); if (flags & kFlagMetal) { // Is the shocking tile onScreen? if (g_hdb->_map->checkXYOnScreen((e->tileX + offX[i]) * kTileWidth, (e->tileY + offY[i]) * kTileHeight)) { @@ -465,10 +464,26 @@ void aiRightBotFindGoal(AIEntity *e) { } } else { switch (e->dir) { - case DIR_UP: e->dir = DIR_DOWN; yv = 1; xv = 0; break; - case DIR_DOWN: e->dir = DIR_UP; yv = -1; xv = 0; break; - case DIR_LEFT: e->dir = DIR_RIGHT; yv = 0; xv = 1; break; - case DIR_RIGHT: e->dir = DIR_LEFT; yv = 0; xv = -1; break; + case DIR_UP: + e->dir = DIR_DOWN; + yv = 1; + xv = 0; + break; + case DIR_DOWN: + e->dir = DIR_UP; + yv = -1; + xv = 0; + break; + case DIR_LEFT: + e->dir = DIR_RIGHT; + yv = 0; + xv = 1; + break; + case DIR_RIGHT: + e->dir = DIR_LEFT; + yv = 0; + xv = -1; + break; case DIR_NONE: warning("aiRightBotFindGoal: DIR_NONE found"); } @@ -593,10 +608,18 @@ void aiPushBotAction(AIEntity *e) { e1->moveSpeed = e->moveSpeed; g_hdb->_ai->setEntityGoal(e1, nx2, ny2); switch (e1->type) { - case AI_CRATE: g_hdb->_sound->playSound(SND_CRATE_SLIDE); break; - case AI_HEAVYBARREL: case AI_BOOMBARREL: g_hdb->_sound->playSound(SND_HEAVY_SLIDE); break; - case AI_LIGHTBARREL: g_hdb->_sound->playSound(SND_LIGHT_SLIDE); break; - default: break; + case AI_CRATE: + g_hdb->_sound->playSound(SND_CRATE_SLIDE); + break; + case AI_HEAVYBARREL: + case AI_BOOMBARREL: + g_hdb->_sound->playSound(SND_HEAVY_SLIDE); + break; + case AI_LIGHTBARREL: + g_hdb->_sound->playSound(SND_LIGHT_SLIDE); + break; + default: + break; } } else { if (e->onScreen) @@ -715,12 +738,10 @@ void aiRailRiderOnUse(AIEntity *e) { g_hdb->_ai->setEntityGoal(p, p->tileX, p->tileY - 1); else g_hdb->_ai->setEntityGoal(p, p->tileX, p->tileY + 1); - } else { - if (p->tileX > e->tileX) - g_hdb->_ai->setEntityGoal(p, p->tileX - 1, p->tileY); - else - g_hdb->_ai->setEntityGoal(p, p->tileX + 1, p->tileY); - } + } else if (p->tileX > e->tileX) + g_hdb->_ai->setEntityGoal(p, p->tileX - 1, p->tileY); + else + g_hdb->_ai->setEntityGoal(p, p->tileX + 1, p->tileY); e->sequence = -1; // Waiting for player to board } @@ -901,6 +922,9 @@ void aiMaintBotAction(AIEntity *e) { static const int xvAhead[5] = {9, 0, 0,-1, 1}; static const int yvAhead[5] = {9,-1, 1, 0, 0}; static const int whistles[3] = {SND_MBOT_WHISTLE1, SND_MBOT_WHISTLE2, SND_MBOT_WHISTLE3}; + static const AIDir lookRight[5] = {DIR_NONE, DIR_RIGHT, DIR_LEFT, DIR_UP, DIR_DOWN}; + static const AIDir lookLeft[5] = {DIR_NONE, DIR_LEFT, DIR_RIGHT, DIR_DOWN, DIR_UP}; + static const AIDir dirList[5] = {DIR_NONE, DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT}; // Waiting at an arrow (or hit by player)? if (e->sequence) { @@ -967,9 +991,6 @@ void aiMaintBotAction(AIEntity *e) { } // Deciding where to go at 4-way else { - AIDir lookRight[5] = {DIR_NONE, DIR_RIGHT, DIR_LEFT, DIR_UP, DIR_DOWN}; - AIDir lookLeft[5] = {DIR_NONE, DIR_LEFT, DIR_RIGHT, DIR_DOWN, DIR_UP}; - AIDir dirList[5] = {DIR_NONE, DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT}; switch (e->sequence) { // HMM case 50: @@ -1057,10 +1078,10 @@ void aiFourFirerInit2(AIEntity *e) { } void aiFourFirerAction(AIEntity *e) { - AIEntity *p = g_hdb->_ai->getPlayer(); - AIState state[5] = {STATE_NONE, STATE_STANDUP, STATE_STANDDOWN, STATE_STANDLEFT, STATE_STANDRIGHT}; - AIDir turn[5] = {DIR_NONE, DIR_RIGHT, DIR_LEFT, DIR_UP, DIR_DOWN}; + static const AIState state[5] = {STATE_NONE, STATE_STANDUP, STATE_STANDDOWN, STATE_STANDLEFT, STATE_STANDRIGHT}; + static const AIDir turn[5] = {DIR_NONE, DIR_RIGHT, DIR_LEFT, DIR_UP, DIR_DOWN}; + AIEntity *p = g_hdb->_ai->getPlayer(); // Time to turn right? if (!e->value1) { e->dir = turn[e->dir]; @@ -1089,11 +1110,32 @@ void aiFourFirerAction(AIEntity *e) { int yv = 0; switch (e->dir) { - case DIR_UP: if (p->x == e->x && p->y < e->y) { shoot = true; yv = -1; } break; - case DIR_DOWN: if (p->x == e->x && p->y > e->y) { shoot = true; yv = 1; } break; - case DIR_LEFT: if (p->y == e->y && p->x < e->x) { shoot = true; xv = -1; } break; - case DIR_RIGHT: if (p->y == e->y && p->x > e->x) { shoot = true; xv = 1; } break; - case DIR_NONE: warning("aiFourFirerAction: DIR_NONE found"); break; + case DIR_UP: + if (p->x == e->x && p->y < e->y) { + shoot = true; + yv = -1; } + break; + case DIR_DOWN: + if (p->x == e->x && p->y > e->y) { + shoot = true; + yv = 1; + } + break; + case DIR_LEFT: + if (p->y == e->y && p->x < e->x) { + shoot = true; + xv = -1; + } + break; + case DIR_RIGHT: + if (p->y == e->y && p->x > e->x) { + shoot = true; + xv = 1; + } + break; + case DIR_NONE: + warning("aiFourFirerAction: DIR_NONE found"); + break; } // Shoot if needed @@ -1142,9 +1184,7 @@ void aiDeadEyeInit2(AIEntity *e) { } void aiDeadEyeWalkInPlace(AIEntity *e) { - AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; - AIDir dir; - AIState s; + static const AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; e->sequence--; @@ -1154,15 +1194,16 @@ void aiDeadEyeWalkInPlace(AIEntity *e) { case 30: case 20: case 10: - dir = (AIDir)(g_hdb->_rnd->getRandomNumber(3) + 1); - s = state[dir]; - e->dir = dir; - e->state = s; - if (e->onScreen) { - if (e->sequence == 50) - g_hdb->_sound->playSound(SND_DEADEYE_AMB01); - else if (e->sequence == 10) - g_hdb->_sound->playSound(SND_DEADEYE_AMB02); + { + int rnd = g_hdb->_rnd->getRandomNumber(3) + 1; + e->dir = (AIDir)rnd; + e->state = state[rnd]; + if (e->onScreen) { + if (e->sequence == 50) + g_hdb->_sound->playSound(SND_DEADEYE_AMB01); + else if (e->sequence == 10) + g_hdb->_sound->playSound(SND_DEADEYE_AMB02); + } } break; case 0: @@ -1172,12 +1213,9 @@ void aiDeadEyeWalkInPlace(AIEntity *e) { } void aiDeadEyeAction(AIEntity *e) { - AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; - int xvAhead[5] = {9, 0, 0, -1, 1}, yvAhead[5] = {9, -1, 1, 0, 0}; - int result; - AIEntity *hit; - AIDir dir; - AIState s; + static const AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; + static const int xvAhead[5] = {9, 0, 0, -1, 1}; + static const int yvAhead[5] = {9, -1, 1, 0, 0}; if (e->sequence) { e->sequence--; @@ -1188,42 +1226,56 @@ void aiDeadEyeAction(AIEntity *e) { // Is player visible to us? AIEntity *p = g_hdb->_ai->getPlayer(); if (e->onScreen && p->level == e->level && !e->blinkFrames) { - int nuts = 0; + bool nuts = false; switch (e->dir) { - case DIR_UP: if (p->tileX == e->tileX && p->tileY < e->tileY) nuts = 1; break; - case DIR_DOWN: if (p->tileX == e->tileX && p->tileY > e->tileY) nuts = 1; break; - case DIR_LEFT: if (p->tileY == e->tileY && p->tileX < e->tileX) nuts = 1; break; - case DIR_RIGHT: if (p->tileY == e->tileY && p->tileX > e->tileX) nuts = 1; break; - case DIR_NONE: warning("aiDeadEyeAction: DIR_NONE found"); break; + case DIR_UP: + if (p->tileX == e->tileX && p->tileY < e->tileY) + nuts = true; + break; + case DIR_DOWN: + if (p->tileX == e->tileX && p->tileY > e->tileY) + nuts = true; + break; + case DIR_LEFT: + if (p->tileY == e->tileY && p->tileX < e->tileX) + nuts = true; + break; + case DIR_RIGHT: + if (p->tileY == e->tileY && p->tileX > e->tileX) + nuts = true; + break; + case DIR_NONE: + warning("aiDeadEyeAction: DIR_NONE found"); + break; } // Did we see the player (and we're done moving)? if (nuts && e->aiAction != aiDeadEyeWalkInPlace) { - int newX, newY, xv, yv, done, okToMove; - e->sequence = 0; e->blinkFrames = 20; - xv = xvAhead[e->dir]; - yv = yvAhead[e->dir]; - newX = e->tileX + xv; - newY = e->tileY + yv; + int xv = xvAhead[e->dir]; + int yv = yvAhead[e->dir]; + int newX = e->tileX + xv; + int newY = e->tileY + yv; - okToMove = done = 0; + bool okToMove = false; + bool done = false; do { - hit = g_hdb->_ai->legalMove(newX, newY, e->level, &result); + int result; + AIEntity *hit = g_hdb->_ai->legalMove(newX, newY, e->level, &result); if (hit && hit->type == AI_GUY) - hit = NULL; + hit = nullptr; if (result && !hit) { - okToMove = 1; + okToMove = true; newX += xv; newY += yv; if (newX == p->tileX && newY == p->tileY) - done = 1; + done = true; } else { newX -= xv; newY -= yv; - done = 1; + done = true; } } while (!done); @@ -1245,34 +1297,34 @@ void aiDeadEyeAction(AIEntity *e) { case 30: case 20: case 10: - dir = (AIDir)(g_hdb->_rnd->getRandomNumber(3)+1); - s = state[dir]; - e->dir = dir; - e->state = s; - - if (e->onScreen) { - if (e->sequence == 50) - g_hdb->_sound->playSound(SND_DEADEYE_AMB01); - else if (e->sequence == 10) - g_hdb->_sound->playSound(SND_DEADEYE_AMB02); + { + int dir = g_hdb->_rnd->getRandomNumber(3) + 1; + e->dir = (AIDir)dir; + e->state = state[dir]; + + if (e->onScreen) { + if (e->sequence == 50) + g_hdb->_sound->playSound(SND_DEADEYE_AMB01); + else if (e->sequence == 10) + g_hdb->_sound->playSound(SND_DEADEYE_AMB02); + } } break; case 0: // Pick a random direction and random number of tiles in that direction - dir = (AIDir)(g_hdb->_rnd->getRandomNumber(3) + 1); + int dir = g_hdb->_rnd->getRandomNumber(3) + 1; int walk = g_hdb->_rnd->getRandomNumber(4) + 1; - int xv, yv; - e->dir = dir; + e->dir = (AIDir)dir; e->state = state[dir]; - xv = xvAhead[dir] * walk; + int xv = xvAhead[dir] * walk; if (e->tileX + xv < 1) xv = 1 - e->tileX; if (e->tileX + xv > g_hdb->_map->_width) xv = g_hdb->_map->_width - e->tileX - 1; - yv = yvAhead[dir] * walk; + int yv = yvAhead[dir] * walk; if (e->tileY + yv < 1) yv = 1 - e->tileY; if (e->tileY + yv > g_hdb->_map->_height) @@ -1281,9 +1333,10 @@ void aiDeadEyeAction(AIEntity *e) { e->value1 = xvAhead[dir]; e->value2 = yvAhead[dir]; e->moveSpeed = kPlayerMoveSpeed; - hit = g_hdb->_ai->legalMove(e->tileX + xvAhead[e->dir], e->tileY + yvAhead[e->dir], e->level, &result); + int result; + AIEntity *hit = g_hdb->_ai->legalMove(e->tileX + xvAhead[e->dir], e->tileY + yvAhead[e->dir], e->level, &result); if (hit && hit->type == AI_GUY) - hit = NULL; + hit = nullptr; if (!hit && result) g_hdb->_ai->setEntityGoal(e, e->tileX + xv, e->tileY + yv); @@ -1303,9 +1356,10 @@ void aiDeadEyeAction(AIEntity *e) { // Did we run into a wall, entity, water, slime etc? // If so, Pick new direction if (onEvenTile(e->x, e->y)) { - hit = g_hdb->_ai->legalMove(e->tileX + e->value1, e->tileY + e->value2, e->level, &result); + int result; + AIEntity *hit = g_hdb->_ai->legalMove(e->tileX + e->value1, e->tileY + e->value2, e->level, &result); if (hit && hit->type == AI_GUY) - hit = NULL; + hit = nullptr; if (!result || hit) { g_hdb->_ai->stopEntity(e); e->state = STATE_MOVEDOWN; @@ -1327,15 +1381,15 @@ void aiDeadEyeAction(AIEntity *e) { void aiLaserInit(AIEntity *e) { e->aiDraw = aiLaserDraw; - e->value1 = e->value2 = 0; // start & end of laser beam + // start & end of laser beam + e->value1 = e->value2 = 0; } void aiLaserInit2(AIEntity *e) { e->draw = g_hdb->_ai->getStandFrameDir(e); if (!g_hdb->_ai->_gfxLaserbeamUD[0]) { char name[64]; - int i; - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { sprintf(name, FORCEFIELD_UD"0%d", i + 1); g_hdb->_ai->_gfxLaserbeamUD[i] = g_hdb->_gfx->loadTile(name); sprintf(name, FORCESPLASH_TOP"0%d", i + 1); @@ -1353,46 +1407,63 @@ void aiLaserInit2(AIEntity *e) { } void aiLaserAction(AIEntity *e) { - int xva[] = {9,0,0,-1,1}, yva[] = {9,-1,1,0,0}; - int nx, ny, moveOK; - AIEntity *hit; + static const int xva[] = {9, 0, 0,-1, 1}; + static const int yva[] = {9,-1, 1, 0, 0}; - hit = e; + AIEntity *hit = e; + int moveOK = 0; do { + int nx = hit->tileX; + int ny = hit->tileY; + if (hit->type != AI_DIVERTER) { hit->int1 = xva[hit->dir]; hit->int2 = yva[hit->dir]; - nx = hit->tileX; - ny = hit->tileY; if (hit->dir == DIR_UP || hit->dir == DIR_DOWN) hit->value1 = ny; else hit->value1 = nx; } else { - nx = hit->tileX; - ny = hit->tileY; // diverter is on y-plane? if (hit->tileX == e->tileX) { hit->value1 = nx; hit->int2 = 0; switch (hit->dir2) { - case DIR_UP: hit->int1 = 1; break; - case DIR_DOWN: hit->int1 = -1; break; - case DIR_LEFT: hit->int1 = -1; break; - case DIR_RIGHT: hit->int1 = 1; break; - case DIR_NONE: break; + case DIR_UP: + hit->int1 = 1; + break; + case DIR_DOWN: + hit->int1 = -1; + break; + case DIR_LEFT: + hit->int1 = -1; + break; + case DIR_RIGHT: + hit->int1 = 1; + break; + case DIR_NONE: + break; } } else { // diverter is on x-plane hit->value1 = ny; hit->int1 = 0; switch (hit->dir2) { - case DIR_UP: hit->int2 = 1; break; - case DIR_DOWN: hit->int2 = 1; break; - case DIR_LEFT: hit->int2 = -1; break; - case DIR_RIGHT: hit->int2 = -1; break; - case DIR_NONE: break; + case DIR_UP: + hit->int2 = 1; + break; + case DIR_DOWN: + hit->int2 = 1; + break; + case DIR_LEFT: + hit->int2 = -1; + break; + case DIR_RIGHT: + hit->int2 = -1; + break; + case DIR_NONE: + break; } } } @@ -1414,7 +1485,6 @@ void aiLaserAction(AIEntity *e) { g_hdb->_ai->killPlayer(DEATH_FRIED); else if (hit->type == AI_BOOMBARREL && hit->state != STATE_EXPLODING && onEvenTile(hit->x, hit->y)) { // hit BOOM BARREL = explodes - aiBarrelExplode(hit); aiBarrelBlowup(hit, nx, ny); } else if (hit->type == AI_LIGHTBARREL || hit->type == AI_HEAVYBARREL || hit->type == AI_CRATE) { @@ -1425,7 +1495,8 @@ void aiLaserAction(AIEntity *e) { moveOK = 0; } else if (onEvenTile(hit->x, hit->y) && hit != g_hdb->_ai->getPlayer()) { switch (hit->type) { - case AI_VORTEXIAN: // cannot kill Vortexians! + // cannot kill Vortexians! + case AI_VORTEXIAN: continue; case AI_BOOMBARREL: @@ -1435,7 +1506,6 @@ void aiLaserAction(AIEntity *e) { case AI_LASER: g_hdb->_ai->_laserRescan = true; break; - case ITEM_KEYCARD_WHITE: case ITEM_KEYCARD_BLUE: case ITEM_KEYCARD_RED: @@ -1563,11 +1633,24 @@ void aiDiverterInit2(AIEntity *e) { if (e->dir2 == DIR_NONE) d = e->dir; switch (d) { - case DIR_DOWN: e->state = STATE_DIVERTER_BL; e->draw = e->standdownGfx[0]; break; - case DIR_UP: e->state = STATE_DIVERTER_BR; e->draw = e->standupGfx[0]; break; - case DIR_LEFT: e->state = STATE_DIVERTER_TL; e->draw = e->standleftGfx[0]; break; - case DIR_RIGHT: e->state = STATE_DIVERTER_TR; e->draw = e->standrightGfx[0]; break; - case DIR_NONE: break; + case DIR_DOWN: + e->state = STATE_DIVERTER_BL; + e->draw = e->standdownGfx[0]; + break; + case DIR_UP: + e->state = STATE_DIVERTER_BR; + e->draw = e->standupGfx[0]; + break; + case DIR_LEFT: + e->state = STATE_DIVERTER_TL; + e->draw = e->standleftGfx[0]; + break; + case DIR_RIGHT: + e->state = STATE_DIVERTER_TR; + e->draw = e->standrightGfx[0]; + break; + case DIR_NONE: + break; } g_hdb->_ai->_laserRescan = true; @@ -1580,22 +1663,35 @@ void aiDiverterAction(AIEntity *e) { // have to reset the state because we might have been moved... switch (e->dir2) { - case DIR_DOWN: e->state = STATE_DIVERTER_BL; e->draw = e->standdownGfx[0]; break; - case DIR_UP: e->state = STATE_DIVERTER_BR; e->draw = e->standupGfx[0]; break; - case DIR_LEFT: e->state = STATE_DIVERTER_TL; e->draw = e->standleftGfx[0]; break; - case DIR_RIGHT: e->state = STATE_DIVERTER_TR; e->draw = e->standrightGfx[0]; break; - case DIR_NONE: break; + case DIR_DOWN: + e->state = STATE_DIVERTER_BL; + e->draw = e->standdownGfx[0]; + break; + case DIR_UP: + e->state = STATE_DIVERTER_BR; + e->draw = e->standupGfx[0]; + break; + case DIR_LEFT: + e->state = STATE_DIVERTER_TL; + e->draw = e->standleftGfx[0]; + break; + case DIR_RIGHT: + e->state = STATE_DIVERTER_TR; + e->draw = e->standrightGfx[0]; + break; + case DIR_NONE: + break; } } } void aiDiverterDraw(AIEntity *e, int mx, int my) { - int i; if (!e->value1 && !e->value2) return; int frame = e->movedownFrames & 3; int onScreen = 0; + int i; switch (e->dir2) { case DIR_UP: if (e->tileY == e->value1 && e->int2) { // going down or right? @@ -1721,6 +1817,9 @@ void aiMeerkatDraw(AIEntity *e, int mx, int my) { } void aiMeerkatAction(AIEntity *e) { + static const int gem_xv[] = { 0, 0,-2,-3,-4,-4,-3,-2,-2,-2,-2,-1,-1, 100}; + static const int gem_yv[] = {-6,-5,-4,-3,-2,-1, 0, 0, 1, 2, 3, 4, 5, 100}; + AIEntity *p = g_hdb->_ai->getPlayer(); switch (e->sequence) { @@ -1787,7 +1886,7 @@ void aiMeerkatAction(AIEntity *e) { case 5: g_hdb->_ai->animateEntity(e); if (!e->animFrame && e->animDelay == e->animCycle) { - e->sequence = 0;; + e->sequence = 0; e->state = STATE_NONE; e->draw = NULL; } @@ -1849,9 +1948,6 @@ void aiMeerkatAction(AIEntity *e) { // blasting a gem outta Guy? if (e->value1) { - int gem_xv[] = {0, 0,-2,-3,-4,-4,-3,-2,-2,-2,-2,-1,-1, 100}; - int gem_yv[] = {-6,-5,-4,-3,-2,-1, 0, 0, 1, 2, 3, 4, 5, 100}; - if (gem_xv[e->blinkFrames] == 100) { e->value1 = 0; e->aiDraw = NULL; @@ -2225,9 +2321,10 @@ void aiGoodFairyInit2(AIEntity *e) { } void aiGoodFairyAction(AIEntity *e) { - AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; - int xvAhead[5] = {9, 0, 0,-1, 1}, yvAhead[5] = {9,-1, 1, 0, 0}; - int xv, yv; + static const AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; + static const int xvAhead[5] = {9, 0, 0,-1, 1}; + static const int yvAhead[5] = {9,-1, 1, 0, 0}; + int result; AIEntity *hit; @@ -2243,12 +2340,10 @@ void aiGoodFairyAction(AIEntity *e) { { // Create a GEM? if (g_hdb->_rnd->getRandomNumber(99) > 98) { - int spawnOK; - // spawn a gem in a random direction int d = g_hdb->_rnd->getRandomNumber(3) + 1; - xv = xvAhead[d]; - yv = yvAhead[d]; + int xv = xvAhead[d]; + int yv = yvAhead[d]; e->sequence = 30; e->state = STATE_MOVEDOWN; @@ -2256,6 +2351,7 @@ void aiGoodFairyAction(AIEntity *e) { if ((g_hdb->_ai->findEntityType(AI_CRATE, e->tileX + xv, e->tileY + yv) != NULL) || (g_hdb->_ai->findEntityType(AI_LIGHTBARREL, e->tileX + xv, e->tileY + yv) != NULL)) return; + int spawnOK; hit = g_hdb->_ai->legalMove(e->tileX + xv, e->tileY + yv, e->level, &spawnOK); uint32 bg_flags = g_hdb->_map->getMapBGTileFlags(e->tileX + xv, e->tileY + yv); if (hit || !spawnOK || (bg_flags & kFlagSpecial)) @@ -2273,9 +2369,8 @@ void aiGoodFairyAction(AIEntity *e) { int tries = 4; do { // pick a random direction, then a random # of tiles in that direction - int rnd = g_hdb->_rnd->getRandomNumber(3) + 1; - AIDir d = (AIDir)rnd; - int walk = g_hdb->_rnd->getRandomNumber(4) + 1; + AIDir d = (AIDir)(g_hdb->_rnd->getRandomNumber(3) + 1); + int walk = g_hdb->_rnd->getRandomNumber(4) + 1; AIEntity *p = g_hdb->_ai->getPlayer(); // if player is within 3 tiles, move closer @@ -2317,14 +2412,15 @@ void aiGoodFairyAction(AIEntity *e) { } e->dir = d; - e->state = state[d]; - xv = xvAhead[d] * walk; + int tmpDir = (int)d; + e->state = state[tmpDir]; + int xv = xvAhead[tmpDir] * walk; if (e->tileX + xv < 1) xv = -e->tileX + 1; if (e->tileX + xv > g_hdb->_map->_width) xv = g_hdb->_map->_width - e->tileX - 1; - yv = yvAhead[d] * walk; + int yv = yvAhead[d] * walk; if (e->tileY + yv < 1) yv = -e->tileY + 1; if (e->tileY + yv > g_hdb->_map->_height) @@ -2425,9 +2521,10 @@ void aiBadFairyInit2(AIEntity *e) { } void aiBadFairyAction(AIEntity *e) { - AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; - int xvAhead[5] = {9, 0, 0,-1, 1}, yvAhead[5] = {9,-1, 1, 0, 0}; - int result; + static const AIState state[5] = {STATE_NONE, STATE_MOVEUP, STATE_MOVEDOWN, STATE_MOVELEFT, STATE_MOVERIGHT}; + static const AIDir opposite[5] = {DIR_NONE, DIR_DOWN, DIR_UP, DIR_RIGHT, DIR_LEFT}; + static const int xvAhead[5] = {9, 0, 0,-1, 1}; + static const int yvAhead[5] = {9,-1, 1, 0, 0}; if (e->sequence) { e->sequence--; @@ -2441,8 +2538,6 @@ void aiBadFairyAction(AIEntity *e) { { // Create a GATE PUDDLE? if (e->onScreen && (g_hdb->_rnd->getRandomNumber(99) > 90) && g_hdb->getActionMode() && (g_hdb->_ai->getGatePuddles() < kMaxGatePuddles)) { - AIDir opposite[] = {DIR_NONE, DIR_DOWN, DIR_UP, DIR_RIGHT, DIR_LEFT}; - if (e->onScreen) g_hdb->_sound->playSound(SND_BADFAIRY_SPELL); @@ -2457,14 +2552,14 @@ void aiBadFairyAction(AIEntity *e) { } int tries = 4; + int result; do { // pick a random direction, then a random # of tiles in that direction - int rnd = g_hdb->_rnd->getRandomNumber(3) + 1; - AIDir d = (AIDir)rnd; + int d = g_hdb->_rnd->getRandomNumber(3) + 1; int walk = g_hdb->_rnd->getRandomNumber(4) + 1; AIEntity *p = g_hdb->_ai->getPlayer(); - e->dir = d; + e->dir = (AIDir)d; e->state = state[d]; int xv = xvAhead[d] * walk; if (e->tileX + xv < 1) @@ -2524,6 +2619,7 @@ void aiBadFairyAction(AIEntity *e) { // did we run into a wall, entity, water, slime etc? // if so, pick a new direction! if (onEvenTile(e->x, e->y)) { + int result; AIEntity *hit = g_hdb->_ai->legalMoveOverWater(e->tileX + e->value1, e->tileY + e->value2, e->level, &result); uint32 bg_flags = g_hdb->_map->getMapBGTileFlags(e->tileX + e->value1, e->tileY + e->value2); if (!result || (hit && hit->type != AI_GUY) || (bg_flags & kFlagSpecial)) { @@ -2562,8 +2658,7 @@ void aiGatePuddleAction(AIEntity *e) { if (e->goalX) { g_hdb->_ai->animateEntity(e); if (hitPlayer(e->x, e->y)) { - int i; - for (i = 0; i < kMaxTeleporters; i++) { + for (int i = 0; i < kMaxTeleporters; i++) { if (g_hdb->_ai->_teleporters[i].anim1 == 2) { // PANIC ZONE? p->tileX = g_hdb->_ai->_teleporters[i].x1; p->tileY = g_hdb->_ai->_teleporters[i].y1; @@ -2637,11 +2732,11 @@ void aiGatePuddleAction(AIEntity *e) { } } else { int rnd = g_hdb->_rnd->getRandomNumber(3) + 1; - int move_ok = 0, nx, ny; - e->dir = (AIDir)rnd; - nx = e->tileX + xva[e->dir]; - ny = e->tileY + yva[e->dir]; + int nx = e->tileX + xva[rnd]; + int ny = e->tileY + yva[rnd]; + + int move_ok; AIEntity *hit = g_hdb->_ai->legalMoveOverWater(nx, ny, e->level, &move_ok); if (hit == p) hit = NULL; @@ -2706,12 +2801,10 @@ void aiIcePuffSnowballInit(AIEntity *e) { } void aiIcePuffSnowballAction(AIEntity *e) { - int result, speed; - AIEntity *hit = NULL; - // check for hit BEFORE moving so snowball is closer to object // NOTE: Need to do logic in this draw routine just in case the ICEPUFF gets stunned! - hit = g_hdb->_ai->legalMoveOverWater(e->value1 / kTileWidth, e->value2 / kTileHeight, e->level, &result); + int result; + AIEntity *hit = g_hdb->_ai->legalMoveOverWater(e->value1 / kTileWidth, e->value2 / kTileHeight, e->level, &result); if (hit && hit->type == AI_GUY && !g_hdb->_ai->playerDead()) { g_hdb->_ai->killPlayer(DEATH_NORMAL); g_hdb->_ai->addAnimateTarget(hit->x, hit->y, 0, 3, ANIM_NORMAL, false, false, GROUP_WATER_SPLASH_SIT); @@ -2725,15 +2818,22 @@ void aiIcePuffSnowballAction(AIEntity *e) { return; } - speed = kPlayerMoveSpeed; + int speed = kPlayerMoveSpeed; if (!g_hdb->getActionMode()) speed >>= 1; switch (e->dir2) { - case DIR_DOWN: e->value2 += speed; break; - case DIR_LEFT: e->value1 -= speed; break; - case DIR_RIGHT: e->value1 += speed; break; - default: break; + case DIR_DOWN: + e->value2 += speed; + break; + case DIR_LEFT: + e->value1 -= speed; + break; + case DIR_RIGHT: + e->value1 += speed; + break; + default: + break; } } @@ -2826,10 +2926,20 @@ void aiIcePuffAction(AIEntity *e) { if (e->animFrame == e->standupFrames) { e->animFrame = 0; switch (e->dir) { - case DIR_DOWN: e->state = STATE_ICEP_THROWDOWN; g_hdb->_sound->playSound(SND_ICEPUFF_THROW); break; - case DIR_LEFT: e->state = STATE_ICEP_THROWLEFT;g_hdb->_sound->playSound(SND_ICEPUFF_THROW); break; - case DIR_RIGHT: e->state = STATE_ICEP_THROWRIGHT; g_hdb->_sound->playSound(SND_ICEPUFF_THROW); break; - default: break; + case DIR_DOWN: + e->state = STATE_ICEP_THROWDOWN; + g_hdb->_sound->playSound(SND_ICEPUFF_THROW); + break; + case DIR_LEFT: + e->state = STATE_ICEP_THROWLEFT; + g_hdb->_sound->playSound(SND_ICEPUFF_THROW); + break; + case DIR_RIGHT: + e->state = STATE_ICEP_THROWRIGHT; + g_hdb->_sound->playSound(SND_ICEPUFF_THROW); + break; + default: + break; } } break; @@ -2919,9 +3029,8 @@ void aiBuzzflyInit(AIEntity *e) { } void aiBuzzflyInit2(AIEntity *e) { - int i; e->draw = g_hdb->_ai->getStandFrameDir(e); - for (i = 0; i < e->movedownFrames; i++) + for (int i = 0; i < e->movedownFrames; i++) { e->standdownGfx[i] = e->movedownGfx[i]; e->standupGfx[i] = e->moveupGfx[i]; @@ -2979,8 +3088,6 @@ void aiBuzzflyAction(AIEntity *e) { //------------------------------------------------------------------- void aiDragonInit(AIEntity *e) { - AIEntity *block; - e->state = STATE_STANDDOWN; e->sequence = 0; // 0 = sleeping e->aiAction = aiDragonAction; @@ -2988,7 +3095,7 @@ void aiDragonInit(AIEntity *e) { e->animCycle = 10; // time between flaps // need to save the dragon's coords and type in the blocking entity for gem-hit-blocking detection - block = spawnBlocking(e->tileX - 1, e->tileY, e->level); + AIEntity *block = spawnBlocking(e->tileX - 1, e->tileY, e->level); block->value1 = (int)AI_DRAGON; sprintf(block->luaFuncUse, "%03d%03d", e->tileX, e->tileY); block = spawnBlocking(e->tileX + 1, e->tileY, e->level); |