2
0
Эх сурвалжийг харах

Move VievXXX logic to server side (except expert ViewEarth)

AlexVinS 10 жил өмнө
parent
commit
f4c683cd5e

+ 7 - 0
AI/VCAI/VCAI.cpp

@@ -530,6 +530,13 @@ void VCAI::showMarketWindow(const IMarket *market, const CGHeroInstance *visitor
 	NET_EVENT_HANDLER;
 }
 
+void VCAI::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions)
+{
+	//TODO: AI support for ViewXXX spell
+	LOG_TRACE(logAi);
+	NET_EVENT_HANDLER;
+}
+
 void VCAI::init(shared_ptr<CCallback> CB)
 {
 	LOG_TRACE(logAi);

+ 1 - 0
AI/VCAI/VCAI.h

@@ -241,6 +241,7 @@ public:
 	virtual void buildChanged(const CGTownInstance *town, BuildingID buildingID, int what) override;
 	virtual void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) override;
 	virtual void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) override;
+	void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;	
 
 	virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) override;
 	virtual void battleEnd(const BattleResult *br) override;

+ 12 - 16
client/CPlayerInterface.cpp

@@ -2189,25 +2189,11 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
 	}
 	const CSpell * spell = CGI->spellh->objects[spellID];
 
-	if(spellID == SpellID::VIEW_AIR)
+	if(spellID == SpellID::VIEW_EARTH)
 	{
+		//TODO: implement on server side
 		int level = caster->getSpellSchoolLevel(spell);
-		
-		adventureInt->worldViewOptions.showAllArtifacts = true;
-		adventureInt->worldViewOptions.showAllHeroes = (level>1);
-		adventureInt->worldViewOptions.showAllTowns = (level>2);
-		
-		viewWorldMap();
-	}
-	else if(spellID == SpellID::VIEW_EARTH)
-	{
-		int level = caster->getSpellSchoolLevel(spell);
-		
-		adventureInt->worldViewOptions.showAllResources = true;
-		adventureInt->worldViewOptions.showAllMines = (level>1);
 		adventureInt->worldViewOptions.showAllTerrain = (level>2);
-				
-		viewWorldMap();
 	}
 	
 	auto castSoundPath = spell->getCastSound();
@@ -2724,3 +2710,13 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance* h, CGPath path)
 
 	duringMovement = false;
 }
+
+void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectPositions)
+{
+	EVENT_HANDLER_CALLED_BY_CLIENT;
+	//TODO: showWorldViewEx
+	
+	std::copy(objectPositions.begin(), objectPositions.end(), std::back_inserter(adventureInt->worldViewOptions.iconPositions));
+	
+	viewWorldMap();
+}

+ 1 - 0
client/CPlayerInterface.h

@@ -196,6 +196,7 @@ public:
 	void showComp(const Component &comp, std::string message) override; //display component in the advmapint infobox
 	void saveGame(COSer & h, const int version) override; //saving
 	void loadGame(CISer & h, const int version) override; //loading
+	void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;	
 
 	//for battles
 	void actionFinished(const BattleAction& action) override;//occurs AFTER action taken by active stack or by the hero

+ 5 - 0
client/NetPacksClient.cpp

@@ -834,6 +834,11 @@ void AdvmapSpellCast::applyCl(CClient *cl)
 	INTERFACE_CALL_IF_PRESENT(caster->getOwner(),advmapSpellCast, caster, spellID);
 }
 
+void ShowWorldViewEx::applyCl(CClient * cl)
+{
+	CALL_ONLY_THAT_INTERFACE(player, showWorldViewEx, objectPositions);
+}
+
 void OpenWindow::applyCl(CClient *cl)
 {
 	switch(window)

+ 83 - 52
client/mapHandler.cpp

@@ -528,6 +528,40 @@ CMapHandler::CMapNormalBlitter::CMapNormalBlitter(CMapHandler * parent)
 	defaultTileRect = Rect(0, 0, tileSize, tileSize);
 }
 
