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

Initial implementation of VIEW_AIR & VIEW_EARTH

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

+ 21 - 0
client/CPlayerInterface.cpp

@@ -2189,6 +2189,27 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
 	}
 	const CSpell * spell = CGI->spellh->objects[spellID];
 
+	if(spellID == SpellID::VIEW_AIR)
+	{
+		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();
 	if (!castSoundPath.empty())
 		CCS->soundh->playSound(castSoundPath);

+ 28 - 19
client/mapHandler.cpp

@@ -616,8 +616,7 @@ void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf
 
 		if (obj->pos.z != pos.z)
 			continue;
-		if (!(*info->visibilityMap)[pos.x][pos.y][pos.z])
-			continue; // TODO needs to skip this check if we have view-air-like spell cast
+		const bool isVisible = (*info->visibilityMap)[pos.x][pos.y][pos.z];
 		if (!obj->visitableAt(pos.x, pos.y))
 			continue;
 
@@ -640,25 +639,32 @@ void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf
 		case Obj::MONOLITH_ONE_WAY_ENTRANCE:
 		case Obj::MONOLITH_ONE_WAY_EXIT:
 		case Obj::MONOLITH_TWO_WAY:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::TELEPORT].bitmap;
+			if(isVisible)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::TELEPORT].bitmap;
 			break;
 		case Obj::SUBTERRANEAN_GATE:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::GATE].bitmap;
+			if(isVisible)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::GATE].bitmap;
 			break;
 		case Obj::ARTIFACT:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::ARTIFACT].bitmap;
+			if(isVisible || info->showAllArtifacts)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::ARTIFACT].bitmap;
 			break;
 		case Obj::TOWN:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::TOWN + ownerIndex].bitmap;
+			if(isVisible || info->showAllTowns)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::TOWN + ownerIndex].bitmap;
 			break;
 		case Obj::HERO:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::HERO + ownerIndex].bitmap;
+			if(isVisible || info->showAllHeroes)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::HERO + ownerIndex].bitmap;
 			break;
 		case Obj::MINE:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::MINE_WOOD + obj->subID + ownerIndex].bitmap;
+			if(isVisible || info->showAllMines)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::MINE_WOOD + obj->subID + ownerIndex].bitmap;
 			break;
 		case Obj::RESOURCE:
-			wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::RES_WOOD + obj->subID + ownerIndex].bitmap;
+			if(isVisible || info->showAllResources)
+				wvIcon = info->iconsDef->ourImages[(int)EWorldViewIcon::RES_WOOD + obj->subID + ownerIndex].bitmap;
 			break;
 		}
 
@@ -904,9 +910,8 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
 		{
 			if (pos.y < 0 || pos.y >= parent->sizes.y)
 				continue;
-
-			if (!canDrawCurrentTile())
-				continue;
+			
+			const bool isVisible = canDrawCurrentTile();
 
 			realTileRect.x = realPos.x;
 			realTileRect.y = realPos.y;
@@ -914,13 +919,17 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
 			const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z];
 			const TerrainTile & tinfo = parent->map->getTile(pos);
 			const TerrainTile * tinfoUpper = pos.y > 0 ? &parent->map->getTile(int3(pos.x, pos.y - 1, pos.z)) : nullptr;
+			
+			if(isVisible || info->showAllTerrain)
+			{
+				drawTileTerrain(targetSurf, tinfo, tile);
+				if (tinfo.riverType)
+					drawRiver(targetSurf, tinfo);
+				drawRoad(targetSurf, tinfo, tinfoUpper);				
+			}
 
-			drawTileTerrain(targetSurf, tinfo, tile);
-			if (tinfo.riverType)
-				drawRiver(targetSurf, tinfo);
-			drawRoad(targetSurf, tinfo, tinfoUpper);
-
-			drawObjects(targetSurf, tile);
+			if(isVisible)
+				drawObjects(targetSurf, tile);
 		}
 	}
 
@@ -940,7 +949,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
 			{
 				const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z];
 
-				if (!(*info->visibilityMap)[pos.x][pos.y][topTile.z])
+				if (!(*info->visibilityMap)[pos.x][pos.y][topTile.z] && !info->showAllTerrain)
 					drawFow(targetSurf);
 
 				// overlay needs to be drawn over fow, because of artifacts-aura-like spells

+ 17 - 2
client/mapHandler.h

@@ -100,7 +100,16 @@ struct MapDrawingInfo
 
 	bool puzzleMode;
 	int3 grailPos; // location of grail for puzzle mode [in tiles]
-
+	
+	
+	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)
 		: scaled(false),
 		  topTile(topTile_),
@@ -113,7 +122,13 @@ struct MapDrawingInfo
 		  heroAnim(0u),
 		  movement(int3()),
 		  puzzleMode(false),
