//Setup AI so that it can ignore or pay attention to some objects void CPlayerAI::Init() { //Scan yoshi's egg mode objects to make sure that we ignore eggs with out matching yoshis if(game_values.gamemode->gamemode == game_mode_eggs) { bool fYoshi[4] = {false, false, false, false}; //Scan Yoshis to see which ones are present for(short i = 0; i < objectcontainer[1].list_end; i++) { CObject * object = objectcontainer[1].list[i]; if(object_moving == object->getObjectType()) { IO_MovingObject * movingobject = (IO_MovingObject*)object; if(movingobject_yoshi == movingobject->getMovingObjectType()) { MO_Yoshi * yoshi = (MO_Yoshi*)movingobject; fYoshi[yoshi->getColor()] = true; } } } //Now scan eggs and ignore any egg that doesn't have a yoshi for(short i = 0; i < objectcontainer[1].list_end; i++) { CObject * object = objectcontainer[1].list[i]; if(object_moving == object->getObjectType()) { IO_MovingObject * movingobject = (IO_MovingObject*)object; if(movingobject_egg == movingobject->getMovingObjectType()) { CO_Egg * egg = (CO_Egg*)movingobject; if(!fYoshi[egg->getColor()]) { AttentionObject * ao = new AttentionObject(); ao->iID = egg->iNetworkID; ao->iType = 1; //Ignore this object ao->iTimer = 0; //Ignore it forever attentionObjects[ao->iID] = ao; } } } } } }
void CPlayerAI::GetNearestObjects() { nearestObjects.Reset(); MO_CarriedObject * carriedItem = pPlayer->carriedItem; bool fInvincible = pPlayer->invincible || pPlayer->shield || pPlayer->shyguy; short iTeamID = pPlayer->teamID; std::map<int, AttentionObject*>::iterator lim = attentionObjects.end(); for (short i = 0; i < objectcontainer[1].list_end; i++) { CObject * object = objectcontainer[1].list[i]; if (attentionObjects.find(object->iNetworkID) != lim) { //DistanceToObject(object, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); continue; } ObjectType type = object->getObjectType(); switch (type) { case object_moving: { IO_MovingObject * movingobject = (IO_MovingObject*)object; MovingObjectType movingtype = movingobject->getMovingObjectType(); if (carriedItem == movingobject) continue; if (movingobject_shell == movingtype) { CO_Shell * shell = (CO_Shell*)movingobject; if (shell->IsThreat()) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (carriedItem) { continue; } else { DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } } else if (movingobject_throwblock == movingtype || (movingobject_throwbox == movingtype && ((CO_ThrowBox*)movingobject)->HasKillVelocity())) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_pirhanaplant == movingtype) { MO_PirhanaPlant * plant = (MO_PirhanaPlant*)movingobject; if (plant->state > 0) DistanceToObjectCenter(plant, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_flag == movingtype) { CO_Flag * flag = (CO_Flag*)movingobject; if (flag->GetInBase() && flag->GetTeamID() == iTeamID) continue; if (carriedItem && carriedItem->getMovingObjectType() == movingobject_flag) continue; DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if (movingobject_yoshi == movingtype) { MO_Yoshi * yoshi = (MO_Yoshi*)movingobject; if (!carriedItem || carriedItem->getMovingObjectType() != movingobject_egg) continue; CO_Egg * egg = (CO_Egg*)carriedItem; if (yoshi->getColor() != egg->getColor()) continue; DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if (movingobject_egg == movingtype) { if (carriedItem && carriedItem->getMovingObjectType() == movingobject_egg) continue; DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if (movingobject_throwbox == movingtype) { if (carriedItem) continue; DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if (movingobject_star == movingtype) { if (carriedItem && carriedItem->getMovingObjectType() == movingobject_star) continue; CGM_Star * starmode = (CGM_Star*)game_values.gamemode; CO_Star * star = (CO_Star*)movingobject; if (star->getType() == 1 || starmode->isplayerstar(pPlayer)) { DistanceToObject(star, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else { DistanceToObject(star, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } } else if (movingobject_coin == movingtype || movingobject_phantokey == movingtype) { DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if (movingobject_collectioncard == movingtype) { int iNumHeldCards = pPlayer->score->subscore[0]; int iHeldCards = pPlayer->score->subscore[1]; if (iNumHeldCards == 3) { int iThreeHeldCards = iHeldCards & 63; //If bot is holding all of the same type of card, then ignore all other cards if (iThreeHeldCards == 42 || iThreeHeldCards == 21 || iThreeHeldCards == 0) { DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } int iTwoHeldCards = iHeldCards & 15; if (iTwoHeldCards == 10 || iTwoHeldCards == 5 || iTwoHeldCards == 0) { DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } } else { MO_CollectionCard * card = (MO_CollectionCard*)movingobject; if (iNumHeldCards == 2) { int iTwoHeldCards = iHeldCards & 15; if (iTwoHeldCards == 10 || iTwoHeldCards == 5 || iTwoHeldCards == 0) { int iCardValue = card->getValue(); if (card->getType() == 1 && ((iTwoHeldCards == 10 && iCardValue != 2) || (iTwoHeldCards == 5 && iCardValue != 1) || (iTwoHeldCards == 0 && iCardValue != 0))) { DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } } } else if (iNumHeldCards == 1) { int iHeldCard = iHeldCards & 3; int iCardValue = card->getValue(); if (card->getType() == 1 || iHeldCard != iCardValue) { DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } } } if (iNumHeldCards == 3) DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); else DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } break; } case object_frenzycard: { DistanceToObject(object, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } case object_pipe_coin: { OMO_PipeCoin * coin = (OMO_PipeCoin*)object; if (coin->GetColor() != 0) { if (coin->GetTeam() == -1 || coin->GetTeam() == pPlayer->teamID) DistanceToObject(coin, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else { DistanceToObject(coin, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } break; } case object_pipe_bonus: { OMO_PipeBonus * bonus = (OMO_PipeBonus*)object; if (bonus->GetType() != 5) { DistanceToObject(bonus, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else { DistanceToObject(bonus, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } break; } case object_pathhazard: case object_orbithazard: { DistanceToObject(object, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } case object_phanto: { OMO_Phanto * phanto = (OMO_Phanto*)object; if (phanto->GetType() == 2 || (carriedItem && carriedItem->getMovingObjectType() == movingobject_phantokey)) { DistanceToObjectCenter(object, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } break; } case object_flamecannon: { IO_FlameCannon * cannon = (IO_FlameCannon *)object; if (cannon->state > 0) DistanceToObject(cannon, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } default: { DistanceToObject(object, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } } } for (short i = 0; i < objectcontainer[0].list_end; i++) { CObject * object = objectcontainer[0].list[i]; if (attentionObjects.find(object->iNetworkID) != lim) { //DistanceToObject(object, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); continue; } ObjectType type = object->getObjectType(); switch (type) { case object_moving: { IO_MovingObject * movingobject = (IO_MovingObject*)object; MovingObjectType movingtype = movingobject->getMovingObjectType(); if (carriedItem == movingobject) continue; if (movingobject_powerup == movingtype) { DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if ((movingobject_fireball == movingtype && ((MO_Fireball*)movingobject)->iTeamID != iTeamID) || movingobject_poisonpowerup == movingtype) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if ((movingobject_goomba == movingtype || movingobject_koopa == movingtype) && movingobject->GetState() == 1) { DistanceToObject(movingobject, &nearestObjects.stomp, &nearestObjects.stompdistance, &nearestObjects.stompwrap); } else if (movingobject_sledgebrother == movingtype) { DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_treasurechest == movingtype) { DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else if (movingobject_flagbase == movingtype) { MO_FlagBase * flagbase = (MO_FlagBase*)movingobject; if (!carriedItem || carriedItem->getMovingObjectType() != movingobject_flag || flagbase->GetTeamID() != iTeamID) continue; DistanceToObject(movingobject, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); } else { continue; } break; } case object_area: { if (((OMO_Area*)object)->getColorID() == pPlayer->colorID) continue; DistanceToObject(object, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } case object_kingofthehill_area: { DistanceToObjectCenter(object, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } default: { DistanceToObject(object, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } } } for (short i = 0; i < objectcontainer[2].list_end; i++) { CObject * object = objectcontainer[2].list[i]; if (attentionObjects.find(object->iNetworkID) != lim) { //DistanceToObject(object, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); continue; } ObjectType type = object->getObjectType(); switch (type) { case object_moving: { IO_MovingObject * movingobject = (IO_MovingObject*)object; MovingObjectType movingtype = movingobject->getMovingObjectType(); if (carriedItem == movingobject) continue; if (movingobject_cheepcheep == movingtype) { DistanceToObject(movingobject, &nearestObjects.stomp, &nearestObjects.stompdistance, &nearestObjects.stompwrap); } else if (movingobject_bulletbill == movingtype) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_hammer == movingtype && ((MO_Hammer*)movingobject)->iTeamID != iTeamID) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_iceblast == movingtype && ((MO_IceBlast*)movingobject)->iTeamID != iTeamID) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_boomerang == movingtype && ((MO_Boomerang*)movingobject)->iTeamID != iTeamID) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_bomb == movingtype && ((CO_Bomb*)movingobject)->iTeamID != iTeamID) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_podobo == movingtype && ((MO_Podobo*)movingobject)->iTeamID != iTeamID) { if (fInvincible) continue; DistanceToObject(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); } else if (movingobject_explosion == movingtype && ((MO_Explosion*)movingobject)->iTeamID != iTeamID) { if (fInvincible) continue; DistanceToObjectCenter(movingobject, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } break; } case object_thwomp: case object_bowserfire: { if (fInvincible) continue; DistanceToObjectCenter(object, &nearestObjects.threat, &nearestObjects.threatdistance, &nearestObjects.threatwrap); break; } case object_race_goal: { if (game_values.gamemode->gamemode != game_mode_race) continue; OMO_RaceGoal * racegoal = (OMO_RaceGoal*)object; if (racegoal->getGoalID() != ((CGM_Race*)game_values.gamemode)->getNextGoal(iTeamID)) continue; DistanceToObject(racegoal, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } default: { DistanceToObject(object, &nearestObjects.goal, &nearestObjects.goaldistance, &nearestObjects.goalwrap); break; } } } //Figure out where the other players are for (short iPlayer = 0; iPlayer < list_players_cnt; iPlayer++) { if (iPlayer == pPlayer->localID || list_players[iPlayer]->state != player_ready) continue; //Find players in jail on own team to tag if (game_values.gamemode->gamemode == game_mode_jail) { if (list_players[iPlayer]->jailtimer > 0 && list_players[iPlayer]->teamID == iTeamID) { DistanceToPlayer(list_players[iPlayer], &nearestObjects.teammate, &nearestObjects.teammatedistance, &nearestObjects.teammatewrap); } } if (list_players[iPlayer]->teamID == iTeamID || list_players[iPlayer]->state != player_ready) continue; //If there is a chicken, only focus on stomping him if (game_values.gamemode->chicken) { if (game_values.gamemode->chicken->teamID != iTeamID && game_values.gamemode->chicken != list_players[iPlayer]) continue; } DistanceToPlayer(list_players[iPlayer], &nearestObjects.player, &nearestObjects.playerdistance, &nearestObjects.playerwrap); } }