int Interface::Basic::EventDigArtifact(void) { Heroes* hero = GetFocusHeroes(); if(hero) { if(hero->isShipMaster()) Dialog::Message("", _("Try looking on land!!!"), Font::BIG, Dialog::OK); else if(hero->GetMaxMovePoints() <= hero->GetMovePoints()) { if(world.GetTiles(hero->GetIndex()).GoodForUltimateArtifact()) { AGG::PlaySound(M82::DIGSOUND); hero->ResetMovePoints(); if(world.DiggingForUltimateArtifact(hero->GetCenter())) { AGG::PlaySound(M82::TREASURE); const Artifact & ultimate = world.GetUltimateArtifact().GetArtifact(); hero->PickupArtifact(ultimate); std::string msg(_("After spending many hours digging here, you have uncovered the %{artifact}")); StringReplace(msg, "%{artifact}", ultimate.GetName()); Dialog::ArtifactInfo(_("Congratulations!"), msg, ultimate()); // set all obelisks visited Kingdom & kingdom = world.GetKingdom(hero->GetColor()); const MapsIndexes obelisks = Maps::GetObjectPositions(MP2::OBJ_OBELISK, true); for(MapsIndexes::const_iterator it = obelisks.begin(); it != obelisks.end(); ++it) if(!hero->isVisited(world.GetTiles(*it), Visit::GLOBAL)) hero->SetVisited(*it, Visit::GLOBAL); kingdom.PuzzleMaps().Update(kingdom.CountVisitedObjects(MP2::OBJ_OBELISK), world.CountObeliskOnMaps()); } else Dialog::Message("", _("Nothing here. Where could it be?"), Font::BIG, Dialog::OK); Cursor::Get().Hide(); iconsPanel.RedrawIcons(ICON_HEROES); Cursor::Get().Show(); Display::Get().Flip(); // check game over for ultimate artifact return GameOver::Result::Get().LocalCheckGameOver(); } else Dialog::Message("", _("Try searching on clear ground."), Font::BIG, Dialog::OK); } } else Dialog::Message("", _("Digging for artifacts requires a whole day, try again tomorrow."), Font::BIG, Dialog::OK); return Game::CANCEL; }
// get priority object for AI independent of distance (1 day) bool AIHeroesPriorityObject(const Heroes & hero, s32 index) { Maps::Tiles & tile = world.GetTiles(index); if(MP2::OBJ_CASTLE == tile.GetObject()) { const Castle* castle = world.GetCastle(Maps::GetPoint(index)); if(castle) { if(hero.GetColor() == castle->GetColor()) { // maybe need join army return hero.Modes(AI::HEROES_HUNTER) && castle->GetArmy().isValid() && ! hero.isVisited(world.GetTiles(castle->GetIndex())); } else if(! hero.isFriends(castle->GetColor())) return AI::HeroesValidObject(hero, index); } } else if(MP2::OBJ_HEROES == tile.GetObject()) { // kill enemy hero const Heroes* hero2 = tile.GetHeroes(); return hero2 && ! hero.isFriends(hero2->GetColor()) && AI::HeroesValidObject(hero, index); } switch(tile.GetObject()) { case MP2::OBJ_MONSTER: case MP2::OBJ_SAWMILL: case MP2::OBJ_MINES: case MP2::OBJ_ALCHEMYLAB: case MP2::OBJ_ARTIFACT: case MP2::OBJ_RESOURCE: case MP2::OBJ_CAMPFIRE: case MP2::OBJ_TREASURECHEST: return AI::HeroesValidObject(hero, index); default: break; } return false; }
void AIHeroesAddedTask(Heroes & hero) { AIHero & ai_hero = AIHeroes::Get(hero); AIKingdom & ai_kingdom = AIKingdoms::Get(hero.GetColor()); Queue & task = ai_hero.sheduled_visit; IndexObjectMap & ai_objects = ai_kingdom.scans; // load minimal distance tasks std::vector<IndexDistance> objs; objs.reserve(ai_objects.size()); for(std::map<s32, int>::const_iterator it = ai_objects.begin(); it != ai_objects.end(); ++it) { const Maps::Tiles & tile = world.GetTiles((*it).first); if(hero.isShipMaster()) { if(MP2::OBJ_COAST != tile.GetObject() && ! tile.isWater()) continue; // check previous positions if(MP2::OBJ_COAST == (*it).second && hero.isVisited(world.GetTiles((*it).first))) continue; } else { if(tile.isWater() && MP2::OBJ_BOAT != tile.GetObject()) continue; } objs.push_back(IndexDistance((*it).first, Maps::GetApproximateDistance(hero.GetIndex(), (*it).first))); } DEBUG(DBG_AI, DBG_INFO, Color::String(hero.GetColor()) << ", hero: " << hero.GetName() << ", task prepare: " << objs.size()); std::sort(objs.begin(), objs.end(), IndexDistance::Shortest); for(std::vector<IndexDistance>::const_iterator it = objs.begin(); it != objs.end(); ++it) { if(task.size() >= HERO_MAX_SHEDULED_TASK) break; const bool validobj = AI::HeroesValidObject(hero, (*it).first); if(validobj && hero.GetPath().Calculate((*it).first)) { DEBUG(DBG_AI, DBG_INFO, Color::String(hero.GetColor()) << ", hero: " << hero.GetName() << ", added tasks: " << MP2::StringObject(ai_objects[(*it).first]) << ", index: " << (*it).first << ", distance: " << (*it).second); task.push_back((*it).first); ai_objects.erase((*it).first); } else { DEBUG(DBG_AI, DBG_TRACE, Color::String(hero.GetColor()) << ", hero: " << hero.GetName() << (!validobj ? ", invalid: " : ", impossible: ") << MP2::StringObject(ai_objects[(*it).first]) << ", index: " << (*it).first << ", distance: " << (*it).second); } } if(task.empty()) AIHeroesAddedRescueTask(hero); }