map editor has much more powerful random height function
You can give parameters now, to influence the map height calculation.
This commit is contained in:
parent
b4fabc2717
commit
4c5440f78c
|
@ -103,6 +103,13 @@ MainWindow::MainWindow(string appPath)
|
||||||
resourceUnderMouse=0;
|
resourceUnderMouse=0;
|
||||||
objectUnderMouse=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;
|
this->appPath = appPath;
|
||||||
Properties::setApplicationPath(executable_path(appPath));
|
Properties::setApplicationPath(executable_path(appPath));
|
||||||
|
|
||||||
|
@ -187,7 +194,7 @@ void MainWindow::init(string fname) {
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
menuEdit->Append(miEditRandomizeHeights, wxT("Randomize &Heights"));
|
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(miEditSwitchSurfaces, wxT("Switch Sur&faces..."));
|
||||||
menuEdit->Append(miEditInfo, wxT("&Info..."));
|
menuEdit->Append(miEditInfo, wxT("&Info..."));
|
||||||
menuEdit->Append(miEditAdvanced, wxT("&Advanced..."));
|
menuEdit->Append(miEditAdvanced, wxT("&Advanced..."));
|
||||||
|
@ -985,10 +992,40 @@ void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event) {
|
||||||
if(program == NULL) {
|
if(program == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
while(true){
|
||||||
|
program->setUndoPoint(ctAll);//randomizeHeights(-300,400,30,3);
|
||||||
|
|
||||||
program->setUndoPoint(ctAll);
|
SimpleDialog simpleDialog;
|
||||||
program->randomizeMapHeights();
|
simpleDialog.addValue("Initial Reset", boolToStr(randomWithReset),"If set to '0' no height reset is done before calculating");
|
||||||
setDirty();
|
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<x<50 default is 3.");
|
||||||
|
if (!simpleDialog.show("Randomize Height")) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
randomWithReset=strToBool(simpleDialog.getValue("Initial Reset"));
|
||||||
|
randomMinimumHeight=strToInt(simpleDialog.getValue("Min Height"));
|
||||||
|
randomMaximumHeight=strToInt(simpleDialog.getValue("Max Height"));
|
||||||
|
randomChanceDevider=strToInt(simpleDialog.getValue("Chance Devider"));
|
||||||
|
randomRecursions=strToInt(simpleDialog.getValue("Smooth Recursions"));
|
||||||
|
|
||||||
|
// set insane inputs to something that does not crash
|
||||||
|
if(randomMinimumHeight>=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) {
|
void MainWindow::onMenuEditRandomize(wxCommandEvent &event) {
|
||||||
|
@ -997,7 +1034,7 @@ void MainWindow::onMenuEditRandomize(wxCommandEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
program->setUndoPoint(ctAll);
|
program->setUndoPoint(ctAll);
|
||||||
program->randomizeMap();
|
program->randomizeFactions();
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,12 @@ private:
|
||||||
int resourceUnderMouse;
|
int resourceUnderMouse;
|
||||||
int objectUnderMouse;
|
int objectUnderMouse;
|
||||||
|
|
||||||
|
bool randomWithReset;
|
||||||
|
int randomMinimumHeight;
|
||||||
|
int randomMaximumHeight;
|
||||||
|
int randomChanceDevider;
|
||||||
|
int randomRecursions;
|
||||||
|
|
||||||
ChangeType enabledGroup;
|
ChangeType enabledGroup;
|
||||||
|
|
||||||
string fileName;
|
string fileName;
|
||||||
|
|
|
@ -153,6 +153,7 @@ Program::Program(int w, int h) {
|
||||||
hideWater=false;
|
hideWater=false;
|
||||||
ofsetX = 0;
|
ofsetX = 0;
|
||||||
ofsetY = 0;
|
ofsetY = 0;
|
||||||
|
|
||||||
map = new MapPreview();
|
map = new MapPreview();
|
||||||
resetFactions(8);
|
resetFactions(8);
|
||||||
renderer.initMapSurface(w, h);
|
renderer.initMapSurface(w, h);
|
||||||
|
@ -564,12 +565,12 @@ void Program::shiftDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Program::randomizeMapHeights() {
|
void Program::randomizeMapHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions) {
|
||||||
if(map) map->randomizeHeights();
|
if(map) map->randomizeHeights(withReset, minimumHeight, maximumHeight, chanceDevider, smoothRecursions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::randomizeMap() {
|
void Program::randomizeFactions() {
|
||||||
if(map) map->randomize();
|
if(map) map->randomizeFactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::switchMapSurfaces(int surf1, int surf2) {
|
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) {
|
void Program::resetFactions(int maxFactions) {
|
||||||
if(map) map->resetFactions(maxFactions);
|
if(map) map->resetFactions(maxFactions);
|
||||||
for (int i = 0; i < map->getMaxFactions(); ++i)
|
randomizeFactions();
|
||||||
map->changeStartLocation(2*i,2*(i%4)+5,i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Program::setMapTitle(const string &title) {
|
bool Program::setMapTitle(const string &title) {
|
||||||
|
|
|
@ -103,7 +103,6 @@ private:
|
||||||
//static Map *map;
|
//static Map *map;
|
||||||
static MapPreview *map;
|
static MapPreview *map;
|
||||||
friend class UndoPoint;
|
friend class UndoPoint;
|
||||||
|
|
||||||
ChangeStack undoStack, redoStack;
|
ChangeStack undoStack, redoStack;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
@ -152,8 +151,8 @@ public:
|
||||||
void shiftUp();
|
void shiftUp();
|
||||||
void shiftDown();
|
void shiftDown();
|
||||||
|
|
||||||
void randomizeMapHeights();
|
void randomizeMapHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions);;
|
||||||
void randomizeMap();
|
void randomizeFactions();
|
||||||
void switchMapSurfaces(int surf1, int surf2);
|
void switchMapSurfaces(int surf1, int surf2);
|
||||||
void loadMap(const string &path);
|
void loadMap(const string &path);
|
||||||
void saveMap(const string &path);
|
void saveMap(const string &path);
|
||||||
|
|
|
@ -207,16 +207,16 @@ public:
|
||||||
void reset(int w, int h, float alt, MapSurfaceType surf);
|
void reset(int w, int h, float alt, MapSurfaceType surf);
|
||||||
void resize(int w, int h, float alt, MapSurfaceType surf);
|
void resize(int w, int h, float alt, MapSurfaceType surf);
|
||||||
void resetFactions(int maxFactions);
|
void resetFactions(int maxFactions);
|
||||||
void randomizeHeights();
|
void randomizeHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions);
|
||||||
void randomize();
|
void randomizeFactions();
|
||||||
|
void smoothSurface(bool limitHeights);
|
||||||
void switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2);
|
void switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2);
|
||||||
|
|
||||||
void loadFromFile(const string &path);
|
void loadFromFile(const string &path);
|
||||||
void saveToFile(const string &path);
|
void saveToFile(const string &path);
|
||||||
|
|
||||||
void resetHeights(int height);
|
void resetHeights(int height);
|
||||||
void sinRandomize(int strenght);
|
void realRandomize(int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions);
|
||||||
void decalRandomize(int strenght);
|
|
||||||
void applyNewHeight(float newHeight, int x, int y, int strenght);
|
void applyNewHeight(float newHeight, int x, int y, int strenght);
|
||||||
|
|
||||||
bool hasFileLoaded() const {return fileLoaded;}
|
bool hasFileLoaded() const {return fileLoaded;}
|
||||||
|
|
|
@ -704,17 +704,13 @@ void MapPreview::setAdvanced(int heightFactor, int waterLevel, int cliffLevel, i
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPreview::randomizeHeights() {
|
void MapPreview::randomizeHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions) {
|
||||||
resetHeights(random.randRange(8, 10));
|
if(withReset) resetHeights(random.randRange(8, 10));
|
||||||
sinRandomize(0);
|
realRandomize(minimumHeight,maximumHeight,chanceDevider,smoothRecursions);
|
||||||
decalRandomize(4);
|
|
||||||
sinRandomize(1);
|
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPreview::randomize() {
|
void MapPreview::randomizeFactions() {
|
||||||
randomizeHeights();
|
|
||||||
|
|
||||||
int slPlaceFactorX = random.randRange(0, 1);
|
int slPlaceFactorX = random.randRange(0, 1);
|
||||||
int slPlaceFactorY = random.randRange(0, 1) * 2;
|
int slPlaceFactorY = random.randRange(0, 1) * 2;
|
||||||
|
|
||||||
|
@ -729,6 +725,40 @@ void MapPreview::randomize() {
|
||||||
hasChanged = true;
|
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) {
|
void MapPreview::switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2) {
|
||||||
if (surf1 >= st_Grass && surf1 <= st_Ground && surf2 >= st_Grass && surf2 <= st_Ground) {
|
if (surf1 >= st_Grass && surf1 <= st_Ground && surf2 >= st_Grass && surf2 <= st_Ground) {
|
||||||
for (int i = 0; i < w; ++i) {
|
for (int i = 0; i < w; ++i) {
|
||||||
|
@ -986,52 +1016,32 @@ void MapPreview::resetHeights(int height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPreview::sinRandomize(int strenght) {
|
void MapPreview::realRandomize(int minimumHeight, int maximumHeight, int _chanceDevider, int _smoothRecursions) {
|
||||||
float sinH1 = random.randRange(5.f, 40.f);
|
int moduloParam=abs(maximumHeight-minimumHeight);
|
||||||
float sinH2 = random.randRange(5.f, 40.f);
|
int chanceDevider=_chanceDevider;
|
||||||
float sinV1 = random.randRange(5.f, 40.f);
|
int smoothRecursions=_smoothRecursions;
|
||||||
float sinV2 = random.randRange(5.f, 40.f);
|
if(moduloParam<2) moduloParam=2;
|
||||||
float ah = static_cast<float>(10 + random.randRange(-2, 2));
|
//printf("moduloParam=%d minimumHeight=%d maximumHeight=%d\n",moduloParam,minimumHeight,maximumHeight);
|
||||||
float bh = static_cast<float>((maxHeight - minHeight)) / static_cast<float>(random.randRange(2, 3));
|
|
||||||
float av = static_cast<float>(10 + random.randRange(-2, 2));
|
|
||||||
float bv = static_cast<float>((maxHeight - minHeight)) / static_cast<float>(random.randRange(2, 3));
|
|
||||||
|
|
||||||
for (int i = 0; i < w; ++i) {
|
// set chanceDevider to something possible
|
||||||
for (int j = 0; j < h; ++j) {
|
if(chanceDevider<2) chanceDevider=2;
|
||||||
float normH = static_cast<float>(i) / w;
|
|
||||||
float normV = static_cast<float>(j) / h;
|
|
||||||
|
|
||||||
#ifdef USE_STREFLOP
|
// set smoothRecursions to something useful
|
||||||
float sh = (streflop::sinf(static_cast<streflop::Simple>(normH * sinH1)) + streflop::sin(static_cast<streflop::Simple>(normH * sinH2))) / 2.f;
|
if(smoothRecursions<0) smoothRecursions=0;
|
||||||
float sv = (streflop::sinf(static_cast<streflop::Simple>(normV * sinV1)) + streflop::sin(static_cast<streflop::Simple>(normV * sinV2))) / 2.f;
|
if(smoothRecursions>1000) smoothRecursions=1000;
|
||||||
#else
|
|
||||||
float sh = (sinf(normH * sinH1) + sin(normH * sinH2)) / 2.f;
|
for (int i = 1; i < w-1; ++i) {
|
||||||
float sv = (sinf(normV * sinV1) + sin(normV * sinV2)) / 2.f;
|
for (int j = 1; j < h-1; ++j) {
|
||||||
#endif
|
if(rand()%chanceDevider==1){
|
||||||
float newHeight = (ah + bh * sh + av + bv * sv) / 2.f;
|
cells[i][j].height=(rand() % moduloParam)+minimumHeight;
|
||||||
applyNewHeight(newHeight, i, j, strenght);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
for( int i = 0; i<smoothRecursions;++i){
|
||||||
|
if(i+1==smoothRecursions)
|
||||||
void MapPreview::decalRandomize(int strenght) {
|
smoothSurface(true);
|
||||||
//first row
|
else
|
||||||
int lastHeight = DEFAULT_MAP_CELL_HEIGHT;
|
smoothSurface(false);
|
||||||
for (int i = 0; i < w; ++i) {
|
|
||||||
lastHeight += random.randRange(-1, 1);
|
|
||||||
lastHeight = clamp(lastHeight, minHeight, maxHeight);
|
|
||||||
applyNewHeight(static_cast<float>(lastHeight), i, 0, strenght);
|
|
||||||
}
|
|
||||||
|
|
||||||
//other rows
|
|
||||||
for (int j = 1; j < h; ++j) {
|
|
||||||
int height = static_cast<int>(cells[0][j-1].height + random.randRange(-1, 1));
|
|
||||||
applyNewHeight(static_cast<float>(clamp(height, minHeight, maxHeight)), 0, j, strenght);
|
|
||||||
for (int i = 1; i < w; ++i) {
|
|
||||||
height = static_cast<int>((cells[i][j-1].height + cells[i-1][j].height) / 2.f + random.randRange(-1, 1));
|
|
||||||
float newHeight = static_cast<float>(clamp(height, minHeight, maxHeight));
|
|
||||||
applyNewHeight(newHeight, i, j, strenght);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue