1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

- Added new trace macro LOG_TRACE which autom. appends leaving func message - Removed old trace macros - Small refactoring in CMapEditManager - Changed documentation comments to /// style for various mapping header files

This commit is contained in:
beegee1
2013-04-16 13:16:58 +00:00
parent feea589648
commit 45fccfb1a6
8 changed files with 397 additions and 958 deletions

View File

@@ -428,28 +428,25 @@ bool compareDanger(const CGObjectInstance *lhs, const CGObjectInstance *rhs)
VCAI::VCAI(void) VCAI::VCAI(void)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
myCb = NULL; myCb = NULL;
makingTurn = NULL; makingTurn = NULL;
TRACE_END(logAi);
} }
VCAI::~VCAI(void) VCAI::~VCAI(void)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
} }
void VCAI::availableCreaturesChanged(const CGDwelling *town) void VCAI::availableCreaturesChanged(const CGDwelling *town)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroMoved(const TryMoveHero & details) void VCAI::heroMoved(const TryMoveHero & details)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if(details.result == TryMoveHero::TELEPORTATION) if(details.result == TryMoveHero::TELEPORTATION)
{ {
@@ -465,84 +462,73 @@ void VCAI::heroMoved(const TryMoveHero & details)
logAi->debugStream() << boost::format("Found a pair of subterranean gates between %s and %s!") % from % to; logAi->debugStream() << boost::format("Found a pair of subterranean gates between %s and %s!") % from % to;
} }
} }
TRACE_END(logAi);
} }
void VCAI::stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute) void VCAI::stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute)
{ {
TRACE_BEGIN_PARAMS(logAi, "isAbsolute '%i'", isAbsolute); LOG_TRACE_PARAMS(logAi, "isAbsolute '%i'", isAbsolute);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroInGarrisonChange(const CGTownInstance *town) void VCAI::heroInGarrisonChange(const CGTownInstance *town)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::centerView(int3 pos, int focusTime) void VCAI::centerView(int3 pos, int focusTime)
{ {
TRACE_BEGIN_PARAMS(logAi, "focusTime '%i'", focusTime); LOG_TRACE_PARAMS(logAi, "focusTime '%i'", focusTime);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst) void VCAI::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::artifactAssembled(const ArtifactLocation &al) void VCAI::artifactAssembled(const ArtifactLocation &al)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showTavernWindow(const CGObjectInstance *townOrTavern) void VCAI::showTavernWindow(const CGObjectInstance *townOrTavern)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showThievesGuildWindow (const CGObjectInstance * obj) void VCAI::showThievesGuildWindow (const CGObjectInstance * obj)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::playerBlocked(int reason) void VCAI::playerBlocked(int reason)
{ {
TRACE_BEGIN_PARAMS(logAi, "reason '%i'", reason); LOG_TRACE_PARAMS(logAi, "reason '%i'", reason);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if (reason == PlayerBlocked::UPCOMING_BATTLE) if (reason == PlayerBlocked::UPCOMING_BATTLE)
status.setBattle(UPCOMING_BATTLE); status.setBattle(UPCOMING_BATTLE);
TRACE_END(logAi);
} }
void VCAI::showPuzzleMap() void VCAI::showPuzzleMap()
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showShipyardDialog(const IShipyard *obj) void VCAI::showShipyardDialog(const IShipyard *obj)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::gameOver(PlayerColor player, bool victory) void VCAI::gameOver(PlayerColor player, bool victory)
{ {
TRACE_BEGIN_PARAMS(logAi, "victory '%i'", victory); LOG_TRACE_PARAMS(logAi, "victory '%i'", victory);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
logAi->debugStream() << boost::format("Player %d: I heard that player %d %s.") % playerID % player.getNum() % (victory ? "won" : "lost"); logAi->debugStream() << boost::format("Player %d: I heard that player %d %s.") % playerID % player.getNum() % (victory ? "won" : "lost");
if(player == playerID) if(player == playerID)
@@ -569,41 +555,36 @@ void VCAI::gameOver(PlayerColor player, bool victory)
finish(); finish();
} }
TRACE_END(logAi);
} }
void VCAI::artifactPut(const ArtifactLocation &al) void VCAI::artifactPut(const ArtifactLocation &al)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::artifactRemoved(const ArtifactLocation &al) void VCAI::artifactRemoved(const ArtifactLocation &al)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::stacksErased(const StackLocation &location) void VCAI::stacksErased(const StackLocation &location)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::artifactDisassembled(const ArtifactLocation &al) void VCAI::artifactDisassembled(const ArtifactLocation &al)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visitedObj, bool start) void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visitedObj, bool start)
{ {
TRACE_BEGIN_PARAMS(logAi, "start '%i'", start); LOG_TRACE_PARAMS(logAi, "start '%i'", start);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if (start) if (start)
{ {
@@ -613,49 +594,44 @@ void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visi
remove_if_present(reservedHeroesMap[visitor], visitedObj); remove_if_present(reservedHeroesMap[visitor], visitedObj);
completeGoal (CGoal(GET_OBJ).sethero(visitor)); //we don't need to visit in anymore completeGoal (CGoal(GET_OBJ).sethero(visitor)); //we don't need to visit in anymore
} }
TRACE_END(logAi);
} }
void VCAI::availableArtifactsChanged(const CGBlackMarket *bm /*= NULL*/) void VCAI::availableArtifactsChanged(const CGBlackMarket *bm /*= NULL*/)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) void VCAI::heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
//buildArmyIn(town); //buildArmyIn(town);
//moveCreaturesToHero(town); //moveCreaturesToHero(town);
TRACE_END(logAi);
} }
void VCAI::tileHidden(const boost::unordered_set<int3, ShashInt3> &pos) void VCAI::tileHidden(const boost::unordered_set<int3, ShashInt3> &pos)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
// BOOST_FOREACH(int3 tile, pos) // BOOST_FOREACH(int3 tile, pos)
// BOOST_FOREACH(const CGObjectInstance *obj, cb->getVisitableObjs(tile)) // BOOST_FOREACH(const CGObjectInstance *obj, cb->getVisitableObjs(tile))
// remove_if_present(visitableObjs, obj); // remove_if_present(visitableObjs, obj);
visitableObjs.erase(boost::remove_if(visitableObjs, [&](const CGObjectInstance *obj){return !myCb->getObj(obj->id);}), visitableObjs.end()); visitableObjs.erase(boost::remove_if(visitableObjs, [&](const CGObjectInstance *obj){return !myCb->getObj(obj->id);}), visitableObjs.end());
TRACE_END(logAi);
} }
void VCAI::tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos) void VCAI::tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
BOOST_FOREACH(int3 tile, pos) BOOST_FOREACH(int3 tile, pos)
BOOST_FOREACH(const CGObjectInstance *obj, myCb->getVisitableObjs(tile)) BOOST_FOREACH(const CGObjectInstance *obj, myCb->getVisitableObjs(tile))
addVisitableObj(obj); addVisitableObj(obj);
TRACE_END(logAi);
} }
void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2) void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
auto firstHero = cb->getHero(hero1); auto firstHero = cb->getHero(hero1);
@@ -672,56 +648,49 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2)
completeGoal(CGoal(VISIT_HERO).sethero(secondHero)); completeGoal(CGoal(VISIT_HERO).sethero(secondHero));
//TODO: exchange artifacts //TODO: exchange artifacts
}); });
TRACE_END(logAi);
} }
void VCAI::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) void VCAI::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val)
{ {
TRACE_BEGIN_PARAMS(logAi, "which '%i', val '%i'", which % val); LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", which % val);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) void VCAI::showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level)
{ {
TRACE_BEGIN_PARAMS(logAi, "level '%i'", level); LOG_TRACE_PARAMS(logAi, "level '%i'", level);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroMovePointsChanged(const CGHeroInstance * hero) void VCAI::heroMovePointsChanged(const CGHeroInstance * hero)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::stackChangedType(const StackLocation &location, const CCreature &newType) void VCAI::stackChangedType(const StackLocation &location, const CCreature &newType)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count) void VCAI::stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::newObject(const CGObjectInstance * obj) void VCAI::newObject(const CGObjectInstance * obj)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if(obj->isVisitable()) if(obj->isVisitable())
addVisitableObj(obj); addVisitableObj(obj);
TRACE_END(logAi);
} }
void VCAI::objectRemoved(const CGObjectInstance *obj) void VCAI::objectRemoved(const CGObjectInstance *obj)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if(remove_if_present(visitableObjs, obj)) if(remove_if_present(visitableObjs, obj))
@@ -738,59 +707,52 @@ void VCAI::objectRemoved(const CGObjectInstance *obj)
{ {
lostHero(cb->getHero(obj->id)); //we can promote, since objectRemoved is killed just before actual deletion lostHero(cb->getHero(obj->id)); //we can promote, since objectRemoved is killed just before actual deletion
} }
TRACE_END(logAi);
} }
void VCAI::showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor) void VCAI::showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
requestActionASAP([=]() requestActionASAP([=]()
{ {
makePossibleUpgrades(visitor); makePossibleUpgrades(visitor);
}); });
TRACE_END(logAi);
} }
void VCAI::playerBonusChanged(const Bonus &bonus, bool gain) void VCAI::playerBonusChanged(const Bonus &bonus, bool gain)
{ {
TRACE_BEGIN_PARAMS(logAi, "gain '%i'", gain); LOG_TRACE_PARAMS(logAi, "gain '%i'", gain);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::newStackInserted(const StackLocation &location, const CStackInstance &stack) void VCAI::newStackInserted(const StackLocation &location, const CStackInstance &stack)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroCreated(const CGHeroInstance*) void VCAI::heroCreated(const CGHeroInstance*)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::advmapSpellCast(const CGHeroInstance * caster, int spellID) void VCAI::advmapSpellCast(const CGHeroInstance * caster, int spellID)
{ {
TRACE_BEGIN_PARAMS(logAi, "spellID '%i", spellID); LOG_TRACE_PARAMS(logAi, "spellID '%i", spellID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) void VCAI::showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID)
{ {
TRACE_BEGIN_PARAMS(logAi, "soundID '%i'", soundID); LOG_TRACE_PARAMS(logAi, "soundID '%i'", soundID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::requestRealized(PackageApplied *pa) void VCAI::requestRealized(PackageApplied *pa)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if(status.haveTurn()) if(status.haveTurn())
{ {
@@ -803,56 +765,49 @@ void VCAI::requestRealized(PackageApplied *pa)
{ {
status.receivedAnswerConfirmation(pa->requestID, pa->result); status.receivedAnswerConfirmation(pa->requestID, pa->result);
} }
TRACE_END(logAi);
} }
void VCAI::receivedResource(int type, int val) void VCAI::receivedResource(int type, int val)
{ {
TRACE_BEGIN_PARAMS(logAi, "type '%i', val '%i'", type % val); LOG_TRACE_PARAMS(logAi, "type '%i', val '%i'", type % val);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::stacksSwapped(const StackLocation &loc1, const StackLocation &loc2) void VCAI::stacksSwapped(const StackLocation &loc1, const StackLocation &loc2)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) void VCAI::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroManaPointsChanged(const CGHeroInstance * hero) void VCAI::heroManaPointsChanged(const CGHeroInstance * hero)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) void VCAI::heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val)
{ {
TRACE_BEGIN_PARAMS(logAi, "which '%', val '%'", which % val); LOG_TRACE_PARAMS(logAi, "which '%', val '%'", which % val);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::battleResultsApplied() void VCAI::battleResultsApplied()
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
assert(status.getBattle() == ENDING_BATTLE); assert(status.getBattle() == ENDING_BATTLE);
status.setBattle(NO_BATTLE); status.setBattle(NO_BATTLE);
TRACE_END(logAi);
} }
void VCAI::objectPropertyChanged(const SetObjectProperty * sop) void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
if(sop->what == ObjProperty::OWNER) if(sop->what == ObjProperty::OWNER)
{ {
@@ -860,33 +815,29 @@ void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
remove_if_present(visitableObjs, myCb->getObj(sop->id)); remove_if_present(visitableObjs, myCb->getObj(sop->id));
//TODO restore lost obj //TODO restore lost obj
} }
TRACE_END(logAi);
} }
void VCAI::buildChanged(const CGTownInstance *town, BuildingID buildingID, int what) void VCAI::buildChanged(const CGTownInstance *town, BuildingID buildingID, int what)
{ {
TRACE_BEGIN_PARAMS(logAi, "what '%i'", what); LOG_TRACE_PARAMS(logAi, "what '%i'", what);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) void VCAI::heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain)
{ {
TRACE_BEGIN_PARAMS(logAi, "gain '%i'", gain); LOG_TRACE_PARAMS(logAi, "gain '%i'", gain);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) void VCAI::showMarketWindow(const IMarket *market, const CGHeroInstance *visitor)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::init(CCallback * CB) void VCAI::init(CCallback * CB)
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
myCb = CB; myCb = CB;
cbc = CB; cbc = CB;
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
@@ -898,39 +849,35 @@ void VCAI::init(CCallback * CB)
fh = new FuzzyHelper(); fh = new FuzzyHelper();
retreiveVisitableObjs(visitableObjs); retreiveVisitableObjs(visitableObjs);
TRACE_END(logAi);
} }
void VCAI::yourTurn() void VCAI::yourTurn()
{ {
TRACE_BEGIN(logAi); LOG_TRACE(logAi);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
status.startedTurn(); status.startedTurn();
makingTurn = new boost::thread(&VCAI::makeTurn, this); makingTurn = new boost::thread(&VCAI::makeTurn, this);
TRACE_END(logAi);
} }
void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID) void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID)
{ {
TRACE_BEGIN_PARAMS(logAi, "queryID '%i'", queryID); LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->name % hero->level)); status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->name % hero->level));
requestActionASAP([=]{ answerQuery(queryID, 0); }); requestActionASAP([=]{ answerQuery(queryID, 0); });
TRACE_END(logAi);
} }
void VCAI::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID) void VCAI::commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID)
{ {
TRACE_BEGIN_PARAMS(logAi, "queryID '%i'", queryID); LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
status.addQuery(queryID, boost::str(boost::format("Commander %s of %s got level %d") % commander->name % commander->armyObj->nodeName() % (int)commander->level)); status.addQuery(queryID, boost::str(boost::format("Commander %s of %s got level %d") % commander->name % commander->armyObj->nodeName() % (int)commander->level));
requestActionASAP([=]{ answerQuery(queryID, 0); }); requestActionASAP([=]{ answerQuery(queryID, 0); });
TRACE_END(logAi);
} }
void VCAI::showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) void VCAI::showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel)
{ {
TRACE_BEGIN_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel); LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
int sel = 0; int sel = 0;
status.addQuery(askID, boost::str(boost::format("Blocking dialog query with %d components - %s") status.addQuery(askID, boost::str(boost::format("Blocking dialog query with %d components - %s")
@@ -946,12 +893,11 @@ void VCAI::showBlockingDialog(const std::string &text, const std::vector<Compone
{ {
answerQuery(askID, sel); answerQuery(askID, sel);
}); });
TRACE_END(logAi);
} }
void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID)
{ {
TRACE_BEGIN_PARAMS(logAi, "removableUnits '%i', queryID '%i'", removableUnits % queryID); LOG_TRACE_PARAMS(logAi, "removableUnits '%i', queryID '%i'", removableUnits % queryID);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
std::string s1 = up ? up->nodeName() : "NONE"; std::string s1 = up ? up->nodeName() : "NONE";
@@ -965,21 +911,18 @@ void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *do
pickBestCreatures (down, up); pickBestCreatures (down, up);
answerQuery(queryID, 0); answerQuery(queryID, 0);
}); });
TRACE_END(logAi);
} }
void VCAI::serialize(COSer<CSaveFile> &h, const int version) void VCAI::serialize(COSer<CSaveFile> &h, const int version)
{ {
TRACE_BEGIN_PARAMS(logAi, "version '%i'", version); LOG_TRACE_PARAMS(logAi, "version '%i'", version);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void VCAI::serialize(CISer<CLoadFile> &h, const int version) void VCAI::serialize(CISer<CLoadFile> &h, const int version)
{ {
TRACE_BEGIN_PARAMS(logAi, "version '%i'", version); LOG_TRACE_PARAMS(logAi, "version '%i'", version);
NET_EVENT_HANDLER; NET_EVENT_HANDLER;
TRACE_END(logAi);
} }
void makePossibleUpgrades(const CArmedInstance *obj) void makePossibleUpgrades(const CArmedInstance *obj)

View File

@@ -219,6 +219,17 @@ bool CLogger::isTraceEnabled() const
return getEffectiveLevel() <= ELogLevel::TRACE; return getEffectiveLevel() <= ELogLevel::TRACE;
} }
CTraceLogger::CTraceLogger(const CLogger * logger, const std::string & beginMessage, const std::string & endMessage)
: logger(logger), endMessage(endMessage)
{
logger->traceStream() << beginMessage;
}
CTraceLogger::~CTraceLogger()
{
logger->traceStream() << endMessage;
}
boost::recursive_mutex CLogManager::smx; boost::recursive_mutex CLogManager::smx;
CLogManager & CLogManager::get() CLogManager & CLogManager::get()

