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