1 #include "Terrain.h" 2 #include "radiant_i18n.h" 3 #include "iradiant.h" 4 #include "iselection.h" 5 #include "gtkutil/dialog.h" 6 #include "../../ui/scripteditor/UFOScriptEditor.h" 7 #include "../../brush/BrushVisit.h" 8 #include "../../brush/Face.h" 9 #include "../../brush/FaceInstance.h" 10 11 #include <string> 12 #include <map> 13 14 namespace scripts 15 { Terrain()16 Terrain::Terrain () : 17 parser("terrain") 18 { 19 _blocks = parser.getEntries(); 20 } 21 ~Terrain()22 Terrain::~Terrain () 23 { 24 } 25 26 namespace 27 { 28 static const std::string& TEXTURES = "textures/"; 29 static const std::size_t TEXTURES_LENGTH = TEXTURES.length(); 30 31 // Functor to add terrain definition to a string stream that is later 32 // saved to the terrain.ufo script file 33 class GenerateTerrainForFaces 34 { 35 private: 36 37 std::stringstream& _os; 38 Terrain* _terrain; 39 40 private: 41 42 /** 43 * @param terrainID The id that is used in the scripts. In general 44 * this is the texture path relative to textures/ 45 * @return @c true if the terrain definition was already defined 46 * in this run, or it is a special texture that is not shown in 47 * the game and thus needs no terrain definition. 48 */ skipTexture(const std::string & terrainID) const49 bool skipTexture (const std::string& terrainID) const 50 { 51 if (_os.str().find(terrainID) != std::string::npos) 52 return true; 53 54 if (terrainID.find("tex_common/") != std::string::npos) 55 return true; 56 57 return false; 58 } 59 60 public: GenerateTerrainForFaces(std::stringstream & os,Terrain * terrain)61 GenerateTerrainForFaces (std::stringstream& os, Terrain* terrain) : 62 _os(os), _terrain(terrain) 63 { 64 } 65 operator ()(Face & face) const66 void operator() (Face& face) const 67 { 68 const std::string texture = face.GetShader(); 69 std::string terrainID = texture.substr(TEXTURES_LENGTH); 70 if (skipTexture(terrainID)) 71 return; 72 73 const DataBlock* dataBlock = _terrain->getTerrainDefitionForTexture(texture); 74 if (!dataBlock) { 75 _os << "terrain " << terrainID << std::endl; 76 _os << "{" << std::endl; 77 _os << "//\tfootstepsound\t\"footsteps/grass2\"" << std::endl; 78 _os << "//\tbouncefraction\t1.0" << std::endl; 79 _os << "}" << std::endl; 80 } 81 } 82 }; 83 } 84 generateTerrainDefinitionsForTextures()85 void Terrain::generateTerrainDefinitionsForTextures () 86 { 87 if (!GlobalSelectionSystem().areFacesSelected()) { 88 gtkutil::infoDialog(_("No faces selected")); 89 return; 90 } 91 92 std::stringstream os; 93 Scene_ForEachSelectedBrushFace(GenerateTerrainForFaces(os, this)); 94 const std::string& newTerrainDefinitions = os.str(); 95 if (newTerrainDefinitions.empty()) { 96 showTerrainDefinitionForTexture(); 97 } else { 98 ui::UFOScriptEditor editor("ufos/terrain.ufo", newTerrainDefinitions); 99 editor.show(); 100 } 101 } 102 getTerrainDefitionForTexture(const std::string & texture)103 const DataBlock* Terrain::getTerrainDefitionForTexture (const std::string& texture) 104 { 105 for (Parser::EntriesIterator i = _blocks.begin(); i != _blocks.end(); ++i) { 106 const DataBlock* blockData = (*i); 107 const std::string terrainID = TEXTURES + blockData->getID(); 108 if (terrainID == texture) 109 return blockData; 110 } 111 return (DataBlock*) 0; 112 } 113 showTerrainDefinitionForTexture()114 void Terrain::showTerrainDefinitionForTexture () 115 { 116 if (!GlobalSelectionSystem().areFacesSelected()) { 117 gtkutil::infoDialog(_("No faces selected")); 118 return; 119 } 120 121 const Face &face = g_SelectedFaceInstances.last().getFace(); 122 const std::string shader = face.GetShader(); 123 124 const DataBlock* blockData = getTerrainDefitionForTexture(shader); 125 if (blockData) { 126 // found it, now show it 127 ui::UFOScriptEditor editor("ufos/" + blockData->getFilename()); 128 editor.goToLine(blockData->getLineNumber()); 129 editor.show(); 130 return; 131 } 132 133 gtkutil::infoDialog(_("Could not find any associated terrain definition")); 134 } 135 } 136