1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Merge branch 'develop' of https://github.com/vcmi/vcmi into develop

This commit is contained in:
DjWarmonger
2016-08-12 17:52:17 +02:00
10 changed files with 103 additions and 95 deletions

View File

@@ -1408,24 +1408,6 @@ bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h, SectorMap &sm)
return false;
}
std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
{
validateVisitableObjs();
std::vector<const CGObjectInstance *> possibleDestinations;
auto sm = getCachedSectorMap(h);
for(const CGObjectInstance *obj : visitableObjs)
{
if (isGoodForVisit(obj, h, *sm))
{
possibleDestinations.push_back(obj);
}
}
boost::sort(possibleDestinations, CDistanceSorter(h.get()));
return possibleDestinations;
}
bool VCAI::isTileNotReserved(const CGHeroInstance * h, int3 t)
{
if (t.valid())
@@ -1468,20 +1450,41 @@ void VCAI::wander(HeroPtr h)
while (h->movement)
{
validateVisitableObjs();
std::vector <ObjectIdRef> dests, tmp;
std::vector <ObjectIdRef> dests;
auto sm = getCachedSectorMap(h);
range::copy(reservedHeroesMap[h], std::back_inserter(tmp)); //also visit our reserved objects - but they are not prioritized to avoid running back and forth
for (auto obj : tmp)
//also visit our reserved objects - but they are not prioritized to avoid running back and forth
vstd::copy_if(reservedHeroesMap[h], std::back_inserter(dests), [&](ObjectIdRef obj) -> bool
{
int3 pos = sm->firstTileToGet(h, obj->visitablePos());
if (pos.valid())
if (isAccessibleForHero (pos, h)) //even nearby objects could be blocked by other heroes :(
dests.push_back(obj); //can't use lambda for member function :(
if(pos.valid() && isAccessibleForHero(pos, h)) //even nearby objects could be blocked by other heroes :(
return true;
return false;
});
int pass = 0;
while(!dests.size() && pass < 3)
{
if(pass < 2) // optimization - first check objects in current sector; then in sectors around
{
auto objs = sm->getNearbyObjs(h, pass);
vstd::copy_if(objs, std::back_inserter(dests), [&](ObjectIdRef obj) -> bool
{
return isGoodForVisit(obj, h, *sm);
});
}
else // we only check full objects list if for some reason there are no objects in closest sectors
{
vstd::copy_if(visitableObjs, std::back_inserter(dests), [&](ObjectIdRef obj) -> bool
{
return isGoodForVisit(obj, h, *sm);
});
}
pass++;
}
range::copy(getPossibleDestinations(h), std::back_inserter(dests));
vstd::erase_if(dests, [&](ObjectIdRef obj) -> bool
{
return !isSafeToVisit(h, sm->firstTileToGet(h, obj->visitablePos()));
@@ -1691,9 +1694,6 @@ void VCAI::clearPathsInfo()
void VCAI::validateVisitableObjs()
{
std::vector<const CGObjectInstance *> hlp;
retreiveVisitableObjs(hlp, true);
std::string errorMsg;
auto shouldBeErased = [&](const CGObjectInstance *obj) -> bool
{
@@ -1701,15 +1701,6 @@ void VCAI::validateVisitableObjs()
return !cb->getObj(obj->id, false); // no verbose output needed as we check object visibility
else
return true;
//why would we have our local logic for object checks? use cb!
//if(!vstd::contains(hlp, obj))
//{
// logAi->errorStream() << helperObjInfo[obj].name << " at " << helperObjInfo[obj].pos << errorMsg;
// return true;
//}
//return false;
};
//errorMsg is captured by ref so lambda will take the new text
@@ -1764,7 +1755,7 @@ std::vector<const CGObjectInstance *> VCAI::getFlaggedObjects() const
std::vector<const CGObjectInstance *> ret;
for(const CGObjectInstance *obj : visitableObjs)
{
if(obj->tempOwner == ai->playerID)
if(obj->tempOwner == playerID)
ret.push_back(obj);
}
return ret;
@@ -3070,10 +3061,7 @@ void SectorMap::exploreNewSector(crint3 pos, int num, CCallback * cbp)
if(t->visitable)
{
auto obj = t->visitableObjects.front();
if (vstd::contains(ai->knownSubterraneanGates, obj))
{
s.subterraneanGates.push_back (obj);
}
s.visitableObjs.push_back(obj);
}
}
}
@@ -3463,3 +3451,19 @@ TerrainTile* SectorMap::getTile(crint3 pos) const
//still we cached this array to avoid any checks
return visibleTiles->operator[](pos.x)[pos.y][pos.z];
}
std::vector<const CGObjectInstance *> SectorMap::getNearbyObjs(HeroPtr h, bool sectorsAround)
{
const Sector *heroSector = &infoOnSectors[retreiveTile(h->visitablePos())];
if(sectorsAround)
{
std::vector<const CGObjectInstance *> ret;
for(auto embarkPoint : heroSector->embarkmentPoints)
{
const Sector *embarkSector = &infoOnSectors[retreiveTile(embarkPoint)];
range::copy(embarkSector->visitableObjs, std::back_inserter(ret));
}
return ret;
}
return heroSector->visitableObjs;
}

View File

@@ -79,7 +79,7 @@ struct SectorMap
int id;
std::vector<int3> tiles;
std::vector<int3> embarkmentPoints; //tiles of other sectors onto which we can (dis)embark
std::vector<const CGObjectInstance *> subterraneanGates;
std::vector<const CGObjectInstance *> visitableObjs;
bool water; //all tiles of sector are land or water
Sector()
{
@@ -106,6 +106,7 @@ struct SectorMap
bool markIfBlocked(ui8 &sec, crint3 pos);
unsigned char &retreiveTile(crint3 pos);
TerrainTile* getTile(crint3 pos) const;
std::vector<const CGObjectInstance *> getNearbyObjs(HeroPtr h, bool sectorsAround);
void makeParentBFS(crint3 source);
@@ -259,7 +260,6 @@ public:
void recruitHero(const CGTownInstance * t, bool throwing = false);
bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h, SectorMap &sm);
std::vector<const CGObjectInstance *> getPossibleDestinations(HeroPtr h);
void buildStructure(const CGTownInstance * t);
//void recruitCreatures(const CGTownInstance * t);
void recruitCreatures(const CGDwelling * d, const CArmedInstance * recruiter);

View File

@@ -36,8 +36,8 @@ extern "C" DLL_EXPORT void BattleAI_GetNewBattleAI(std::shared_ptr<CBattleGameIn
template<typename rett>
std::shared_ptr<rett> createAny(const boost::filesystem::path& libpath, const std::string& methodName)
{
typedef void(*TGetAIFun)(std::shared_ptr<rett>&);
typedef void(*TGetNameFun)(char*);
typedef void(*TGetAIFun)(std::shared_ptr<rett>&);
typedef void(*TGetNameFun)(char*);
char temp[150];
@@ -105,7 +105,7 @@ std::shared_ptr<rett> createAny(const boost::filesystem::path& libpath, const st
std::shared_ptr<rett> ret;
getAI(ret);
if(!ret)
logGlobal->errorStream() << "Cannot get AI!";
logGlobal->error("Cannot get AI!");
return ret;
}

View File

@@ -490,12 +490,12 @@ int CGameState::pickUnusedHeroTypeRandomly(PlayerColor owner)
return RandomGeneratorUtil::nextItem(otherHeroes, rand)->getNum();
}
logGlobal->errorStream() << "No free allowed heroes!";
logGlobal->error("No free allowed heroes!");
auto notAllowedHeroesButStillBetterThanCrash = getUnusedAllowedHeroes(true);
if(notAllowedHeroesButStillBetterThanCrash.size())
return notAllowedHeroesButStillBetterThanCrash.begin()->getNum();
logGlobal->errorStream() << "No free heroes at all!";
logGlobal->error("No free heroes at all!");
assert(0); //current code can't handle this situation
return -1; // no available heroes at all
}
@@ -769,13 +769,13 @@ void CGameState::init(StartInfo * si)
return;
}
VLC->arth->initAllowedArtifactsList(map->allowedArtifact);
logGlobal->infoStream() << "Map loaded!";
logGlobal->info("Map loaded!");
checkMapChecksum();
day = 0;
logGlobal->debugStream() << "Initialization:";
logGlobal->debug("Initialization:");
initPlayerStates();
placeCampaignHeroes();
@@ -792,7 +792,7 @@ void CGameState::init(StartInfo * si)
initVisitingAndGarrisonedHeroes();
initFogOfWar();
logGlobal->debugStream() << "\tChecking objectives";
logGlobal->debug("\tChecking objectives");
map->checkForObjectives(); //needs to be run when all objects are properly placed
auto seedAfterInit = rand.nextInt();
@@ -812,7 +812,7 @@ void CGameState::initNewGame()
{
if(scenarioOps->createRandomMap())
{
logGlobal->infoStream() << "Create random map.";
logGlobal->info("Create random map.");
CStopWatch sw;
// Gen map
@@ -874,7 +874,7 @@ void CGameState::initDuel()
{
logGlobal->infoStream() << "Loading duel settings from JSON file: " << scenarioOps->mapname;
dp = DuelParameters::fromJSON(scenarioOps->mapname);
logGlobal->infoStream() << "JSON file has been successfully read!";
logGlobal->info("JSON file has been successfully read!");
}
else
{
@@ -974,7 +974,7 @@ void CGameState::checkMapChecksum()
logGlobal->infoStream() << "\tServer checksum for " << scenarioOps->mapname <<": "<< scenarioOps->mapfileChecksum;
if(map->checksum != scenarioOps->mapfileChecksum)
{
logGlobal->errorStream() << "Wrong map checksum!!!";
logGlobal->error("Wrong map checksum!!!");
throw std::runtime_error("Wrong checksum");
}
}
@@ -986,7 +986,7 @@ void CGameState::checkMapChecksum()
void CGameState::initGrailPosition()
{
logGlobal->debugStream() << "\tPicking grail position";
logGlobal->debug("\tPicking grail position");
//pick grail location
if(map->grailPos.x < 0 || map->grailRadius) //grail not set or set within a radius around some place
{
@@ -1025,14 +1025,14 @@ void CGameState::initGrailPosition()
}
else
{
logGlobal->warnStream() << "Warning: Grail cannot be placed, no appropriate tile found!";
logGlobal->warn("Grail cannot be placed, no appropriate tile found!");
}
}
}
void CGameState::initRandomFactionsForPlayers()
{
logGlobal->debugStream() << "\tPicking random factions for players";
logGlobal->debug("\tPicking random factions for players");
for(auto & elem : scenarioOps->playerInfos)
{
if(elem.second.castle==-1)
@@ -1048,7 +1048,7 @@ void CGameState::initRandomFactionsForPlayers()
void CGameState::randomizeMapObjects()
{
logGlobal->debugStream() << "\tRandomizing objects";
logGlobal->debug("\tRandomizing objects");
for(CGObjectInstance *obj : map->objects)
{
if(!obj) continue;
@@ -1072,7 +1072,7 @@ void CGameState::randomizeMapObjects()
void CGameState::initPlayerStates()
{
logGlobal->debugStream() << "\tCreating player entries in gs";
logGlobal->debug("\tCreating player entries in gs");
for(auto & elem : scenarioOps->playerInfos)
{
std::pair<PlayerColor, PlayerState> ins(elem.first,PlayerState());
@@ -1114,10 +1114,10 @@ void CGameState::placeCampaignHeroes()
if(!crossoverHeroes.heroesFromAnyPreviousScenarios.empty())
{
logGlobal->debugStream() << "\tGenerate list of hero placeholders";
logGlobal->debug("\tGenerate list of hero placeholders");
auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
logGlobal->debugStream() << "\tPrepare crossover heroes";
logGlobal->debug("\tPrepare crossover heroes");
prepareCrossoverHeroes(campaignHeroReplacements, scenarioOps->campState->getCurrentScenario().travelOptions);
// remove same heroes on the map which will be added through crossover heroes
@@ -1137,7 +1137,7 @@ void CGameState::placeCampaignHeroes()
}
}
logGlobal->debugStream() << "\tReplace placeholders with heroes";
logGlobal->debug("\tReplace placeholders with heroes");
replaceHeroesPlaceholders(campaignHeroReplacements);
// remove hero placeholders on map
@@ -1169,7 +1169,7 @@ void CGameState::placeCampaignHeroes()
}
else
{
logGlobal->errorStream() << "No free hero type ID found to replace prison.";
logGlobal->error("No free hero type ID found to replace prison.");
assert(0);
}
}
@@ -1365,7 +1365,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
void CGameState::placeStartingHeroes()
{
logGlobal->debugStream() << "\tGiving starting hero";
logGlobal->debug("\tGiving starting hero");
for(auto & playerSettingPair : scenarioOps->playerInfos)
{
@@ -1393,7 +1393,7 @@ void CGameState::placeStartingHeroes()
void CGameState::initStartingResources()
{
logGlobal->debugStream() << "\tSetting up resources";
logGlobal->debug("\tSetting up resources");
const JsonNode config(ResourceID("config/startres.json"));
const JsonVector &vector = config["difficulty"].Vector();
const JsonNode &level = vector[scenarioOps->difficulty];
@@ -1465,7 +1465,7 @@ void CGameState::initHeroes()
{
if (hero->getOwner() == PlayerColor::UNFLAGGABLE)
{
logGlobal->warnStream() << "Warning - hero with uninitialized owner!";
logGlobal->warn("Hero with uninitialized owner!");
continue;
}
@@ -1539,7 +1539,7 @@ void CGameState::initHeroes()
}
}
if(maxB < 0)
logGlobal->warnStream() << "Warning - cannot give bonus to hero cause there are no heroes!";
logGlobal->warn("Cannot give bonus to hero cause there are no heroes!");
else
giveCampaignBonusToHero(heroes[maxB]);
}
@@ -1617,7 +1617,7 @@ void CGameState::giveCampaignBonusToHero(CGHeroInstance * hero)
void CGameState::initFogOfWar()
{
logGlobal->debugStream() << "\tFog of war"; //FIXME: should be initialized after all bonuses are set
logGlobal->debug("\tFog of war"); //FIXME: should be initialized after all bonuses are set
for(auto & elem : teams)
{
elem.second.fogOfWarMap.resize(map->width);
@@ -1649,7 +1649,7 @@ void CGameState::initFogOfWar()
void CGameState::initStartingBonus()
{
logGlobal->debugStream() << "\tStarting bonuses";
logGlobal->debug("\tStarting bonuses");
for(auto & elem : players)
{
//starting bonus
@@ -1679,7 +1679,7 @@ void CGameState::initStartingBonus()
{
if(!elem.second.heroes.size())
{
logGlobal->debugStream() << "Cannot give starting artifact - no heroes!";
logGlobal->error("Cannot give starting artifact - no heroes!");
break;
}
CArtifact *toGive;
@@ -1695,7 +1695,7 @@ void CGameState::initStartingBonus()
void CGameState::initTowns()
{
logGlobal->debugStream() << "\tTowns";
logGlobal->debug("\tTowns");
//campaign bonuses for towns
if (scenarioOps->mode == StartInfo::CAMPAIGN)
@@ -1846,7 +1846,7 @@ void CGameState::initTowns()
void CGameState::initMapObjects()
{
logGlobal->debugStream() << "\tObject initialization";
logGlobal->debug("\tObject initialization");
// objCaller->preInit();
for(CGObjectInstance *obj : map->objects)
{

View File

@@ -132,7 +132,7 @@ void Unicode::trimRight(std::string & text, const size_t amount/* =1 */)
return;
//todo: more efficient algorithm
for(int i = 0; i< amount; i++){
auto b = text.begin();
auto b = text.begin();
auto e = text.end();
size_t lastLen = 0;
size_t len = 0;
@@ -141,14 +141,14 @@ void Unicode::trimRight(std::string & text, const size_t amount/* =1 */)
size_t n = getCharacterSize(*b);
if(!isValidCharacter(&(*b),e-b))
{
logGlobal->errorStream() << "Invalid UTF8 sequence";
{
logGlobal->error("Invalid UTF8 sequence");
break;//invalid sequence will be trimmed
}
len += n;
b += n;
}
}
text.resize(lastLen);
}
@@ -217,13 +217,13 @@ std::string CLegacyConfigParser::extractQuotedString()
char * begin = curr;
while (curr < end && *curr != '\t' && *curr != '\r' && *curr != '\"')//find end of string or next quoted part start
curr++;
curr++;
ret += std::string(begin, curr);
if(curr>=end || *curr != '\"')
return ret;
}
}
else // end of string
return ret;
}

View File

@@ -80,7 +80,7 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
toBlock += BattleHex::LEFT;
if(!toBlock.isValid())
logGlobal->errorStream() << "Misplaced obstacle!";
logGlobal->error("Misplaced obstacle!");
else
ret.push_back(toBlock);
}
@@ -577,7 +577,7 @@ ui64 CHeroHandler::reqExp (ui32 level) const
}
else
{
logGlobal->warnStream() << "A hero has reached unsupported amount of experience";
logGlobal->warn("A hero has reached unsupported amount of experience");
return expPerLevel[expPerLevel.size()-1];
}
}

View File

@@ -113,11 +113,11 @@ CConnection::CConnection(std::string host, std::string port, std::string Name)
//we shouldn't be here - error handling
connerror1:
logNetwork->errorStream() << "Something went wrong... checking for error info";
logNetwork->error("Something went wrong... checking for error info");
if(error)
logNetwork->errorStream() << error;
else
logNetwork->errorStream() << "No error info. ";
logNetwork->error("No error info.");
delete io_service;
//delete socket;
throw std::runtime_error("Can't establish connection :(");

View File

@@ -23,7 +23,7 @@
BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain_Type)
{
logGlobal->infoStream() << "CMapEditManager_DrawTerrain_Type start";
logGlobal->info("CMapEditManager_DrawTerrain_Type start");
try
{
auto map = make_unique<CMap>();
@@ -103,21 +103,22 @@ BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain_Type)
}
catch(const std::exception & e)
{
logGlobal->errorStream() << "CMapEditManager_DrawTerrain_Type crash" << "\n" << e.what();
logGlobal->error("CMapEditManager_DrawTerrain_Type crash");
logGlobal->error(e.what());
throw;
}
logGlobal->infoStream() << "CMapEditManager_DrawTerrain_Type finish";
logGlobal->info("CMapEditManager_DrawTerrain_Type finish");
}
BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain_View)
{
logGlobal->infoStream() << "CMapEditManager_DrawTerrain_View start";
logGlobal->info("CMapEditManager_DrawTerrain_View start");
try
{
// Load maps and json config
const auto originalMap = CMapService::loadMap("test/TerrainViewTest");
auto map = CMapService::loadMap("test/TerrainViewTest");
logGlobal->infoStream() << "Loaded test map successfully.";
logGlobal->info("Loaded test map successfully.");
// Validate edit manager
auto editManager = map->getEditManager();
@@ -163,14 +164,16 @@ BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain_View)
}
}
BOOST_CHECK(isInRange);
if(!isInRange) logGlobal->errorStream() << "No or invalid pattern found for current position.";
if(!isInRange)
logGlobal->error("No or invalid pattern found for current position.");
}
}
}
catch(const std::exception & e)
{
logGlobal->infoStream() << "CMapEditManager_DrawTerrain_View crash"<< "\n" << e.what();
logGlobal->info("CMapEditManager_DrawTerrain_View crash");
logGlobal->info(e.what());
throw;
}
logGlobal->infoStream() << "CMapEditManager_DrawTerrain_View finish";
logGlobal->info("CMapEditManager_DrawTerrain_View finish");
}

View File

@@ -78,7 +78,8 @@ BOOST_AUTO_TEST_CASE(CMapFormatVCMI_Simple)
tmp.flush();
tmp.close();
logGlobal->infoStream() << "Test map has been saved to " << path;
logGlobal->info("Test map has been saved to:");
logGlobal->info(path.string());
}
BOOST_TEST_CHECKPOINT("CMapFormatVCMI_Simple saved");

View File

@@ -31,7 +31,7 @@ CVcmiTestConfig::CVcmiTestConfig()
settings.init();
logConfig.configure();
loadDLLClasses();
logGlobal->infoStream() << "Initialized global test setup.";
logGlobal->info("Initialized global test setup.");
const std::string TEST_DATA_DIR = "test/";