Przeglądaj źródła

Enabled & fixed -Woverloaded-virtual warning from gcc/cland

- fixed almost all instances of overloaded-virtual warning
- cleared up inheritance & method overrides in code affected by warning
Ivan Savenko 2 lat temu
rodzic
commit
2855606a88

+ 1 - 1
AI/BattleAI/BattleAI.cpp

@@ -79,7 +79,7 @@ CBattleAI::~CBattleAI()
 	}
 }
 
-void CBattleAI::init(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB)
+void CBattleAI::initBattleInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB)
 {
 	setCbc(CB);
 	env = ENV;

+ 1 - 1
AI/BattleAI/BattleAI.h

@@ -65,7 +65,7 @@ public:
 	CBattleAI();
 	~CBattleAI();
 
-	void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB) override;
+	void initBattleInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB) override;
 	void attemptCastingSpell();
 
 	void evaluateCreatureSpellcast(const CStack * stack, PossibleSpellcast & ps); //for offensive damaging spells only

+ 1 - 1
AI/EmptyAI/CEmptyAI.cpp

@@ -20,7 +20,7 @@ void CEmptyAI::loadGame(BinaryDeserializer & h, const int version)
 {
 }
 
-void CEmptyAI::init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
+void CEmptyAI::initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
 {
 	cb = CB;
 	env = ENV;

+ 1 - 1
AI/EmptyAI/CEmptyAI.h

@@ -22,7 +22,7 @@ public:
 	virtual void saveGame(BinarySerializer & h, const int version) override;
 	virtual void loadGame(BinaryDeserializer & h, const int version) override;
 
-	void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
+	void initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
 	void yourTurn() override;
 	void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
 	void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override;

+ 1 - 1
AI/Nullkiller/AIGateway.cpp

@@ -514,7 +514,7 @@ boost::optional<BattleAction> AIGateway::makeSurrenderRetreatDecision(
 }
 
 
-void AIGateway::init(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB)
+void AIGateway::initGameInterface(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB)
 {
 	LOG_TRACE(logAi);
 	myCb = CB;

+ 1 - 1
AI/Nullkiller/AIGateway.h

@@ -110,7 +110,7 @@ public:
 
 	std::string getBattleAIName() const override;
 
-	void init(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB) override;
+	void initGameInterface(std::shared_ptr<Environment> env, std::shared_ptr<CCallback> CB) override;
 	void yourTurn() override;
 
 	void heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id

+ 1 - 1
AI/StupidAI/StupidAI.cpp

@@ -28,7 +28,7 @@ CStupidAI::~CStupidAI()
 	print("destroyed");
 }
 
-void CStupidAI::init(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB)
+void CStupidAI::initBattleInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB)
 {
 	print("init called, saving ptr to IBattleCallback");
 	env = ENV;

+ 1 - 1
AI/StupidAI/StupidAI.h

@@ -25,7 +25,7 @@ public:
 	CStupidAI();
 	~CStupidAI();
 
-	void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB) override;
+	void initBattleInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB) override;
 	void actionFinished(const BattleAction &action) override;//occurs AFTER every action taken by any stack or by the hero
 	void actionStarted(const BattleAction &action) override;//occurs BEFORE every action taken by any stack or by the hero
 	BattleAction activeStack(const CStack * stack) override; //called when it's turn of that stack

+ 1 - 1
AI/VCAI/VCAI.cpp

@@ -583,7 +583,7 @@ void VCAI::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions)
 	NET_EVENT_HANDLER;
 }
 
-void VCAI::init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
+void VCAI::initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
 {
 	LOG_TRACE(logAi);
 	env = ENV;

+ 1 - 1
AI/VCAI/VCAI.h

@@ -143,7 +143,7 @@ public:
 
 	std::string getBattleAIName() const override;
 
-	void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
+	void initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
 	void yourTurn() override;
 
 	void heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id

+ 1 - 6
CCallback.cpp

@@ -335,11 +335,6 @@ int3 CCallback::getGuardingCreaturePosition(int3 tile)
 	return gs->map->guardingCreaturePositions[tile.z][tile.x][tile.y];
 }
 