+SDL_Surface * CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId, PlayerColor owner) const
+{
+	int ownerIndex = 0;
+	if(owner < PlayerColor::PLAYER_LIMIT)
+	{
+		ownerIndex = owner.getNum() * 19;
+	}
+	else if (owner == PlayerColor::NEUTRAL)
+	{
+		ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * 19;
+	}
+	
+	switch(id)
+	{
+	case Obj::MONOLITH_ONE_WAY_ENTRANCE:
+	case Obj::MONOLITH_ONE_WAY_EXIT:
+	case Obj::MONOLITH_TWO_WAY:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::TELEPORT].bitmap;
+	case Obj::SUBTERRANEAN_GATE:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::GATE].bitmap;
+	case Obj::ARTIFACT:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::ARTIFACT].bitmap;
+	case Obj::TOWN:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::TOWN + ownerIndex].bitmap;
+	case Obj::HERO:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::HERO + ownerIndex].bitmap;
+	case Obj::MINE:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::MINE_WOOD + subId + ownerIndex].bitmap;
+	case Obj::RESOURCE:
+		return info->iconsDef->ourImages[(int)EWorldViewIcon::RES_WOOD + subId + ownerIndex].bitmap;
+	}	
+	return nullptr;	
+}
+
 void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos()
 {
 	bool outsideLeft = topTile.x < 0;
@@ -609,71 +643,61 @@ void CMapHandler::CMapWorldViewBlitter::drawElement(EMapCacheType cacheType, SDL
 
 void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const
 {
+	auto drawIcon = [this,targetSurf](Obj id, si32 subId, PlayerColor owner)
+	{
+		SDL_Surface * wvIcon = this->objectToIcon(id, subId, owner);
+
+		if (nullptr != wvIcon)
+		{
+			// centering icon on the object
+			Rect destRect(realPos.x + tileSize / 2 - wvIcon->w / 2, realPos.y + tileSize / 2 - wvIcon->h / 2, wvIcon->w, wvIcon->h);
+			CSDL_Ext::blitSurface(wvIcon, nullptr, targetSurf, &destRect);
+		}
+	};
+
 	auto & objects = tile.objects;
 	for(auto & object : objects)
 	{
 		const CGObjectInstance * obj = object.obj;
 
-		if (obj->pos.z != pos.z)
-			continue;
+		const bool sameLevel = obj->pos.z == pos.z;			
 		const bool isVisible = (*info->visibilityMap)[pos.x][pos.y][pos.z];
-		if (!obj->visitableAt(pos.x, pos.y))
-			continue;
+		const bool isVisitable = obj->visitableAt(pos.x, pos.y);
 
-		auto &ownerRaw = obj->tempOwner;
-		int ownerIndex = 0;
-		if (ownerRaw < PlayerColor::PLAYER_LIMIT)
-		{
-			ownerIndex = ownerRaw.getNum() * 19;
-		}
-		else if (ownerRaw == PlayerColor::NEUTRAL)
-		{
-			ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * 19;
-		}
+		if(sameLevel && isVisible && isVisitable)
+			drawIcon(obj->ID, obj->subID, obj->tempOwner);
+	}
+}
 
-		SDL_Surface * wvIcon = nullptr;
-		switch (obj->ID)
-		{
-		default:
+void CMapHandler::CMapWorldViewBlitter::drawOverlayEx(SDL_Surface * targetSurf)
+{
+	if(nullptr == info->additionalIcons)
+		return;
+		
+	const int3 bottomRight = pos + tileCount;
+	
+	for(const ObjectPosInfo & iconInfo : *(info->additionalIcons))
+	{
+		if(!iconInfo.pos.z == pos.z)
 			continue;
-		case Obj::MONOLITH_ONE_WAY_ENTRANCE:
-		case Obj::MONOLITH_ONE_WAY_EXIT:
-		case Obj::MONOLITH_TWO_WAY:
-			if(isVisible)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::TELEPORT].bitmap;
-			break;
-		case Obj::SUBTERRANEAN_GATE:
-			if(isVisible)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::GATE].bitmap;
-			break;
-		case Obj::ARTIFACT:
-			if(isVisible || info->showAllArtifacts)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::ARTIFACT].bitmap;
-			break;
-		case Obj::TOWN:
-			if(isVisible || info->showAllTowns)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::TOWN + ownerIndex].bitmap;
-			break;
-		case Obj::HERO:
-			if(isVisible || info->showAllHeroes)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::HERO + ownerIndex].bitmap;
-			break;
-		case Obj::MINE:
-			if(isVisible || info->showAllMines)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::MINE_WOOD + obj->subID + ownerIndex].bitmap;
-			break;
-		case Obj::RESOURCE:
-			if(isVisible || info->showAllResources)
-				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::RES_WOOD + obj->subID + ownerIndex].bitmap;
-			break;
-		}
-
-		if (wvIcon)
+		
+		if((iconInfo.pos.x < topTile.x) || (iconInfo.pos.y < topTile.y))
+			continue;
+		
+		if((iconInfo.pos.x > bottomRight.x) || (iconInfo.pos.y > bottomRight.y))
+			continue;		
+		
+		realPos.x = initPos.x + (iconInfo.pos.x - topTile.x) * tileSize;
+		realPos.y = initPos.x + (iconInfo.pos.y - topTile.y) * tileSize;
+		
+		SDL_Surface * wvIcon = this->objectToIcon(iconInfo.id, iconInfo.subId, iconInfo.owner);				
+		
+		if (nullptr != wvIcon)
 		{
 			// centering icon on the object
 			Rect destRect(realPos.x + tileSize / 2 - wvIcon->w / 2, realPos.y + tileSize / 2 - wvIcon->h / 2, wvIcon->w, wvIcon->h);
 			CSDL_Ext::blitSurface(wvIcon, nullptr, targetSurf, &destRect);
-		}
+		}		
 	}
 }
 
