void CMap::checkForObjectives() { // NOTE: probably should be moved to MapFormatH3M.cpp for (TriggeredEvent & event : triggeredEvents) { auto patcher = [&](EventCondition cond) -> EventExpression::Variant { switch (cond.condition) { break; case EventCondition::HAVE_ARTIFACT: boost::algorithm::replace_first(event.onFulfill, "%s", VLC->arth->artifacts[cond.objectType]->Name()); break; case EventCondition::HAVE_CREATURES: boost::algorithm::replace_first(event.onFulfill, "%s", VLC->creh->creatures[cond.objectType]->nameSing); boost::algorithm::replace_first(event.onFulfill, "%d", boost::lexical_cast<std::string>(cond.value)); break; case EventCondition::HAVE_RESOURCES: boost::algorithm::replace_first(event.onFulfill, "%s", VLC->generaltexth->restypes[cond.objectType]); boost::algorithm::replace_first(event.onFulfill, "%d", boost::lexical_cast<std::string>(cond.value)); break; case EventCondition::HAVE_BUILDING: if (isInTheMap(cond.position)) cond.object = getObjectiveObjectFrom(cond.position, Obj::TOWN); break; case EventCondition::CONTROL: if (isInTheMap(cond.position)) cond.object = getObjectiveObjectFrom(cond.position, Obj::EObj(cond.objectType)); if (cond.object) { const CGTownInstance *town = dynamic_cast<const CGTownInstance*>(cond.object); if (town) boost::algorithm::replace_first(event.onFulfill, "%s", town->name); const CGHeroInstance *hero = dynamic_cast<const CGHeroInstance*>(cond.object); if (hero) boost::algorithm::replace_first(event.onFulfill, "%s", hero->name); } break; case EventCondition::DESTROY: if (isInTheMap(cond.position)) cond.object = getObjectiveObjectFrom(cond.position, Obj::EObj(cond.objectType)); if (cond.object) { const CGHeroInstance *hero = dynamic_cast<const CGHeroInstance*>(cond.object); if (hero) boost::algorithm::replace_first(event.onFulfill, "%s", hero->name); } break; case EventCondition::TRANSPORT: cond.object = getObjectiveObjectFrom(cond.position, Obj::TOWN); //break; case EventCondition::DAYS_PASSED: //break; case EventCondition::IS_HUMAN: //break; case EventCondition::DAYS_WITHOUT_TOWN: //break; case EventCondition::STANDARD_WIN: } return cond; }; event.trigger = event.trigger.morph(patcher); } }
bool CMap::isCoastalTile(const int3 & pos) const { //todo: refactoring: extract neighbor tile iterator and use it in GameState static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0), int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) }; if(!isInTheMap(pos)) { logGlobal->errorStream() << "Coastal check outside of map :"<<pos; return false; } if(isWaterTile(pos)) return false; for (auto & dir : dirs) { const int3 hlp = pos + dir; if(!isInTheMap(hlp)) continue; const TerrainTile &hlpt = getTile(hlp); if(hlpt.isWater()) return true; } return false; }
int3 CMap::guardingCreaturePosition (int3 pos) const { const int3 originalPos = pos; // Give monster at position priority. if (!isInTheMap(pos)) return int3(-1, -1, -1); const TerrainTile &posTile = getTile(pos); if (posTile.visitable) { for (CGObjectInstance* obj : posTile.visitableObjects) { if(obj->blockVisit) { if (obj->ID == Obj::MONSTER) // Monster return pos; else return int3(-1, -1, -1); //blockvis objects are not guarded by neighbouring creatures } } } // See if there are any monsters adjacent. bool water = posTile.isWater(); pos -= int3(1, 1, 0); // Start with top left. for (int dx = 0; dx < 3; dx++) { for (int dy = 0; dy < 3; dy++) { if (isInTheMap(pos)) { const auto & tile = getTile(pos); if (tile.visitable && (tile.isWater() == water)) { for (CGObjectInstance* obj : tile.visitableObjects) { if (obj->ID == Obj::MONSTER && checkForVisitableDir(pos, &posTile, originalPos)) // Monster being able to attack investigated tile { return pos; } } } } pos.y++; } pos.y -= 3; pos.x++; } return int3(-1, -1, -1); }
bool CMap::isWaterTile(const int3 &pos) const { return isInTheMap(pos) && getTile(pos).terType == ETerrainType::WATER; }
const TerrainTile & CMap::getTile(const int3 & tile) const { assert(isInTheMap(tile)); return terrain[tile.x][tile.y][tile.z]; }
bool CMap::isWaterTile(const int3 &pos) const { return isInTheMap(pos) && getTile(pos).isWater(); }