-void CCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo &out)
-{
-	gs->calculatePaths(hero, out);
-}
-
 void CCallback::dig( const CGObjectInstance *hero )
 {
 	DigWithHero dwh;
@@ -400,4 +395,4 @@ boost::optional<BattleAction> CBattleCallback::makeSurrenderRetreatDecision(
 	const BattleStateInfoForRetreat & battleState)
 {
 	return cl->playerint[getPlayerID().get()]->makeSurrenderRetreatDecision(battleState);
-}
+}

+ 0 - 2
CCallback.h

@@ -133,8 +133,6 @@ public:
 	virtual int3 getGuardingCreaturePosition(int3 tile);
 	virtual std::shared_ptr<const CPathsInfo> getPathsInfo(const CGHeroInstance * h);
 
-	virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);
-
 	//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
 	void registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents);
 	void unregisterBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents);

+ 2 - 5
CMakeLists.txt

@@ -204,10 +204,8 @@ if(MINGW OR MSVC)
 		add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 		add_definitions(-D_SCL_SECURE_NO_WARNINGS)
 
-		# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /w4") # Enable all warnings
-
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
-		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250") # 4250: 'class1' : inherits 'class2::member' via dominance
+		#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250") # 4250: 'class1' : inherits 'class2::member' via dominance
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") # 4251: class 'xxx' needs to have dll-interface to be used by clients of class 'yyy'
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4275") # 4275: non dll-interface class 'xxx' used as base for dll-interface class
 
@@ -252,9 +250,8 @@ if(CMAKE_COMPILER_IS_GNUCXX OR NOT WIN32) #so far all *nix compilers support suc
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")   # low chance of valid reports, a lot of emitted warnings
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch")             # large number of false-positives, disabled
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare")       # low chance of any significant issues
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-overloaded-virtual") # research
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder")            # research
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-varargs")            # research - fuzzylite - Operation.h
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-varargs")            # emitted in fuzzylite headers, disabled
 
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=array-bounds") # false positives in boost::multiarray during release build, keep as warning-only

+ 2 - 2
client/CPlayerInterface.cpp

@@ -146,7 +146,7 @@ CPlayerInterface::~CPlayerInterface()
 	if (LOCPLINT == this)
 		LOCPLINT = nullptr;
 }
-void CPlayerInterface::init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
+void CPlayerInterface::initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
 {
 	cb = CB;
 	env = ENV;
@@ -689,7 +689,7 @@ void CPlayerInterface::battleStart(const CCreatureSet *army1, const CCreatureSet
 	if (settings["adventure"]["quickCombat"].Bool())
 	{
 		autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
-		autofightingAI->init(env, cb);
+		autofightingAI->initBattleInterface(env, cb);
 		autofightingAI->battleStart(army1, army2, int3(0,0,0), hero1, hero2, side);
 		isAutoFightOn = true;
 		cb->registerBattleInterface(autofightingAI);

+ 1 - 1
client/CPlayerInterface.h

@@ -221,7 +221,7 @@ public:
 	void openTownWindow(const CGTownInstance * town); //shows townscreen
 	void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
 	void updateInfo(const CGObjectInstance * specific);
-	void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
+	void initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB) override;
 	int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
 	void activateForSpectator(); // TODO: spectator probably need own player interface class
 

+ 2 - 2
client/Client.cpp

@@ -509,7 +509,7 @@ void CClient::installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInte
 	logGlobal->trace("\tInitializing the interface for player %s", color.getStr());
 	auto cb = std::make_shared<CCallback>(gs, color, this);
 	battleCallbacks[color] = cb;
-	gameInterface->init(playerEnvironments.at(color), cb);
+	gameInterface->initGameInterface(playerEnvironments.at(color), cb);
 
 	installNewBattleInterface(gameInterface, color, battlecb);
 }
@@ -525,7 +525,7 @@ void CClient::installNewBattleInterface(std::shared_ptr<CBattleGameInterface> ba
 		logGlobal->trace("\tInitializing the battle interface for player %s", color.getStr());
 		auto cbc = std::make_shared<CBattleCallback>(color, this);
 		battleCallbacks[color] = cbc;
-		battleInterface->init(playerEnvironments.at(color), cbc);
+		battleInterface->initBattleInterface(playerEnvironments.at(color), cbc);
 	}
 }
 