@@ -791,6 +815,11 @@ void CMapHandler::CMapBlitter::drawFrame(SDL_Surface * targetSurf) const
 	drawElement(EMapCacheType::FRAME, parent->ttiles[pos.x][pos.y][topTile.z].terbitmap, nullptr, targetSurf, &destRect);
 }
 
+void CMapHandler::CMapBlitter::drawOverlayEx(SDL_Surface * targetSurf)
+{
+//nothing to do here
+}
+
 void CMapHandler::CMapBlitter::drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const
 {
 	drawElement(EMapCacheType::HERO_FLAGS, sourceSurf, sourceRect, targetSurf, destRect, false);
@@ -981,6 +1010,8 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
 			}
 		}
 	}
+	
+	drawOverlayEx(targetSurf);	
 
 	// drawDebugGrid()
 	if (settings["session"]["showGrid"].Bool())

+ 8 - 11
client/mapHandler.h

@@ -2,6 +2,7 @@
 
 
 #include "../lib/int3.h"
+#include "../lib/spells/ViewSpellInt.h"
 #include "gui/Geometries.h"
 #include "SDL.h"
 
@@ -101,13 +102,8 @@ struct MapDrawingInfo
 	bool puzzleMode;
 	int3 grailPos; // location of grail for puzzle mode [in tiles]
 	
+	const std::vector<ObjectPosInfo> * additionalIcons;
 	
-	bool showAllArtifacts; //for basic viewAir
-	bool showAllHeroes; //for advanced viewAir
-	bool showAllTowns; //for expert viewAir
-	
-	bool showAllResources; //for basic viewEarth
-	bool showAllMines; //for advanced viewEarth 
 	bool showAllTerrain; //for expert viewEarth
 	
 	MapDrawingInfo(int3 &topTile_, const std::vector< std::vector< std::vector<ui8> > > * visibilityMap_, SDL_Rect * drawBounds_, CDefHandler * iconsDef_ = nullptr)
@@ -123,11 +119,7 @@ struct MapDrawingInfo
 		  movement(int3()),
 		  puzzleMode(false),
 		  grailPos(int3()),
-		  showAllArtifacts(false),
-		  showAllHeroes(false),
-		  showAllTowns(false),
-		  showAllResources(false),
-		  showAllMines(false),
+		  additionalIcons(nullptr),
 		  showAllTerrain(false)
 	{}
 
@@ -253,6 +245,8 @@ class CMapHandler
 		virtual void drawFow(SDL_Surface * targetSurf) const;
 		/// draws map border frame on current position
 		virtual void drawFrame(SDL_Surface * targetSurf) const;
+		/// draws additional icons (for VIEW_AIR, VIEW_EARTH spells atm)
+		virtual void drawOverlayEx(SDL_Surface * targetSurf);
 
 		// third drawing pass
 
