- added some initial work to support FBO (frame buffer objects)

- added many NULL check guards throughout the code
- added a safe mutex around ptr access of background thread on custom menu
This commit is contained in:
Mark Vejvoda 2010-11-01 16:44:05 +00:00
parent d8c11ebe71
commit 9978cbeff5
16 changed files with 946 additions and 394 deletions

View File

@ -413,7 +413,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
}
else {
canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
localCacheForUnitCellMovement[node->pos][sucPos] = canUnitMoveToCell;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
localCacheForUnitCellMovement[node->pos][sucPos] = canUnitMoveToCell;
}
}
if(openPos(sucPos) == false && canUnitMoveToCell == true) {

View File

@ -50,6 +50,9 @@ GameCamera::GameCamera() : pos(0.f, defaultHeight, 0.f),
cacheVisibleQuad.clear();
MaxVisibleQuadItemCache = config.getInt("MaxVisibleQuadItemCache",intToStr(-1).c_str());
if(Config::getInstance().getBool("DisableCaching","false") == true) {
MaxVisibleQuadItemCache = 0;
}
//config
speed= 15.f / GameConstants::cameraFps;

View File

@ -32,6 +32,7 @@
using namespace Shared::Graphics;
using namespace Shared::Graphics::Gl;
using namespace Shared::Util;
using namespace Shared::Graphics;
namespace Glest { namespace Game{
@ -2960,7 +2961,7 @@ void Renderer::clearZBuffer(){
glClear(GL_DEPTH_BUFFER_BIT);
}
void Renderer::loadConfig(){
void Renderer::loadConfig() {
Config &config= Config::getInstance();
//cache most used config params
@ -2986,6 +2987,36 @@ void Renderer::loadConfig(){
}
}
Texture2D *Renderer::saveScreenToTexture(int x, int y, int width, int height) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Config &config= Config::getInstance();
Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
int maxAnisotropy = config.getInt("FilterMaxAnisotropy");
Texture2D *texture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
//texture->setFormat(Texture::fRgba);
texture->setForceCompressionDisabled(true);
texture->setMipmap(false);
//Pixmap2D *pixmapScreenShot = new Pixmap2D(width, height, 3);
Pixmap2D *pixmapScreenShot = texture->getPixmap();
pixmapScreenShot->init(width, height, 3);
//const Metrics &sm= Metrics::getInstance();
//pixmapScreenShot->init(sm.getScreenW(), sm.getScreenH(), 3);
texture->init(textureFilter,maxAnisotropy);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//glFinish();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
glReadPixels(x, y, pixmapScreenShot->getW(), pixmapScreenShot->getH(),
GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return texture;
}
void Renderer::saveScreen(const string &path) {
const Metrics &sm= Metrics::getInstance();
@ -3834,6 +3865,14 @@ void Renderer::renderTile(const Vec2i &pos) {
}
void Renderer::renderQuad(int x, int y, int w, int h, const Texture2D *texture) {
if(w < 0) {
w = texture->getPixmap()->getW();
}
if(h < 0) {
h = texture->getPixmap()->getH();
}
glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(texture)->getHandle());
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2i(0, 1);
@ -4055,7 +4094,8 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
}
void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
int screenPosX, int screenPosY) {
int screenPosX, int screenPosY,
Texture2D **renderToTexture) {
float alt=0;
float showWater=0;
int renderMapHeight=64;
@ -4077,23 +4117,75 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
assertGl();
/*
if(renderToTexture != NULL) {
Config &config= Config::getInstance();
Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
int maxAnisotropy = config.getInt("FilterMaxAnisotropy");
*renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
//texture->setFormat(Texture::fAlpha);
texture->setMipmap(false);
Pixmap2D *pixmapScreenShot = texture->getPixmap();
pixmapScreenShot->init(metrics.getVirtualW(), metrics.getVirtualH(), 3);
//pixmapScreenShot->init(map->getW(),map->getH(),3);
//pixmapScreenShot->init(200, 360, 3);
texture->setForceCompressionDisabled(true);
texture->init(textureFilter,maxAnisotropy);
//texture->initFrameBuffer();
//texture->attachFrameBufferToTexture();
//texture->initRenderBuffer();
//texture->attachRenderBuffer();
texture->setup_FBO_RBO();
if(texture->checkFrameBufferStatus() == false) {
//printf("******************** WARNING CANNOT Attach to FBO!\n");
texture->end();
delete texture;
*renderToTexture=NULL;
}
}
*/
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
//glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// glViewport(screenPosX, screenPosY, sizeH,sizeW);
//glViewport(screenPosX, screenPosY, metrics.getVirtualW(),metrics.getVirtualH());
// glOrtho(0, clientW, 0, clientH, -1, 1);
//glOrtho(screenPosX, screenPosX+clientW, screenPosY+clientH, screenPosY, 0, 1);
glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1);
//gluOrtho2D (0, metrics.getVirtualW(), 0, metrics.getVirtualH());
//glEnable( GL_SCISSOR_TEST );
//glScissor(screenPosX, screenPosY,metrics.getVirtualW(), metrics.getVirtualH());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(static_cast<float>(screenPosX),static_cast<float>(screenPosY)-clientH,0.0f);
//glEnable( GL_SCISSOR_TEST );
//glScissor(screenPosX, screenPosY,screenPosX-clientW, screenPosY-clientH);
//int newX = screenPosX - (metrics.getVirtualW() / 2);
//int newY = screenPosY - (metrics.getVirtualH() / 2);
//int newX = 0;
//int newY = 0;
//glTranslatef(static_cast<float>(newX),static_cast<float>(newY),0.0f);
glPushAttrib(GL_CURRENT_BIT);
//glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f);
glLineWidth(1);
@ -4108,11 +4200,21 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
showWater = (showWater > 0)? showWater:0;
Vec3f surfColor;
switch (map->getSurface(i, j)) {
case st_Grass: surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); break;
case st_Secondary_Grass: surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); break;
case st_Road: surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); break;
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;
case st_Grass:
surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater);
break;
case st_Secondary_Grass:
surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater);
break;
case st_Road:
surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater);
break;
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;
}
glColor3fv(surfColor.ptr());
@ -4127,20 +4229,42 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
//objects
if(renderAll == true) {
switch (map->getObject(i, j)) {
case 0: glColor3f(0.f, 0.f, 0.f); break;
case 1: glColor3f(1.f, 0.f, 0.f); break;
case 2: glColor3f(1.f, 1.f, 1.f); break;
case 3: glColor3f(0.5f, 0.5f, 1.f); break;
case 4: glColor3f(0.f, 0.f, 1.f); break;
case 5: glColor3f(0.5f, 0.5f, 0.5f); break;
case 6: glColor3f(1.f, 0.8f, 0.5f); break;
case 7: glColor3f(0.f, 1.f, 1.f); break;
case 8: glColor3f(0.7f, 0.1f, 0.3f); break;
case 9: glColor3f(0.5f, 1.f, 0.1f); break;
case 10: glColor3f(1.f, 0.2f, 0.8f); break;// we don't render unvisible blocking objects
case 0:
glColor3f(0.f, 0.f, 0.f);
break;
case 1:
glColor3f(1.f, 0.f, 0.f);
break;
case 2:
glColor3f(1.f, 1.f, 1.f);
break;
case 3:
glColor3f(0.5f, 0.5f, 1.f);
break;
case 4:
glColor3f(0.f, 0.f, 1.f);
break;
case 5:
glColor3f(0.5f, 0.5f, 0.5f);
break;
case 6:
glColor3f(1.f, 0.8f, 0.5f);
break;
case 7:
glColor3f(0.f, 1.f, 1.f);
break;
case 8:
glColor3f(0.7f, 0.1f, 0.3f);
break;
case 9:
glColor3f(0.5f, 1.f, 0.1f);
break;
case 10:
glColor3f(1.f, 0.2f, 0.8f);
break;// we don't render unvisible blocking objects
}
if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ){
if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) {
glPointSize(cellSize / 2.f);
glBegin(GL_POINTS);
glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f);
@ -4211,15 +4335,16 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
}
//start locations
glLineWidth(3);
// force playerCrossSize to be at least of size 4
if(cellSize<4)
playerCrossSize=4;
else
playerCrossSize=cellSize;
if(cellSize < 4) {
playerCrossSize = 4;
}
else {
playerCrossSize = cellSize;
}
for (int i = 0; i < map->getMaxFactions(); i++) {
switch (i) {
@ -4245,8 +4370,29 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//glDisable( GL_SCISSOR_TEST );
//glViewport(0, 0, 0, 0);
if(renderToTexture != NULL) {
//*renderToTexture = saveScreenToTexture(screenPosX, screenPosY, metrics.getVirtualW(), metrics.getVirtualH());
//*renderToTexture = saveScreenToTexture(0, 0, metrics.getVirtualW(), metrics.getVirtualH());
/*
Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
if(texture != NULL) {
//*renderToTexture = saveScreenToTexture(screenPosX, screenPosY, clientW, clientH);
texture->dettachFrameBufferFromTexture();
// Signal the threads queue to add a screenshot save request
//MutexSafeWrapper safeMutex(&saveScreenShotThreadAccessor);
//saveScreenQueue.push_back(make_pair("bob.png",texture->getPixmap()));
//*renderToTexture=NULL;
//safeMutex.ReleaseLock();
//texture->teardown_FBO_RBO();
}
*/
}
assertGl();
}

View File

@ -339,7 +339,7 @@ public:
void renderMinimap();
void renderDisplay();
void renderMenuBackground(const MenuBackground *menuBackground);
void renderMapPreview(const MapPreview *map, bool renderAll, int screenX, int screenY);
void renderMapPreview(const MapPreview *map, bool renderAll, int screenX, int screenY,Texture2D **renderToTexture=NULL);
//computing
bool computePosition(const Vec2i &screenPos, Vec2i &worldPos);
@ -392,6 +392,8 @@ public:
uint64 getCurrentPixelByteCount(ResourceScope rs=rsGame) const;
unsigned int getSaveScreenQueueSize();
Texture2D *saveScreenToTexture(int x, int y, int width, int height);
private:
//private misc
float computeSunAngle(float time);

View File

@ -59,6 +59,7 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
factionTexture=NULL;
currentTechName_factionPreview="";
currentFactionName_factionPreview="";
mapPreviewTexture=NULL;
publishToMasterserverThread = NULL;
Lang &lang= Lang::getInstance();
@ -487,6 +488,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
GraphicComponent::applyAllCustomProperties(containerName);
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = false;
publishToMasterserverThread = new SimpleTaskThread(this,0,25);
publishToMasterserverThread->setUniqueID(__FILE__);
publishToMasterserverThread->start();
@ -497,16 +501,28 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, b
MenuStateCustomGame::~MenuStateCustomGame() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
needToBroadcastServerSettings = false;
needToRepublishToMasterserver = false;
if(publishToMasterserverThreadInDeletion == false) {
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
if(publishToMasterserverThread != NULL) {
needToBroadcastServerSettings = false;
needToRepublishToMasterserver = false;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
}
else {
safeMutexPtr.ReleaseLock();
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
cleanupFactionTexture();
cleanupMapPreviewTexture();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -514,6 +530,9 @@ MenuStateCustomGame::~MenuStateCustomGame() {
void MenuStateCustomGame::returnToParentMenu(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
needToBroadcastServerSettings = false;
needToRepublishToMasterserver = false;
bool returnToMasterServerMenu = parentMenuIsMs;
@ -521,6 +540,8 @@ void MenuStateCustomGame::returnToParentMenu(){
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -563,9 +584,13 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
needToRepublishToMasterserver = false;
safeMutex.ReleaseLock();
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1024,8 +1049,13 @@ void MenuStateCustomGame::PlayNow() {
needToRepublishToMasterserver = false;
safeMutex.ReleaseLock();
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1090,7 +1120,12 @@ void MenuStateCustomGame::render() {
Renderer &renderer= Renderer::getInstance();
if(factionTexture != NULL) {
renderer.renderTextureQuad(800,600,200,150,factionTexture,1);
renderer.renderTextureQuad(800,600,200,150,factionTexture,0.7);
}
if(mapPreviewTexture != NULL) {
//renderer.renderTextureQuad(10,350,-1,-1,mapPreviewTexture,0.7);
renderer.renderTextureQuad(800,300,200,150,mapPreviewTexture,0.7);
//printf("=================> Rendering map preview texture\n");
}
if(mainMessageBox.getEnabled()){
@ -1179,7 +1214,8 @@ void MenuStateCustomGame::render() {
if(program != NULL) program->renderProgramMsgBox();
if(enableMapPreview && (mapPreview.hasFileLoaded() == true)) {
if( enableMapPreview == true &&
mapPreview.hasFileLoaded() == true) {
int mouseX = mainMenu->getMouseX();
int mouseY = mainMenu->getMouseY();
@ -1187,7 +1223,15 @@ void MenuStateCustomGame::render() {
renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim);
bool renderAll = (listBoxFogOfWar.getSelectedItemIndex() == 1);
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350);
if(mapPreviewTexture == NULL) {
//printf("=================> Rendering map preview into a texture BEFORE (%p)\n", mapPreviewTexture);
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture);
//printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture);
}
else {
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350);
}
}
renderer.renderChatManager(&chatManager);
@ -2214,6 +2258,9 @@ void MenuStateCustomGame::loadMapInfo(string file, MapInfo *mapInfo, bool loadMa
if(loadMapPreview == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mapPreview.loadFromFile(file.c_str());
//printf("Loading map preview MAP\n");
cleanupMapPreviewTexture();
}
}
catch(exception &e) {
@ -2625,4 +2672,21 @@ void MenuStateCustomGame::cleanupFactionTexture() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void MenuStateCustomGame::cleanupMapPreviewTexture() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//printf("CLEANUP map preview texture\n");
if(mapPreviewTexture != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mapPreviewTexture->end();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete mapPreviewTexture;
mapPreviewTexture = NULL;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}}//end namespace

View File

@ -101,6 +101,8 @@ private:
std::map<string,string> publishToServerInfo;
SimpleTaskThread *publishToMasterserverThread;
Mutex masterServerThreadAccessor;
Mutex publishToMasterserverThreadPtrChangeAccessor;
bool publishToMasterserverThreadInDeletion;
bool parentMenuIsMs;
int soundConnectionCount;
@ -132,6 +134,8 @@ private:
Texture2D *factionTexture;
MapPreview mapPreview;
Texture2D *mapPreviewTexture;
bool autostart;
std::map<int,int> lastSelectedTeamIndex;
@ -157,6 +161,8 @@ private:
bool hasNetworkGameSettings();
void loadGameSettings(GameSettings *gameSettings);
void loadMapInfo(string file, MapInfo *mapInfo,bool loadMapPreview);
void cleanupMapPreviewTexture();
void reloadFactions(bool keepExistingSelectedItem);
void updateControlers();
void closeUnusedSlots();

View File

@ -20,8 +20,9 @@
#include "sound_renderer.h"
#include "renderer.h"
#include "tech_tree.h"
#include "leak_dumper.h"
#include "game.h"
#include "config.h"
#include "leak_dumper.h"
using namespace Shared::Util;
@ -672,148 +673,123 @@ void Faction::resetResourceAmount(const ResourceType *rt){
bool Faction::isResourceTargetInCache(const Vec2i &pos, bool incrementUseCounter) {
bool result = false;
if(cacheResourceTargetList.size() > 0) {
std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.find(pos);
result = (iter != cacheResourceTargetList.end());
if(result == true && incrementUseCounter == true) {
iter->second++;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.find(pos);
result = (iter != cacheResourceTargetList.end());
if(result == true && incrementUseCounter == true) {
iter->second++;
}
}
}
return result;
}
void Faction::addResourceTargetToCache(const Vec2i &pos) {
bool duplicateEntry = isResourceTargetInCache(pos,true);
if(duplicateEntry == false) {
cacheResourceTargetList[pos] = 1;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
bool duplicateEntry = isResourceTargetInCache(pos,true);
if(duplicateEntry == false) {
cacheResourceTargetList[pos] = 1;
}
}
}
void Faction::removeResourceTargetFromCache(const Vec2i &pos) {
if(cacheResourceTargetList.size() > 0) {
std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.find(pos);
if(iter != cacheResourceTargetList.end()) {
cacheResourceTargetList.erase(pos);
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.find(pos);
if(iter != cacheResourceTargetList.end()) {
cacheResourceTargetList.erase(pos);
}
}
}
}
void Faction::addCloseResourceTargetToCache(const Vec2i &pos) {
if(cachedCloseResourceTargetLookupList.find(pos) == cachedCloseResourceTargetLookupList.end()) {
const Map *map = world->getMap();
const int harvestDistance = 5;
for(int j = -harvestDistance; j <= harvestDistance; ++j) {
for(int k = -harvestDistance; k <= harvestDistance; ++k) {
Vec2i newPos = pos + Vec2i(j,k);
if(isResourceTargetInCache(newPos) == false) {
if(map->isInside(newPos.x, newPos.y)) {
Resource *r = map->getSurfaceCell(map->toSurfCoords(newPos))->getResource();
if(r != NULL) {
//addResourceTargetToCache(newPos);
cacheResourceTargetList[newPos] = 1;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cachedCloseResourceTargetLookupList.find(pos) == cachedCloseResourceTargetLookupList.end()) {
const Map *map = world->getMap();
const int harvestDistance = 5;
for(int j = -harvestDistance; j <= harvestDistance; ++j) {
for(int k = -harvestDistance; k <= harvestDistance; ++k) {
Vec2i newPos = pos + Vec2i(j,k);
if(isResourceTargetInCache(newPos) == false) {
if(map->isInside(newPos.x, newPos.y)) {
Resource *r = map->getSurfaceCell(map->toSurfCoords(newPos))->getResource();
if(r != NULL) {
//addResourceTargetToCache(newPos);
cacheResourceTargetList[newPos] = 1;
}
}
}
}
}
}
cachedCloseResourceTargetLookupList[pos] = true;
cachedCloseResourceTargetLookupList[pos] = true;
}
}
}
Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type) {
Vec2i result(-1);
if(cacheResourceTargetList.size() > 0) {
std::vector<Vec2i> deleteList;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
std::vector<Vec2i> deleteList;
const int harvestDistance = 5;
const Map *map = world->getMap();
Vec2i pos = unit->getPos();
const int harvestDistance = 5;
const Map *map = world->getMap();
Vec2i pos = unit->getPos();
bool foundCloseResource = false;
// First look immediately around the unit's position
for(int j = -harvestDistance; j <= harvestDistance && foundCloseResource == false; ++j) {
for(int k = -harvestDistance; k <= harvestDistance && foundCloseResource == false; ++k) {
Vec2i newPos = pos + Vec2i(j,k);
if(map->isInside(newPos) == true && isResourceTargetInCache(newPos) == false) {
const SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(newPos));
if( sc != NULL && sc->getResource() != NULL) {
const Resource *resource = sc->getResource();
if(resource->getType() != NULL && resource->getType() == type) {
if(result.x < 0 || unit->getPos().dist(newPos) < unit->getPos().dist(result)) {
if(unit->isBadHarvestPos(newPos) == false) {
result = newPos;
foundCloseResource = true;
break;
}
}
}
}
else {
deleteList.push_back(newPos);
}
}
}
}
if(foundCloseResource == false) {
// Now check the whole cache
for(std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.begin();
iter != cacheResourceTargetList.end() && foundCloseResource == false;
++iter) {
const Vec2i &cache = iter->first;
if(map->isInside(cache) == true) {
const SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(cache));
if( sc != NULL && sc->getResource() != NULL) {
const Resource *resource = sc->getResource();
if(resource->getType() != NULL && resource->getType() == type) {
if(result.x < 0 || unit->getPos().dist(cache) < unit->getPos().dist(result)) {
if(unit->isBadHarvestPos(cache) == false) {
result = cache;
// Close enough to our position, no more looking
if(unit->getPos().dist(result) <= (harvestDistance * 2)) {
bool foundCloseResource = false;
// First look immediately around the unit's position
for(int j = -harvestDistance; j <= harvestDistance && foundCloseResource == false; ++j) {
for(int k = -harvestDistance; k <= harvestDistance && foundCloseResource == false; ++k) {
Vec2i newPos = pos + Vec2i(j,k);
if(map->isInside(newPos) == true && isResourceTargetInCache(newPos) == false) {
const SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(newPos));
if( sc != NULL && sc->getResource() != NULL) {
const Resource *resource = sc->getResource();
if(resource->getType() != NULL && resource->getType() == type) {
if(result.x < 0 || unit->getPos().dist(newPos) < unit->getPos().dist(result)) {
if(unit->isBadHarvestPos(newPos) == false) {
result = newPos;
foundCloseResource = true;
break;
}
}
}
}
}
else {
deleteList.push_back(cache);
else {
deleteList.push_back(newPos);
}
}
}
else {
deleteList.push_back(cache);
}
}
}
if(deleteList.size() > 0) {
cleanupResourceTypeTargetCache(&deleteList);
}
}
return result;
}
void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr) {
if(cacheResourceTargetList.size() > 0) {
if(deleteListPtr != NULL || difftime(time(NULL),lastResourceTargettListPurge) >= 120) {
lastResourceTargettListPurge = time(NULL);
std::vector<Vec2i> deleteList;
if(deleteListPtr != NULL) {
deleteList = *deleteListPtr;
}
else {
if(foundCloseResource == false) {
// Now check the whole cache
for(std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.begin();
iter != cacheResourceTargetList.end(); ++iter) {
iter != cacheResourceTargetList.end() && foundCloseResource == false;
++iter) {
const Vec2i &cache = iter->first;
if(world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache)) != NULL) {
Resource *resource = world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache))->getResource();
if(resource == NULL) {
if(map->isInside(cache) == true) {
const SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(cache));
if( sc != NULL && sc->getResource() != NULL) {
const Resource *resource = sc->getResource();
if(resource->getType() != NULL && resource->getType() == type) {
if(result.x < 0 || unit->getPos().dist(cache) < unit->getPos().dist(result)) {
if(unit->isBadHarvestPos(cache) == false) {
result = cache;
// Close enough to our position, no more looking
if(unit->getPos().dist(result) <= (harvestDistance * 2)) {
foundCloseResource = true;
break;
}
}
}
}
}
else {
deleteList.push_back(cache);
}
}
@ -822,9 +798,44 @@ void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr)
}
}
}
for(int i = 0; i < deleteList.size(); ++i) {
Vec2i &cache = deleteList[i];
cacheResourceTargetList.erase(cache);
if(deleteList.size() > 0) {
cleanupResourceTypeTargetCache(&deleteList);
}
}
}
return result;
}
void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr) {
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(cacheResourceTargetList.size() > 0) {
if(deleteListPtr != NULL || difftime(time(NULL),lastResourceTargettListPurge) >= 120) {
lastResourceTargettListPurge = time(NULL);
std::vector<Vec2i> deleteList;
if(deleteListPtr != NULL) {
deleteList = *deleteListPtr;
}
else {
for(std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.begin();
iter != cacheResourceTargetList.end(); ++iter) {
const Vec2i &cache = iter->first;
if(world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache)) != NULL) {
Resource *resource = world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache))->getResource();
if(resource == NULL) {
deleteList.push_back(cache);
}
}
else {
deleteList.push_back(cache);
}
}
}
for(int i = 0; i < deleteList.size(); ++i) {
Vec2i &cache = deleteList[i];
cacheResourceTargetList.erase(cache);
}
}
}
}
@ -832,40 +843,42 @@ void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr)
std::vector<Vec2i> Faction::findCachedPath(const Vec2i &target, Unit *unit) {
std::vector<Vec2i> result;
if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
// Lets find the shortest and most successful path already taken by a
// similar sized unit
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
// Lets find the shortest and most successful path already taken by a
// similar sized unit
bool foundCachedPath = false;
bool foundCachedPath = false;
std::vector<FactionPathSuccessCache> &cacheList = successfulPathFinderTargetList[target];
int unitSize = unit->getType()->getSize();
for(int i = 0; i < cacheList.size(); ++i) {
FactionPathSuccessCache &cache = cacheList[i];
if(cache.unitSize <= unitSize) {
vector<std::pair<vector<Vec2i>, int> > &pathQueue = cache.pathQueue;
std::vector<FactionPathSuccessCache> &cacheList = successfulPathFinderTargetList[target];
int unitSize = unit->getType()->getSize();
for(int i = 0; i < cacheList.size(); ++i) {
FactionPathSuccessCache &cache = cacheList[i];
if(cache.unitSize <= unitSize) {
vector<std::pair<vector<Vec2i>, int> > &pathQueue = cache.pathQueue;
for(int j = 0; j < pathQueue.size(); ++j) {
// Now start at the end of the path and see how many nodes
// until we reach a cell near the unit's current position
std::pair<vector<Vec2i>, int> &path = pathQueue[j];
for(int j = 0; j < pathQueue.size(); ++j) {
// Now start at the end of the path and see how many nodes
// until we reach a cell near the unit's current position
std::pair<vector<Vec2i>, int> &path = pathQueue[j];
for(int k = path.first.size() - 1; k >= 0; --k) {
if(world->getMap()->canMove(unit, unit->getPos(), path.first[k]) == true) {
if(foundCachedPath == false) {
for(int l = k; l < path.first.size(); ++l) {
result.push_back(path.first[l]);
}
}
else {
if(result.size() > (path.first.size() - k)) {
for(int k = path.first.size() - 1; k >= 0; --k) {
if(world->getMap()->canMove(unit, unit->getPos(), path.first[k]) == true) {
if(foundCachedPath == false) {
for(int l = k; l < path.first.size(); ++l) {
result.push_back(path.first[l]);
}
}
else {
if(result.size() > (path.first.size() - k)) {
for(int l = k; l < path.first.size(); ++l) {
result.push_back(path.first[l]);
}
}
}
foundCachedPath = true;
break;
}
foundCachedPath = true;
break;
}
}
}
@ -876,53 +889,55 @@ std::vector<Vec2i> Faction::findCachedPath(const Vec2i &target, Unit *unit) {
}
void Faction::addCachedPath(const Vec2i &target, Unit *unit) {
if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
FactionPathSuccessCache cache;
cache.unitSize = unit->getType()->getSize();
cache.pathQueue.push_back(make_pair<vector<Vec2i>, int>(unit->getCurrentTargetPathTaken().second,1));
successfulPathFinderTargetList[target].push_back(cache);
}
else {
bool finishedAdd = false;
std::pair<Vec2i,std::vector<Vec2i> > currentTargetPathTaken = unit->getCurrentTargetPathTaken();
std::vector<FactionPathSuccessCache> &cacheList = successfulPathFinderTargetList[target];
int unitSize = unit->getType()->getSize();
for(int i = 0; i < cacheList.size() && finishedAdd == false; ++i) {
FactionPathSuccessCache &cache = cacheList[i];
if(cache.unitSize <= unitSize) {
vector<std::pair<vector<Vec2i>, int> > &pathQueue = cache.pathQueue;
if(Config::getInstance().getBool("DisableCaching","false") == false) {
if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) {
FactionPathSuccessCache cache;
cache.unitSize = unit->getType()->getSize();
cache.pathQueue.push_back(make_pair<vector<Vec2i>, int>(unit->getCurrentTargetPathTaken().second,1));
successfulPathFinderTargetList[target].push_back(cache);
}
else {
bool finishedAdd = false;
std::pair<Vec2i,std::vector<Vec2i> > currentTargetPathTaken = unit->getCurrentTargetPathTaken();
std::vector<FactionPathSuccessCache> &cacheList = successfulPathFinderTargetList[target];
int unitSize = unit->getType()->getSize();
for(int i = 0; i < cacheList.size() && finishedAdd == false; ++i) {
FactionPathSuccessCache &cache = cacheList[i];
if(cache.unitSize <= unitSize) {
vector<std::pair<vector<Vec2i>, int> > &pathQueue = cache.pathQueue;
for(int j = 0; j < pathQueue.size() && finishedAdd == false; ++j) {
// Now start at the end of the path and see how many nodes are the same
std::pair<vector<Vec2i>, int> &path = pathQueue[j];
int minPathSize = std::min(path.first.size(),currentTargetPathTaken.second.size());
int intersectIndex = -1;
for(int j = 0; j < pathQueue.size() && finishedAdd == false; ++j) {
// Now start at the end of the path and see how many nodes are the same
std::pair<vector<Vec2i>, int> &path = pathQueue[j];
int minPathSize = std::min(path.first.size(),currentTargetPathTaken.second.size());
int intersectIndex = -1;
for(int k = 0; k < minPathSize; ++k) {
if(path.first[path.first.size() - k - 1] != currentTargetPathTaken.second[currentTargetPathTaken.second.size() - k - 1]) {
intersectIndex = k;
break;
for(int k = 0; k < minPathSize; ++k) {
if(path.first[path.first.size() - k - 1] != currentTargetPathTaken.second[currentTargetPathTaken.second.size() - k - 1]) {
intersectIndex = k;
break;
}
}
// New path is same or longer than old path so replace
// old path with new
if(intersectIndex + 1 == path.first.size()) {
path.first = currentTargetPathTaken.second;
path.second++;
finishedAdd = true;
}
// Old path is same or longer than new path so
// do nothing
else if(intersectIndex + 1 == currentTargetPathTaken.second.size()) {
path.second++;
finishedAdd = true;
}
}
// New path is same or longer than old path so replace
// old path with new
if(intersectIndex + 1 == path.first.size()) {
path.first = currentTargetPathTaken.second;
path.second++;
finishedAdd = true;
// If new path is >= 10 cells add it
if(finishedAdd == false && currentTargetPathTaken.second.size() >= 10) {
pathQueue.push_back(make_pair<vector<Vec2i>, int>(currentTargetPathTaken.second,1));
}
// Old path is same or longer than new path so
// do nothing
else if(intersectIndex + 1 == currentTargetPathTaken.second.size()) {
path.second++;
finishedAdd = true;
}
}
// If new path is >= 10 cells add it
if(finishedAdd == false && currentTargetPathTaken.second.size() >= 10) {
pathQueue.push_back(make_pair<vector<Vec2i>, int>(currentTargetPathTaken.second,1));
}
}
}

View File

@ -50,7 +50,6 @@ Object::~Object(){
delete resource;
Renderer &renderer= Renderer::getInstance();
//renderer.setQuadCacheDirty(true);
renderer.removeObjectFromQuadCache(this);
}

View File

@ -296,7 +296,6 @@ Unit::~Unit(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Renderer &renderer= Renderer::getInstance();
//renderer.setQuadCacheDirty(true);
renderer.removeUnitFromQuadCache(this);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);

View File

@ -106,8 +106,53 @@ Map::~Map(){
Logger::getInstance().add("Cells", true);
delete [] cells;
cells = NULL;
delete [] surfaceCells;
surfaceCells = NULL;
delete [] startLocations;
startLocations = NULL;
}
int Map::getSurfaceCellArraySize() const {
return (surfaceW * surfaceH);
}
SurfaceCell *Map::getSurfaceCell(int sx, int sy) const {
int arrayIndex = sy * surfaceW + sx;
if(arrayIndex >= getSurfaceCellArraySize()) {
throw runtime_error("arrayIndex >= getSurfaceCellArraySize()");
}
else if(surfaceCells == NULL) {
throw runtime_error("surfaceCells == NULL");
}
return &surfaceCells[arrayIndex];
}
int Map::getCellArraySize() const {
return (w * h);
}
Cell *Map::getCell(int x, int y) const {
int arrayIndex = y * w + x;
if(arrayIndex >= getCellArraySize()) {
throw runtime_error("arrayIndex >= getCellArraySize()");
}
else if(cells == NULL) {
throw runtime_error("cells == NULL");
}
return &cells[arrayIndex];
}
Vec2i Map::getStartLocation(int locationIndex) const {
if(locationIndex >= maxPlayers) {
throw runtime_error("locationIndex >= maxPlayers");
}
else if(startLocations == NULL) {
throw runtime_error("startLocations == NULL");
}
return startLocations[locationIndex];
}
void Map::load(const string &path, TechTree *techTree, Tileset *tileset){
@ -152,7 +197,7 @@ void Map::load(const string &path, TechTree *techTree, Tileset *tileset){
//start locations
startLocations= new Vec2i[maxPlayers];
for(int i=0; i<maxPlayers; ++i){
for(int i=0; i<maxPlayers; ++i) {
int x, y;
readBytes = fread(&x, sizeof(int32), 1, f);
readBytes = fread(&y, sizeof(int32), 1, f);
@ -161,8 +206,8 @@ void Map::load(const string &path, TechTree *techTree, Tileset *tileset){
//cells
cells= new Cell[w*h];
surfaceCells= new SurfaceCell[surfaceW*surfaceH];
cells= new Cell[getCellArraySize()];
surfaceCells= new SurfaceCell[getSurfaceCellArraySize()];
//read heightmap
for(int j=0; j<surfaceH; ++j){
@ -847,9 +892,9 @@ void Map::computeInterpolatedHeights(){
void Map::smoothSurface(){
float *oldHeights= new float[surfaceW*surfaceH];
float *oldHeights= new float[getSurfaceCellArraySize()];
for(int i=0; i<surfaceW*surfaceH; ++i){
for(int i=0; i < getSurfaceCellArraySize(); ++i) {
oldHeights[i]= surfaceCells[i].getHeight();
}

View File

@ -177,9 +177,11 @@ public:
void load(const string &path, TechTree *techTree, Tileset *tileset);
//get
Cell *getCell(int x, int y) const {return &cells[y*w+x];}
Cell *getCell(int x, int y) const;
int getCellArraySize() const;
Cell *getCell(const Vec2i &pos) const {return getCell(pos.x, pos.y);}
SurfaceCell *getSurfaceCell(int sx, int sy) const {return &surfaceCells[sy*surfaceW+sx];}
int getSurfaceCellArraySize() const;
SurfaceCell *getSurfaceCell(int sx, int sy) const;
SurfaceCell *getSurfaceCell(const Vec2i &sPos) const {return getSurfaceCell(sPos.x, sPos.y);}
int getW() const {return w;}
int getH() const {return h;}
@ -188,7 +190,7 @@ public:
int getMaxPlayers() const {return maxPlayers;}
float getHeightFactor() const {return heightFactor;}
float getWaterLevel() const {return waterLevel;}
Vec2i getStartLocation(int loactionIndex) const {return startLocations[loactionIndex];}
Vec2i getStartLocation(int locationIndex) const;
bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel;}
bool getSubmerged(const Cell *c) const {return c->getHeight()<waterLevel;}
bool getDeepSubmerged(const SurfaceCell *sc) const {return sc->getHeight()<waterLevel-(1.5f/heightFactor);}

View File

@ -113,7 +113,7 @@ void Tileset::load(const string &dir, Checksum *checksum){
checksum->addFile(path);
try{
try {
Logger::getInstance().add("Tileset: "+formatString(name), true);
Renderer &renderer= Renderer::getInstance();
@ -242,13 +242,13 @@ void Tileset::load(const string &dir, Checksum *checksum){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(rnd<sunnyProb){
if(rnd < sunnyProb) {
weather= wSunny;
}
else if(rnd<rainyProb){
else if(rnd < rainyProb) {
weather= wRainy;
}
else{
else {
weather= wSnowy;
}
@ -256,7 +256,7 @@ void Tileset::load(const string &dir, Checksum *checksum){
}
//Exception handling (conversions and so on);
catch(const exception &e){
catch(const exception &e) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
throw runtime_error("Error: " + path + "\n" + e.what());
}
@ -271,18 +271,16 @@ const Pixmap2D *Tileset::getSurfPixmap(int type, int var) const{
return &surfPixmaps[type][var % vars];
}
void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture){
void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture) {
//center textures
if(leftUp==rightUp && leftUp==leftDown && leftUp==rightDown){
if(leftUp == rightUp && leftUp == leftDown && leftUp == rightDown) {
//texture variation according to probability
float r= random.randRange(0.f, 1.f);
int var= 0;
float max= 0.f;
for(int i=0; i<surfProbs[leftUp].size(); ++i){
for(int i=0; i < surfProbs[leftUp].size(); ++i) {
max+= surfProbs[leftUp][i];
if(r<=max){
if(r <= max) {
var= i;
break;
}
@ -292,21 +290,18 @@ void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, V
coord= si.getCoord();
texture= si.getTexture();
}
//spatted textures
else{
else {
int var= random.randRange(0, transitionVars);
SurfaceInfo si(
getSurfPixmap(leftUp, var),
getSurfPixmap(rightUp, var),
getSurfPixmap(leftDown, var),
getSurfPixmap(rightDown, var));
SurfaceInfo si( getSurfPixmap(leftUp, var),
getSurfPixmap(rightUp, var),
getSurfPixmap(leftDown, var),
getSurfPixmap(rightDown, var));
surfaceAtlas.addSurface(&si);
coord= si.getCoord();
texture= si.getTexture();
}
}
}}// end namespace

View File

@ -246,9 +246,21 @@ void World::loadScenario(const string &path, Checksum *checksum){
void World::updateAllFactionUnits() {
scriptManager->onTimerTriggerEvent();
//units
for(int i=0; i<getFactionCount(); ++i) {
for(int j=0; j<getFaction(i)->getUnitCount(); ++j) {
unitUpdater.updateUnit(getFaction(i)->getUnit(j));
int factionCount = getFactionCount();
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
unitUpdater.updateUnit(unit);
}
}
}
@ -262,17 +274,27 @@ void World::underTakeDeadFactionUnits() {
}
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick);
int factionCount = getFactionCount();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, factionCount = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,factionCount);
//undertake the dead
for(int i=0; i<getFactionCount(); ++i){
for(int i = 0; i< factionCount; ++i) {
if(factionIdxToTick == -1 || factionIdxToTick == i) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, i = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,i);
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factionIdxToTick = %d, i = %d, unitCount = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdxToTick,i,unitCount);
int unitCount = getFaction(i)->getUnitCount();
for(int j= unitCount - 1; j >= 0; j--){
Unit *unit= getFaction(i)->getUnit(j);
if(unit->getToBeUndertaken()) {
for(int j= unitCount - 1; j >= 0; j--) {
Unit *unit= faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
if(unit->getToBeUndertaken() == true) {
unit->undertake();
delete unit;
//j--;
@ -284,11 +306,18 @@ void World::underTakeDeadFactionUnits() {
void World::updateAllFactionConsumableCosts() {
//food costs
for(int i=0; i<techTree->getResourceTypeCount(); ++i){
const ResourceType *rt= techTree->getResourceType(i);
if(rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps)==0){
for(int i=0; i<getFactionCount(); ++i){
getFaction(i)->applyCostsOnInterval(rt);
int resourceTypeCount = techTree->getResourceTypeCount();
int factionCount = getFactionCount();
for(int i = 0; i < resourceTypeCount; ++i) {
const ResourceType *rt = techTree->getResourceType(i);
if(rt != NULL && rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps) == 0) {
for(int j = 0; j < factionCount; ++j) {
Faction *faction = getFaction(j);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
faction->applyCostsOnInterval(rt);
}
}
}
@ -415,35 +444,51 @@ void World::tick() {
//increase hp
//int i = factionIdxToTick;
for(int i=0; i<getFactionCount(); ++i) {
int factionCount = getFactionCount();
for(int i = 0; i < factionCount; ++i) {
if(factionIdxToTick == -1 || i == factionIdxToTick) {
for(int j=0; j<getFaction(i)->getUnitCount(); ++j) {
getFaction(i)->getUnit(j)->tick();
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
unit->tick();
}
}
}
//compute resources balance
//int k = factionIdxToTick;
for(int k=0; k<getFactionCount(); ++k) {
factionCount = getFactionCount();
for(int k = 0; k < factionCount; ++k) {
if(factionIdxToTick == -1 || k == factionIdxToTick) {
Faction *faction= getFaction(k);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
//for each resource
for(int i=0; i<techTree->getResourceTypeCount(); ++i) {
for(int i = 0; i < techTree->getResourceTypeCount(); ++i) {
const ResourceType *rt= techTree->getResourceType(i);
//if consumable
if(rt->getClass()==rcConsumable) {
if(rt != NULL && rt->getClass()==rcConsumable) {
int balance= 0;
for(int j=0; j<faction->getUnitCount(); ++j) {
for(int j = 0; j < faction->getUnitCount(); ++j) {
//if unit operative and has this cost
const Unit *u= faction->getUnit(j);
if(u->isOperative()) {
if(u != NULL && u->isOperative()) {
const Resource *r= u->getType()->getCost(rt);
if(r!=NULL) {
balance-= u->getType()->getCost(rt)->getAmount();
if(r != NULL) {
balance -= u->getType()->getCost(rt)->getAmount();
}
}
}
@ -459,7 +504,7 @@ void World::tick() {
}
Unit* World::findUnitById(int id) const {
for(int i= 0; i<getFactionCount(); ++i){
for(int i= 0; i<getFactionCount(); ++i) {
const Faction* faction= getFaction(i);
Unit* unit = faction->findUnit(id);
if(unit != NULL) {
@ -469,36 +514,42 @@ Unit* World::findUnitById(int id) const {
return NULL;
}
const UnitType* World::findUnitTypeById(const FactionType* factionType, int id){
for(int i= 0; i<factionType->getUnitTypeCount(); ++i){
const UnitType* unitType= factionType->getUnitType(i);
if(unitType->getId()==id){
const UnitType* World::findUnitTypeById(const FactionType* factionType, int id) {
if(factionType == NULL) {
throw runtime_error("factionType == NULL");
}
for(int i= 0; i < factionType->getUnitTypeCount(); ++i) {
const UnitType *unitType = factionType->getUnitType(i);
if(unitType != NULL && unitType->getId() == id) {
return unitType;
}
}
return NULL;
}
//looks for a place for a unit around a start lociacion, returns true if succeded
bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated){
bool freeSpace=false;
//looks for a place for a unit around a start location, returns true if succeded
bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated) {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
bool freeSpace=false;
int size= unit->getType()->getSize();
Field currField= unit->getCurrField();
for(int r=1; r<radius; r++){
for(int i=-r; i<r; ++i){
for(int j=-r; j<r; ++j){
Vec2i pos= Vec2i(i,j)+startLoc;
if(spaciated){
const int spacing= 2;
for(int r = 1; r < radius; r++) {
for(int i = -r; i < r; ++i) {
for(int j = -r; j < r; ++j) {
Vec2i pos= Vec2i(i,j) + startLoc;
if(spaciated) {
const int spacing = 2;
freeSpace= map.isFreeCells(pos-Vec2i(spacing), size+spacing*2, currField);
}
else{
else {
freeSpace= map.isFreeCells(pos, size, currField);
}
if(freeSpace){
if(freeSpace) {
unit->setPos(pos);
unit->setMeetingPos(pos-Vec2i(1));
return true;
@ -510,12 +561,16 @@ bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spacia
}
//clears a unit old position from map and places new position
void World::moveUnitCells(Unit *unit){
void World::moveUnitCells(Unit *unit) {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
Vec2i newPos= unit->getTargetPos();
//newPos must be free or the same pos as current
assert(map.getCell(unit->getPos())->getUnit(unit->getCurrField())==unit || map.isFreeCell(newPos, unit->getCurrField()));
// Only change cell plaement in map if the new position is different
// Only change cell placement in map if the new position is different
// from the old one
if(newPos != unit->getPos()) {
map.clearUnitCells(unit, unit->getPos());
@ -525,10 +580,10 @@ void World::moveUnitCells(Unit *unit){
unit->getFaction()->addCloseResourceTargetToCache(newPos);
//water splash
if(tileset.getWaterEffects() && unit->getCurrField()==fLand){
if(map.getSubmerged(map.getCell(unit->getLastPos()))){
int unitSize=unit->getType()->getSize();
for(int i=0; i<3; ++i){
if(tileset.getWaterEffects() && unit->getCurrField() == fLand) {
if(map.getSubmerged(map.getCell(unit->getLastPos()))) {
int unitSize= unit->getType()->getSize();
for(int i = 0; i < 3; ++i) {
waterEffects.addWaterSplash(
Vec2f(unit->getLastPos().x+(float)unitSize/2.0f+random.randRange(-0.9f, -0.1f), unit->getLastPos().y+random.randRange(-0.9f, -0.1f)+(float)unitSize/2.0f), unit->getType()->getSize());
}
@ -539,29 +594,40 @@ void World::moveUnitCells(Unit *unit){
}
//returns the nearest unit that can store a type of resource given a position and a faction
Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt){
Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt) {
float currDist= infinity;
Unit *currUnit= NULL;
for(int i=0; i<getFaction(factionIndex)->getUnitCount(); ++i){
if(factionIndex >= getFactionCount()) {
throw runtime_error("factionIndex >= getFactionCount()");
}
for(int i=0; i < getFaction(factionIndex)->getUnitCount(); ++i) {
Unit *u= getFaction(factionIndex)->getUnit(i);
float tmpDist= u->getPos().dist(pos);
if(tmpDist<currDist && u->getType()->getStore(rt)>0 && u->isOperative()){
currDist= tmpDist;
currUnit= u;
}
if(u != NULL) {
float tmpDist= u->getPos().dist(pos);
if(tmpDist < currDist && u->getType()->getStore(rt) > 0 && u->isOperative()) {
currDist= tmpDist;
currUnit= u;
}
}
}
return currUnit;
}
bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const{
//a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell
return
visibleQuad.isInside(unit->getPos()) &&
toRenderUnit(unit);
bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
//a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell
return visibleQuad.isInside(unit->getPos()) && toRenderUnit(unit);
}
bool World::toRenderUnit(const Unit *unit) const{
bool World::toRenderUnit(const Unit *unit) const {
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
return
(map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isVisible(thisTeamIndex) &&
@ -571,10 +637,10 @@ bool World::toRenderUnit(const Unit *unit) const{
map.getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->isExplored(thisTeamIndex));
}
void World::createUnit(const string &unitName, int factionIndex, const Vec2i &pos){
void World::createUnit(const string &unitName, int factionIndex, const Vec2i &pos) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitName [%s] factionIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,unitName.c_str(),factionIndex);
if(factionIndex<factions.size()){
if(factionIndex < factions.size()) {
Faction* faction= &factions[factionIndex];
if(faction->getIndex() != factionIndex) {
@ -600,49 +666,47 @@ void World::createUnit(const string &unitName, int factionIndex, const Vec2i &po
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
if(placeUnit(pos, generationArea, unit, true)){
if(placeUnit(pos, generationArea, unit, true)) {
unit->create(true);
unit->born();
scriptManager->onUnitCreated(unit);
}
else{
else {
throw runtime_error("Unit cant be placed");
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
}
else
{
else {
throw runtime_error("Invalid faction index in createUnitAtPosition: " + intToStr(factionIndex));
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void World::giveResource(const string &resourceName, int factionIndex, int amount){
if(factionIndex<factions.size()){
void World::giveResource(const string &resourceName, int factionIndex, int amount) {
if(factionIndex < factions.size()) {
Faction* faction= &factions[factionIndex];
const ResourceType* rt= techTree->getResourceType(resourceName);
faction->incResourceAmount(rt, amount);
}
else
{
else {
throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex));
}
}
void World::givePositionCommand(int unitId, const string &commandName, const Vec2i &pos){
void World::givePositionCommand(int unitId, const string &commandName, const Vec2i &pos) {
Unit* unit= findUnitById(unitId);
if(unit!=NULL){
if(unit != NULL) {
CommandClass cc;
if(commandName=="move"){
if(commandName=="move") {
cc= ccMove;
}
else if(commandName=="attack"){
else if(commandName=="attack") {
cc= ccAttack;
}
else{
else {
throw runtime_error("Invalid position commmand: " + commandName);
}
@ -650,140 +714,158 @@ void World::givePositionCommand(int unitId, const string &commandName, const Vec
unit->giveCommand(new Command( unit->getType()->getFirstCtOfClass(cc), pos ));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
throw runtime_error("Invalid unitId index in givePositionCommand: " + intToStr(unitId) + " commandName = " + commandName);
}
}
void World::giveAttackCommand(int unitId, int unitToAttackId) {
Unit* unit= findUnitById(unitId);
if(unit != NULL){
if(unit != NULL) {
Unit* targetUnit = findUnitById(unitToAttackId);
if(targetUnit != NULL) {
const CommandType *ct= unit->getType()->getFirstAttackCommand(targetUnit->getCurrField());
const CommandType *ct = unit->getType()->getFirstAttackCommand(targetUnit->getCurrField());
if(ct != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Unit [%s] is attacking [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getFullName().c_str(),targetUnit->getFullName().c_str());
unit->giveCommand(new Command(ct,targetUnit));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
throw runtime_error("Invalid ct in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId));
}
}
else {
throw runtime_error("Invalid unitToAttackId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId));
}
}
else {
throw runtime_error("Invalid unitId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId));
}
}
void World::giveProductionCommand(int unitId, const string &producedName){
void World::giveProductionCommand(int unitId, const string &producedName) {
Unit *unit= findUnitById(unitId);
if(unit!=NULL){
if(unit != NULL) {
const UnitType *ut= unit->getType();
//Search for a command that can produce the unit
for(int i= 0; i<ut->getCommandTypeCount(); ++i){
for(int i= 0; i< ut->getCommandTypeCount(); ++i) {
const CommandType* ct= ut->getCommandType(i);
if(ct->getClass()==ccProduce){
if(ct != NULL && ct->getClass() == ccProduce) {
const ProduceCommandType *pct= static_cast<const ProduceCommandType*>(ct);
if(pct->getProducedUnit()->getName()==producedName){
if(pct != NULL && pct->getProducedUnit()->getName() == producedName) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(pct));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
}
}
}
else {
throw runtime_error("Invalid unitId index in giveProductionCommand: " + intToStr(unitId) + " producedName = " + producedName);
}
}
void World::giveUpgradeCommand(int unitId, const string &upgradeName){
void World::giveUpgradeCommand(int unitId, const string &upgradeName) {
Unit *unit= findUnitById(unitId);
if(unit!=NULL){
if(unit != NULL) {
const UnitType *ut= unit->getType();
//Search for a command that can produce the unit
for(int i= 0; i<ut->getCommandTypeCount(); ++i){
for(int i= 0; i < ut->getCommandTypeCount(); ++i) {
const CommandType* ct= ut->getCommandType(i);
if(ct->getClass()==ccUpgrade){
if(ct != NULL && ct->getClass() == ccUpgrade) {
const UpgradeCommandType *uct= static_cast<const UpgradeCommandType*>(ct);
if(uct->getProducedUpgrade()->getName()==upgradeName){
if(uct != NULL && uct->getProducedUpgrade()->getName() == upgradeName) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unit->giveCommand(new Command(uct));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
}
}
}
else {
throw runtime_error("Invalid unitId index in giveUpgradeCommand: " + intToStr(unitId) + " upgradeName = " + upgradeName);
}
}
int World::getResourceAmount(const string &resourceName, int factionIndex){
if(factionIndex<factions.size()){
int World::getResourceAmount(const string &resourceName, int factionIndex) {
if(factionIndex < factions.size()) {
Faction* faction= &factions[factionIndex];
const ResourceType* rt= techTree->getResourceType(resourceName);
return faction->getResource(rt)->getAmount();
}
else
{
throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex));
else {
throw runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex) + " resourceName = " + resourceName);
}
}
Vec2i World::getStartLocation(int factionIndex){
if(factionIndex<factions.size()){
Vec2i World::getStartLocation(int factionIndex) {
if(factionIndex < factions.size()) {
Faction* faction= &factions[factionIndex];
return map.getStartLocation(faction->getStartLocationIndex());
}
else
{
else {
throw runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex));
}
}
Vec2i World::getUnitPosition(int unitId){
Vec2i World::getUnitPosition(int unitId) {
Unit* unit= findUnitById(unitId);
if(unit==NULL){
throw runtime_error("Can not find unit to get position");
if(unit == NULL) {
throw runtime_error("Can not find unit to get position unitId = " + intToStr(unitId));
}
return unit->getPos();
}
int World::getUnitFactionIndex(int unitId){
int World::getUnitFactionIndex(int unitId) {
Unit* unit= findUnitById(unitId);
if(unit==NULL){
throw runtime_error("Can not find unit to get position");
if(unit == NULL) {
throw runtime_error("Can not find Faction unit to get position unitId = " + intToStr(unitId));
}
return unit->getFactionIndex();
}
int World::getUnitCount(int factionIndex){
if(factionIndex<factions.size()){
int World::getUnitCount(int factionIndex) {
if(factionIndex < factions.size()) {
Faction* faction= &factions[factionIndex];
int count= 0;
for(int i= 0; i<faction->getUnitCount(); ++i){
for(int i= 0; i < faction->getUnitCount(); ++i) {
const Unit* unit= faction->getUnit(i);
if(unit->isAlive()){
if(unit != NULL && unit->isAlive()) {
++count;
}
}
return count;
}
else
{
else {
throw runtime_error("Invalid faction index in getUnitCount: " + intToStr(factionIndex));
}
}
int World::getUnitCountOfType(int factionIndex, const string &typeName){
if(factionIndex<factions.size()){
int World::getUnitCountOfType(int factionIndex, const string &typeName) {
if(factionIndex < factions.size()) {
Faction* faction= &factions[factionIndex];
int count= 0;
for(int i= 0; i< faction->getUnitCount(); ++i){
for(int i= 0; i< faction->getUnitCount(); ++i) {
const Unit* unit= faction->getUnit(i);
if(unit->isAlive() && unit->getType()->getName()==typeName){
if(unit != NULL && unit->isAlive() && unit->getType()->getName() == typeName) {
++count;
}
}
return count;
}
else
{
else {
throw runtime_error("Invalid faction index in getUnitCountOfType: " + intToStr(factionIndex));
}
}
@ -793,7 +875,7 @@ int World::getUnitCountOfType(int factionIndex, const string &typeName){
// ==================== private init ====================
//init basic cell state
void World::initCells(bool fogOfWar){
void World::initCells(bool fogOfWar) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Logger::getInstance().add("State cells", true);
@ -801,6 +883,9 @@ void World::initCells(bool fogOfWar){
for(int j=0; j< map.getSurfaceH(); ++j) {
SurfaceCell *sc= map.getSurfaceCell(i, j);
if(sc == NULL) {
throw runtime_error("sc == NULL");
}
sc->setFowTexCoord(Vec2f(
i/(next2Power(map.getSurfaceW())-1.f),
@ -820,22 +905,35 @@ void World::initCells(bool fogOfWar){
}
//init surface textures
void World::initSplattedTextures(){
void World::initSplattedTextures() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i=0; i<map.getSurfaceW()-1; ++i){
for(int j=0; j<map.getSurfaceH()-1; ++j){
for(int i = 0; i < map.getSurfaceW() - 1; ++i) {
for(int j = 0; j < map.getSurfaceH() - 1; ++j) {
Vec2f coord;
const Texture2D *texture=NULL;
SurfaceCell *sc00= map.getSurfaceCell(i, j);
SurfaceCell *sc10= map.getSurfaceCell(i+1, j);
SurfaceCell *sc01= map.getSurfaceCell(i, j+1);
SurfaceCell *sc11= map.getSurfaceCell(i+1, j+1);
tileset.addSurfTex(
sc00->getSurfaceType(),
sc10->getSurfaceType(),
sc01->getSurfaceType(),
sc11->getSurfaceType(),
coord, texture);
if(sc00 == NULL) {
throw runtime_error("sc00 == NULL");
}
if(sc10 == NULL) {
throw runtime_error("sc10 == NULL");
}
if(sc01 == NULL) {
throw runtime_error("sc01 == NULL");
}
if(sc11 == NULL) {
throw runtime_error("sc11 == NULL");
}
tileset.addSurfTex( sc00->getSurfaceType(),
sc10->getSurfaceType(),
sc01->getSurfaceType(),
sc11->getSurfaceType(),
coord, texture);
sc00->setSurfTexCoord(coord);
sc00->setSurfaceTexture(texture);
}
@ -844,11 +942,15 @@ void World::initSplattedTextures(){
}
//creates each faction looking at each faction name contained in GameSettings
void World::initFactionTypes(GameSettings *gs){
void World::initFactionTypes(GameSettings *gs) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Logger::getInstance().add("Faction types", true);
if(gs->getFactionCount() > map.getMaxPlayers()){
if(gs == NULL) {
throw runtime_error("gs == NULL");
}
if(gs->getFactionCount() > map.getMaxPlayers()) {
throw runtime_error("This map only supports "+intToStr(map.getMaxPlayers())+" players");
}
@ -865,9 +967,11 @@ void World::initFactionTypes(GameSettings *gs){
for(int i=0; i < factions.size(); ++i) {
FactionType *ft= techTree->getTypeByName(gs->getFactionTypeName(i));
factions[i].init(
ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i),
gs->getStartLocationIndex(i), i==thisFactionIndex, gs->getDefaultResources());
if(ft == NULL) {
throw runtime_error("ft == NULL");
}
factions[i].init(ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i),
gs->getStartLocationIndex(i), i==thisFactionIndex, gs->getDefaultResources());
stats.setTeam(i, gs->getTeam(i));
stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i)));
@ -885,26 +989,30 @@ void World::initFactionTypes(GameSettings *gs){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void World::initMinimap(){
void World::initMinimap() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
minimap.init(map.getW(), map.getH(), this, game->getGameSettings()->getFogOfWar());
minimap.init(map.getW(), map.getH(), this, game->getGameSettings()->getFogOfWar());
Logger::getInstance().add("Compute minimap surface", true);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
//place units randomly aroud start location
void World::initUnits(){
void World::initUnits() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Logger::getInstance().add("Generate elements", true);
//put starting units
for(int i=0; i<getFactionCount(); ++i){
for(int i = 0; i < getFactionCount(); ++i) {
Faction *f= &factions[i];
const FactionType *ft= f->getType();
for(int j=0; j<ft->getStartingUnitCount(); ++j){
for(int j = 0; j < ft->getStartingUnitCount(); ++j) {
const UnitType *ut= ft->getStartingUnit(j);
int initNumber= ft->getStartingUnitAmount(j);
for(int l=0; l<initNumber; l++){
for(int l = 0; l < initNumber; l++) {
UnitPathInterface *newpath = NULL;
switch(game->getGameSettings()->getPathFinderType()) {
@ -922,11 +1030,11 @@ void World::initUnits(){
int startLocationIndex= f->getStartLocationIndex();
if(placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)){
if(placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)) {
unit->create(true);
unit->born();
}
else{
else {
throw runtime_error("Unit cant be placed, this error is caused because there is no enough place to put the units near its start location, make a better map: "+unit->getType()->getName() + " Faction: "+intToStr(i));
}
if (unit->getType()->hasSkillClass(scBeBuilt)) {
@ -944,7 +1052,7 @@ void World::initUnits(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void World::initMap(){
void World::initMap() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
map.init();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -952,7 +1060,7 @@ void World::initMap(){
// ==================== exploration ====================
void World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex){
void World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex) {
Chrono chrono;
chrono.start();

View File

@ -25,10 +25,29 @@ namespace Shared{ namespace Graphics{ namespace Gl{
class TextureGl {
protected:
GLuint handle;
GLuint renderBufferId;
GLuint frameBufferId;
public:
TextureGl();
GLuint getHandle() const {return handle;}
virtual ~TextureGl();
GLuint getHandle() const {return handle;}
GLuint getRenderBufferHandle() const {return renderBufferId;}
GLuint getFrameBufferHandle() const {return frameBufferId;}
void initRenderBuffer();
void initFrameBuffer();
void attachRenderBuffer();
void attachFrameBufferToTexture();
bool checkFrameBufferStatus();
void dettachFrameBufferFromTexture();
void setup_FBO_RBO();
void teardown_FBO_RBO();
virtual int getTextureWidth() const = 0;
virtual int getTextureHeight() const = 0;
void OutputTextureDebugInfo(Texture::Format format, int components, const string path,uint64 rawSize,GLenum texType);
};
@ -44,6 +63,9 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return Texture1D::getTextureWidth();}
virtual int getTextureHeight() const { return Texture1D::getTextureHeight();}
};
// =====================================================
@ -57,6 +79,9 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return Texture2D::getTextureWidth();}
virtual int getTextureHeight() const { return Texture2D::getTextureHeight();}
};
// =====================================================
@ -71,6 +96,9 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return Texture3D::getTextureWidth();}
virtual int getTextureHeight() const { return Texture3D::getTextureHeight();}
};
// =====================================================
@ -85,6 +113,10 @@ public:
virtual void init(Filter filter, int maxAnisotropy= 1);
virtual void end(bool deletePixelBuffer=true);
virtual int getTextureWidth() const { return TextureCube::getTextureWidth();}
virtual int getTextureHeight() const { return TextureCube::getTextureHeight();}
};
}}}//end namespace

View File

@ -95,7 +95,7 @@ public:
// class Texture1D
// =====================================================
class Texture1D: public Texture{
class Texture1D: public Texture {
protected:
Pixmap1D pixmap;
@ -107,6 +107,10 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return pixmap.getW();}
virtual int getTextureHeight() const {return -1;}
};
// =====================================================
@ -125,13 +129,16 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return pixmap.getW();}
virtual int getTextureHeight() const {return pixmap.getH();}
};
// =====================================================
// class Texture3D
// =====================================================
class Texture3D: public Texture{
class Texture3D: public Texture {
protected:
Pixmap3D pixmap;
@ -143,6 +150,9 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return pixmap.getW();}
virtual int getTextureHeight() const {return pixmap.getH();}
};
// =====================================================
@ -161,6 +171,9 @@ public:
virtual string getPath() const;
virtual void deletePixels();
virtual uint64 getPixelByteCount() const {return pixmap.getPixelByteCount();}
virtual int getTextureWidth() const {return -1;}
virtual int getTextureHeight() const {return -1;}
};
}}//end namespace

View File

@ -421,7 +421,130 @@ GLint toInternalFormatGl(Texture::Format format, int components){
}
TextureGl::TextureGl() {
handle=0;
handle = 0;
renderBufferId = 0;
frameBufferId = 0;
}
void TextureGl::setup_FBO_RBO() {
if(getTextureWidth() < 0 || getTextureHeight() < 0) {
throw runtime_error("getTextureWidth() < 0 || getTextureHeight() < 0");
}
printf("getTextureWidth() = %d, getTextureHeight() = %d\n",getTextureWidth(),getTextureHeight());
GLint width=0;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width);
GLint height=0;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height);
printf("width = %d, height = %d\n",width,height);
//RGBA8 2D texture, 24 bit depth texture, 256x256
//glGenTextures(1, &color_tex);
//glBindTexture(GL_TEXTURE_2D, color_tex);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//NULL means reserve texture memory, but texels are undefined
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
//-------------------------
glGenFramebuffersEXT(1, &frameBufferId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
//Attach 2D texture to this FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0);
//-------------------------
glGenRenderbuffersEXT(1, &renderBufferId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight());
//-------------------------
//Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId);
//-------------------------
//Does the GPU support current FBO configuration?
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
printf("FBO attachment OK!\n");
break;
default:
printf("FBO attachment BAD!\n");
break;
}
//-------------------------
//and now you can render to GL_TEXTURE_2D
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void TextureGl::teardown_FBO_RBO() {
//----------------
//Bind 0, which means render to back buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
//And in the end, cleanup
//Delete resources
//glDeleteTextures(1, &handle);
glDeleteRenderbuffersEXT(1, &frameBufferId);
//Bind 0, which means render to back buffer, as a result, fb is unbound
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &frameBufferId);
}
void TextureGl::initRenderBuffer() {
// create a renderbuffer object to store depth info
glGenRenderbuffersEXT(1, &renderBufferId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight());
//glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
void TextureGl::initFrameBuffer() {
// create a framebuffer object
glGenFramebuffersEXT(1, &frameBufferId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
}
void TextureGl::attachRenderBuffer() {
// attach the renderbuffer to depth attachment point
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId);
}
void TextureGl::attachFrameBufferToTexture() {
// attach the texture to FBO color attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0);
}
bool TextureGl::checkFrameBufferStatus() {
// check FBO status
// Does the GPU support current FBO configuration?
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
printf("checkFrameBufferStatus() status = %d [%X]\n",status,status);
return false;
}
return true;
}
void TextureGl::dettachFrameBufferFromTexture() {
// switch back to window-system-provided framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
TextureGl::~TextureGl() {
if(renderBufferId != 0) {
glDeleteRenderbuffersEXT(1, &renderBufferId);
renderBufferId = 0;
}
if(frameBufferId != 0) {
glDeleteFramebuffersEXT(1, &frameBufferId);
frameBufferId = 0;
}
//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
// =====================================================
@ -492,7 +615,7 @@ void Texture1DGl::init(Filter filter, int maxAnisotropy) {
if(error!=GL_NO_ERROR){
//throw runtime_error("Error creating texture 1D");
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture 1D, returned: %d [%s] w = %d, glCompressionFormat = %d",error,pixmap.getPath().c_str(),pixmap.getW(),glCompressionFormat);
sprintf(szBuf,"Error creating texture 1D, returned: %d (%X) [%s] w = %d, glCompressionFormat = %d",error,error,pixmap.getPath().c_str(),pixmap.getW(),glCompressionFormat);
throw runtime_error(szBuf);
}
}
@ -579,17 +702,15 @@ void Texture2DGl::init(Filter filter, int maxAnisotropy) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(
GL_TEXTURE_2D, 0, glCompressionFormat,
pixmap.getW(), pixmap.getH(),
0, glFormat, GL_UNSIGNED_BYTE, pixels);
GLint error= glGetError();
glTexImage2D(GL_TEXTURE_2D, 0, glCompressionFormat,pixmap.getW(),
pixmap.getH(),0, glFormat, GL_UNSIGNED_BYTE, pixels);
GLint error= glGetError();
//throw runtime_error("TEST!");
if(error != GL_NO_ERROR) {
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture 2D, returned: %d [%s] w = %d, h = %d, glInternalFormat = %d, glFormat = %d, glCompressionFormat = %d",error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),glInternalFormat,glFormat,glCompressionFormat);
sprintf(szBuf,"Error creating texture 2D, returned: %d (%X) [%s] w = %d, h = %d, glInternalFormat = %d, glFormat = %d, glCompressionFormat = %d",error,error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),glInternalFormat,glFormat,glCompressionFormat);
throw runtime_error(szBuf);
}
}
@ -665,7 +786,7 @@ void Texture3DGl::init(Filter filter, int maxAnisotropy) {
if(error != GL_NO_ERROR) {
//throw runtime_error("Error creating texture 3D");
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture 3D, returned: %d [%s] w = %d, h = %d, d = %d, glCompressionFormat = %d",error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),pixmap.getD(),glCompressionFormat);
sprintf(szBuf,"Error creating texture 3D, returned: %d (%X) [%s] w = %d, h = %d, d = %d, glCompressionFormat = %d",error,error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),pixmap.getD(),glCompressionFormat);
throw runtime_error(szBuf);
}
inited= true;
@ -762,7 +883,7 @@ void TextureCubeGl::init(Filter filter, int maxAnisotropy) {
if(error != GL_NO_ERROR) {
//throw runtime_error("Error creating texture cube");
char szBuf[1024]="";
sprintf(szBuf,"Error creating texture cube, returned: %d [%s] w = %d, h = %d, glCompressionFormat = %d",error,currentPixmap->getPath().c_str(),currentPixmap->getW(),currentPixmap->getH(),glCompressionFormat);
sprintf(szBuf,"Error creating texture cube, returned: %d (%X) [%s] w = %d, h = %d, glCompressionFormat = %d",error,error,currentPixmap->getPath().c_str(),currentPixmap->getW(),currentPixmap->getH(),glCompressionFormat);
throw runtime_error(szBuf);
}
@ -798,7 +919,7 @@ void TextureGl::OutputTextureDebugInfo(Texture::Format format, int components,co
glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_COMPRESSED, &compressed);
int error = glGetError();
printf("**** Texture compressed status: %d, error [%d]\n",compressed,error);
printf("**** Texture compressed status: %d, error [%d] (%X)\n",compressed,error,error);
bool isCompressed = (compressed == 1);
compressed=0;
@ -810,12 +931,12 @@ void TextureGl::OutputTextureDebugInfo(Texture::Format format, int components,co
percent = ((double)compressed / (double)rawSize) * (double)100.0;
}
printf("**** Texture image size in video RAM: %d [%.2f%%], error [%d]\n",compressed,percent,error);
printf("**** Texture image size in video RAM: %d [%.2f%%], error [%d] (%X)\n",compressed,percent,error,error);
compressed=0;
glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_INTERNAL_FORMAT, &compressed);
error = glGetError();
printf("**** Texture image compression format used: %d, error [%d]\n",compressed,error);
printf("**** Texture image compression format used: %d, error [%d] (%X)\n",compressed,error,error);
}
}