+ 1 - 1
client/battle/CBattleInterface.cpp

@@ -875,7 +875,7 @@ void CBattleInterface::bAutofightf()
 		blockUI(true);
 
 		auto ai = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());
-		ai->init(curInt->env, curInt->cb);
+		ai->initBattleInterface(curInt->env, curInt->cb);
 		ai->battleStart(army1, army2, int3(0,0,0), attackingHeroInstance, defendingHeroInstance, curInt->cb->battleGetMySide());
 		curInt->autofightingAI = ai;
 		curInt->cb->registerBattleInterface(ai);

+ 5 - 0
client/widgets/TextControls.cpp

@@ -558,6 +558,11 @@ void CTextInput::keyPressed(const SDL_KeyboardEvent & key)
 	}
 }
 
+void CTextInput::setText(const std::string & nText)
+{
+	setText(nText, false);
+}
+
 void CTextInput::setText(const std::string & nText, bool callCb)
 {
 	CLabel::setText(nText);

+ 2 - 1
client/widgets/TextControls.h

@@ -204,7 +204,8 @@ protected:
 public:
 	CFunctionList<void(const std::string &)> cb;
 	CFunctionList<void(std::string &, const std::string &)> filters;
-	void setText(const std::string & nText, bool callCb = false);
+	void setText(const std::string & nText) override;
+	void setText(const std::string & nText, bool callCb);
 
 	CTextInput(const Rect & Pos, EFonts font, const CFunctionList<void(const std::string &)> & CB);
 	CTextInput(const Rect & Pos, const Point & bgOffset, const std::string & bgName, const CFunctionList<void(const std::string &)> & CB);

+ 8 - 2
lib/CGameInfoCallback.cpp

@@ -171,7 +171,7 @@ void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, SlotID stackPo
 	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!");
 	ERROR_RET_IF(!obj->hasStackAtSlot(stackPos), "There is no such stack!");
-	out = gs->getUpgradeInfo(obj->getStack(stackPos));
+	gs->getUpgradeInfo(obj, stackPos, out);
 	//return gs->getUpgradeInfo(obj->getStack(stackPos));
 }
 
@@ -402,7 +402,7 @@ int CGameInfoCallback::getDate(Date::EDateType mode) const
 bool CGameInfoCallback::isVisible(int3 pos, boost::optional<PlayerColor> Player) const
 {
 	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
-	return gs->map->isInTheMap(pos) && (!Player || gs->isVisible(pos, *Player));
+	return gs->isVisible(pos, *Player);
 }
 
 bool CGameInfoCallback::isVisible(int3 pos) const
@@ -933,6 +933,12 @@ void CGameInfoCallback::calculatePaths(std::shared_ptr<PathfinderConfig> config)
 	gs->calculatePaths(config);
 }
 
+void CGameInfoCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo &out)
+{
+	gs->calculatePaths(hero, out);
+}
+
+
 const CArtifactInstance * CGameInfoCallback::getArtInstance( ArtifactInstanceID aid ) const
 {
 	return gs->map->artInstances[aid.num];

+ 12 - 5
lib/CGameInfoCallback.h

@@ -25,6 +25,7 @@ struct TerrainTile;
 struct PlayerState;
 class CTown;
 struct StartInfo;
+struct CPathsInfo;
 
 struct InfoAboutHero;
 struct InfoAboutTown;
@@ -134,9 +135,6 @@ protected:
 	CGameInfoCallback();
 	CGameInfoCallback(CGameState *GS, boost::optional<PlayerColor> Player);
 	bool hasAccess(boost::optional<PlayerColor> playerId) const;
-	bool isVisible(int3 pos, boost::optional<PlayerColor> Player) const;
-	bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> Player) const;
-	bool isVisible(const CGObjectInstance *obj) const;
 
 	bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode
 	bool isOwnedOrVisited(const CGObjectInstance *obj) const;
