1 ////////////////////////////////////////////////////////////////////////////////
2 //    Scorched3D (c) 2000-2011
3 //
4 //    This file is part of Scorched3D.
5 //
6 //    Scorched3D is free software; you can redistribute it and/or modify
7 //    it under the terms of the GNU General Public License as published by
8 //    the Free Software Foundation; either version 2 of the License, or
9 //    (at your option) any later version.
10 //
11 //    Scorched3D is distributed in the hope that it will be useful,
12 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //    GNU General Public License for more details.
15 //
16 //    You should have received a copy of the GNU General Public License along
17 //    with this program; if not, write to the Free Software Foundation, Inc.,
18 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20 
21 #include <landscapemap/RoofMaps.h>
22 #include <landscapemap/HeightMapLoader.h>
23 #include <image/ImageFactory.h>
24 #include <common/ProgressCounter.h>
25 #include <engine/ScorchedContext.h>
26 #include <landscapedef/LandscapeDefinitionCache.h>
27 #include <landscapedef/LandscapeDefn.h>
28 
RoofMaps(LandscapeDefinitionCache & defnCache)29 RoofMaps::RoofMaps(LandscapeDefinitionCache &defnCache) :
30 	defnCache_(defnCache), roofBaseHeight_(0)
31 {
32 }
33 
~RoofMaps()34 RoofMaps::~RoofMaps()
35 {
36 }
37 
generateMaps(ScorchedContext & context,ProgressCounter * counter)38 void RoofMaps::generateMaps(
39 	ScorchedContext &context,
40 	ProgressCounter *counter)
41 {
42 	generateRMap(context, counter);
43 }
44 
getRoofOn()45 bool RoofMaps::getRoofOn()
46 {
47 	return (defnCache_.getDefn()->roof->getType() == LandscapeDefnType::eRoofCavern);
48 }
49 
getRoofHeight(int x,int y)50 fixed RoofMaps::getRoofHeight(int x, int y)
51 {
52 	if (!getRoofOn())
53 	{
54 		return fixed::MAX_FIXED;
55 	}
56 
57 	if (x >= 0 && y >= 0 && x<=rmap_.getMapWidth() && y<=rmap_.getMapHeight())
58 	{
59 		return rmap_.getHeight(x, y);
60 	}
61 	return roofBaseHeight_;
62 }
63 
getInterpRoofHeight(fixed x,fixed y)64 fixed RoofMaps::getInterpRoofHeight(fixed x, fixed y)
65 {
66 	if (!getRoofOn())
67 	{
68 		return fixed::MAX_FIXED;
69 	}
70 
71 	if (x >= 0 && y >= 0 && x<=rmap_.getMapWidth() && y<=rmap_.getMapHeight())
72 	{
73 		return rmap_.getInterpHeight(x, y);
74 	}
75 	return roofBaseHeight_;
76 }
77 
generateRMap(ScorchedContext & context,ProgressCounter * counter)78 void RoofMaps::generateRMap(
79 	ScorchedContext &context,
80 	ProgressCounter *counter)
81 {
82 	// calculate roof size and set it
83 	int mapWidth = defnCache_.getDefn()->getLandscapeWidth();
84 	int mapHeight = defnCache_.getDefn()->getLandscapeHeight();
85 	rmap_.create(mapWidth, mapHeight, true);
86 	deformRMap_.create(rmap_.getMapWidth(), rmap_.getMapHeight(), true);
87 	roofBaseHeight_ = 0;
88 
89 	// Generate the roof
90 	if (getRoofOn())
91 	{
92 		LandscapeDefnRoofCavern *cavern =
93 			(LandscapeDefnRoofCavern *) defnCache_.getDefn()->roof;
94 
95 		roofBaseHeight_ = fixed(cavern->height);
96 
97 		bool smooth = false;
98 		if (!HeightMapLoader::generateTerrain(
99 			defnCache_.getSeed() + 1,
100 			cavern->heightmap,
101 			rmap_,
102 			smooth,
103 			counter))
104 		{
105 			S3D::dialogExit("Landscape", "Failed to generate roof");
106 		}
107 
108 		// Reverse heights (up-side-down)
109 		for (int j=0; j<=rmap_.getMapHeight(); j++)
110 		{
111 			for (int i=0; i<=rmap_.getMapWidth(); i++)
112 			{
113 				fixed height = rmap_.getHeight(i, j);
114 				height = fixed(cavern->height) - height;
115 				rmap_.setHeight(i, j, height);
116 			}
117 		}
118 
119 		// Generate the deform map (if any)
120 		if (cavern->deform->getType() == LandscapeDefnType::eDeformFile)
121 		{
122 			LandscapeDefnDeformFile *file =
123 				(LandscapeDefnDeformFile *) cavern->deform;
124 
125 			// Load the landscape
126 			Image image = ImageFactory::loadImage(S3D::eModLocation, file->file);
127 			if (!image.getBits())
128 			{
129 				S3D::dialogExit("HeightMapLoader", S3D::formatStringBuffer(
130 					"Error: Unable to find deform roof map \"%s\"",
131 					file->file.c_str()));
132 			}
133 			if (!image.getLossless())
134 			{
135 				S3D::dialogExit("HeightMapLoader", S3D::formatStringBuffer(
136 					"Error: Deform landscape map \"%s\" is not a lossless image format",
137 					file->file.c_str()));
138 			}
139 			HeightMapLoader::loadTerrain(
140 				deformRMap_,
141 				image,
142 				file->levelsurround,
143 				counter);
144 
145 			for (int j=0; j<=deformRMap_.getMapHeight(); j++)
146 			{
147 				for (int i=0; i<=deformRMap_.getMapWidth(); i++)
148 				{
149 					fixed height = deformRMap_.getHeight(i, j);
150 					height = fixed(cavern->height) - height;
151 					deformRMap_.setHeight(i, j, height);
152 				}
153 			}
154 		}
155 		else
156 		{
157 			for (int x=0; x<rmap_.getMapWidth(); x++)
158 			{
159 				for (int y=0; y<rmap_.getMapHeight(); y++)
160 				{
161 					deformRMap_.setHeight(x, y, rmap_.getHeight(x, y));
162 				}
163 			}
164 		}
165 	}
166 }
167