@@ -308,6 +302,8 @@ class CMapHandler
 
 	class CMapWorldViewBlitter : public CMapBlitter
 	{
+	private:
+		SDL_Surface * objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
 	protected:
 		void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
 						 SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const override;
@@ -316,6 +312,7 @@ class CMapHandler
 		void drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const override;
 		void drawObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const override;
 		void drawFrame(SDL_Surface * targetSurf) const override {}
+		void drawOverlayEx(SDL_Surface * targetSurf);
 		void init(const MapDrawingInfo * info) override;
 		SDL_Rect clip(SDL_Surface * targetSurf) const override;
 

+ 6 - 7
client/windows/CAdvmapInterface.cpp

@@ -1854,16 +1854,15 @@ CAdvMapInt::WorldViewOptions::WorldViewOptions()
 
 void CAdvMapInt::WorldViewOptions::clear()
 {
-	showAllArtifacts = showAllHeroes = showAllTowns = showAllResources  = showAllMines = showAllTerrain = false;
+	showAllTerrain = false;
+	
+	iconPositions.clear();
 }
 
 void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
 {
-	info.showAllArtifacts = showAllArtifacts;
-	info.showAllHeroes = showAllHeroes;
-	info.showAllTowns = showAllTowns;
-	info.showAllResources = showAllResources;
-	info.showAllMines = showAllMines;
-	info.showAllTerrain = showAllTerrain;	
+	info.showAllTerrain = showAllTerrain;
+	
+	info.additionalIcons = &iconPositions;	
 }
 

+ 4 - 6
client/windows/CAdvmapInterface.h

@@ -6,6 +6,8 @@
 #include "../widgets/TextControls.h"
 #include "../widgets/Buttons.h"
 
+#include "../../lib/spells/ViewSpellInt.h"
+
 class CDefHandler;
 class CCallback;
 struct CGPath;
@@ -131,14 +133,10 @@ public:
 	
 	struct WorldViewOptions
 	{
-		bool showAllArtifacts; //for basic viewAir
-		bool showAllHeroes; //for advanced viewAir
-		bool showAllTowns; //for expert viewAir
-		
-		bool showAllResources; //for basic viewEarth
-		bool showAllMines; //for advanced viewEarth 
 		bool showAllTerrain; //for expert viewEarth
 		
+		std::vector<ObjectPosInfo> iconPositions;
+		
 		WorldViewOptions();
 		
 		void clear();

+ 4 - 0
lib/CGameInterface.h

@@ -5,6 +5,8 @@
 #include "IGameEventsReceiver.h"
 #include "CGameStateFwd.h"
 
+#include "spells/ViewSpellInt.h"
+
 /*
  * CGameInterface.h, part of VCMI engine
  *
@@ -93,6 +95,8 @@ public:
 	// all stacks operations between these objects become allowed, interface has to call onEnd when done
 	virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) = 0;
 	virtual void finish(){}; //if for some reason we want to end
+	
+	virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions){};
 };
 
 class DLL_LINKAGE CDynLibHandler

+ 5 - 4
lib/CMakeLists.txt

@@ -56,10 +56,11 @@ set(lib_SRCS
 
 		spells/CSpellHandler.cpp
 		spells/ISpellMechanics.cpp
-                spells/AdventureSpellMechanics.cpp
-                spells/BattleSpellMechanics.cpp
-                spells/CreatureSpellMechanics.cpp
-                spells/CDefaultSpellMechanics.cpp
+        spells/AdventureSpellMechanics.cpp
+        spells/BattleSpellMechanics.cpp
+        spells/CreatureSpellMechanics.cpp
+        spells/CDefaultSpellMechanics.cpp
+        spells/ViewSpellInt.cpp
 
 		BattleAction.cpp
 		BattleHex.cpp

+ 18 - 0
lib/NetPacks.h

@@ -16,6 +16,8 @@
 #include "mapping/CMap.h"
 #include "CObstacleInstance.h"
 
+#include "spells/ViewSpellInt.h"
+
 /*
  * NetPacks.h, part of VCMI engine
  *
@@ -1685,6 +1687,22 @@ struct AdvmapSpellCast : public CPackForClient //108
 	}
 };
 
+struct ShowWorldViewEx : public CPackForClient //4000
+{
+	PlayerColor player;
+	
+	std::vector<ObjectPosInfo> objectPositions;
+	
+	ShowWorldViewEx(){type = 4000;}
+	
+	void applyCl(CClient *cl);
+	
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & player & objectPositions;
+	}	
+};
+
 /***********************************************************************************************************/
 
 struct CommitPackage : public CPackForServer

+ 2 - 0
lib/VCMI_lib.cbp

@@ -302,6 +302,8 @@
 		<Unit filename="spells/CreatureSpellMechanics.h" />
 		<Unit filename="spells/ISpellMechanics.cpp" />
 		<Unit filename="spells/ISpellMechanics.h" />
+		<Unit filename="spells/ViewSpellInt.cpp" />
+		<Unit filename="spells/ViewSpellInt.h" />
 		<Unit filename="vcmi_endian.h" />
 		<Extensions>
 			<code_completion />

+ 1 - 0
lib/VCMI_lib.vcxproj

@@ -193,6 +193,7 @@
     <ClCompile Include="spells\BattleSpellMechanics.cpp" />
     <ClCompile Include="spells\CreatureSpellMechanics.cpp" />
     <ClCompile Include="spells\CDefaultSpellMechanics.cpp" />
+    <ClCompile Include="spells\ViewSpellInt.cpp" />
     <ClCompile Include="filesystem\AdapterLoaders.cpp" />
     <ClCompile Include="filesystem\CArchiveLoader.cpp" />
     <ClCompile Include="filesystem\CBinaryReader.cpp" />

+ 1 - 0
lib/registerTypes/RegisterTypes.h

@@ -248,6 +248,7 @@ void registerTypesClientPacks1(Serializer &s)
 	s.template registerType<CPackForClient, HeroVisit>();
 	s.template registerType<CPackForClient, SetCommanderProperty>();
 	s.template registerType<CPackForClient, ChangeObjectVisitors>();
+	s.template registerType<CPackForClient, ShowWorldViewEx>();
 }
 
 template<typename Serializer>

+ 25 - 4
lib/spells/AdventureSpellMechanics.cpp

@@ -240,13 +240,34 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 	return true;
 }
 