@@ -151,7 +149,6 @@ public:
 	const Player * getPlayer(PlayerColor color) const override;
 	virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const;
 	virtual int getResource(PlayerColor Player, Res::ERes which) const;
-	virtual bool isVisible(int3 pos) const;
 	virtual PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const;
 	virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
 	virtual EPlayerStatus::EStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player
@@ -159,6 +156,13 @@ public:
 	PlayerColor getLocalPlayer() const override; //player that is currently owning given client (if not a client, then returns current player)
 	virtual const PlayerSettings * getPlayerSettings(PlayerColor color) const;
 
+	//map
+	virtual bool isVisible(int3 pos, boost::optional<PlayerColor> Player) const;
+	virtual bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> Player) const;
+	virtual bool isVisible(const CGObjectInstance *obj) const;
+	virtual bool isVisible(int3 pos) const;
+
+
 	//armed object
 	virtual void getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out)const;
 
@@ -192,6 +196,7 @@ public:
 	virtual bool isInTheMap(const int3 &pos) const;
 	virtual void getVisibleTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, int3::EDistanceFormula distanceFormula = int3::DIST_2D) const;
 	virtual void calculatePaths(std::shared_ptr<PathfinderConfig> config);
+	virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);
 
 	//town
 	virtual const CGTownInstance* getTown(ObjectInstanceID objid) const;
@@ -222,6 +227,9 @@ public:
 class DLL_LINKAGE CPlayerSpecificInfoCallback : public CGameInfoCallback
 {
 public:
+	// keep player-specific override in scope
+	using CGameInfoCallback::howManyTowns;
+
 	virtual int howManyTowns() const;
 	virtual int howManyHeroes(bool includeGarrisoned = true) const;
 	virtual int3 getGrailPos(double *outKnownRatio);
@@ -242,5 +250,4 @@ public:
 	//virtual const PlayerSettings * getPlayerSettings(PlayerColor color) const;
 };
 
-
 VCMI_LIB_NAMESPACE_END

+ 2 - 2
lib/CGameInterface.cpp

@@ -170,7 +170,7 @@ void CAdventureAI::battleStart(const CCreatureSet * army1, const CCreatureSet *
 	assert(!battleAI);
 	assert(cbc);
 	battleAI = CDynLibHandler::getNewBattleAI(getBattleAIName());
-	battleAI->init(env, cbc);
+	battleAI->initBattleInterface(env, cbc);
 	battleAI->battleStart(army1, army2, tile, hero1, hero2, side);
 }
 
