diff --git a/source/glest_map_editor/main.cpp b/source/glest_map_editor/main.cpp index 6fa21798..3af0041e 100644 --- a/source/glest_map_editor/main.cpp +++ b/source/glest_map_editor/main.cpp @@ -103,6 +103,13 @@ MainWindow::MainWindow(string appPath) resourceUnderMouse=0; objectUnderMouse=0; + // default values for random height calculation that turned out to be quite useful + randomWithReset=true; + randomMinimumHeight=-300; + randomMaximumHeight=400; + randomChanceDevider=30; + randomRecursions=3; + this->appPath = appPath; Properties::setApplicationPath(executable_path(appPath)); @@ -187,7 +194,7 @@ void MainWindow::init(string fname) { // --------------------------------------------------------- menuEdit->Append(miEditRandomizeHeights, wxT("Randomize &Heights")); - menuEdit->Append(miEditRandomize, wxT("Randomi&ze Heights/Players")); + menuEdit->Append(miEditRandomize, wxT("Randomi&ze Players")); menuEdit->Append(miEditSwitchSurfaces, wxT("Switch Sur&faces...")); menuEdit->Append(miEditInfo, wxT("&Info...")); menuEdit->Append(miEditAdvanced, wxT("&Advanced...")); @@ -985,10 +992,40 @@ void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event) { if(program == NULL) { return; } + while(true){ + program->setUndoPoint(ctAll);//randomizeHeights(-300,400,30,3); - program->setUndoPoint(ctAll); - program->randomizeMapHeights(); - setDirty(); + SimpleDialog simpleDialog; + simpleDialog.addValue("Initial Reset", boolToStr(randomWithReset),"If set to '0' no height reset is done before calculating"); + simpleDialog.addValue("Min Height", intToStr(randomMinimumHeight),"Lowest random height. example: -300 or below if you want water , 0 if you don't want water."); + simpleDialog.addValue("Max Height", intToStr(randomMaximumHeight),"Max random height. A good value is 400"); + simpleDialog.addValue("Chance Devider", intToStr(randomChanceDevider),"Defines how often you get a hill or hole default is 30. Bigger number, less hills/holes."); + simpleDialog.addValue("Smooth Recursions", intToStr(randomRecursions),"Number of recursions cycles to smooth the hills and holes. 0=randomMaximumHeight) randomMinimumHeight=randomMaximumHeight-1; + if(randomChanceDevider<1) randomChanceDevider=1; + + // set randomRecursions to something useful + if(randomRecursions<0) randomRecursions=0; + if(randomRecursions>50) randomRecursions=50; + + program->randomizeMapHeights(randomWithReset, randomMinimumHeight, randomMaximumHeight, + randomChanceDevider, randomRecursions); + } + catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); + } } void MainWindow::onMenuEditRandomize(wxCommandEvent &event) { @@ -997,7 +1034,7 @@ void MainWindow::onMenuEditRandomize(wxCommandEvent &event) { } program->setUndoPoint(ctAll); - program->randomizeMap(); + program->randomizeFactions(); setDirty(); } diff --git a/source/glest_map_editor/main.h b/source/glest_map_editor/main.h index f68fd6f8..33447b3e 100644 --- a/source/glest_map_editor/main.h +++ b/source/glest_map_editor/main.h @@ -197,6 +197,12 @@ private: int resourceUnderMouse; int objectUnderMouse; + bool randomWithReset; + int randomMinimumHeight; + int randomMaximumHeight; + int randomChanceDevider; + int randomRecursions; + ChangeType enabledGroup; string fileName; diff --git a/source/glest_map_editor/program.cpp b/source/glest_map_editor/program.cpp index 0fa5d3cb..d95a5f35 100644 --- a/source/glest_map_editor/program.cpp +++ b/source/glest_map_editor/program.cpp @@ -153,6 +153,7 @@ Program::Program(int w, int h) { hideWater=false; ofsetX = 0; ofsetY = 0; + map = new MapPreview(); resetFactions(8); renderer.initMapSurface(w, h); @@ -564,12 +565,12 @@ void Program::shiftDown() { } -void Program::randomizeMapHeights() { - if(map) map->randomizeHeights(); +void Program::randomizeMapHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions) { + if(map) map->randomizeHeights(withReset, minimumHeight, maximumHeight, chanceDevider, smoothRecursions); } -void Program::randomizeMap() { - if(map) map->randomize(); +void Program::randomizeFactions() { + if(map) map->randomizeFactions(); } void Program::switchMapSurfaces(int surf1, int surf2) { @@ -588,8 +589,7 @@ void Program::resize(int w, int h, int alt, int surf) { void Program::resetFactions(int maxFactions) { if(map) map->resetFactions(maxFactions); - for (int i = 0; i < map->getMaxFactions(); ++i) - map->changeStartLocation(2*i,2*(i%4)+5,i); + randomizeFactions(); } bool Program::setMapTitle(const string &title) { diff --git a/source/glest_map_editor/program.h b/source/glest_map_editor/program.h index 12fd8920..3648aa26 100644 --- a/source/glest_map_editor/program.h +++ b/source/glest_map_editor/program.h @@ -103,7 +103,6 @@ private: //static Map *map; static MapPreview *map; friend class UndoPoint; - ChangeStack undoStack, redoStack; void init(); @@ -152,8 +151,8 @@ public: void shiftUp(); void shiftDown(); - void randomizeMapHeights(); - void randomizeMap(); + void randomizeMapHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions);; + void randomizeFactions(); void switchMapSurfaces(int surf1, int surf2); void loadMap(const string &path); void saveMap(const string &path); diff --git a/source/shared_lib/include/map/map_preview.h b/source/shared_lib/include/map/map_preview.h index 84b38a09..48ac8d62 100644 --- a/source/shared_lib/include/map/map_preview.h +++ b/source/shared_lib/include/map/map_preview.h @@ -207,16 +207,16 @@ public: void reset(int w, int h, float alt, MapSurfaceType surf); void resize(int w, int h, float alt, MapSurfaceType surf); void resetFactions(int maxFactions); - void randomizeHeights(); - void randomize(); + void randomizeHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions); + void randomizeFactions(); + void smoothSurface(bool limitHeights); void switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2); void loadFromFile(const string &path); void saveToFile(const string &path); void resetHeights(int height); - void sinRandomize(int strenght); - void decalRandomize(int strenght); + void realRandomize(int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions); void applyNewHeight(float newHeight, int x, int y, int strenght); bool hasFileLoaded() const {return fileLoaded;} diff --git a/source/shared_lib/sources/map/map_preview.cpp b/source/shared_lib/sources/map/map_preview.cpp index e3c1208d..d494bc89 100644 --- a/source/shared_lib/sources/map/map_preview.cpp +++ b/source/shared_lib/sources/map/map_preview.cpp @@ -704,17 +704,13 @@ void MapPreview::setAdvanced(int heightFactor, int waterLevel, int cliffLevel, i hasChanged = true; } -void MapPreview::randomizeHeights() { - resetHeights(random.randRange(8, 10)); - sinRandomize(0); - decalRandomize(4); - sinRandomize(1); +void MapPreview::randomizeHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions) { + if(withReset) resetHeights(random.randRange(8, 10)); + realRandomize(minimumHeight,maximumHeight,chanceDevider,smoothRecursions); hasChanged = true; } -void MapPreview::randomize() { - randomizeHeights(); - +void MapPreview::randomizeFactions() { int slPlaceFactorX = random.randRange(0, 1); int slPlaceFactorY = random.randRange(0, 1) * 2; @@ -729,6 +725,40 @@ void MapPreview::randomize() { hasChanged = true; } +void MapPreview::smoothSurface(bool limitHeight) { + float *oldHeights = new float[w*h]; + + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + oldHeights[i*w+j] = cells[i][j].height; + //printf("count=%d height=%f h=%f\n",i*w+h,oldHeights[i*w+h],cells[i][j].height); + } + } + + for (int i = 1; i < w - 1; ++i) { + for (int j = 1; j < h - 1; ++j) { + float height = 0.f; + float numUsedToSmooth = 0.f; + for (int k = -1; k <= 1; ++k) { + for (int l = -1; l <= 1; ++l) { + int tmpHeight=oldHeights[(j + k) * w + (i + l)]; + if(limitHeight && tmpHeight>20){ + tmpHeight=20; + } + if(limitHeight && tmpHeight<0){ + tmpHeight=0; + } + height += tmpHeight; + numUsedToSmooth++; + } + } + height /= numUsedToSmooth; + cells[i][j].height=height; + } + } + delete[] oldHeights; +} + void MapPreview::switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2) { if (surf1 >= st_Grass && surf1 <= st_Ground && surf2 >= st_Grass && surf2 <= st_Ground) { for (int i = 0; i < w; ++i) { @@ -986,52 +1016,32 @@ void MapPreview::resetHeights(int height) { } } -void MapPreview::sinRandomize(int strenght) { - float sinH1 = random.randRange(5.f, 40.f); - float sinH2 = random.randRange(5.f, 40.f); - float sinV1 = random.randRange(5.f, 40.f); - float sinV2 = random.randRange(5.f, 40.f); - float ah = static_cast(10 + random.randRange(-2, 2)); - float bh = static_cast((maxHeight - minHeight)) / static_cast(random.randRange(2, 3)); - float av = static_cast(10 + random.randRange(-2, 2)); - float bv = static_cast((maxHeight - minHeight)) / static_cast(random.randRange(2, 3)); +void MapPreview::realRandomize(int minimumHeight, int maximumHeight, int _chanceDevider, int _smoothRecursions) { + int moduloParam=abs(maximumHeight-minimumHeight); + int chanceDevider=_chanceDevider; + int smoothRecursions=_smoothRecursions; + if(moduloParam<2) moduloParam=2; + //printf("moduloParam=%d minimumHeight=%d maximumHeight=%d\n",moduloParam,minimumHeight,maximumHeight); - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - float normH = static_cast(i) / w; - float normV = static_cast(j) / h; + // set chanceDevider to something possible + if(chanceDevider<2) chanceDevider=2; -#ifdef USE_STREFLOP - float sh = (streflop::sinf(static_cast(normH * sinH1)) + streflop::sin(static_cast(normH * sinH2))) / 2.f; - float sv = (streflop::sinf(static_cast(normV * sinV1)) + streflop::sin(static_cast(normV * sinV2))) / 2.f; -#else - float sh = (sinf(normH * sinH1) + sin(normH * sinH2)) / 2.f; - float sv = (sinf(normV * sinV1) + sin(normV * sinV2)) / 2.f; -#endif - float newHeight = (ah + bh * sh + av + bv * sv) / 2.f; - applyNewHeight(newHeight, i, j, strenght); + // set smoothRecursions to something useful + if(smoothRecursions<0) smoothRecursions=0; + if(smoothRecursions>1000) smoothRecursions=1000; + + for (int i = 1; i < w-1; ++i) { + for (int j = 1; j < h-1; ++j) { + if(rand()%chanceDevider==1){ + cells[i][j].height=(rand() % moduloParam)+minimumHeight; + } } } -} - -void MapPreview::decalRandomize(int strenght) { - //first row - int lastHeight = DEFAULT_MAP_CELL_HEIGHT; - for (int i = 0; i < w; ++i) { - lastHeight += random.randRange(-1, 1); - lastHeight = clamp(lastHeight, minHeight, maxHeight); - applyNewHeight(static_cast(lastHeight), i, 0, strenght); - } - - //other rows - for (int j = 1; j < h; ++j) { - int height = static_cast(cells[0][j-1].height + random.randRange(-1, 1)); - applyNewHeight(static_cast(clamp(height, minHeight, maxHeight)), 0, j, strenght); - for (int i = 1; i < w; ++i) { - height = static_cast((cells[i][j-1].height + cells[i-1][j].height) / 2.f + random.randRange(-1, 1)); - float newHeight = static_cast(clamp(height, minHeight, maxHeight)); - applyNewHeight(newHeight, i, j, strenght); - } + for( int i = 0; i