diff options
| author | Strangerke | 2019-07-25 16:30:59 +0200 | 
|---|---|---|
| committer | Eugene Sandulenko | 2019-09-03 17:17:28 +0200 | 
| commit | becfce8bfc42d53dfa72e28e29a90fabe12f43bc (patch) | |
| tree | 4feaa9cfa12c794a4d5ee91b29ec0551c4ec6e12 | |
| parent | 174b8c31cf4355d18220d8d984df60451ff42efd (diff) | |
| download | scummvm-rg350-becfce8bfc42d53dfa72e28e29a90fabe12f43bc.tar.gz scummvm-rg350-becfce8bfc42d53dfa72e28e29a90fabe12f43bc.tar.bz2 scummvm-rg350-becfce8bfc42d53dfa72e28e29a90fabe12f43bc.zip | |
HDB: More cleanup in ai-bots
| -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); | 