@@ -262,7 +262,7 @@ void CAdventureAI::loadGame(BinaryDeserializer & h, const int version) /*loading
 		h & dllName;
 		battleAI = CDynLibHandler::getNewBattleAI(dllName);
 		assert(cbc); //it should have been set by the one who new'ed us
-		battleAI->init(env, cbc);
+		battleAI->initBattleInterface(env, cbc);
 	}
 }
 

+ 2 - 3
lib/CGameInterface.h

@@ -52,7 +52,6 @@ struct StackLocation;
 class CStackInstance;
 class CCommanderInstance;
 class CStack;
-struct CPathsInfo;
 class CCreature;
 class CLoadFile;
 class CSaveFile;
@@ -78,7 +77,7 @@ public:
 	std::string dllName;
 
 	virtual ~CBattleGameInterface() {};
-	virtual void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB){};
+	virtual void initBattleInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB){};
 
 	//battle call-ins
 	virtual BattleAction activeStack(const CStack * stack)=0; //called when it's turn of that stack
@@ -90,7 +89,7 @@ class DLL_LINKAGE CGameInterface : public CBattleGameInterface, public IGameEven
 {
 public:
 	virtual ~CGameInterface() = default;
-	virtual void init(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB){};
+	virtual void initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB){};
 	virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
 
 	//pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id

+ 20 - 8
lib/CGameState.cpp

@@ -1957,7 +1957,16 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & r
 		*RandomGeneratorUtil::nextItem(t.terType->battleFields, rand));
 }
 
-UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
+
+void CGameState::getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const
+{
+	assert(obj);
+	assert(obj->hasStackAtSlot(stackPos));
+
+	out = getUpgradeInfo(obj->getStack(stackPos));
+}
+
+UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack) const
 {
 	UpgradeInfo ret;
 	const CCreature *base = stack.type;
@@ -2021,7 +2030,7 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 	return ret;
 }
 
-PlayerRelations::PlayerRelations CGameState::getPlayerRelations( PlayerColor color1, PlayerColor color2 )
+PlayerRelations::PlayerRelations CGameState::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const
 {
 	if ( color1 == color2 )
 		return PlayerRelations::SAME_PLAYER;
@@ -2042,8 +2051,7 @@ void CGameState::apply(CPack *pack)
 
 void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out)
 {
-	CPathfinder pathfinder(out, this, hero);
-	pathfinder.calculatePaths();
+	calculatePaths(std::make_shared<SingleHeroPathfinderConfig>(out, this, hero));
 }
 
 void CGameState::calculatePaths(std::shared_ptr<PathfinderConfig> config)
@@ -2187,17 +2195,21 @@ void CGameState::updateRumor()
 	while(!rumor.update(rumorId, rumorExtra));
 }
 
-bool CGameState::isVisible(int3 pos, PlayerColor player)
+bool CGameState::isVisible(int3 pos, boost::optional<PlayerColor> player) const
 {
+	if (!map->isInTheMap(pos))
+		return false;
+	if (!player)
+		return true;
 	if(player == PlayerColor::NEUTRAL)
 		return false;
-	if(player.isSpectator())
+	if(player->isSpectator())
 		return true;
 
-	return (*getPlayerTeam(player)->fogOfWarMap)[pos.z][pos.x][pos.y];
+	return (*getPlayerTeam(*player)->fogOfWarMap)[pos.z][pos.x][pos.y];
 }
 
-bool CGameState::isVisible( const CGObjectInstance *obj, boost::optional<PlayerColor> player )
+bool CGameState::isVisible( const CGObjectInstance *obj, boost::optional<PlayerColor> player ) const
 {
 	if(!player)
 		return true;

+ 8 - 5
lib/CGameState.h

@@ -178,10 +178,11 @@ public:
 
 	void apply(CPack *pack);
 	BattleField battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
-	UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
-	PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
+
+	void getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const override;
+	PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const override;
 	bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
-	void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
+	void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out) override; //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
 	void calculatePaths(std::shared_ptr<PathfinderConfig> config) override;
 	int3 guardingCreaturePosition (int3 pos) const override;
 	std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
@@ -197,8 +198,9 @@ public:
 	void obtainPlayersStats(SThievesGuildInfo & tgi, int level); //fills tgi with info about other players that is available at given level of thieves' guild
 	std::map<ui32, ConstTransitivePtr<CGHeroInstance> > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns
 
-	bool isVisible(int3 pos, PlayerColor player);
-	bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> player);
+
+	bool isVisible(int3 pos, boost::optional<PlayerColor> player) const override;
+	bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> player) const override;
 
 	int getDate(Date::EDateType mode=Date::DAY) const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
 
@@ -292,6 +294,7 @@ private:
 	std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
 	int pickUnusedHeroTypeRandomly(PlayerColor owner); // picks a unused hero type randomly
 	int pickNextHeroType(PlayerColor owner); // picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
+	UpgradeInfo getUpgradeInfo(const CStackInstance &stack) const;
 
 	// ---- data -----
 	std::shared_ptr<CApplier<CBaseForGSApply>> applier;

+ 14 - 24
lib/CPathfinder.cpp

@@ -254,16 +254,6 @@ PathfinderConfig::PathfinderConfig(
 {
 }
 
-CPathfinder::CPathfinder(
-	CPathsInfo & _out,
-	CGameState * _gs,
-	const CGHeroInstance * _hero)
-	: CPathfinder(
-		_gs,
-		std::make_shared<SingleHeroPathfinderConfig>(_out, _gs, _hero))
-{
-}
-
 std::vector<std::shared_ptr<IPathfindingRule>> SingleHeroPathfinderConfig::buildRuleSet()
 {
 	return std::vector<std::shared_ptr<IPathfindingRule>>{
@@ -289,7 +279,7 @@ CPathfinderHelper * SingleHeroPathfinderConfig::getOrCreatePathfinderHelper(cons
 CPathfinder::CPathfinder(
 	CGameState * _gs,
 	std::shared_ptr<PathfinderConfig> config)
-	: CGameInfoCallback(_gs, boost::optional<PlayerColor>())
+	: gamestate(_gs)
 	, config(config)
 	, source()
 	, destination()
@@ -329,14 +319,14 @@ void CPathfinder::calculatePaths()
 
 	for(auto initialNode : initialNodes)
 	{
-		if(!isInTheMap(initialNode->coord)/* || !gs->map->isInTheMap(dest)*/) //check input
+		if(!gamestate->isInTheMap(initialNode->coord)/* || !gs->map->isInTheMap(dest)*/) //check input
 		{
 			logGlobal->error("CGameState::calculatePaths: Hero outside the gs->map? How dare you...");
 			throw std::runtime_error("Wrong checksum");
 		}
 