View File

@@ -126,15 +126,25 @@ extern DLL_LINKAGE CLogger * logBonus;
extern DLL_LINKAGE CLogger * logNetwork; extern DLL_LINKAGE CLogger * logNetwork;
extern DLL_LINKAGE CLogger * logAi; extern DLL_LINKAGE CLogger * logAi;
/// Macros for tracing the control flow of the application conveniently. If the TRACE_BEGIN macro is used it should be /// RAII class for tracing the program execution.
/// the first statement in the function, whereas the TRACE_END should be last one before a return statement. /// It prints "Leaving function XYZ" automatically when the object gets destructed.
/// Logging traces via this macro have almost no impact when the trace is disabled. class DLL_LINKAGE CTraceLogger
#define TRACE_BEGIN(logger) logger->traceStream() << boost::format("Entering %s.") % BOOST_CURRENT_FUNCTION; {
#define TRACE_BEGIN_PARAMS(logger, formatStr, params) if(logger->isTraceEnabled()) logger->traceStream() << \ public:
boost::format("Entering %s: " + std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params; CTraceLogger(const CLogger * logger, const std::string & beginMessage, const std::string & endMessage);
#define TRACE_END(logger) logger->traceStream() << boost::format("Leaving %s.") % BOOST_CURRENT_FUNCTION; ~CTraceLogger();
#define TRACE_END_PARAMS(logger, formatStr, params) if(logger->isTraceEnabled()) logger->traceStream() << \
boost::format("Leaving %s: " + std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params; private:
const CLogger * logger;
std::string endMessage;
};
/// Macros for tracing the control flow of the application conveniently. If the LOG_TRACE macro is used it should be
/// the first statement in the function. Logging traces via this macro have almost no impact when the trace is disabled.
#define LOG_TRACE(logger) if(logger->isTraceEnabled()) CTraceLogger ctl00(logger, boost::str(boost::format("Entering %s.") % BOOST_CURRENT_FUNCTION), \
boost::str(boost::format("Leaving %s.") % BOOST_CURRENT_FUNCTION))
#define LOG_TRACE_PARAMS(logger, formatStr, params) if(logger->isTraceEnabled()) CTraceLogger ctl00(logger, boost::str(boost::format("Entering %s: " + \
std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params), boost::str(boost::format("Leaving %s.") % BOOST_CURRENT_FUNCTION))
/* ---------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------- */
/* Implementation/Detail classes, Private API */ /* Implementation/Detail classes, Private API */

