예제 #1
0
//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;
					}
				}
			}
		}
	}
}
예제 #2
0
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);
    }
}