-		source.setNode(gs, initialNode);
-		auto hlp = config->getOrCreatePathfinderHelper(source, gs);
+		source.setNode(gamestate, initialNode);
+		auto hlp = config->getOrCreatePathfinderHelper(source, gamestate);
 
 		if(hlp->isHeroPatrolLocked())
 			continue;
@@ -349,14 +339,14 @@ void CPathfinder::calculatePaths()
 		counter++;
 		auto node = topAndPop();
 
-		source.setNode(gs, node);
+		source.setNode(gamestate, node);
 		source.node->locked = true;
 
 		int movement = source.node->moveRemains;
 		uint8_t turn = source.node->turns;
 		float cost = source.node->getCost();
 
-		auto hlp = config->getOrCreatePathfinderHelper(source, gs);
+		auto hlp = config->getOrCreatePathfinderHelper(source, gamestate);
 
 		hlp->updateTurnInfo(turn);
 		if(!movement)
@@ -368,7 +358,7 @@ void CPathfinder::calculatePaths()
 		}
 
 		source.isInitialPosition = source.nodeHero == hlp->hero;
-		source.updateInfo(hlp, gs);
+		source.updateInfo(hlp, gamestate);
 
 		//add accessible neighbouring nodes to the queue
 		auto neighbourNodes = config->nodeStorage->calculateNeighbours(source, config.get(), hlp);
@@ -380,8 +370,8 @@ void CPathfinder::calculatePaths()
 			if(!hlp->isLayerAvailable(neighbour->layer))
 				continue;
 
-			destination.setNode(gs, neighbour);
-			hlp = config->getOrCreatePathfinderHelper(destination, gs);
+			destination.setNode(gamestate, neighbour);
+			hlp = config->getOrCreatePathfinderHelper(destination, gamestate);
 
 			if(!hlp->isPatrolMovementAllowed(neighbour->coord))
 				continue;
@@ -393,7 +383,7 @@ void CPathfinder::calculatePaths()
 			destination.turn = turn;
 			destination.movementLeft = movement;
 			destination.cost = cost;
-			destination.updateInfo(hlp, gs);
+			destination.updateInfo(hlp, gamestate);
 			destination.isGuardianTile = destination.guarded && isDestinationGuardian();
 
 			for(auto rule : config->rules)
@@ -410,7 +400,7 @@ void CPathfinder::calculatePaths()
 		} //neighbours loop
 
 		//just add all passable teleport exits
-		hlp = config->getOrCreatePathfinderHelper(source, gs);
+		hlp = config->getOrCreatePathfinderHelper(source, gamestate);
 
 		/// For now we disable teleports usage for patrol movement
 		/// VCAI not aware about patrol and may stuck while attempt to use teleport