View File

@@ -29,25 +29,14 @@ class IModableArt;
class IQuestObject; class IQuestObject;
class CInputStream; class CInputStream;
/** /// The hero name struct consists of the hero id and the hero name.
* The hero name struct consists of the hero id and the hero name.
*/
struct DLL_LINKAGE SHeroName struct DLL_LINKAGE SHeroName
{ {
/**
* Default c-tor.
*/
SHeroName(); SHeroName();
/** the id of the hero */
int heroId; int heroId;
/** the name of the hero */
std::string heroName; std::string heroName;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -67,91 +56,39 @@ enum EAiTactic
}; };
} }
/** /// The player info constains data about which factions are allowed, AI tactical settings,
* The player info constains data about which factions are allowed, AI tactical settings, /// the main hero name, where to generate the hero, whether the faction should be selected randomly,...
* the main hero name, where to generate the hero, whether the faction should be selected randomly,...
*/
struct DLL_LINKAGE PlayerInfo struct DLL_LINKAGE PlayerInfo
{ {
/**
* Default constructor.
*/
PlayerInfo(); PlayerInfo();
/** /// Gets the default faction id or -1 for a random faction.
* Gets the default faction id or -1 for a random faction.
*
* @return the default faction id or -1 for a random faction
*/
si8 defaultCastle() const; si8 defaultCastle() const;
/// Gets the default hero id or -1 for a random hero.
/**
* Gets -1 for random hero.
*
* @return -1 for random hero
*/
si8 defaultHero() const; si8 defaultHero() const;
bool canAnyonePlay() const; bool canAnyonePlay() const;
/** True if the player can be played by a human. */
bool canHumanPlay; bool canHumanPlay;
/** True if th player can be played by the computer */
bool canComputerPlay; bool canComputerPlay;
EAiTactic::EAiTactic aiTactic; /// The default value is EAiTactic::RANDOM.
/** Defines the tactical setting of the AI. The default value is EAiTactic::RANDOM. */
EAiTactic::EAiTactic aiTactic;
/** A list of unique IDs of allowed factions. */
std::set<TFaction> allowedFactions; std::set<TFaction> allowedFactions;
/** Unused. True if the faction should be chosen randomly. */
bool isFactionRandom; bool isFactionRandom;
si32 mainHeroPortrait; /// The default value is -1.
/** Specifies the ID of the main hero with chosen portrait. The default value is -1. */
si32 mainHeroPortrait;
/** The name of the main hero. */
std::string mainHeroName; std::string mainHeroName;
std::vector<SHeroName> heroesNames; /// List of renamed heroes.
/** The list of renamed heroes. */ bool hasMainTown; /// The default value is false.
std::vector<SHeroName> heroesNames; bool generateHeroAtMainTown; /// The default value is false.
/** True if the player has a main town. The default value is false. */
bool hasMainTown;
/** True if the main hero should be generated at the main town. The default value is false. */
bool generateHeroAtMainTown;
/** The position of the main town. */
int3 posOfMainTown; int3 posOfMainTown;
TeamID team; /// The default value is 255 representing that the player belongs to no team.
/** The team id to which the player belongs to. The default value is 255 representing that the player belongs to no team. */ bool generateHero; /// Unused.
TeamID team; si32 p7; /// Unknown and unused.
bool hasHero; /// Player has a (custom?) hero
/** Unused. True if a hero should be generated. */ si32 customHeroID; /// ID of custom hero, -1 if none
bool generateHero; /// Unused. Count of hero placeholders containing hero type.
/// WARNING: powerPlaceholders sometimes gives false 0 (eg. even if there is one placeholder), maybe different meaning ???
/** Unknown and unused. */
si32 p7;
/** Player has a (custom?) hero */
bool hasHero;
/** ID of custom hero, -1 if none */
si32 customHeroID;
/**
* Unused. Count of hero placeholders containing hero type.
* WARNING: powerPlaceholders sometimes gives false 0 (eg. even if there is one placeholder),
* maybe different meaning ???
*/
ui8 powerPlaceholders; ui8 powerPlaceholders;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -161,31 +98,16 @@ struct DLL_LINKAGE PlayerInfo
} }
}; };
/** /// The loss condition describes the condition to lose the game. (e.g. lose all own heroes/castles)
* The loss condition describes the condition to lose the game. (e.g. lose all own heroes/castles)
*/
struct DLL_LINKAGE LossCondition struct DLL_LINKAGE LossCondition
{ {
/**
* Default constructor.
*/
LossCondition(); LossCondition();
/** specifies the condition type */
ELossConditionType::ELossConditionType typeOfLossCon; ELossConditionType::ELossConditionType typeOfLossCon;
int3 pos; /// the position of an object which mustn't be lost
/** the position of an object which mustn't be lost */ si32 timeLimit; /// time limit in days, -1 if not used
int3 pos;
/** time limit in days, -1 if not used */
si32 timeLimit;
/** set during map parsing: hero/town (depending on typeOfLossCon); nullptr if not used */
const CGObjectInstance * obj; const CGObjectInstance * obj;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -193,41 +115,25 @@ struct DLL_LINKAGE LossCondition
} }
}; };
/** /// The victory condition describes the condition to win the game. (e.g. defeat all enemy heroes/castles,
* The victory condition describes the condition to win the game. (e.g. defeat all enemy heroes/castles, /// receive a specific artifact, ...)
* receive a specific artifact, ...)
*/
struct DLL_LINKAGE VictoryCondition struct DLL_LINKAGE VictoryCondition
{ {
/**
* Default constructor.
*/
VictoryCondition(); VictoryCondition();
/** specifies the condition type */
EVictoryConditionType::EVictoryConditionType condition; EVictoryConditionType::EVictoryConditionType condition;
bool allowNormalVictory; /// true if a normal victory is allowed (defeat all enemy towns, heroes)
/** true if a normal victory is allowed (defeat all enemy towns, heroes) */
bool allowNormalVictory;
/** true if this victory condition also applies to the AI */
bool appliesToAI; bool appliesToAI;
/// pos of city to upgrade (3); pos of town to build grail, {-1,-1,-1} if not relevant (4); hero pos (5); town pos(6);
/** pos of city to upgrade (3); pos of town to build grail, {-1,-1,-1} if not relevant (4); hero pos (5); town pos(6); monster pos (7); destination pos(8) */ /// monster pos (7); destination pos(8)
int3 pos; int3 pos;
/// artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8)
/** artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8) */
si32 objectId; si32 objectId;
/// needed count for creatures (1) / resource (2); upgraded town hall level (3);
/** needed count for creatures (1) / resource (2); upgraded town hall level (3); */
si32 count; si32 count;
/// object of specific monster / city / hero instance (NULL if not used); set during map parsing
/** object of specific monster / city / hero instance (NULL if not used); set during map parsing */
const CGObjectInstance * obj; const CGObjectInstance * obj;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -235,20 +141,12 @@ struct DLL_LINKAGE VictoryCondition
} }
}; };
/** /// The rumor struct consists of a rumor name and text.
* The rumor struct consists of a rumor name and text.
*/
struct DLL_LINKAGE Rumor struct DLL_LINKAGE Rumor
{ {
/** the name of the rumor */
std::string name; std::string name;
/** the content of the rumor */
std::string text; std::string text;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -256,31 +154,16 @@ struct DLL_LINKAGE Rumor
} }
}; };
/** /// The disposed hero struct describes which hero can be hired from which player.
* The disposed hero struct describes which hero can be hired from which player.
*/
struct DLL_LINKAGE DisposedHero struct DLL_LINKAGE DisposedHero
{ {
/**
* Default c-tor.
*/
DisposedHero(); DisposedHero();
/** the id of the hero */
ui32 heroId; ui32 heroId;
ui16 portrait; /// The portrait id of the hero, 0xFF is default.
/** the portrait id of the hero, 0xFF is default */
ui16 portrait;
/** the name of the hero */
std::string name; std::string name;
ui8 players; /// Who can hire this hero (bitfield).
/** who can hire this hero (bitfield) */
ui8 players;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -288,61 +171,25 @@ struct DLL_LINKAGE DisposedHero
} }
}; };
/** /// The map event is an event which e.g. gives or takes resources of a specific
* The map event is an event which e.g. gives or takes resources of a specific /// amount to/from players and can appear regularly or once a time.
* amount to/from players and can appear regularly or once a time.
*/
class DLL_LINKAGE CMapEvent class DLL_LINKAGE CMapEvent
{ {
public: public:
/**
* Default c-tor.
*/
CMapEvent(); CMapEvent();
/**
* Returns true if this map event occurs earlier than the other map event for the first time.
*
* @param other the other map event to compare with
* @return true if this event occurs earlier than the other map event, false if not
*/
bool earlierThan(const CMapEvent & other) const; bool earlierThan(const CMapEvent & other) const;
/**
* Returns true if this map event occurs earlier than or at the same day than the other map event for the first time.
*
* @param other the other map event to compare with
* @return true if this event occurs earlier than or at the same day than the other map event, false if not
*/
bool earlierThanOrEqual(const CMapEvent & other) const; bool earlierThanOrEqual(const CMapEvent & other) const;
/** the name of the event */
std::string name; std::string name;
/** the message to display */
std::string message; std::string message;
/** gained or taken resources */
TResources resources; TResources resources;
ui8 players; // affected players, bit field?
/** affected players */
ui8 players;
/** affected humans */
ui8 humanAffected; ui8 humanAffected;
/** affacted computer players */
ui8 computerAffected; ui8 computerAffected;
/** the day counted continously when the event happens */
ui32 firstOccurence; ui32 firstOccurence;
ui32 nextOccurence; /// specifies after how many days the event will occur the next time; 0 if event occurs only one time
/** specifies after how many days the event will occur the next time; 0 if event occurs only one time */
ui32 nextOccurence;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -351,29 +198,16 @@ public:
} }
}; };
/** /// The castle event builds/adds buildings/creatures for a specific town.
* The castle event builds/adds buildings/creatures for a specific town.
*/
class DLL_LINKAGE CCastleEvent: public CMapEvent class DLL_LINKAGE CCastleEvent: public CMapEvent
{ {
public: public:
/**
* Default c-tor.
*/
CCastleEvent(); CCastleEvent();
/** build specific buildings */
std::set<BuildingID> buildings; std::set<BuildingID> buildings;
/** additional creatures in i-th level dwelling */
std::vector<si32> creatures; std::vector<si32> creatures;
/** owner of this event */
CGTownInstance * town; CGTownInstance * town;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -398,109 +232,38 @@ enum ERoadType
}; };
} }
/** /// The terrain tile describes the terrain type and the visual representation of the terrain.
* The terrain tile describes the terrain type and the visual representation of the terrain. /// Furthermore the struct defines whether the tile is visitable or/and blocked and which objects reside in it.
* Furthermore the struct defines whether the tile is visitable or/and blocked and which objects reside in it.
*/
struct DLL_LINKAGE TerrainTile struct DLL_LINKAGE TerrainTile
{ {
/**
* Default c-tor.
*/
TerrainTile(); TerrainTile();
/** /// Gets true if the terrain is not a rock. If from is water/land, same type is also required.
* Gets true if the terrain is not a rock. If from is water/land, same type is also required.
*
* @param from
* @return
*/
bool entrableTerrain(const TerrainTile * from = NULL) const; bool entrableTerrain(const TerrainTile * from = NULL) const;
/**
* Gets true if the terrain is not a rock. If from is water/land, same type is also required.
*
* @param allowLand
* @param allowSea
* @return
*/
bool entrableTerrain(bool allowLand, bool allowSea) const; bool entrableTerrain(bool allowLand, bool allowSea) const;
/// Checks for blocking objects and terraint type (water / land).
/**
* Checks for blocking objects and terraint type (water / land).
*
* @param from
* @return
*/
bool isClear(const TerrainTile * from = NULL) const; bool isClear(const TerrainTile * from = NULL) const;
/// Gets the ID of the top visitable object or -1 if there is none.
/**
* Gets the ID of the top visitable object or -1 if there is none.
*
* @return the ID of the top visitable object or -1 if there is none
*/
int topVisitableId() const; int topVisitableId() const;
/**
* Gets true if the terrain type is water.
*
* @return true if the terrain type is water
*/
bool isWater() const; bool isWater() const;
/**
* Gets true if the terrain tile is coastal.
*
* @return true if the terrain tile is coastal
*/
bool isCoastal() const; bool isCoastal() const;
/**
* Gets true if the terrain tile has favourable winds.
*
* @return true if the terrain tile has favourable winds
*/
bool hasFavourableWinds() const; bool hasFavourableWinds() const;
/** the type of terrain */
ETerrainType terType; ETerrainType terType;
/** the visual representation of the terrain */
ui8 terView; ui8 terView;
/** the type of the river. 0 if there is no river */
ERiverType::ERiverType riverType; ERiverType::ERiverType riverType;
/** the direction of the river */
ui8 riverDir; ui8 riverDir;
/** the type of the road. 0 if there is no river */
ERoadType::ERoadType roadType; ERoadType::ERoadType roadType;
/** the direction of the road */
ui8 roadDir; ui8 roadDir;
/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
/** /// 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favourable Winds effect
* first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
* 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favourable Winds effect
*/
ui8 extTileFlags; ui8 extTileFlags;
/** true if it is visitable, false if not */
bool visitable; bool visitable;
/** true if it is blocked, false if not */
bool blocked; bool blocked;
/** pointers to objects which the hero can visit while being on this tile */
std::vector<CGObjectInstance *> visitableObjects; std::vector<CGObjectInstance *> visitableObjects;
/** pointers to objects that are blocking this tile */
std::vector<CGObjectInstance *> blockingObjects; std::vector<CGObjectInstance *> blockingObjects;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int version) void serialize(Handler & h, const int version)
{ {
@@ -522,80 +285,31 @@ enum EMapFormat
}; };
} }
/** /// The map header holds information about loss/victory condition,map format, version, players, height, width,...
* The map header holds information about loss/victory condition,
* map format, version, players, height, width,...
*/
class DLL_LINKAGE CMapHeader class DLL_LINKAGE CMapHeader
{ {
public: public:
/**
* Default constructor.
*/
CMapHeader(); CMapHeader();
/**
* D-tor.
*/
virtual ~CMapHeader(); virtual ~CMapHeader();
/** The version of the map. The default value is EMapFormat::SOD. */ EMapFormat::EMapFormat version; /// The default value is EMapFormat::SOD.
EMapFormat::EMapFormat version; si32 height; /// The default value is 72.
si32 width; /// The default value is 72.
/** The height of the map. The default value is 72. */ bool twoLevel; /// The default value is true.
si32 height;
/** The width of the map. The default value is 72. */
si32 width;
/** Specifies if the map has two levels. The default value is true. */
bool twoLevel;
/** The name of the map. */
std::string name; std::string name;
/** The description of the map. */
std::string description; std::string description;
ui8 difficulty; /// The default value is 1 representing a normal map difficulty.
/** /// Specifies the maximum level to reach for a hero. A value of 0 states that there is no
* Specifies the difficulty of the map ranging from 0 easy to 4 impossible. /// maximum level for heroes. This is the default value.
* The default value is 1 representing a normal map difficulty.
*/
ui8 difficulty;
/**
* Specifies the maximum level to reach for a hero. A value of 0 states that there is no
* maximum level for heroes.
*/
ui8 levelLimit; ui8 levelLimit;
LossCondition lossCondition; /// The default value is lose all your towns and heroes.
/** Specifies the loss condition. The default value is lose all your towns and heroes. */ VictoryCondition victoryCondition; /// The default value is defeat all enemies.
LossCondition lossCondition; std::vector<PlayerInfo> players; /// The default size of the vector is PlayerColor::PLAYER_LIMIT.
/** Specifies the victory condition. The default value is defeat all enemies. */
VictoryCondition victoryCondition;
/** A list containing information about players. The default size of the vector is PlayerColor::PLAYER_LIMIT. */
std::vector<PlayerInfo> players;
/** The number of teams. */
ui8 howManyTeams; ui8 howManyTeams;
/**
* A list of allowed heroes. The index is the hero id and the value = hero allowed.
* The default value is a list of default allowed heroes. See CHeroHandler::getDefaultAllowedHeroes for more info.
*/
std::vector<bool> allowedHeroes; std::vector<bool> allowedHeroes;
/** A list of placeholded heroes. The index is the id of a hero type. */
std::vector<ui16> placeholdedHeroes; std::vector<ui16> placeholdedHeroes;
bool areAnyPlayers; /// Unused. True if there are any playable players on the map.
/** Unused. True if there are any playable players on the map. */
bool areAnyPlayers;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler & h, const int Version) void serialize(Handler & h, const int Version)
{ {
@@ -604,176 +318,55 @@ public:
} }
}; };
/** /// The map contains the map header, the tiles of the terrain, objects, heroes, towns, rumors...
* The map contains the map header, the tiles of the terrain, objects,
* heroes, towns, rumors...
*/
class DLL_LINKAGE CMap : public CMapHeader class DLL_LINKAGE CMap : public CMapHeader
{ {
public: public:
/**
* Default constructor.
*/
CMap(); CMap();
/**
* Destructor.
*/
~CMap(); ~CMap();
/**
* Erases an artifact instance.
*
* @param art the artifact to erase
*/
void eraseArtifactInstance(CArtifactInstance * art);
/**
* Gets the topmost object or the lowermost object depending on the flag
* lookForHero from the specified position.
*
* @param pos the position of the tile
* @param lookForHero true if you want to get the lowermost object, false if
* you want to get the topmost object
* @return the object at the given position and level
*/
const CGObjectInstance * getObjectiveObjectFrom(int3 pos, bool lookForHero);
/**
* Sets the victory/loss condition objectives.
*/
void checkForObjectives();
/**
* Adds an visitable/blocking object to a terrain tile.
*
* @param obj the visitable/blocking object to add to a tile
*/
void addBlockVisTiles(CGObjectInstance * obj);
/**
* Removes an visitable/blocking object from a terrain tile.
*
* @param obj the visitable/blocking object to remove from a tile
* @param total
*/
void removeBlockVisTiles(CGObjectInstance * obj, bool total = false);
/**
* Gets the terrain tile of the specified position.
*
* @param tile the position of the tile
* @return the terrain tile of the specified position
*/
TerrainTile & getTile(const int3 & tile);
/**
* Gets the terrain tile as a const of the specified position.
*
* @param tile the position of the tile
* @return the terrain tile as a const of the specified position
*/
const TerrainTile & getTile(const int3 & tile) const;
/**
* Gets the hero with the given id.
* @param heroId the hero id
* @return the hero with the given id
*/
CGHeroInstance * getHero(int heroId);
/**
* Validates if the position is in the bounds of the map.
*
* @param pos the position to test
* @return true if the position is in the bounds of the map
*/
bool isInTheMap(const int3 & pos) const;
/**
* Validates if the tile at the given position is a water terrain type.
*
* @param pos the position to test
* @return true if the tile at the given position is a water terrain type
*/
bool isWaterTile(const int3 & pos) const;
/**
* Adds the specified artifact instance to the list of artifacts of this map.
*
* @param art the artifact which should be added to the list of artifacts
*/
void addNewArtifactInstance(CArtifactInstance * art);
/**
* Adds the specified quest instance to the list of quests.
*
* @param quest the quest object which should be added to the list of quests
*/
void addQuest(CGObjectInstance * quest);
/**
* Initializes the terrain of the map by allocating memory.
*/
void initTerrain(); void initTerrain();
/** the checksum of the map */ TerrainTile & getTile(const int3 & tile);
const TerrainTile & getTile(const int3 & tile) const;
bool isInTheMap(const int3 & pos) const;
bool isWaterTile(const int3 & pos) const;
void addBlockVisTiles(CGObjectInstance * obj);
void removeBlockVisTiles(CGObjectInstance * obj, bool total = false);
void addNewArtifactInstance(CArtifactInstance * art);
void eraseArtifactInstance(CArtifactInstance * art);
void addQuest(CGObjectInstance * quest);
/// Gets the topmost object or the lowermost object depending on the flag lookForHero from the specified position.
const CGObjectInstance * getObjectiveObjectFrom(int3 pos, bool lookForHero);
CGHeroInstance * getHero(int heroId);
/// Sets the victory/loss condition objectives ??
void checkForObjectives();
ui32 checksum; ui32 checksum;
/// a 3-dimensional array of terrain tiles, access is as follows: x, y, level. where level=1 is underground
/** a 3-dimensional array of terrain tiles, access is as follows: x, y, level. where level=1 is underground */
TerrainTile*** terrain; TerrainTile*** terrain;
/** list of rumors */
std::vector<Rumor> rumors; std::vector<Rumor> rumors;
/** list of disposed heroes */
std::vector<DisposedHero> disposedHeroes; std::vector<DisposedHero> disposedHeroes;
/** list of predefined heroes */
std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes; std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;
/** list of .def files with definitions from .h3m (may be custom) */
std::vector<ConstTransitivePtr<CGDefInfo> > customDefs; std::vector<ConstTransitivePtr<CGDefInfo> > customDefs;
/** list of allowed spells, index is the spell id */
std::vector<bool> allowedSpell; std::vector<bool> allowedSpell;
/** list of allowed artifacts, index is the artifact id */
std::vector<bool> allowedArtifact; std::vector<bool> allowedArtifact;
/** list of allowed abilities, index is the ability id */
std::vector<bool> allowedAbilities; std::vector<bool> allowedAbilities;
/** list of map events */
std::list<CMapEvent> events; std::list<CMapEvent> events;
/** specifies the position of the grail */
int3 grailPos; int3 grailPos;
/** specifies the radius of the grail */
int grailRadious; int grailRadious;
/** list of objects */
std::vector< ConstTransitivePtr<CGObjectInstance> > objects; std::vector< ConstTransitivePtr<CGObjectInstance> > objects;
/** list of heroes */
std::vector< ConstTransitivePtr<CGHeroInstance> > heroes; std::vector< ConstTransitivePtr<CGHeroInstance> > heroes;
/** list of towns */
std::vector< ConstTransitivePtr<CGTownInstance> > towns; std::vector< ConstTransitivePtr<CGTownInstance> > towns;
/** list of artifacts */
std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances; std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances;
/** list of quests */
std::vector< ConstTransitivePtr<CQuest> > quests; std::vector< ConstTransitivePtr<CQuest> > quests;
/// associative list to identify which hero/creature id belongs to which object id(index for objects)
/** associative list to identify which hero/creature id belongs to which object id(index for objects) */
bmap<si32, ObjectInstanceID> questIdentifierToId; bmap<si32, ObjectInstanceID> questIdentifierToId;
/**
* Serialize method.
*/
template <typename Handler> template <typename Handler>
void serialize(Handler &h, const int formatVersion) void serialize(Handler &h, const int formatVersion)
{ {

View File

@@ -5,119 +5,8 @@
#include "../filesystem/CResourceLoader.h" #include "../filesystem/CResourceLoader.h"
#include "../CDefObjInfoHandler.h" #include "../CDefObjInfoHandler.h"
const std::string TerrainViewPattern::FLIP_MODE_SAME_IMAGE = "sameImage"; CMapEditManager::CMapEditManager(CMap * map, int randomSeed /*= std::time(nullptr)*/)
const std::string TerrainViewPattern::FLIP_MODE_DIFF_IMAGES = "diffImages"; : map(map)
const std::string TerrainViewPattern::RULE_DIRT = "D";
const std::string TerrainViewPattern::RULE_SAND = "S";
const std::string TerrainViewPattern::RULE_TRANSITION = "T";
const std::string TerrainViewPattern::RULE_NATIVE = "N";
const std::string TerrainViewPattern::RULE_ANY = "?";
TerrainViewPattern::TerrainViewPattern() : minPoints(0), flipMode(FLIP_MODE_SAME_IMAGE),
terGroup(ETerrainGroup::NORMAL)
{
}
TerrainViewPattern::WeightedRule::WeightedRule() : points(0)
{
}
bool TerrainViewPattern::WeightedRule::isStandardRule() const
{
return TerrainViewPattern::RULE_ANY == name || TerrainViewPattern::RULE_DIRT == name
|| TerrainViewPattern::RULE_NATIVE == name || TerrainViewPattern::RULE_SAND == name
|| TerrainViewPattern::RULE_TRANSITION == name;
}
CTerrainViewPatternConfig::CTerrainViewPatternConfig()
{
const JsonNode config(ResourceID("config/terrainViewPatterns.json"));
const std::map<std::string, ETerrainGroup::ETerrainGroup> terGroups
= boost::assign::map_list_of("normal", ETerrainGroup::NORMAL)("dirt", ETerrainGroup::DIRT)
("sand", ETerrainGroup::SAND)("water", ETerrainGroup::WATER)("rock", ETerrainGroup::ROCK);
BOOST_FOREACH(auto terMapping, terGroups)
{
BOOST_FOREACH(const JsonNode & ptrnNode, config[terMapping.first].Vector())
{
TerrainViewPattern pattern;
// Read pattern data
const JsonVector & data = ptrnNode["data"].Vector();
if(data.size() != 9)
{
throw std::runtime_error("Size of pattern's data vector has to be 9.");
}
for(int i = 0; i < data.size(); ++i)
{
std::string cell = data[i].String();
boost::algorithm::erase_all(cell, " ");
std::vector<std::string> rules;
boost::split(rules, cell, boost::is_any_of(","));
BOOST_FOREACH(std::string ruleStr, rules)
{
std::vector<std::string> ruleParts;
boost::split(ruleParts, ruleStr, boost::is_any_of("-"));
TerrainViewPattern::WeightedRule rule;
rule.name = ruleParts[0];
if(ruleParts.size() > 1)
{
rule.points = boost::lexical_cast<int>(ruleParts[1]);
}
pattern.data[i].push_back(rule);
}
}
// Read mapping
std::string mappingStr = ptrnNode["mapping"].String();
boost::algorithm::erase_all(mappingStr, " ");
std::vector<std::string> mappings;
boost::split(mappings, mappingStr, boost::is_any_of(","));
BOOST_FOREACH(std::string mapping, mappings)
{
std::vector<std::string> range;
boost::split(range, mapping, boost::is_any_of("-"));
pattern.mapping.push_back(std::make_pair(boost::lexical_cast<int>(range[0]),
boost::lexical_cast<int>(range.size() > 1 ? range[1] : range[0])));
}
// Read optional attributes
pattern.id = ptrnNode["id"].String();
pattern.minPoints = static_cast<int>(ptrnNode["minPoints"].Float());
pattern.flipMode = ptrnNode["flipMode"].String();
if(pattern.flipMode.empty())
{
pattern.flipMode = TerrainViewPattern::FLIP_MODE_SAME_IMAGE;
}
pattern.terGroup = terMapping.second;
patterns[terMapping.second].push_back(pattern);
}
}
}
const std::vector<TerrainViewPattern> & CTerrainViewPatternConfig::getPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const
{
return patterns.find(terGroup)->second;
}
const TerrainViewPattern & CTerrainViewPatternConfig::getPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const
{
const std::vector<TerrainViewPattern> & groupPatterns = getPatternsForGroup(terGroup);
BOOST_FOREACH(const TerrainViewPattern & pattern, groupPatterns)
{
if(id == pattern.id)
{
return pattern;
}
}
throw std::runtime_error("Pattern with ID not found: " + id);
}
CMapEditManager::CMapEditManager(const CTerrainViewPatternConfig * terViewPatternConfig, CMap * map, int randomSeed /*= std::time(nullptr)*/)
: map(map), terViewPatternConfig(terViewPatternConfig)
{ {
gen.seed(randomSeed); gen.seed(randomSeed);
} }
@@ -164,7 +53,7 @@ void CMapEditManager::updateTerrainViews(int posx, int posy, int width, int heig
for(int j = posy; j < posy + height; ++j) for(int j = posy; j < posy + height; ++j)
{ {
const std::vector<TerrainViewPattern> & patterns = const std::vector<TerrainViewPattern> & patterns =
terViewPatternConfig->getPatternsForGroup(getTerrainGroup(map->terrain[i][j][mapLevel].terType)); CTerrainViewPatternConfig::get().getPatternsForGroup(getTerrainGroup(map->terrain[i][j][mapLevel].terType));
// Detect a pattern which fits best // Detect a pattern which fits best
int bestPattern = -1, bestFlip = -1; int bestPattern = -1, bestFlip = -1;
@@ -282,7 +171,7 @@ CMapEditManager::ValidationResult CMapEditManager::validateTerrainView(int posx,
{ {
if(recDepth == 0) if(recDepth == 0)
{ {
const TerrainViewPattern & patternForRule = terViewPatternConfig->getPatternById(pattern.terGroup, rule.name); const TerrainViewPattern & patternForRule = CTerrainViewPatternConfig::get().getPatternById(pattern.terGroup, rule.name);
ValidationResult rslt = validateTerrainView(cx, cy, mapLevel, patternForRule, 1); ValidationResult rslt = validateTerrainView(cx, cy, mapLevel, patternForRule, 1);
if(!rslt.result) if(!rslt.result)
{ {
@@ -432,3 +321,128 @@ CMapEditManager::ValidationResult::ValidationResult(bool result, const std::stri
{ {
} }
const std::string TerrainViewPattern::FLIP_MODE_SAME_IMAGE = "sameImage";
const std::string TerrainViewPattern::FLIP_MODE_DIFF_IMAGES = "diffImages";
const std::string TerrainViewPattern::RULE_DIRT = "D";
const std::string TerrainViewPattern::RULE_SAND = "S";
const std::string TerrainViewPattern::RULE_TRANSITION = "T";
const std::string TerrainViewPattern::RULE_NATIVE = "N";
const std::string TerrainViewPattern::RULE_ANY = "?";
TerrainViewPattern::TerrainViewPattern() : minPoints(0), flipMode(FLIP_MODE_SAME_IMAGE),
terGroup(ETerrainGroup::NORMAL)
{
}
TerrainViewPattern::WeightedRule::WeightedRule() : points(0)
{
}
bool TerrainViewPattern::WeightedRule::isStandardRule() const
{
return TerrainViewPattern::RULE_ANY == name || TerrainViewPattern::RULE_DIRT == name
|| TerrainViewPattern::RULE_NATIVE == name || TerrainViewPattern::RULE_SAND == name
|| TerrainViewPattern::RULE_TRANSITION == name;
}
boost::mutex CTerrainViewPatternConfig::smx;
CTerrainViewPatternConfig & CTerrainViewPatternConfig::get()
{
TLockGuard _(smx);
static CTerrainViewPatternConfig instance;
return instance;
}
CTerrainViewPatternConfig::CTerrainViewPatternConfig()
{
const JsonNode config(ResourceID("config/terrainViewPatterns.json"));
const std::map<std::string, ETerrainGroup::ETerrainGroup> terGroups
= boost::assign::map_list_of("normal", ETerrainGroup::NORMAL)("dirt", ETerrainGroup::DIRT)
("sand", ETerrainGroup::SAND)("water", ETerrainGroup::WATER)("rock", ETerrainGroup::ROCK);
BOOST_FOREACH(auto terMapping, terGroups)
{
BOOST_FOREACH(const JsonNode & ptrnNode, config[terMapping.first].Vector())
{
TerrainViewPattern pattern;
// Read pattern data
const JsonVector & data = ptrnNode["data"].Vector();
if(data.size() != 9)
{
throw std::runtime_error("Size of pattern's data vector has to be 9.");
}
for(int i = 0; i < data.size(); ++i)
{
std::string cell = data[i].String();
boost::algorithm::erase_all(cell, " ");
std::vector<std::string> rules;
boost::split(rules, cell, boost::is_any_of(","));
BOOST_FOREACH(std::string ruleStr, rules)
{
std::vector<std::string> ruleParts;
boost::split(ruleParts, ruleStr, boost::is_any_of("-"));
TerrainViewPattern::WeightedRule rule;
rule.name = ruleParts[0];
if(ruleParts.size() > 1)
{
rule.points = boost::lexical_cast<int>(ruleParts[1]);
}
pattern.data[i].push_back(rule);
}
}
// Read mapping
std::string mappingStr = ptrnNode["mapping"].String();
boost::algorithm::erase_all(mappingStr, " ");
std::vector<std::string> mappings;
boost::split(mappings, mappingStr, boost::is_any_of(","));
BOOST_FOREACH(std::string mapping, mappings)
{
std::vector<std::string> range;
boost::split(range, mapping, boost::is_any_of("-"));
pattern.mapping.push_back(std::make_pair(boost::lexical_cast<int>(range[0]),
boost::lexical_cast<int>(range.size() > 1 ? range[1] : range[0])));
}
// Read optional attributes
pattern.id = ptrnNode["id"].String();
pattern.minPoints = static_cast<int>(ptrnNode["minPoints"].Float());
pattern.flipMode = ptrnNode["flipMode"].String();
if(pattern.flipMode.empty())
{
pattern.flipMode = TerrainViewPattern::FLIP_MODE_SAME_IMAGE;
}
pattern.terGroup = terMapping.second;
patterns[terMapping.second].push_back(pattern);
}
}
}
CTerrainViewPatternConfig::~CTerrainViewPatternConfig()
{
}
const std::vector<TerrainViewPattern> & CTerrainViewPatternConfig::getPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const
{
return patterns.find(terGroup)->second;
}
const TerrainViewPattern & CTerrainViewPatternConfig::getPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const
{
const std::vector<TerrainViewPattern> & groupPatterns = getPatternsForGroup(terGroup);
BOOST_FOREACH(const TerrainViewPattern & pattern, groupPatterns)
{
if(id == pattern.id)
{
return pattern;
}
}
throw std::runtime_error("Pattern with ID not found: " + id);
}

View File

@@ -15,12 +15,11 @@
#include "CMap.h" #include "CMap.h"
class CGObjectInstance; class CGObjectInstance;
class CTerrainViewPatternConfig;
class TerrainViewPattern;
namespace ETerrainGroup namespace ETerrainGroup
{ {
/**
* This enumeration lists terrain groups which differ in the terrain view frames alignment.
*/
enum ETerrainGroup enum ETerrainGroup
{ {
NORMAL, NORMAL,
@@ -31,263 +30,134 @@ namespace ETerrainGroup
}; };
} }
/** /// The map edit manager provides functionality for drawing terrain and placing
* The terrain view pattern describes a specific composition of terrain tiles /// objects on the map.
* in a 3x3 matrix and notes which terrain view frame numbers can be used.
*/
struct TerrainViewPattern
{
/**
* A weighted rule struct is a combination of the rule name and optionally points.
*/
struct WeightedRule
{
/** The name of the rule. Can be any value of the RULE_* constants or a ID of a another pattern. */
std::string name;
/** Optional. A rule can have points. Patterns may have a minimum count of points to reach to be successful. */
int points;
/**
* Constructor.
*/
WeightedRule();
/**
* Gets true if this rule is a standard rule which means that it has a value of one of the RULE_* constants.
*
* @return true for a standard rule
*/
bool isStandardRule() const;
};
/** Constant for the flip mode same image. Pattern will be flipped and the same image will be used(which is given in the mapping). */
static const std::string FLIP_MODE_SAME_IMAGE;
/** Constant for the flip mode different images. Pattern will be flipped and different images will be used(mapping area is divided into 4 parts) */
static const std::string FLIP_MODE_DIFF_IMAGES;
/** Constant for the rule dirt, meaning a dirty border is required. */
static const std::string RULE_DIRT;
/** Constant for the rule sand, meaning a sandy border is required. */
static const std::string RULE_SAND;
/** Constant for the rule transition, meaning a dirty OR sandy border is required. */
static const std::string RULE_TRANSITION;
/** Constant for the rule native, meaning a native type is required. */
static const std::string RULE_NATIVE;
/** Constant for the rule any, meaning a native type, dirty OR sandy border is required. */
static const std::string RULE_ANY;
/**
* Default constructor.
*/
TerrainViewPattern();
/**
* The pattern data.
*
* It can be visualized as a 3x3 matrix:
* [ ][ ][ ]
* [ ][ ][ ]
* [ ][ ][ ]
*
* The box in the center belongs always to the native terrain type and
* is the point of origin. Depending on the terrain type different rules
* can be used. Their meaning differs also from type to type.
*
* std::vector -> several rules can be used in one cell
*/
std::array<std::vector<WeightedRule>, 9> data;
/** The identifier of the pattern, if it's referenced from a another pattern. */
std::string id;
/**
* This describes the mapping between this pattern and the corresponding range of frames
* which should be used for the ter view.
*
* std::vector -> size=1: typical, size=2: if this pattern should map to two different types of borders
* std::pair -> 1st value: lower range, 2nd value: upper range
*/
std::vector<std::pair<int, int> > mapping;
/** The minimum points to reach to to validate the pattern successfully. */
int minPoints;
/** Describes if flipping is required and which mapping should be used. */
std::string flipMode;
/** The terrain group to which the pattern belongs to. */
ETerrainGroup::ETerrainGroup terGroup;
};
/**
* The terrain view pattern config loads pattern data from the filesystem.
*/
class CTerrainViewPatternConfig
{
public:
/**
* Constructor. Initializes the patterns data.
*/
CTerrainViewPatternConfig();
/**
* Gets the patterns for a specific group of terrain.
*
* @param terGroup the terrain group e.g. normal for grass, lava,... OR dirt OR sand,...
* @return a vector containing patterns
*/
const std::vector<TerrainViewPattern> & getPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const;
/**
* Gets a pattern by ID. Throws if pattern isn't available(config error).
*
* @param terGroup the terrain group e.g. normal for grass, lava,... OR dirt OR sand,...
* @param id the id of the pattern
* @return the pattern which matches the ID
*/
const TerrainViewPattern & getPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const;
private:
/** The patterns data. */
std::map<ETerrainGroup::ETerrainGroup, std::vector<TerrainViewPattern> > patterns;
};
/**
* The map edit manager provides functionality for drawing terrain and placing
* objects on the map.
*
* TODO add undo / selection functionality for the map editor
*/
class CMapEditManager class CMapEditManager
{ {
public: public:
/** CMapEditManager(CMap * map, int randomSeed = std::time(nullptr));
* Constructor. The map object / terrain data has to be initialized.
*
* @param terViewPatternConfig the terrain view pattern config
* @param map the map object which should be edited
* @param randomSeed optional. the seed which is used for generating randomly terrain views
*/
CMapEditManager(const CTerrainViewPatternConfig * terViewPatternConfig, CMap * map, int randomSeed = std::time(nullptr));
/** /// Clears the terrain. The free level is filled with water and the underground level with rock.
* Clears the terrain. The free level is filled with water and the
* underground level with rock.
*/
void clearTerrain(); void clearTerrain();
/**
* Draws terrain.
*
* @param terType the type of the terrain to draw
* @param posx the x coordinate
* @param posy the y coordinate
* @param width the height of the terrain to draw
* @param height the width of the terrain to draw
* @param underground true if you want to draw at the underground, false if open
*/
void drawTerrain(ETerrainType terType, int posx, int posy, int width, int height, bool underground); void drawTerrain(ETerrainType terType, int posx, int posy, int width, int height, bool underground);
/**
* Inserts an object.
*
* @param obj the object to insert
* @param posx the x coordinate
* @param posy the y coordinate
* @param underground true if you want to draw at the underground, false if open
*/
void insertObject(CGObjectInstance * obj, int posx, int posy, bool underground); void insertObject(CGObjectInstance * obj, int posx, int posy, bool underground);
private: private:
/**
* The validation result struct represents the result of a pattern validation.
*/
struct ValidationResult struct ValidationResult
{ {
/**
* Constructor.
*
* @param result the result of the validation either true or false
* @param transitionReplacement optional. the replacement of a T rule, either D or S
*/
ValidationResult(bool result, const std::string & transitionReplacement = ""); ValidationResult(bool result, const std::string & transitionReplacement = "");
/** The result of the validation. */
bool result; bool result;
/// The replacement of a T rule, either D or S.
/** The replacement of a T rule, either D or S. */
std::string transitionReplacement; std::string transitionReplacement;
}; };
/**
* Updates the terrain view ids in the specified area.
*
* @param posx the x coordinate
* @param posy the y coordinate
* @param width the height of the terrain to update
* @param height the width of the terrain to update
* @param mapLevel the map level, 0 for open and 1 for underground
*/
void updateTerrainViews(int posx, int posy, int width, int height, int mapLevel); void updateTerrainViews(int posx, int posy, int width, int height, int mapLevel);
/**
* Gets the terrain group by the terrain type number.
*
* @param terType the terrain type
* @return the terrain group
*/
ETerrainGroup::ETerrainGroup getTerrainGroup(ETerrainType terType) const; ETerrainGroup::ETerrainGroup getTerrainGroup(ETerrainType terType) const;
/// Validates the terrain view of the given position and with the given pattern.
/**
* Validates the terrain view of the given position and with the given pattern.
*
* @param posx the x position
* @param posy the y position
* @param mapLevel the map level, 0 for open and 1 for underground
* @param pattern the pattern to validate the terrain view with
* @param recDepth the depth of the recursion, 0 for no recursion - 1 for recursion
* @return a validation result struct
*/
ValidationResult validateTerrainView(int posx, int posy, int mapLevel, const TerrainViewPattern & pattern, int recDepth = 0) const; ValidationResult validateTerrainView(int posx, int posy, int mapLevel, const TerrainViewPattern & pattern, int recDepth = 0) const;
/// Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
/**
* Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
*
* @param terType the terrain type to test
* @return true if the terrain type is a sand type, otherwise false
*/
bool isSandType(ETerrainType terType) const; bool isSandType(ETerrainType terType) const;
/**
* Gets a flipped pattern.
*
* @param pattern the original pattern to flip
* @param flip the flip mode value, see FLIP_PATTERN_* constants for details
* @return the flipped pattern
*/
TerrainViewPattern getFlippedPattern(const TerrainViewPattern & pattern, int flip) const; TerrainViewPattern getFlippedPattern(const TerrainViewPattern & pattern, int flip) const;
/** Constant for flipping a pattern horizontally. */
static const int FLIP_PATTERN_HORIZONTAL = 1; static const int FLIP_PATTERN_HORIZONTAL = 1;
/** Constant for flipping a pattern vertically. */
static const int FLIP_PATTERN_VERTICAL = 2; static const int FLIP_PATTERN_VERTICAL = 2;
/** Constant for flipping a pattern horizontally and vertically. */
static const int FLIP_PATTERN_BOTH = 3; static const int FLIP_PATTERN_BOTH = 3;
/** The map object to edit. */
CMap * map; CMap * map;
/** The random number generator. */
CRandomGenerator gen; CRandomGenerator gen;
};
/** The terrain view pattern config. */
const CTerrainViewPatternConfig * terViewPatternConfig; /* ---------------------------------------------------------------------------- */
/* Implementation/Detail classes, Private API */
/* ---------------------------------------------------------------------------- */
/// The terrain view pattern describes a specific composition of terrain tiles
/// in a 3x3 matrix and notes which terrain view frame numbers can be used.
struct TerrainViewPattern
{
struct WeightedRule
{
WeightedRule();
/// Gets true if this rule is a standard rule which means that it has a value of one of the RULE_* constants.
bool isStandardRule() const;
/// The name of the rule. Can be any value of the RULE_* constants or a ID of a another pattern.
std::string name;
/// Optional. A rule can have points. Patterns may have a minimum count of points to reach to be successful.
int points;
};
/// Constant for the flip mode same image. Pattern will be flipped and the same image will be used(which is given in the mapping).
static const std::string FLIP_MODE_SAME_IMAGE;
/// Constant for the flip mode different images. Pattern will be flipped and different images will be used(mapping area is divided into 4 parts)
static const std::string FLIP_MODE_DIFF_IMAGES;
/// Constant for the rule dirt, meaning a dirty border is required.
static const std::string RULE_DIRT;
/// Constant for the rule sand, meaning a sandy border is required.
static const std::string RULE_SAND;
/// Constant for the rule transition, meaning a dirty OR sandy border is required.
static const std::string RULE_TRANSITION;
/// Constant for the rule native, meaning a native type is required.
static const std::string RULE_NATIVE;
/// Constant for the rule any, meaning a native type, dirty OR sandy border is required.
static const std::string RULE_ANY;
TerrainViewPattern();
/// The pattern data can be visualized as a 3x3 matrix:
/// [ ][ ][ ]
/// [ ][ ][ ]
/// [ ][ ][ ]
///
/// The box in the center belongs always to the native terrain type and
/// is the point of origin. Depending on the terrain type different rules
/// can be used. Their meaning differs also from type to type.
///
/// std::vector -> several rules can be used in one cell
std::array<std::vector<WeightedRule>, 9> data;
/// The identifier of the pattern, if it's referenced from a another pattern.
std::string id;
/// This describes the mapping between this pattern and the corresponding range of frames
/// which should be used for the ter view.
///
/// std::vector -> size=1: typical, size=2: if this pattern should map to two different types of borders
/// std::pair -> 1st value: lower range, 2nd value: upper range
std::vector<std::pair<int, int> > mapping;
/// The minimum points to reach to to validate the pattern successfully.
int minPoints;
/// Describes if flipping is required and which mapping should be used.
std::string flipMode;
ETerrainGroup::ETerrainGroup terGroup;
};
/// The terrain view pattern config loads pattern data from the filesystem.
class CTerrainViewPatternConfig
{
public:
static CTerrainViewPatternConfig & get();
const std::vector<TerrainViewPattern> & getPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const;
const TerrainViewPattern & getPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const;
private:
CTerrainViewPatternConfig();
~CTerrainViewPatternConfig();
std::map<ETerrainGroup::ETerrainGroup, std::vector<TerrainViewPattern> > patterns;
static boost::mutex smx;
}; };

View File

@@ -377,8 +377,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
map = make_unique<CMap>(); map = make_unique<CMap>();
addHeaderInfo(); addHeaderInfo();
terViewPatternConfig = make_unique<CTerrainViewPatternConfig>(); mapMgr = make_unique<CMapEditManager>(map.get(), randomSeed);
mapMgr = make_unique<CMapEditManager>(terViewPatternConfig.get(), map.get(), randomSeed);
genTerrain(); genTerrain();
genTowns(); genTowns();

View File

@@ -186,6 +186,5 @@ private:
std::unique_ptr<CMap> map; std::unique_ptr<CMap> map;
CRandomGenerator gen; CRandomGenerator gen;
int randomSeed; int randomSeed;
std::unique_ptr<CTerrainViewPatternConfig> terViewPatternConfig;
std::unique_ptr<CMapEditManager> mapMgr; std::unique_ptr<CMapEditManager> mapMgr;
}; };