From e03b029bea2eb36dfffc44a61a9158eb331372bb Mon Sep 17 00:00:00 2001 From: Titus Tscharntke Date: Tue, 8 Feb 2011 03:50:59 +0000 Subject: [PATCH] Cliffs work and some map cleanup; ( !!currently old maps are broken in editor!! ) --- .../menu/menu_state_connected_game.cpp | 13 +- .../menu/menu_state_custom_game.cpp | 14 +- source/glest_game/world/map.cpp | 40 +- source/glest_game/world/map.h | 2 + source/glest_map_editor/main.cpp | 4 +- source/glest_map_editor/map.cpp | 810 ------------------ source/glest_map_editor/map.h | 147 ---- source/glest_map_editor/program.cpp | 4 +- source/glest_map_editor/program.h | 2 +- source/shared_lib/include/map/map_preview.h | 32 +- .../sources/graphics/gl/base_renderer.cpp | 12 +- source/shared_lib/sources/map/map_preview.cpp | 58 +- 12 files changed, 105 insertions(+), 1033 deletions(-) delete mode 100644 source/glest_map_editor/map.cpp delete mode 100644 source/glest_map_editor/map.h diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 3e9a4614..7a535aed 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -29,6 +29,7 @@ #include #include "cache_manager.h" #include "leak_dumper.h" +#include "map_preview.h" namespace Glest{ namespace Game{ @@ -1674,16 +1675,6 @@ void MenuStateConnectedGame::loadFactionTexture(string filepath) { bool MenuStateConnectedGame::loadMapInfo(string file, MapInfo *mapInfo, bool loadMapPreview) { - struct MapFileHeader{ - int32 version; - int32 maxPlayers; - int32 width; - int32 height; - int32 altFactor; - int32 waterLevel; - int8 title[128]; - }; - Lang &lang= Lang::getInstance(); bool mapLoaded = false; @@ -1707,7 +1698,7 @@ bool MenuStateConnectedGame::loadMapInfo(string file, MapInfo *mapInfo, bool loa mapInfo->size.x= header.width; mapInfo->size.y= header.height; - mapInfo->players= header.maxPlayers; + mapInfo->players= header.maxFactions; mapInfo->desc= lang.get("MaxPlayers")+": "+intToStr(mapInfo->players)+"\n"; mapInfo->desc+=lang.get("Size")+": "+intToStr(mapInfo->size.x) + " x " + intToStr(mapInfo->size.y); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index a37a84c9..bbcb3a03 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -29,6 +29,7 @@ #include #include "cache_manager.h" #include "leak_dumper.h" +#include "map_preview.h" namespace Glest{ namespace Game{ @@ -2433,17 +2434,6 @@ bool MenuStateCustomGame::hasNetworkGameSettings() { } void MenuStateCustomGame::loadMapInfo(string file, MapInfo *mapInfo, bool loadMapPreview) { - - struct MapFileHeader{ - int32 version; - int32 maxPlayers; - int32 width; - int32 height; - int32 altFactor; - int32 waterLevel; - int8 title[128]; - }; - Lang &lang= Lang::getInstance(); try{ @@ -2456,7 +2446,7 @@ void MenuStateCustomGame::loadMapInfo(string file, MapInfo *mapInfo, bool loadMa mapInfo->size.x= header.width; mapInfo->size.y= header.height; - mapInfo->players= header.maxPlayers; + mapInfo->players= header.maxFactions; mapInfo->desc= lang.get("MaxPlayers")+": "+intToStr(mapInfo->players)+"\n"; mapInfo->desc+=lang.get("Size")+": "+intToStr(mapInfo->size.x) + " x " + intToStr(mapInfo->size.y); diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 00d3b32e..56511110 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -27,6 +27,7 @@ #include "faction.h" #include "command.h" #include "leak_dumper.h" +#include "map_preview.h" using namespace Shared::Graphics; using namespace Shared::Util; @@ -157,19 +158,6 @@ Vec2i Map::getStartLocation(int locationIndex) const { Checksum Map::load(const string &path, TechTree *techTree, Tileset *tileset) { Checksum mapChecksum; - - struct MapFileHeader{ - int32 version; - int32 maxPlayers; - int32 width; - int32 height; - int32 altFactor; - int32 waterLevel; - int8 title[128]; - int8 author[128]; - int8 description[256]; - }; - try{ FILE *f = fopen(path.c_str(), "rb"); if(f != NULL) { @@ -187,15 +175,27 @@ Checksum Map::load(const string &path, TechTree *techTree, Tileset *tileset) { throw runtime_error("Map height is not a power of 2"); } - heightFactor= header.altFactor; + heightFactor= header.heightFactor; waterLevel= static_cast((header.waterLevel-0.01f)/heightFactor); title= header.title; - maxPlayers= header.maxPlayers; + maxPlayers= header.maxFactions; surfaceW= header.width; surfaceH= header.height; w= surfaceW*cellScale; h= surfaceH*cellScale; - + cliffLevel = 0; + if(header.version==1){ + //desc = header.description; + } + else if(header.version==2){ + //desc = header.extension_data.extension_data.version2.short_desc; + if(header.extension_data.version2.cliffLevel>0){ + cliffLevel=static_cast((header.extension_data.version2.cliffLevel)/heightFactor); + } + else { + cliffLevel=0; + } + } //start locations startLocations= new Vec2i[maxPlayers]; @@ -1092,24 +1092,20 @@ void Map::computeInterpolatedHeights(){ } } - void Map::smoothSurface(Tileset *tileset) { - - float minCliffHeightDifference=0.0f; float *oldHeights = new float[getSurfaceCellArraySize()]; for (int i = 0; i < getSurfaceCellArraySize(); ++i) { oldHeights[i] = surfaceCells[i].getHeight(); } - + printf("argh %f\n",cliffLevel); for (int i = 1; i < surfaceW - 1; ++i) { for (int j = 1; j < surfaceH - 1; ++j) { - float height = 0.f; float numUsedToSmooth = 0.f; for (int k = -1; k <= 1; ++k) { for (int l = -1; l <= 1; ++l) { - if (minCliffHeightDifference<=0.1f || minCliffHeightDifference > abs(oldHeights[(j) * surfaceW + (i)] + if (cliffLevel<=0.1f || cliffLevel > abs(oldHeights[(j) * surfaceW + (i)] - oldHeights[(j + k) * surfaceW + (i + l)])) { height += oldHeights[(j + k) * surfaceW + (i + l)]; numUsedToSmooth++; diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index b1ca5c1d..dd3bd9a9 100755 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -156,6 +156,7 @@ private: string title; float waterLevel; float heightFactor; + float cliffLevel; int w; int h; int surfaceW; @@ -192,6 +193,7 @@ public: int getMaxPlayers() const {return maxPlayers;} float getHeightFactor() const {return heightFactor;} float getWaterLevel() const {return waterLevel;} + float getCliffLevel() const {return cliffLevel;} Vec2i getStartLocation(int locationIndex) const; bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()getHeight()getMap()->getHeightFactor()),"(lower means map is more more zoomed in)"); simpleDialog.addValue("Water Level", intToStr(program->getMap()->getWaterLevel()),"(water is visible below this, and walkable until 1.5 less)"); + simpleDialog.addValue("Cliff Level", intToStr(program->getMap()->getCliffLevel()),"(neighboring fields with at least this heights difference are cliffs)"); if (!simpleDialog.show("Advanced")) return; try { program->setMapAdvanced( strToInt(simpleDialog.getValue("Height Factor")), - strToInt(simpleDialog.getValue("Water Level"))); + strToInt(simpleDialog.getValue("Water Level")), + strToInt(simpleDialog.getValue("Cliff Level"))); } catch (const exception &e) { MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); diff --git a/source/glest_map_editor/map.cpp b/source/glest_map_editor/map.cpp deleted file mode 100644 index 3244df09..00000000 --- a/source/glest_map_editor/map.cpp +++ /dev/null @@ -1,810 +0,0 @@ -// ============================================================== -// This file is part of Glest (www.glest.org) -// -// Copyright (C) 2001-2008 Marti�o Figueroa -// -// You can redistribute this code and/or modify it under -// the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version -// ============================================================== - -// This file is not used anymore - -/* -#include "map.h" - -#include -#include - -using namespace Shared::Util; -using namespace std; - -namespace MapEditor { - -// =============================================== -// class Map -// =============================================== - -// ================== PUBLIC ===================== - -Map::Map() { - altFactor = 3; - waterLevel = 4; - cells = NULL; - startLocations = NULL; - reset(128, 128, 10.f, 1); - resetFactions(8); - title = ""; - desc = ""; - author = ""; - refAlt = 10; -} - -Map::~Map() { - delete [] startLocations; - startLocations = NULL; - - for (int i = 0; i < h; i++) { - delete [] cells[i]; - } - delete [] cells; - cells = NULL; -} - - -float Map::getHeight(int x, int y) const { - return cells[x][y].height; -} - -int Map::getSurface(int x, int y) const { - return cells[x][y].surface; -} - -int Map::getObject(int x, int y) const { - return cells[x][y].object; -} - -int Map::getResource(int x, int y) const { - return cells[x][y].resource; -} - -int Map::getStartLocationX(int index) const { - return startLocations[index].x; -} - -int Map::getStartLocationY(int index) const { - return startLocations[index].y; -} - -static int get_dist(int delta_x, int delta_y) { - float dx = (float) delta_x; - float dy = (float)delta_y; - - return static_cast(sqrtf(dx * dx + dy * dy)); -} - -void Map::glestChangeHeight(int x, int y, int height, int radius) { - - for (int i = x - radius + 1; i < x + radius; i++) { - for (int j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - int dist = get_dist(i - x, j - y); - if (radius > dist) { - int oldAlt = static_cast(cells[i][j].height); - int altInc = height * (radius - dist - 1) / radius; - if (height > 0) { - altInc++; - } - if (height < 0) { - altInc--; - } - int newAlt = refAlt + altInc; - if ((height > 0 && newAlt > oldAlt) || (height < 0 && newAlt < oldAlt) || height == 0) { - if (newAlt >= 0 && newAlt <= 20) { - cells[i][j].height = static_cast(newAlt); - } - } - } - } - } - } -} - - -void Map::pirateChangeHeight(int x, int y, int height, int radius) { - // Make sure not to try and blanket change the height over the bounds - // Find our goal height for the centre of the brush - int goalAlt; - int overBounds = refAlt + height; - if (overBounds > 20) { - goalAlt = 20; - } - else if (overBounds < 0) { - goalAlt = 0; - } else { - goalAlt = overBounds; - } - - // If the radius is 1 don't bother doing any calculations - if (radius == 1) { - if(inside(x, y)){ - cells[x][y].height = (float)goalAlt; - } - return; - } - - // Get Old height reference points and compute gradients - // from the heights of the sides and corners of the brush to the centre goal height - float gradient[3][3]; // [i][j] - int indexI = 0; - for (int i = x - radius; i <= x + radius; i += radius) { - int indexJ = 0; - for (int j = y - radius; j <= y + radius; j += radius) { - // round off the corners - int ti, tj; - if (abs(i - x) == abs(j - y)) { - ti = (int)((i - x) * 0.707 + x + 0.5); - tj = (int)((j - y) * 0.707 + y + 0.5); - } else { - ti = i; - tj = j; - } - if (inside(ti, tj)) { - gradient[indexI][indexJ] = (cells[ti][tj].height - goalAlt) / radius; - //} else if (dist == 0) { - //gradient[indexI][indexJ] = 0; - } else { - // assume outside the map bounds is height 10 - gradient[indexI][indexJ] = (10.0f - (float)goalAlt) / (float)radius; - } - //std::cout << "gradient[" << indexI << "][" << indexJ << "] = " << gradient[indexI][indexJ] << std::endl; - //std::cout << "derived from height " << cells[ti][tj].height << " at " << ti << " " << tj << std::endl; - indexJ++; - } - indexI++; - } - //std::cout << endl; - - // A brush with radius n cells should have a true radius of n-1 distance - radius -= 1; - for (int i = x - radius; i <= x + radius; i++) { - for (int j = y - radius; j <= y + radius; j++) { - int dist = get_dist(i - x, j - y); - if (inside(i, j) && dist < radius) { - // Normalize di and dj and round them to an int so they can be used as indicies - float normIf = (float(i - x)/ radius); - float normJf = (float(j - y)/ radius); - int normI[2]; - int normJ[2]; - float usedGrad; - - // Build a search box to find the gradients we are concerned about - // Find the nearest i indices - if (normIf < -0.33) { - normI[0] = 0; - if (normIf == 0) { - normI[1] = 0; - } else { - normI[1] = 1; - } - } else if (normIf < 0.33) { - normI[0] = 1; - if (normIf > 0) { - normI[1] = 2; - } else if (normIf < 0) { - normI[1] = 0; - } else { // (normIf == 0) - normI[1] = 1; - } - } else { - normI[0] = 2; - if (normIf == 1) { - normI[1] = 2; - } else { - normI[1] = 1; - } - } - // find nearest j indices - if (normJf < -0.33) { - normJ[0] = 0; - if (normJf == 0) { - normJ[1] = 0; - } else { - normJ[1] = 1; - } - } else if (normJf < 0.33) { - normJ[0] = 1; - if (normJf > 0) { - normJ[1] = 2; - } else if (normJf < 0) { - normJ[1] = 0; - } else { // (normJf == 0) - normJ[1] = 1; - } - } else { - normJ[0] = 2; - if (normJf == 1) { - normJ[1] = 2; - } else { - normJ[1] = 1; - } - } - - // Determine which gradients to use and take a weighted average - if (abs(normIf) > abs(normJf)) { - usedGrad = - gradient[normI[0]] [normJ[0]] * abs(normJf) + - gradient[normI[0]] [normJ[1]] * (1 - abs(normJf)); - } else if (abs(normIf) < abs(normJf)) { - usedGrad = - gradient[normI[0]] [normJ[0]] * abs(normIf) + - gradient[normI[1]] [normJ[0]] * (1 - abs(normIf)); - } else { - usedGrad = - gradient[normI[0]] [normJ[0]]; - } - - - float newAlt = usedGrad * dist + goalAlt; - - // if the change in height and what is supposed to be the change in height - // are the same sign then we can change the height - if ( ((newAlt - cells[i][j].height) > 0 && height > 0) || - ((newAlt - cells[i][j].height) < 0 && height < 0) || - height == 0) { - cells[i][j].height = newAlt; - } - } - } - } -} - -void Map::setHeight(int x, int y, float height) { - cells[x][y].height = height; -} - -void Map::setRefAlt(int x, int y) { - if (inside(x, y)) { - refAlt = static_cast(cells[x][y].height); - } -} - -void Map::flipX() { - Cell **oldCells = cells; - - cells = new Cell*[w]; - for (int i = 0; i < w; i++) { - cells[i] = new Cell[h]; - for (int j = 0; j < h; j++) { - cells[i][j].height = oldCells[w-i-1][j].height; - cells[i][j].object = oldCells[w-i-1][j].object; - cells[i][j].resource = oldCells[w-i-1][j].resource; - cells[i][j].surface = oldCells[w-i-1][j].surface; - } - } - - for (int i = 0; i < maxFactions; ++i) { - startLocations[i].x = w - startLocations[i].x - 1; - } - - for (int i = 0; i < w; i++) { - delete [] oldCells[i]; - } - delete [] oldCells; -} - -void Map::flipY() { - Cell **oldCells = cells; - - cells = new Cell*[w]; - for (int i = 0; i < w; i++) { - cells[i] = new Cell[h]; - for (int j = 0; j < h; j++) { - cells[i][j].height = oldCells[i][h-j-1].height; - cells[i][j].object = oldCells[i][h-j-1].object; - cells[i][j].resource = oldCells[i][h-j-1].resource; - cells[i][j].surface = oldCells[i][h-j-1].surface; - } - } - - for (int i = 0; i < maxFactions; ++i) { - startLocations[i].y = h - startLocations[i].y - 1; - } - - for (int i = 0; i < w; i++) { - delete [] oldCells[i]; - } - delete [] oldCells; -} - -void Map::mirrorX() { // copy left to right - for (int i = 0; i < w/2; i++) { - for (int j = 0; j < h; j++) { - cells[w-i-1][j].height = cells[i][j].height; - cells[w-i-1][j].object = cells[i][j].object; - cells[w-i-1][j].resource = cells[i][j].resource; - cells[w-i-1][j].surface = cells[i][j].surface; - } - } -} - -void Map::mirrorY() { // copy top to bottom - for (int i = 0; i < w; i++) { - for (int j = 0; j < h/2; j++) { - cells[i][h-j-1].height = cells[i][j].height; - cells[i][h-j-1].object = cells[i][j].object; - cells[i][h-j-1].resource = cells[i][j].resource; - cells[i][h-j-1].surface = cells[i][j].surface; - } - } -} - -void Map::mirrorXY() { // copy leftbottom to topright - for (int i = 0; i < w-1; i++) { - for (int j = i+1; j < h; j++) { - cells[i][j].height = cells[j][i].height; - cells[i][j].object = cells[j][i].object; - cells[i][j].resource = cells[j][i].resource; - cells[i][j].surface = cells[j][i].surface; - } - } -} - -// void Map::rotatecopyX(); -// void Map::rotatecopyY(); -// void Map::rotatecopyXY(); -// void Map::rotatecopyCorner(); - - -void Map::changeSurface(int x, int y, int surface, int radius) { - int i, j; - int dist; - - for (i = x - radius + 1; i < x + radius; i++) { - for (j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - dist = get_dist(i - x, j - y); - if (radius >= dist) { - cells[i][j].surface = surface; - } - } - } - } -} - -void Map::setSurface(int x, int y, int surface) { - cells[x][y].surface = surface; -} - -void Map::changeObject(int x, int y, int object, int radius) { - int i, j; - int dist; - - for (i = x - radius + 1; i < x + radius; i++) { - for (j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - dist = get_dist(i - x, j - y); - if (radius >= dist) { - cells[i][j].object = object; - cells[i][j].resource = 0; - } - } - } - } -} - -void Map::setObject(int x, int y, int object) { - cells[x][y].object = object; - if (object != 0) cells[x][y].resource = 0; -} - -void Map::changeResource(int x, int y, int resource, int radius) { - int i, j; - int dist; - - for (i = x - radius + 1; i < x + radius; i++) { - for (j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - dist = get_dist(i - x, j - y); - if (radius >= dist) { - cells[i][j].resource = resource; - cells[i][j].object = 0; - } - } - } - } -} - -void Map::setResource(int x, int y, int resource) { - cells[x][y].resource = resource; - if (resource != 0) cells[x][y].object = 0; -} - -void Map::changeStartLocation(int x, int y, int faction) { - if ((faction - 1) < maxFactions && inside(x, y)) { - startLocations[faction].x = x; - startLocations[faction].y = y; - } -} - -bool Map::inside(int x, int y) { - return (x >= 0 && x < w && y >= 0 && y < h); -} - -void Map::reset(int w, int h, float alt, int surf) { - if (w < 16 || h < 16) { - throw runtime_error("Size of map must be at least 16x16"); - return; - } - - if (w > 1024 || h > 1024) { - throw runtime_error("Size of map can be at most 1024x1024"); - return; - } - - if (alt < 0 || alt > 20) { - throw runtime_error("Height must be in the range 0-20"); - return; - } - - if (surf < 1 || surf > 5) { - throw runtime_error("Surface must be in the range 1-5"); - return; - } - - if (cells != NULL) { - for (int i = 0; i < this->w; i++) { - delete [] cells[i]; - } - delete [] cells; - } - - this->w = w; - this->h = h; - this->maxFactions = maxFactions; - - cells = new Cell*[w]; - for (int i = 0; i < w; i++) { - cells[i] = new Cell[h]; - for (int j = 0; j < h; j++) { - cells[i][j].height = alt; - cells[i][j].object = 0; - cells[i][j].resource = 0; - cells[i][j].surface = surf; - } - } -} - -void Map::resize(int w, int h, float alt, int surf) { - if (w < 16 || h < 16) { - throw runtime_error("Size of map must be at least 16x16"); - return; - } - - if (w > 1024 || h > 1024) { - throw runtime_error("Size of map can be at most 1024x1024"); - return; - } - - if (alt < 0 || alt > 20) { - throw runtime_error("Height must be in the range 0-20"); - return; - } - - if (surf < 1 || surf > 5) { - throw runtime_error("Surface must be in the range 1-5"); - return; - } - - int oldW = this->w; - int oldH = this->h; - this->w = w; - this->h = h; - this->maxFactions = maxFactions; - - //create new cells - Cell **oldCells = cells; - cells = new Cell*[w]; - for (int i = 0; i < w; i++) { - cells[i] = new Cell[h]; - for (int j = 0; j < h; j++) { - cells[i][j].height = alt; - cells[i][j].object = 0; - cells[i][j].resource = 0; - cells[i][j].surface = surf; - } - } - - int wOffset = w < oldW ? 0 : (w - oldW) / 2; - int hOffset = h < oldH ? 0 : (h - oldH) / 2; - //assign old values to cells - for (int i = 0; i < oldW; i++) { - for (int j = 0; j < oldH; j++) { - if (i + wOffset < w && j + hOffset < h) { - cells[i+wOffset][j+hOffset].height = oldCells[i][j].height; - cells[i+wOffset][j+hOffset].object = oldCells[i][j].object; - cells[i+wOffset][j+hOffset].resource = oldCells[i][j].resource; - cells[i+wOffset][j+hOffset].surface = oldCells[i][j].surface; - } - } - } - for (int i = 0; i < maxFactions; ++i) { - startLocations[i].x += wOffset; - startLocations[i].y += hOffset; - } - - //delete old cells - if (oldCells != NULL) { - for (int i = 0; i < oldW; i++) - delete [] oldCells[i]; - delete [] oldCells; - } -} - -void Map::resetFactions(int maxPlayers) { - if (maxPlayers<1 || maxPlayers>8){ - throw runtime_error("Max Players must be in the range 1-8"); - } - - // perhaps we should NOT remove current starting posititons, since the user just want to change number of players.... - if (startLocations != NULL) { - delete [] startLocations; - startLocations = NULL; - } - - maxFactions = maxPlayers; - - startLocations = new StartLocation[maxFactions]; - for (int i = 0; i < maxFactions; i++) { - startLocations[i].x = 0; - startLocations[i].y = 0; - } -} - -void Map::setTitle(const string &title) { - this->title = title; -} - -void Map::setDesc(const string &desc) { - this->desc = desc; -} - -void Map::setAuthor(const string &author) { - this->author = author; -} - -void Map::setAdvanced(int altFactor, int waterLevel) { - this->altFactor = altFactor; - this->waterLevel = waterLevel; -} - -int Map::getHeightFactor() const { - return altFactor; -} - -int Map::getWaterLevel() const { - return waterLevel; -} - -void Map::randomizeHeights() { - resetHeights(random.randRange(8, 10)); - sinRandomize(0); - decalRandomize(4); - sinRandomize(1); -} - -void Map::randomize() { - randomizeHeights(); - - int slPlaceFactorX = random.randRange(0, 1); - int slPlaceFactorY = random.randRange(0, 1) * 2; - - for (int i = 0; i < maxFactions; ++i) { - StartLocation sl; - float slNoiseFactor = random.randRange(0.5f, 0.8f); - - sl.x = static_cast(w * slNoiseFactor * ((i + slPlaceFactorX) % 2) + w * (1.f - slNoiseFactor) / 2.f); - sl.y = static_cast(h * slNoiseFactor * (((i + slPlaceFactorY) / 2) % 2) + h * (1.f - slNoiseFactor) / 2.f); - startLocations[i] = sl; - } -} - -void Map::switchSurfaces(int surf1, int surf2) { - if (surf1 > 0 && surf1 <= 5 && surf2 > 0 && surf2 <= 5) { - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - if (cells[i][j].surface == surf1) { - cells[i][j].surface = surf2; - } else if (cells[i][j].surface == surf2) { - cells[i][j].surface = surf1; - } - } - } - } else { - throw runtime_error("Incorrect surfaces"); - } -} - -void Map::loadFromFile(const string &path) { - - FILE *f1 = fopen(path.c_str(), "rb"); - if (f1 != NULL) { - - //read header - MapFileHeader header; - size_t bytes = fread(&header, sizeof(MapFileHeader), 1, f1); - - altFactor = header.altFactor; - waterLevel = header.waterLevel; - title = header.title; - author = header.author; - desc = header.description; - - //read start locations - resetFactions(header.maxFactions); - for (int i = 0; i < maxFactions; ++i) { - bytes = fread(&startLocations[i].x, sizeof(int32), 1, f1); - bytes = fread(&startLocations[i].y, sizeof(int32), 1, f1); - } - - //read Heights - reset(header.width, header.height, 10, 1); - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - bytes = fread(&cells[i][j].height, sizeof(float), 1, f1); - } - } - - //read surfaces - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - bytes = fread(&cells[i][j].surface, sizeof(int8), 1, f1); - } - } - - //read objects - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - int8 obj=0; - bytes = fread(&obj, sizeof(int8), 1, f1); - if (obj <= 10) { - cells[i][j].object = obj; - } else { - cells[i][j].resource = obj - 10; - } - } - } - - fclose(f1); - } else { - throw runtime_error("error opening map file: " + path); - } -} - - -void Map::saveToFile(const string &path) { - - FILE *f1 = fopen(path.c_str(), "wb"); - if (f1 != NULL) { - - //write header - MapFileHeader header; - - header.version = 1; - header.maxFactions = maxFactions; - header.width = w; - header.height = h; - header.altFactor = altFactor; - header.waterLevel = waterLevel; - strncpy(header.title, title.c_str(), 128); - strncpy(header.author, author.c_str(), 128); - strncpy(header.description, desc.c_str(), 256); - - fwrite(&header, sizeof(MapFileHeader), 1, f1); - - //write start locations - for (int i = 0; i < maxFactions; ++i) { - fwrite(&startLocations[i].x, sizeof(int32), 1, f1); - fwrite(&startLocations[i].y, sizeof(int32), 1, f1); - } - - //write Heights - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - fwrite(&cells[i][j].height, sizeof(float32), 1, f1); - } - } - - //write surfaces - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - fwrite(&cells[i][j].surface, sizeof(int8), 1, f1); - } - } - - //write objects - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - if (cells[i][j].resource == 0) - fwrite(&cells[i][j].object, sizeof(int8), 1, f1); - else { - int8 res = cells[i][j].resource + 10; - fwrite(&res, sizeof(int8), 1, f1); - } - } - } - - fclose(f1); - - } else { - throw runtime_error("Error opening map file: " + path); - } - - void randomHeight(int x, int y, int height); -} - -// ==================== PRIVATE ==================== - -void Map::resetHeights(int height) { - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - cells[i][j].height = static_cast(height); - } - } -} - -void Map::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) / random.randRange(2, 3)); - float av = static_cast(10 + random.randRange(-2, 2)); - float bv = static_cast((maxHeight - minHeight) / random.randRange(2, 3)); - - 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; - - float sh = (sinf(normH * sinH1) + sin(normH * sinH2)) / 2.f; - float sv = (sinf(normV * sinV1) + sin(normV * sinV2)) / 2.f; - - float newHeight = (ah + bh * sh + av + bv * sv) / 2.f; - applyNewHeight(newHeight, i, j, strenght); - } - } -} - -void Map::decalRandomize(int strenght) { - //first row - int lastHeight = 10; - 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); - } - } -} - -void Map::applyNewHeight(float newHeight, int x, int y, int strenght) { - cells[x][y].height = static_cast(((cells[x][y].height * strenght) + newHeight) / (strenght + 1)); -} - -}// end namespace - -*/ - - diff --git a/source/glest_map_editor/map.h b/source/glest_map_editor/map.h deleted file mode 100644 index c98571ef..00000000 --- a/source/glest_map_editor/map.h +++ /dev/null @@ -1,147 +0,0 @@ -// ============================================================== -// This file is part of Glest (www.glest.org) -// -// Copyright (C) 2001-2008 Martiño Figueroa -// -// You can redistribute this code and/or modify it under -// the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version -// ============================================================== - -// This file is not used anymore - -/* -#ifndef _MAPEDITOR_MAP_H_ -#define _MAPEDITOR_MAP_H_ - -#include "util.h" -#include "types.h" -#include "randomgen.h" - -using Shared::Platform::int8; -using Shared::Platform::int32; -using Shared::Platform::float32; -using Shared::Util::RandomGen; - -namespace MapEditor { - -struct MapFileHeader { - int32 version; - int32 maxFactions; - int32 width; - int32 height; - int32 altFactor; - int32 waterLevel; - int8 title[128]; - int8 author[128]; - int8 description[256]; -}; - -// =============================================== -// class Map -// =============================================== - -class Map { -public: - static const int maxHeight = 20; - static const int minHeight = 0; - -private: - struct Cell { - int surface; - int object; - int resource; - float height; - }; - - struct StartLocation { - int x; - int y; - }; - - RandomGen random; - string title; - string author; - string desc; - string recScn; - int type; - int h; - int w; - int altFactor; - int waterLevel; - Cell **cells; - int maxFactions; - StartLocation *startLocations; - int refAlt; - -public: - Map(); - ~Map(); - float getHeight(int x, int y) const; - int getSurface(int x, int y) const; - int getObject(int x, int y) const; - int getResource(int x, int y) const; - int getStartLocationX(int index) const; - int getStartLocationY(int index) const; - int getHeightFactor() const; - int getWaterLevel() const; - bool inside(int x, int y); - - void setRefAlt(int x, int y); - void setAdvanced(int altFactor, int waterLevel); - void setTitle(const string &title); - void setDesc(const string &desc); - void setAuthor(const string &author); - - int getH() const {return h;} - int getW() const {return w;} - int getMaxFactions() const {return maxFactions;} - string getTitle() const {return title;} - string getDesc() const {return desc;} - string getAuthor() const {return author;} - - void glestChangeHeight(int x, int y, int height, int radius); - void pirateChangeHeight(int x, int y, int height, int radius); - void changeSurface(int x, int y, int surface, int radius); - void changeObject(int x, int y, int object, int radius); - void changeResource(int x, int y, int resource, int radius); - void changeStartLocation(int x, int y, int player); - - void setHeight(int x, int y, float height); - void setSurface(int x, int y, int surface); - void setObject(int x, int y, int object); - void setResource(int x, int y, int resource); - - void flipX(); - void flipY(); - void mirrorX(); - void mirrorY(); - void mirrorXY(); - void rotatecopyX(); - void rotatecopyY(); - void rotatecopyXY(); - void rotatecopyCorner(); - void reset(int w, int h, float alt, int surf); - void resize(int w, int h, float alt, int surf); - void resetFactions(int maxFactions); - void randomizeHeights(); - void randomize(); - void switchSurfaces(int surf1, int surf2); - - void loadFromFile(const string &path); - void saveToFile(const string &path); - -public: - void resetHeights(int height); - void sinRandomize(int strenght); - void decalRandomize(int strenght); - void applyNewHeight(float newHeight, int x, int y, int strenght); -}; - -}// end namespace - -#endif - -*/ - diff --git a/source/glest_map_editor/program.cpp b/source/glest_map_editor/program.cpp index 3aed1d82..14b56b09 100644 --- a/source/glest_map_editor/program.cpp +++ b/source/glest_map_editor/program.cpp @@ -605,8 +605,8 @@ bool Program::setGridOnOff() { return grid; } -void Program::setMapAdvanced(int altFactor, int waterLevel) { - if(map) map->setAdvanced(altFactor, waterLevel); +void Program::setMapAdvanced(int altFactor, int waterLevel, int cliffLevel) { + if(map) map->setAdvanced(altFactor, waterLevel, cliffLevel); } void Program::loadMap(const string &path) { diff --git a/source/glest_map_editor/program.h b/source/glest_map_editor/program.h index 92e35e4a..ee9db32f 100644 --- a/source/glest_map_editor/program.h +++ b/source/glest_map_editor/program.h @@ -148,7 +148,7 @@ public: bool setMapTitle(const string &title); bool setMapDesc(const string &desc); bool setMapAuthor(const string &author); - void setMapAdvanced(int altFactor, int waterLevel); + void setMapAdvanced(int altFactor, int waterLevel, int minimumCliffHeight); //misc void renderMap(int w, int h); diff --git a/source/shared_lib/include/map/map_preview.h b/source/shared_lib/include/map/map_preview.h index 115cf6ce..3153f7b6 100644 --- a/source/shared_lib/include/map/map_preview.h +++ b/source/shared_lib/include/map/map_preview.h @@ -36,6 +36,7 @@ enum MapSurfaceType { static const int MAX_TITLE_LENGTH = 128; static const int MAX_AUTHOR_LENGTH = 128; static const int MAX_DESCRIPTION_LENGTH = 256; +static const int MAX_DESCRIPTION_LENGTH_VERSION2 = 128; static const int MIN_MAP_CELL_DIMENSION = 16; static const int MAX_MAP_CELL_DIMENSION = 1024; @@ -55,17 +56,33 @@ static const MapSurfaceType DEFAULT_MAP_CELL_SURFACE_TYPE = st_Grass; static const int DEFAULT_MAP_CELL_HEIGHT_FACTOR = 3; static const int DEFAULT_MAP_WATER_DEPTH = 4; +static const int DEFAULT_CLIFF_HEIGHT = 0; + +static const int MAP_FORMAT_VERSION=2; + + +typedef union { + int8 description[MAX_DESCRIPTION_LENGTH]; + + struct { + int8 short_desc[MAX_DESCRIPTION_LENGTH_VERSION2]; + int32 magic; // 0x01020304 for meta + int32 cliffLevel; + int8 meta[120]; + } version2; +} uniondata; + struct MapFileHeader { int32 version; int32 maxFactions; int32 width; int32 height; - int32 altFactor; + int32 heightFactor; int32 waterLevel; int8 title[MAX_TITLE_LENGTH]; int8 author[MAX_AUTHOR_LENGTH]; - int8 description[MAX_DESCRIPTION_LENGTH]; + uniondata extension_data; }; // =============================================== @@ -98,8 +115,9 @@ private: int type; int h; int w; - int altFactor; + int heightFactor; int waterLevel; + int cliffLevel; //Cell **cells; std::vector > cells; @@ -114,17 +132,19 @@ public: MapPreview(); ~MapPreview(); float getHeight(int x, int y) const; + bool isCliff(int x,int y); MapSurfaceType getSurface(int x, int y) const; int getObject(int x, int y) const; int getResource(int x, int y) const; int getStartLocationX(int index) const; int getStartLocationY(int index) const; - int getHeightFactor() const; - int getWaterLevel() const; + int getHeightFactor() const{return heightFactor;} + int getWaterLevel() const{return waterLevel;} + int getCliffLevel() const{return cliffLevel;} bool inside(int x, int y); void setRefAlt(int x, int y); - void setAdvanced(int altFactor, int waterLevel); + void setAdvanced(int heightFactor, int waterLevel, int cliffLevel); void setTitle(const string &title); void setDesc(const string &desc); void setAuthor(const string &author); diff --git a/source/shared_lib/sources/graphics/gl/base_renderer.cpp b/source/shared_lib/sources/graphics/gl/base_renderer.cpp index 5cf2b1aa..f284ee8a 100644 --- a/source/shared_lib/sources/graphics/gl/base_renderer.cpp +++ b/source/shared_lib/sources/graphics/gl/base_renderer.cpp @@ -61,7 +61,7 @@ void BaseRenderer::renderMap(MapPreview *map, int x, int y, && i * cellSize + x < clientW && clientH - cellSize - j * cellSize + y > -cellSize && clientH - cellSize - j * cellSize + y < clientH) { - + bool isCliff=false; // needed to speedup things //surface alt = map->getHeight(i, j) / 20.f; showWater = map->getWaterLevel()/ 20.f - alt; @@ -74,7 +74,13 @@ void BaseRenderer::renderMap(MapPreview *map, int x, int y, case st_Stone: surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); break; case st_Ground: surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break; } - + if(map->getCliffLevel()>0) + {// we maybe need to render cliff surfColor + if(map->isCliff(i, j)){ + surfColor = Vec3f(0.95f * alt, 0.8f * alt, 0.0f * alt + showWater); + isCliff=true; + } + } glColor3fv(surfColor.ptr()); glBegin(GL_TRIANGLE_STRIP); @@ -99,7 +105,7 @@ void BaseRenderer::renderMap(MapPreview *map, int x, int y, case 10: glColor3f(1.f, 0.2f, 0.8f); break; } - if (map->getObject(i, j) != 0) { + if (map->getObject(i, j) != 0 || isCliff ) { glPointSize(cellSize / 2.f); glBegin(GL_POINTS); glVertex2i(i * cellSize + cellSize / 2, clientH - j * cellSize - cellSize / 2); diff --git a/source/shared_lib/sources/map/map_preview.cpp b/source/shared_lib/sources/map/map_preview.cpp index 6683043a..b2a5661c 100644 --- a/source/shared_lib/sources/map/map_preview.cpp +++ b/source/shared_lib/sources/map/map_preview.cpp @@ -29,8 +29,9 @@ namespace Shared { namespace Map { MapPreview::MapPreview() { fileLoaded = false; - altFactor = DEFAULT_MAP_CELL_HEIGHT_FACTOR; + heightFactor = DEFAULT_MAP_CELL_HEIGHT_FACTOR; waterLevel = DEFAULT_MAP_WATER_DEPTH; + cliffLevel = DEFAULT_CLIFF_HEIGHT; //cells = NULL; cells.clear(); //startLocations = NULL; @@ -60,6 +61,24 @@ float MapPreview::getHeight(int x, int y) const { return cells[x][y].height; } +bool MapPreview::isCliff(int x, int y){ + if(cliffLevel == 0) + return false; + for(int k= -1; k <= 1; ++k){ + for(int l= -1; l <= 1; ++l){ + int xToCheck= x + l; + int yToCheck= y + k; + if(xToCheck < 0 || yToCheck < 0 || xToCheck >= w || yToCheck >= h){ + //ignore + } + else if(cliffLevel <= abs(getHeight(x, y) - getHeight(xToCheck, yToCheck))){ + return true; + } + } + return false; + } +} + MapSurfaceType MapPreview::getSurface(int x, int y) const { return static_cast(cells[x][y].surface); } @@ -588,17 +607,10 @@ void MapPreview::setAuthor(const string &author) { this->author = author; } -void MapPreview::setAdvanced(int altFactor, int waterLevel) { - this->altFactor = altFactor; +void MapPreview::setAdvanced(int heightFactor, int waterLevel, int cliffLevel) { + this->heightFactor = heightFactor; this->waterLevel = waterLevel; -} - -int MapPreview::getHeightFactor() const { - return altFactor; -} - -int MapPreview::getWaterLevel() const { - return waterLevel; + this->cliffLevel = cliffLevel; } void MapPreview::randomizeHeights() { @@ -651,11 +663,18 @@ void MapPreview::loadFromFile(const string &path) { MapFileHeader header; size_t bytes = fread(&header, sizeof(MapFileHeader), 1, f1); - altFactor = header.altFactor; + heightFactor = header.heightFactor; waterLevel = header.waterLevel; title = header.title; author = header.author; - desc = header.description; + cliffLevel = 0; + if(header.version==1){ + desc = header.extension_data.description; + } + else if(header.version==2){ + desc = header.extension_data.version2.short_desc; + cliffLevel=header.extension_data.version2.cliffLevel; + } //read start locations resetFactions(header.maxFactions); @@ -711,15 +730,18 @@ void MapPreview::saveToFile(const string &path) { //write header MapFileHeader header; - header.version = 1; + header.version = MAP_FORMAT_VERSION; header.maxFactions = maxFactions; header.width = w; header.height = h; - header.altFactor = altFactor; + header.heightFactor = heightFactor; header.waterLevel = waterLevel; - strncpy(header.title, title.c_str(), 128); - strncpy(header.author, author.c_str(), 128); - strncpy(header.description, desc.c_str(), 256); + strncpy(header.title, title.c_str(), MAX_TITLE_LENGTH); + strncpy(header.author, author.c_str(), MAX_AUTHOR_LENGTH); + strncpy(header.extension_data.version2.short_desc, desc.c_str(), MAX_DESCRIPTION_LENGTH_VERSION2); + header.extension_data.version2.magic= 0x01020304; + header.extension_data.version2.cliffLevel= cliffLevel; + fwrite(&header, sizeof(MapFileHeader), 1, f1);