@@ -430,7 +420,7 @@ void CPathfinder::calculatePaths()
 			if(teleportNode->accessible == CGPathNode::BLOCKED)
 				continue;
 
-			destination.setNode(gs, teleportNode);
+			destination.setNode(gamestate, teleportNode);
 			destination.turn = turn;
 			destination.movementLeft = movement;
 			destination.cost = cost;
@@ -903,7 +893,7 @@ CGPathNode::ENodeAction CPathfinder::getTeleportDestAction() const
 
 bool CPathfinder::isDestinationGuardian() const
 {
-	return gs->guardingCreaturePosition(destination.node->coord) == destination.node->coord;
+	return gamestate->guardingCreaturePosition(destination.node->coord) == destination.node->coord;
 }
 
 void CPathfinderHelper::initializePatrol()
@@ -927,7 +917,7 @@ void CPathfinderHelper::initializePatrol()
 void CPathfinder::initializeGraph()
 {
 	INodeStorage * nodeStorage = config->nodeStorage.get();
-	nodeStorage->initialize(config->options, gs);
+	nodeStorage->initialize(config->options, gamestate);
 }
 
 bool CPathfinderHelper::canMoveBetween(const int3 & a, const int3 & b) const

+ 3 - 2
lib/CPathfinder.h

@@ -472,12 +472,11 @@ public:
 	static std::vector<std::shared_ptr<IPathfindingRule>> buildRuleSet();
 };
 
