00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <landscapedef/LandscapeDefn.h>
00022 #include <landscapedef/LandscapeDefinitions.h>
00023 #include <common/Defines.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <time.h>
00027
00028 static LandscapeDefnType *fetchTankStartDefnType(const char *type)
00029 {
00030 if (0 == strcmp(type, "height")) return new LandscapeDefnStartHeight;
00031 S3D::dialogMessage("LandscapeDefnType", S3D::formatStringBuffer("Unknown tankstart type %s", type));
00032 return 0;
00033 }
00034
00035 static LandscapeDefnType *fetchHeightMapDefnType(const char *type)
00036 {
00037 if (0 == strcmp(type, "generate")) return new LandscapeDefnHeightMapGenerate;
00038 if (0 == strcmp(type, "file")) return new LandscapeDefnHeightMapFile;
00039 S3D::dialogMessage("LandscapeDefnType", S3D::formatStringBuffer("Unknown heightmap type %s", type));
00040 return 0;
00041 }
00042
00043 static LandscapeDefnType *fetchRoofMapDefnType(const char *type)
00044 {
00045 if (0 == strcmp(type, "sky")) return new LandscapeDefnTypeNone;
00046 if (0 == strcmp(type, "cavern")) return new LandscapeDefnRoofCavern;
00047 S3D::dialogMessage("LandscapeDefnType", S3D::formatStringBuffer("Unknown roof type %s", type));
00048 return 0;
00049 }
00050
00051 static bool parseMinMax(XMLNode *parent, const char *name,
00052 fixed &min, fixed &max)
00053 {
00054 XMLNode *node = 0;
00055 if (!parent->getNamedChild(name, node)) return false;
00056 if (!node->getNamedChild("max", max)) return false;
00057 if (!node->getNamedChild("min", min)) return false;
00058 return node->failChildren();
00059 }
00060
00061 static bool parseMinMaxInt(XMLNode *parent, const char *name,
00062 int &min, int &max)
00063 {
00064 XMLNode *node = 0;
00065 if (!parent->getNamedChild(name, node)) return false;
00066 if (!node->getNamedChild("max", max)) return false;
00067 if (!node->getNamedChild("min", min)) return false;
00068 return node->failChildren();
00069 }
00070
00071 bool LandscapeDefnTypeNone::readXML(XMLNode *node)
00072 {
00073 return node->failChildren();
00074 }
00075
00076 LandscapeDefnRoofCavern::LandscapeDefnRoofCavern() : heightmap(0)
00077 {
00078 }
00079
00080 LandscapeDefnRoofCavern::~LandscapeDefnRoofCavern()
00081 {
00082 delete heightmap;
00083 }
00084
00085 bool LandscapeDefnRoofCavern::readXML(XMLNode *node)
00086 {
00087 if (!node->getNamedChild("width", width)) return false;
00088 if (!node->getNamedChild("height", height)) return false;
00089 {
00090 XMLNode *heightNode;
00091 std::string heightmaptype;
00092 if (!node->getNamedChild("heightmap", heightNode)) return false;
00093 if (!heightNode->getNamedParameter("type", heightmaptype)) return false;
00094 if (!(heightmap = fetchHeightMapDefnType(heightmaptype.c_str()))) return false;
00095 if (!heightmap->readXML(heightNode)) return false;
00096 }
00097 return node->failChildren();
00098 }
00099
00100 bool LandscapeDefnStartHeight::readXML(XMLNode *node)
00101 {
00102 if (!node->getNamedChild("startcloseness", startcloseness)) return false;
00103 if (!parseMinMax(node, "height", heightmin, heightmax)) return false;
00104 if (!node->getNamedChild("startmask", startmask)) return false;
00105 if (!node->getNamedChild("flatness", flatness, false))
00106 {
00107 flatness = 0;
00108 }
00109 if (!startmask.empty())
00110 {
00111 if (!S3D::checkDataFile(startmask.c_str())) return false;
00112 }
00113 return node->failChildren();
00114 }
00115
00116 bool LandscapeDefnHeightMapFile::readXML(XMLNode *node)
00117 {
00118 if (!node->getNamedChild("file", file)) return false;
00119 if (!node->getNamedChild("levelsurround", levelsurround)) return false;
00120 if (!S3D::checkDataFile(file.c_str())) return false;
00121 return node->failChildren();
00122 }
00123
00124 bool LandscapeDefnHeightMapGenerate::readXML(XMLNode *node)
00125 {
00126 if (!node->getNamedChild("mask", mask)) return false;
00127 if (!parseMinMaxInt(node, "landhills",
00128 landhillsmin, landhillsmax)) return false;
00129 if (!parseMinMax(node, "landheight",
00130 landheightmin, landheightmax)) return false;
00131 if (!parseMinMax(node, "landpeakwidthx",
00132 landpeakwidthxmin, landpeakwidthxmax)) return false;
00133 if (!parseMinMax(node, "landpeakwidthy",
00134 landpeakwidthymin, landpeakwidthymax)) return false;
00135 if (!parseMinMax(node, "landpeakheight",
00136 landpeakheightmin, landpeakheightmax)) return false;
00137 if (!node->getNamedChild("landsmoothing", landsmoothing)) return false;
00138 if (!node->getNamedChild("levelsurround", levelsurround)) return false;
00139
00140 noisefactor = 1;
00141 noiseheight = noisewidth = 64;
00142 node->getNamedChild("noisefactor", noisefactor, false);
00143 node->getNamedChild("noisewidth", noisewidth, false);
00144 node->getNamedChild("noiseheight", noiseheight, false);
00145
00146 errosions = 0;
00147 errosionlayering = 0;
00148 errosionsurroundsize = 25;
00149 errosionforce = fixed(1) / fixed(25);
00150 errosionmaxdepth = fixed(4);
00151 errosionsurroundforce = fixed(1);
00152 node->getNamedChild("errosions", errosions, false);
00153 node->getNamedChild("errosionlayering", errosionlayering, false);
00154 node->getNamedChild("errosionforce", errosionforce, false);
00155 node->getNamedChild("errosionmaxdepth", errosionmaxdepth, false);
00156 node->getNamedChild("errosionsurroundforce", errosionsurroundforce, false);
00157 node->getNamedChild("errosionsurroundsize", errosionsurroundsize, false);
00158
00159 if (!mask.empty())
00160 {
00161 if (!S3D::checkDataFile(mask.c_str())) return false;
00162 }
00163 return node->failChildren();
00164 }
00165
00166 LandscapeDefn::LandscapeDefn() :
00167 heightmap(0), tankstart(0), roof(0)
00168 {
00169 }
00170
00171 LandscapeDefn::~LandscapeDefn()
00172 {
00173 }
00174
00175 bool LandscapeDefn::readXML(LandscapeDefinitions *definitions, XMLNode *node)
00176 {
00177 if (!node->getNamedChild("minplayers", minplayers)) return false;
00178 if (!node->getNamedChild("maxplayers", maxplayers)) return false;
00179 if (!node->getNamedChild("landscapewidth", landscapewidth)) return false;
00180 if (!node->getNamedChild("landscapeheight", landscapeheight)) return false;
00181
00182 if (landscapewidth % 32 != 0 ||
00183 landscapeheight % 32 != 0)
00184 {
00185 S3D::dialogMessage("Scorched3D",
00186 S3D::formatStringBuffer(
00187 "ERROR: Landscape width and height must each be a multiple of 32.\n"
00188 "Specified size : %ix%i", landscapewidth, landscapeheight));
00189 return false;
00190 }
00191 if (!node->getNamedChild("arenawidth", arenawidth, false)) arenawidth = landscapewidth;
00192 if (!node->getNamedChild("arenaheight", arenaheight, false)) arenaheight = landscapeheight;
00193 if (arenawidth > landscapewidth ||
00194 arenaheight > landscapeheight)
00195 {
00196 S3D::dialogMessage("Scorched3D",
00197 S3D::formatStringBuffer(
00198 "ERROR: Arena width and height must each be less than or equal to the landscape size.\n"
00199 "Specified size : %ix%i", arenawidth, arenaheight));
00200 return false;
00201 }
00202 arenax = (landscapewidth - arenawidth) / 2;
00203 arenay = (landscapeheight - arenaheight) / 2;
00204
00205 {
00206 XMLNode *startNode;
00207 std::string tankstarttype;
00208 if (!node->getNamedChild("tankstart", startNode)) return false;
00209 if (!startNode->getNamedParameter("type", tankstarttype)) return false;
00210 if (!(tankstart = fetchTankStartDefnType(tankstarttype.c_str()))) return false;
00211 if (!tankstart->readXML(startNode)) return false;
00212 }
00213 {
00214 XMLNode *heightNode;
00215 std::string heightmaptype;
00216 if (!node->getNamedChild("heightmap", heightNode)) return false;
00217 if (!heightNode->getNamedParameter("type", heightmaptype)) return false;
00218 if (!(heightmap = fetchHeightMapDefnType(heightmaptype.c_str()))) return false;
00219 if (!heightmap->readXML(heightNode)) return false;
00220 }
00221 {
00222 XMLNode *roofNode;
00223 std::string rooftype;
00224 if (!node->getNamedChild("roof", roofNode)) return false;
00225 if (!roofNode->getNamedParameter("type", rooftype)) return false;
00226 if (!(roof = fetchRoofMapDefnType(rooftype.c_str()))) return false;
00227 if (!roof->readXML(roofNode)) return false;
00228 }
00229
00230 if (!texDefn.readXML(definitions, node)) return false;
00231
00232 return node->failChildren();
00233 }
00234