mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 03:32:35 +01:00
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;
|
||||
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<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) {
|
||||
@ -997,7 +1034,7 @@ void MainWindow::onMenuEditRandomize(wxCommandEvent &event) {
|
||||
}
|
||||
|
||||
program->setUndoPoint(ctAll);
|
||||
program->randomizeMap();
|
||||
program->randomizeFactions();
|
||||
setDirty();
|
||||
}
|
||||
|
||||
|
@ -197,6 +197,12 @@ private:
|
||||
int resourceUnderMouse;
|
||||
int objectUnderMouse;
|
||||
|
||||
bool randomWithReset;
|
||||
int randomMinimumHeight;
|
||||
int randomMaximumHeight;
|
||||
int randomChanceDevider;
|
||||
int randomRecursions;
|
||||
|
||||
ChangeType enabledGroup;
|
||||
|
||||
string fileName;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;}
|
||||
|
@ -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<float>(10 + random.randRange(-2, 2));
|
||||
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));
|
||||
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<float>(i) / w;
|
||||
float normV = static_cast<float>(j) / h;
|
||||
// set chanceDevider to something possible
|
||||
if(chanceDevider<2) chanceDevider=2;
|
||||
|
||||
#ifdef USE_STREFLOP
|
||||
float sh = (streflop::sinf(static_cast<streflop::Simple>(normH * sinH1)) + streflop::sin(static_cast<streflop::Simple>(normH * sinH2))) / 2.f;
|
||||
float sv = (streflop::sinf(static_cast<streflop::Simple>(normV * sinV1)) + streflop::sin(static_cast<streflop::Simple>(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<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);
|
||||
}
|
||||
for( int i = 0; i<smoothRecursions;++i){
|
||||
if(i+1==smoothRecursions)
|
||||
smoothSurface(true);
|
||||
else
|
||||
smoothSurface(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user