-		  grailPos(int3())
+		  grailPos(int3()),
+		  showAllArtifacts(false),
+		  showAllHeroes(false),
+		  showAllTowns(false),
+		  showAllResources(false),
+		  showAllMines(false),
+		  showAllTerrain(false)
 	{}
 
 	ui8 getHeroAnim() const { return otherheroAnim ? anim : heroAnim; }

+ 25 - 1
client/windows/CAdvmapInterface.cpp

@@ -310,7 +310,7 @@ void CTerrainRect::showAll(SDL_Surface * to)
 		MapDrawingInfo info(adventureInt->position, &LOCPLINT->cb->getVisibilityMap(), &pos, adventureInt->worldViewIconsDef);
 		info.scaled = true;
 		info.scale = adventureInt->worldViewScale;
-
+		adventureInt->worldViewOptions.adjustDrawingInfo(info);
 		CGI->mh->drawTerrainRectNew(to, &info);
 	}
 }
@@ -1783,6 +1783,9 @@ void CAdvMapInt::changeMode(EAdvMapMode newMode, float newScale /* = 0.4f */)
 			townList.activate();
 			heroList.activate();
 			infoBar.activate();
+			
+			worldViewOptions.clear();
+			
 			break;
 		case EAdvMapMode::WORLD_VIEW:
 			panelMain->deactivate();
@@ -1843,3 +1846,24 @@ void CAdventureOptions::showScenarioInfo()
 		GH.pushInt(new CScenarioInfo(LOCPLINT->cb->getMapHeader(), LOCPLINT->cb->getStartInfo()));
 	}
 }
+
+CAdvMapInt::WorldViewOptions::WorldViewOptions()
+{
+	clear();
+}
+
+void CAdvMapInt::WorldViewOptions::clear()
+{
+	showAllArtifacts = showAllHeroes = showAllTowns = showAllResources  = showAllMines = showAllTerrain = false;
+}
+
+void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
+{
+	info.showAllArtifacts = showAllArtifacts;
+	info.showAllHeroes = showAllHeroes;
+	info.showAllTowns = showAllTowns;
+	info.showAllResources = showAllResources;
+	info.showAllMines = showAllMines;
+	info.showAllTerrain = showAllTerrain;	
+}
+

+ 21 - 0
client/windows/CAdvmapInterface.h

@@ -18,6 +18,8 @@ class IShipyard;
 enum class EMapAnimRedrawStatus;
 class CFadeAnimation;
 
+struct MapDrawingInfo;
+
 /*****************************/
 
 /*
@@ -126,6 +128,25 @@ public:
 
 	EAdvMapMode mode;
 	float worldViewScale;
+	
+	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
+		
+		WorldViewOptions();
+		
+		void clear();
+		
+		void adjustDrawingInfo(MapDrawingInfo & info);		
+	};
+	
+	WorldViewOptions worldViewOptions; 	
 
 	SDL_Surface * bg;
 	SDL_Surface * bgWorldView;

+ 11 - 0
lib/spells/AdventureSpellMechanics.cpp

@@ -253,3 +253,14 @@ bool TownPortalMechanics::applyAdventureEffects(const SpellCastEnvironment * env
 	env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1);	
 	return true;
 }
+
+
+bool ViewAirMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const
+{
+	return true; //implemented on client side
+}
+
+bool ViewEarthMechanics::applyAdventureEffects(const SpellCastEnvironment* env, AdventureSpellCastParameters& parameters) const
+{
+	return true; //implemented on client side
+}

+ 18 - 0
lib/spells/AdventureSpellMechanics.h

@@ -55,3 +55,21 @@ public:
 protected:
 	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
 };
+
+class ViewAirMechanics: public DefaultSpellMechanics 
+{
+public:	
+	ViewAirMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+protected:
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+};
+
+class ViewEarthMechanics: public DefaultSpellMechanics 
+{
+public:	
+	ViewEarthMechanics(CSpell * s): DefaultSpellMechanics(s){};	
+protected:
+	bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override;	
+};
+
+

+ 4 - 2
lib/spells/ISpellMechanics.cpp

@@ -74,10 +74,12 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
 		return new AdventureBonusingMechanics(s, Bonus::WATER_WALKING);
 	case SpellID::TOWN_PORTAL:
 		return new TownPortalMechanics(s);
-	case SpellID::VISIONS:
 	case SpellID::VIEW_EARTH:
+		return new ViewEarthMechanics(s);
+	case SpellID::VIEW_AIR:			
+		return new ViewAirMechanics(s);
+	case SpellID::VISIONS:
 	case SpellID::DISGUISE:
-	case SpellID::VIEW_AIR:	
 	default:		
 		if(s->isRisingSpell())
 			return new SpecialRisingSpellMechanics(s);