-class CPathfinder : private CGameInfoCallback
+class CPathfinder
 {
 public:
 	friend class CPathfinderHelper;
 
-	CPathfinder(CPathsInfo & _out, CGameState * _gs, const CGHeroInstance * _hero);
 	CPathfinder(
 		CGameState * _gs,
 		std::shared_ptr<PathfinderConfig> config);
@@ -485,6 +484,8 @@ public:
 	void calculatePaths(); //calculates possible paths for hero, uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
 
 private:
+	CGameState * gamestate;
+
 	typedef EPathfindingLayer ELayer;
 
 	std::shared_ptr<PathfinderConfig> config;

+ 10 - 0
lib/IGameCallback.h

@@ -116,6 +116,16 @@ public:
 class DLL_LINKAGE CNonConstInfoCallback : public CPrivilegedInfoCallback
 {
 public:
+	//keep const version of callback accessible
+	using CGameInfoCallback::getPlayerState;
+	using CGameInfoCallback::getTeam;
+	using CGameInfoCallback::getPlayerTeam;
+	using CGameInfoCallback::getHero;
+	using CGameInfoCallback::getTown;
+	using CGameInfoCallback::getTile;
+	using CGameInfoCallback::getArtInstance;
+	using CGameInfoCallback::getObjInstance;
+
 	PlayerState * getPlayerState(PlayerColor color, bool verbose = true);
 	TeamState *getTeam(TeamID teamID);//get team by team ID
 	TeamState *getPlayerTeam(PlayerColor color);// get team by player color

+ 2 - 0
lib/mapObjects/CGHeroInstance.h

@@ -46,6 +46,8 @@ class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator,
 	friend class CCampaignState;
 	friend class CMapLoaderH3M;
 
+	using CArmedInstance::getPosition; //FIXME: recheck: overloaded-virtual
+
 private:
 	std::set<SpellID> spells; //known spells (spell IDs)
 

+ 1 - 1
lib/mapObjects/CRewardableObject.cpp

@@ -1157,7 +1157,7 @@ std::vector<ui32> CGMagicSpring::getAvailableRewards(const CGHeroInstance * hero
 	auto tiles = getVisitableOffsets();
 	for (size_t i=0; i<tiles.size(); i++)
 	{
-		if (pos - tiles[i] == hero->getPosition() && info[i].numOfGrants == 0)
+		if (pos - tiles[i] == hero->visitablePos() && info[i].numOfGrants == 0)
 		{
 			return std::vector<ui32>(1, (ui32)i);
 		}

+ 5 - 0
lib/mapObjects/MiscObjects.cpp

@@ -75,6 +75,11 @@ bool CTeamVisited::wasVisited(PlayerColor player) const
 	return wasVisited(cb->getPlayerState(player)->team);
 }
 
+bool CTeamVisited::wasVisited(const CGHeroInstance * h) const
+{
+	return wasVisited(h->tempOwner);
+}
+
 bool CTeamVisited::wasVisited(TeamID team) const
 {
 	for(auto i : players)

+ 1 - 0
lib/mapObjects/MiscObjects.h

@@ -23,6 +23,7 @@ class DLL_LINKAGE CTeamVisited: public CGObjectInstance
 public:
 	std::set<PlayerColor> players; //players that visited this object
 
+	bool wasVisited (const CGHeroInstance * h) const override;
 	bool wasVisited(PlayerColor player) const override;
 	bool wasVisited(TeamID team) const;
 	void setPropertyDer(ui8 what, ui32 val) override;

+ 1 - 1
lib/spells/AdventureSpellMechanics.cpp

@@ -186,7 +186,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
 			if(b->hero)
 				continue; //we're looking for unoccupied boat
 
-			double nDist = b->pos.dist2d(parameters.caster->getPosition());
+			double nDist = b->pos.dist2d(parameters.caster->visitablePos());
 			if(!nearest || nDist < dist) //it's first boat or closer than previous
 			{
 				nearest = b;

+ 5 - 5
server/CGameHandler.cpp

@@ -950,7 +950,7 @@ void CGameHandler::battleAfterLevelUp(const BattleResult &result)
 	if (visitObjectAfterVictory && result.winner==0 && !finishingBattle->winnerHero->stacks.empty())
 	{
 		logGlobal->trace("post-victory visit");
-		visitObjectOnTile(*getTile(finishingBattle->winnerHero->getPosition()), finishingBattle->winnerHero);
+		visitObjectOnTile(*getTile(finishingBattle->winnerHero->visitablePos()), finishingBattle->winnerHero);
 	}
 	visitObjectAfterVictory = false;
 
@@ -2356,7 +2356,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
 
 	const bool canFly = pathfinderHelper->hasBonusOfType(Bonus::FLYING_MOVEMENT);
 	const bool canWalkOnSea = pathfinderHelper->hasBonusOfType(Bonus::WATER_WALKING);
-	const int cost = pathfinderHelper->getMovementCost(h->getPosition(), hmpos, nullptr, nullptr, h->movement);
+	const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movement);
 
 	//it's a rock or blocked and not visitable tile
 	//OR hero is on land and dest is water and (there is not present only one object - boat)
@@ -6013,7 +6013,7 @@ bool CGameHandler::dig(const CGHeroInstance *h)
 {
 	for (auto i = gs->map->objects.cbegin(); i != gs->map->objects.cend(); i++) //unflag objs
 	{
-		if (*i && (*i)->ID == Obj::HOLE  &&  (*i)->pos == h->getPosition())
+		if (*i && (*i)->ID == Obj::HOLE  &&  (*i)->pos == h->visitablePos())
 		{
 			complain("Cannot dig - there is already a hole under the hero!");
 			return false;
@@ -6026,7 +6026,7 @@ bool CGameHandler::dig(const CGHeroInstance *h)
 	//create a hole
 	NewObject no;
 	no.ID = Obj::HOLE;
-	no.pos = h->getPosition();
+	no.pos = h->visitablePos();
 	no.subID = 0;
 	sendAndApply(&no);
 
@@ -6038,7 +6038,7 @@ bool CGameHandler::dig(const CGHeroInstance *h)
 
 	InfoWindow iw;
 	iw.player = h->tempOwner;
-	if (gs->map->grailPos == h->getPosition())
+	if (gs->map->grailPos == h->visitablePos())
 	{
 		iw.text.addTxt(MetaString::GENERAL_TXT, 58); //"Congratulations! After spending many hours digging here, your hero has uncovered the "
 		iw.text.addTxt(MetaString::ART_NAMES, ArtifactID::GRAIL);