+bool ViewMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const
+{
+	ShowWorldViewEx pack;
+	
+	pack.player = parameters.caster->tempOwner;
+	
+	const int spellLevel = parameters.caster->getSpellSchoolLevel(owner);
+	
+	for(const CGObjectInstance * obj : env->getMap()->objects)
+	{
+		//we need to send only not visible objects
+		
+		if(filterObject(obj, spellLevel))
+			pack.objectPositions.push_back(ObjectPosInfo(obj));
+	}	
+	
+	env->sendAndApply(&pack);
+	
+	return true;	
+}
 
-bool ViewAirMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const
+bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
 {
-	return true; //implemented on client side
+	return (obj->ID == Obj::ARTIFACT) || (spellLevel>1 && obj->ID == Obj::HERO) || (spellLevel>2 && obj->ID == Obj::TOWN);
 }
 
-bool ViewEarthMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const
+bool ViewEarthMechanics::filterObject(const CGObjectInstance * obj, const int spellLevel) const
 {
-	return true; //implemented on client side
+	return (obj->ID == Obj::RESOURCE) || (spellLevel>1 && obj->ID == Obj::MINE);
 }
+

+ 14 - 5
lib/spells/AdventureSpellMechanics.h

@@ -45,20 +45,29 @@ protected:
 	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
 };
 
-class ViewAirMechanics: public DefaultSpellMechanics 
+class ViewMechanics: public DefaultSpellMechanics 
 {
 public:	
-	ViewAirMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+	ViewMechanics(CSpell * s): DefaultSpellMechanics(s){};
 protected:
 	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	virtual bool filterObject(const CGObjectInstance * obj, const int spellLevel) const = 0;
 };
 
-class ViewEarthMechanics: public DefaultSpellMechanics 
+class ViewAirMechanics: public ViewMechanics 
 {
 public:	
-	ViewEarthMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+	ViewAirMechanics(CSpell * s): ViewMechanics(s){};	
 protected:
-	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+	bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;
+};
+
+class ViewEarthMechanics: public ViewMechanics 
+{
+public:	
+	ViewEarthMechanics(CSpell * s): ViewMechanics(s){};	
+protected:
+	bool filterObject(const CGObjectInstance * obj, const int spellLevel) const override;	
 };
 
 

+ 27 - 0
lib/spells/ViewSpellInt.cpp

@@ -0,0 +1,27 @@
+/*
+ * ViewSpellInt.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+
+#include "StdInc.h"
+
+#include "ViewSpellInt.h"
+
+#include "../mapObjects/CObjectHandler.h"
+
+ObjectPosInfo::ObjectPosInfo():
+	pos(),id(Obj::NO_OBJ), subId(-1), owner(PlayerColor::CANNOT_DETERMINE)
+{
+	
+}
+
+ObjectPosInfo::ObjectPosInfo(const CGObjectInstance * obj):
+	pos(obj->pos),id(obj->ID), subId(obj->subID), owner(obj->tempOwner)
+{
+	
+}

+ 32 - 0
lib/spells/ViewSpellInt.h

@@ -0,0 +1,32 @@
+/*
+ * ViewSpellInt.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+ 
+ #pragma once
+ 
+ #include "../int3.h" 
+ #include "../GameConstants.h"
+ 
+ class CGObjectInstance;
+ 
+ struct DLL_LINKAGE ObjectPosInfo
+ {
+ 	int3 pos; 	
+ 	Obj id;
+ 	si32 subId;
+ 	PlayerColor owner;
+ 	ObjectPosInfo();
+ 	ObjectPosInfo(const CGObjectInstance * obj);
+ 	
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & pos & id & subId & owner;
+	} 	
+ };
+