diff --git a/source/glest_game/ai/ai.cpp b/source/glest_game/ai/ai.cpp index 0656ecda..e1a2af7d 100644 --- a/source/glest_game/ai/ai.cpp +++ b/source/glest_game/ai/ai.cpp @@ -472,7 +472,40 @@ void Ai::massiveAttack(const Vec2i &pos, Field field, bool ultraAttack){ } bool alreadyAttacking= (unit->getCurrSkill()->getClass() == scAttack); - if(!alreadyAttacking && act!=NULL && (ultraAttack || isWarrior)) { + + bool unitSignalledToAttack = false; + if( alreadyAttacking == false && + unit->getType()->hasSkillClass(scAttack) && + (aiInterface->getControlType() == ctCpuUltra || + aiInterface->getControlType() == ctCpuMega || + aiInterface->getControlType() == ctNetworkCpuUltra || + aiInterface->getControlType() == ctNetworkCpuMega)) { + //printf("~~~~~~~~ Unit [%s - %d] checking if unit is being attacked\n",unit->getFullName().c_str(),unit->getId()); + + std::pair beingAttacked = aiInterface->getWorld()->getUnitUpdater()->unitBeingAttacked(unit); + if(beingAttacked.first == true) { + Unit *enemy = beingAttacked.second; + const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField()); + //printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] act_forenemy [%p] enemy->getCurrField() = %d\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId(),act_forenemy,enemy->getCurrField()); + + if(act_forenemy != NULL) { + //printf("~~~~~~~~ Unit [%s - %d] WILL ATTACK [%s - %d]\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId()); + aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos()); + unitSignalledToAttack = true; + } + else { + const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField()); + //printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] asct_forenemy [%p] enemy->getCurrField() = %d\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId(),asct_forenemy,enemy->getCurrField()); + if(asct_forenemy != NULL) { + //printf("~~~~~~~~ Unit [%s - %d] WILL ATTACK [%s - %d]\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId()); + aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos()); + unitSignalledToAttack = true; + } + } + } + } + if(alreadyAttacking == false && act!=NULL && (ultraAttack || isWarrior) && + unitSignalledToAttack == false) { aiInterface->giveCommand(i, act, pos); } } diff --git a/source/glest_game/ai/ai_interface.h b/source/glest_game/ai/ai_interface.h index 511d4e39..e34c3f4f 100644 --- a/source/glest_game/ai/ai_interface.h +++ b/source/glest_game/ai/ai_interface.h @@ -95,6 +95,7 @@ public: bool isFreeCells(const Vec2i &pos, int size, Field field); const Unit *getFirstOnSightEnemyUnit(Vec2i &pos, Field &field, int radius); Map * getMap(); + World * getWorld() { return world; } private: string getLogFilename() const {return "ai"+intToStr(factionIndex)+".log";} diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 394e3219..199197da 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -43,6 +43,7 @@ Game *thisGamePtr = NULL; const float PHOTO_MODE_MAXHEIGHT = 500.0; Game::Game() : ProgramState(NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); originalDisplayMsgCallback = NULL; aiInterfaces.clear(); } @@ -50,6 +51,7 @@ Game::Game() : ProgramState(NULL) { Game::Game(Program *program, const GameSettings *gameSettings): ProgramState(program), lastMousePos(0), isFirstRender(true) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); this->program = program; @@ -102,6 +104,7 @@ Game::Game(Program *program, const GameSettings *gameSettings): } Game::~Game() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Object::setStateCallback(NULL); @@ -156,6 +159,7 @@ Game::~Game() { //this->program->reInitGl(); //renderer.reinitAll(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } bool Game::quitTriggered() { @@ -2172,4 +2176,8 @@ Vec2i Game::getPerformanceTimerResults() { return results; } +void Game::consoleAddLine(string line) { + console.addLine(line); +} + }}//end namespace diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 04bdd90b..6b1c73bd 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -180,6 +180,7 @@ public: bool getGameOver() { return gameOver; } bool hasGameStarted() { return gameStarted;} virtual vector processTech(string techName); + virtual void consoleAddLine(string line); private: //render diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 15e24902..a1a1803e 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -140,6 +140,8 @@ const Vec4f Renderer::defColor= Vec4f(1.f, 1.f, 1.f, 1.f); //const float Renderer::maxLightDist= 100.f; const float Renderer::maxLightDist= 1000.f; +bool Renderer::rendererEnded = true; + const int MIN_FPS_NORMAL_RENDERING = 15; const int MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD = 25; @@ -148,6 +150,7 @@ const int OBJECT_SELECT_OFFSET=100000000; // ==================== constructor and destructor ==================== Renderer::Renderer() { + Renderer::rendererEnded = false; this->allowRenderUnitTitles = false; this->menu = NULL; this->game = NULL; @@ -277,7 +280,11 @@ void Renderer::simpleTask(BaseThread *callingThread) { } } -Renderer &Renderer::getInstance(){ +bool Renderer::isEnded() { + return Renderer::rendererEnded; +} + +Renderer &Renderer::getInstance() { static Renderer renderer; return renderer; } @@ -438,6 +445,9 @@ void Renderer::reset3dMenu() { // ==================== end ==================== void Renderer::end() { + if(Renderer::rendererEnded == true) { + return; + } std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); crcFactionPreviewTextureCache.clear(); @@ -465,6 +475,8 @@ void Renderer::end() { glDeleteLists(list2d, 1); list2d = 0; } + + Renderer::rendererEnded = true; } void Renderer::endGame() { diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index f0f7556a..b1f102b8 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -278,13 +278,14 @@ private: VisibleQuadContainerVBOCache * GetSurfaceVBOs(SurfaceData *cellData); void ReleaseSurfaceVBOs(); std::map > > mapSurfaceData; - + static bool rendererEnded; private: Renderer(); ~Renderer(); public: static Renderer &getInstance(); + static bool isEnded(); void reinitAll(); diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index bfed3b50..81363489 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -82,6 +82,9 @@ namespace Glest{ namespace Game{ bool disableBacktrace = false; bool gameInitialized = false; static char *application_binary=NULL; +static string mg_app_name = ""; +static string mailStringSupport = ""; +static bool sdl_quitCalled = false; FileCRCPreCacheThread *preCacheThread=NULL; @@ -136,27 +139,45 @@ enum GAME_ARG_TYPE { string runtimeErrorMsg = ""; -static void cleanupProcessObjects() { - showCursor(true); - restoreVideoMode(true); - +void cleanupCRCThread() { if(preCacheThread != NULL) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); time_t elapsed = time(NULL); preCacheThread->signalQuit(); for(;preCacheThread->canShutdown(false) == false && - difftime(time(NULL),elapsed) <= 15;) { + difftime(time(NULL),elapsed) <= 45;) { //sleep(150); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - sleep(25); + if(preCacheThread->canShutdown(true)) { + delete preCacheThread; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + preCacheThread = NULL; + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //sleep(25); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +static void cleanupProcessObjects() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + showCursor(true); + restoreVideoMode(true); + + cleanupCRCThread(); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(Renderer::isEnded() == false) Renderer::getInstance().end(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Renderer::getInstance().end(); SystemFlags::Close(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::SHUTDOWN_PROGRAM_MODE=true; } @@ -170,7 +191,7 @@ void fatal(const char *s, ...) // failure exit defvformatstring(msg,s,s); string errText = string(msg) + " [" + runtimeErrorMsg + "]"; //puts(msg); - string sErr = string(GameConstants::application_name) + " fatal error"; + string sErr = string(mg_app_name) + " fatal error"; SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",errText.c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",errText.c_str()); @@ -193,7 +214,10 @@ void fatal(const char *s, ...) // failure exit program = NULL; // END - SDL_Quit(); + if(sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } exit(EXIT_FAILURE); } @@ -202,7 +226,7 @@ void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) { EXCEPTION_RECORD *er = ep->ExceptionRecord; CONTEXT *context = ep->ContextRecord; stringType out, t; - formatstring(out)("%s Exception: 0x%x [0x%x]\n\n", GameConstants::application_name, er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1); + formatstring(out)("%s Exception: 0x%x [0x%x]\n\n", mg_app_name, er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1); STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0}; SymInitialize(GetCurrentProcess(), NULL, TRUE); @@ -230,7 +254,7 @@ void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) { class ExceptionHandler: public PlatformExceptionHandler{ public: virtual void handle() { - string msg = "#1 An error occurred and " + string(GameConstants::application_name) + " will close.\nPlease report this bug to "+mailString; + string msg = "#1 An error occurred and " + string(mg_app_name) + " will close.\nPlease report this bug to "+mailString; #ifdef WIN32 msg += ", attaching the generated " + getCrashDumpFileName()+ " file."; #endif @@ -294,19 +318,19 @@ public: #endif static void handleRuntimeError(const char *msg) { - //printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized); - + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Program *program = Program::getInstance(); - //printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized); - + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n",__FILE__,__FUNCTION__,__LINE__,program,gameInitialized,msg); SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,program); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,program); string errMsg = (msg != NULL ? msg : "null"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) - if(disableBacktrace == false) { + if(disableBacktrace == false && sdl_quitCalled == false) { errMsg += "\nStack Trace:\n"; //errMsg += "To find line #'s use:\n"; //errMsg += "readelf --debug-dump=decodedline %s | egrep 0xaddress-of-stack\n"; @@ -319,7 +343,7 @@ public: // errMsg += string(stack_strings[i]) + "\n"; //} - //printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); char szBuf[4096]=""; for(size_t i = 1; i < stack_depth; i++) { @@ -387,11 +411,13 @@ public: } #endif - //printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(program && gameInitialized == true) { //printf("\nprogram->getState() [%p]\n",program->getState()); if(program->getState() != NULL) { @@ -412,22 +438,33 @@ public: } } else { - string err = "#2 An error occurred and " + - string(GameConstants::application_name) + - " will close.\nError msg = [" + - errMsg + - "]\n\nPlease report this bug to "+mailString; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + string err = "#2 An error occurred and "; + if(sdl_quitCalled == false) { + err += mg_app_name; + } + err += " will close.\nError msg = [" + errMsg + "]\n\nPlease report this bug to "; + if(sdl_quitCalled == false) { + err += mailStringSupport; + } #ifdef WIN32 err += string(", attaching the generated ") + getCrashDumpFileName() + string(" file."); #endif + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + message(err); } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // Now try to shutdown threads if possible delete program; program = NULL; // END + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + #ifdef WIN32 showCursor(true); @@ -438,22 +475,41 @@ public: #endif //printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + cleanupProcessObjects(); - SDL_Quit(); - exit(-1); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + abort(); } static int DisplayMessage(const char *msg, bool exitApp) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); Program *program = Program::getInstance(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); + if(program && gameInitialized == true) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); program->showMessage(msg); } else { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); message(msg); } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); + if(exitApp == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg); @@ -463,11 +519,17 @@ public: program = NULL; // END + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); cleanupProcessObjects(); - SDL_Quit(); + + if(sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } exit(-1); } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); return 0; } }; @@ -492,8 +554,10 @@ MainWindow::MainWindow(Program *program){ } MainWindow::~MainWindow(){ + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete program; program = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MainWindow::eventMouseDown(int x, int y, MouseButton mouseButton){ @@ -734,6 +798,16 @@ void MainWindow::eventKeyDown(char key){ path += string("screen") + intToStr(i + queueSize) + string(".") + fileFormat; FILE *f= fopen(path.c_str(), "rb"); if(f == NULL) { + Lang &lang= Lang::getInstance(); + char szBuf[1024]=""; + if(lang.get("ScreenshotSavedTo").length() > 0 && lang.get("ScreenshotSavedTo")[0] != '?') { + sprintf(szBuf,lang.get("ScreenshotSavedTo").c_str(),path.c_str()); + } + else { + sprintf(szBuf,"Screenshot will be saved to: %s",path.c_str()); + } + program->consoleAddLine(szBuf); + Renderer::getInstance().saveScreen(path); break; } @@ -1643,6 +1717,8 @@ int glestMain(int argc, char** argv) { AllocRegistry memoryLeaks = AllocRegistry::getInstance(); #endif + mg_app_name = GameConstants::application_name; + mailStringSupport = mailString; SystemFlags::ENABLE_THREADED_LOGGING = false; disableBacktrace = false; bool foundInvalidArgs = false; @@ -2133,19 +2209,9 @@ int glestMain(int argc, char** argv) { // } } - if(preCacheThread != NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__); - time_t elapsed = time(NULL); - preCacheThread->signalQuit(); - for(;preCacheThread->canShutdown(false) == false && - difftime(time(NULL),elapsed) <= 15;) { - //sleep(150); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - sleep(25); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } + cleanupCRCThread(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); showCursor(true); @@ -2165,21 +2231,24 @@ int glestMain(int argc, char** argv) { ExceptionHandler::handleRuntimeError("Unknown error!"); } + cleanupCRCThread(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete mainWindow; mainWindow = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //showCursor(true); //restoreVideoMode(true); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); GraphicComponent::clearRegisteredComponents(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return 0; @@ -2199,8 +2268,18 @@ __try { #endif int result = glestMain(argc, argv); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); cleanupProcessObjects(); - SDL_Quit(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return result; #ifdef WIN32_STACK_TRACE diff --git a/source/glest_game/main/program.cpp b/source/glest_game/main/program.cpp index 2796f49f..bcd593a0 100644 --- a/source/glest_game/main/program.cpp +++ b/source/glest_game/main/program.cpp @@ -157,20 +157,29 @@ void Program::initScenario(WindowGl *window, string autoloadScenarioName) { } Program::~Program(){ + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete programState; programState = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + Renderer::getInstance().end(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //restore video mode restoreDisplaySettings(); singleton = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(soundThreadManager != NULL) { BaseThread::shutdownAndWait(soundThreadManager); delete soundThreadManager; soundThreadManager = NULL; } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void Program::keyDown(char key){ @@ -615,4 +624,11 @@ void Program::reInitGl() { window->initGl(config.getInt("ColorBits"), config.getInt("DepthBits"), config.getInt("StencilBits"),config.getBool("HardwareAcceleration","false"),config.getBool("FullScreenAntiAliasing","false")); } } + +void Program::consoleAddLine(string line) { + if(programState != NULL) { + programState->consoleAddLine(line); + } +} + }}//end namespace diff --git a/source/glest_game/main/program.h b/source/glest_game/main/program.h index e6953e9e..b18e5d05 100644 --- a/source/glest_game/main/program.h +++ b/source/glest_game/main/program.h @@ -86,6 +86,7 @@ public: virtual Stats quitAndToggleState() { return Stats(); }; virtual Program * getProgram() { return program; } virtual void setForceMouseRender(bool value) { forceMouseRender=value;} + virtual void consoleAddLine(string line) { }; }; // =============================== @@ -172,6 +173,8 @@ public: void stopSoundSystem(); void startSoundSystem(); + virtual void consoleAddLine(string line); + private: void setDisplaySettings(); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index f5d5c6dd..67040fc3 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -49,6 +49,7 @@ struct FormatString { MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, bool openNetworkSlots,bool parentMenuIsMasterserver, bool autostart) : MenuState(program, mainMenu, "new-game") { + forceWaitForShutdown = true; this->autostart = autostart; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] autostart = %d\n",__FILE__,__FUNCTION__,__LINE__,autostart); @@ -561,8 +562,22 @@ void MenuStateCustomGame::cleanup() { publishToMasterserverThread->setThreadOwnerValid(false); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(publishToMasterserverThread->canShutdown(true) == true && - publishToMasterserverThread->shutdownAndWait() == true) { + + if(forceWaitForShutdown == true) { + time_t elapsed = time(NULL); + publishToMasterserverThread->signalQuit(); + for(;publishToMasterserverThread->canShutdown(false) == false && + difftime(time(NULL),elapsed) <= 15;) { + //sleep(150); + } + if(publishToMasterserverThread->canShutdown(true)) { + delete publishToMasterserverThread; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + publishToMasterserverThread = NULL; + } + else if(publishToMasterserverThread->canShutdown(true) == true && + publishToMasterserverThread->shutdownAndWait() == true) { //printf("IN MenuStateCustomGame cleanup - C\n"); delete publishToMasterserverThread; } @@ -577,15 +592,20 @@ void MenuStateCustomGame::cleanup() { cleanupMapPreviewTexture(); + if(forceWaitForShutdown == true) { + NetworkManager::getInstance().end(); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); } MenuStateCustomGame::~MenuStateCustomGame() { - //printf("IN MenuStateCustomGame Destructor - A\n"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); cleanup(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MenuStateCustomGame::returnToParentMenu() { @@ -608,6 +628,7 @@ void MenuStateCustomGame::returnToParentMenu() { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + forceWaitForShutdown = false; if(returnToMasterServerMenu) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); cleanup(); @@ -1033,6 +1054,7 @@ void MenuStateCustomGame::PlayNow() { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); saveGameSettingsToFile("lastCustomGamSettings.mgg"); + forceWaitForShutdown = false; closeUnusedSlots(); CoreData &coreData= CoreData::getInstance(); SoundRenderer &soundRenderer= SoundRenderer::getInstance(); @@ -1176,6 +1198,7 @@ void MenuStateCustomGame::PlayNow() { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); cleanup(); Game *newGame = new Game(program, &gameSettings); + forceWaitForShutdown = false; program->setState(newGame); return; } diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index 0e12f87f..04cc48b3 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -153,6 +153,8 @@ private: int32 lastCheckedCRCMapValue; vector > factionCRCList; + bool forceWaitForShutdown; + public: MenuStateCustomGame(Program *program, MainMenu *mainMenu ,bool openNetworkSlots= false, bool parentMenuIsMasterserver=false, bool autostart=false); virtual ~MenuStateCustomGame(); diff --git a/source/glest_game/network/network_manager.cpp b/source/glest_game/network/network_manager.cpp index 77215023..f73f3156 100644 --- a/source/glest_game/network/network_manager.cpp +++ b/source/glest_game/network/network_manager.cpp @@ -27,6 +27,7 @@ NetworkManager &NetworkManager::getInstance(){ } NetworkManager::NetworkManager() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); gameNetworkInterface= NULL; @@ -36,6 +37,7 @@ NetworkManager::NetworkManager() { } void NetworkManager::init(NetworkRole networkRole, bool publishEnabled) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,networkRole,gameNetworkInterface); assert(gameNetworkInterface==NULL); @@ -57,6 +59,7 @@ void NetworkManager::init(NetworkRole networkRole, bool publishEnabled) { } void NetworkManager::end() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); //printf("==========] DELETING gameNetworkInterface [%p]\n",gameNetworkInterface); @@ -65,6 +68,7 @@ void NetworkManager::end() { gameNetworkInterface= NULL; networkRole= nrIdle; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); } @@ -75,7 +79,7 @@ void NetworkManager::update() { } bool NetworkManager::isNetworkGame() { - return networkRole==nrClient || getServerInterface()->getConnectedSlotCount()>0; + return networkRole==nrClient || (networkRole==nrServer && getServerInterface()->getConnectedSlotCount()>0); } GameNetworkInterface* NetworkManager::getGameNetworkInterface(bool throwErrorOnNull) { diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index 32190ad8..345af882 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -537,14 +537,44 @@ const HarvestCommandType *UnitType::getFirstHarvestCommand(const ResourceType *r } const AttackCommandType *UnitType::getFirstAttackCommand(Field field) const{ - for(int i=0; igetName().c_str(),(int)commandTypes.size()); + + for(int i = 0; i < commandTypes.size(); ++i){ + if(commandTypes[i] == NULL) { + throw runtime_error("commandTypes[i] == NULL"); + } + + //printf("$$$ Unit [%s] i = %d, commandTypes[i] [%s]\n",this->getName().c_str(),(int)i, commandTypes[i]->toString().c_str()); if(commandTypes[i]->getClass()== ccAttack){ - const AttackCommandType *act= static_cast(commandTypes[i]); - if(act->getAttackSkillType()->getAttackField(field)){ + const AttackCommandType *act= dynamic_cast(commandTypes[i]); + if(act->getAttackSkillType()->getAttackField(field)) { + //printf("## Unit [%s] i = %d, is found\n",this->getName().c_str(),(int)i); return act; } } } + + return NULL; +} + +const AttackStoppedCommandType *UnitType::getFirstAttackStoppedCommand(Field field) const{ + //printf("$$$ Unit [%s] commandTypes.size() = %d\n",this->getName().c_str(),(int)commandTypes.size()); + + for(int i = 0; i < commandTypes.size(); ++i){ + if(commandTypes[i] == NULL) { + throw runtime_error("commandTypes[i] == NULL"); + } + + //printf("$$$ Unit [%s] i = %d, commandTypes[i] [%s]\n",this->getName().c_str(),(int)i, commandTypes[i]->toString().c_str()); + if(commandTypes[i]->getClass()== ccAttackStopped){ + const AttackStoppedCommandType *act= dynamic_cast(commandTypes[i]); + if(act->getAttackSkillType()->getAttackField(field)) { + //printf("## Unit [%s] i = %d, is found\n",this->getName().c_str(),(int)i); + return act; + } + } + } + return NULL; } diff --git a/source/glest_game/types/unit_type.h b/source/glest_game/types/unit_type.h index 649b9747..5e0f5667 100644 --- a/source/glest_game/types/unit_type.h +++ b/source/glest_game/types/unit_type.h @@ -180,6 +180,7 @@ public: const CommandType *getFirstCtOfClass(CommandClass commandClass) const; const HarvestCommandType *getFirstHarvestCommand(const ResourceType *resourceType,const Faction *faction) const; const AttackCommandType *getFirstAttackCommand(Field field) const; + const AttackStoppedCommandType *getFirstAttackStoppedCommand(Field field) const; const RepairCommandType *getFirstRepairCommand(const UnitType *repaired) const; //get totals diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 7d710884..d4974f7f 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -518,7 +518,7 @@ void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) { Command *command= unit->getCurrCommand(); const AttackStoppedCommandType *asct= static_cast(command->getCommandType()); - Unit *enemy; + Unit *enemy=NULL; if(unit->getCommandSize() > 1) { @@ -526,7 +526,14 @@ void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) { return; } - if(attackableOnRange(unit, &enemy, asct->getAttackSkillType())){ + float distToUnit=-1; + std::pair result = make_pair(false,(Unit *)NULL); + unitBeingAttacked(result, unit, asct->getAttackSkillType(), &distToUnit); + if(result.first == true) { + unit->setCurrSkill(asct->getAttackSkillType()); + unit->setTarget(result.second); + } + else if(attackableOnRange(unit, &enemy, asct->getAttackSkillType())) { unit->setCurrSkill(asct->getAttackSkillType()); unit->setTarget(enemy); } @@ -537,6 +544,53 @@ void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); } +void UnitUpdater::unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast, float *currentDistToUnit) { + //std::pair result = make_pair(false,(Unit *)NULL); + + float distToUnit = -1; + if(currentDistToUnit != NULL) { + distToUnit = *currentDistToUnit; + } + if(ast != NULL) { + vector enemies = enemyUnitsOnRange(unit,ast); + for(unsigned j = 0; j < enemies.size(); ++j) { + Unit *enemy = enemies[j]; + + //printf("~~~~~~~~ Unit [%s - %d] enemy # %d found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),j,enemy->getFullName().c_str(),enemy->getId(),unit->getCenteredPos().dist(enemy->getCenteredPos())); + + if(distToUnit < 0 || unit->getCenteredPos().dist(enemy->getCenteredPos()) < distToUnit) { + distToUnit = unit->getCenteredPos().dist(enemy->getCenteredPos()); + result.first = true; + result.second = enemy; + } + } + } + + if(currentDistToUnit != NULL) { + *currentDistToUnit = distToUnit; + } + +// if(result.first == true) { +// printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),result.second->getFullName().c_str(),result.second->getId(),distToUnit); +// } + //return result; +} + +std::pair UnitUpdater::unitBeingAttacked(const Unit *unit) { + std::pair result = make_pair(false,(Unit *)NULL); + + float distToUnit = -1; + for(unsigned int i = 0; i < unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *st = unit->getType()->getSkillType(i); + const AttackSkillType *ast = dynamic_cast(st); + unitBeingAttacked(result, unit, ast, &distToUnit); + } + +// if(result.first == true) { +// printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),result.second->getFullName().c_str(),result.second->getId(),distToUnit); +// } + return result; +} // ==================== updateBuild ==================== @@ -1957,21 +2011,28 @@ bool UnitUpdater::unitOnRange(const Unit *unit, int range, Unit **rangedPtr, } //attack enemies that can attack first + float distToUnit=-1; Unit* enemySeen = NULL; for(int i = 0; i< enemies.size(); ++i) { - if(enemies[i]->isAlive() == true) { + Unit *enemy = enemies[i]; + + if(enemy->isAlive() == true) { // Here we default to first enemy if no attackers found if(enemySeen == NULL) { - *rangedPtr = enemies[i]; - enemySeen = enemies[i]; + *rangedPtr = enemy; + enemySeen = enemy; result = true; } // Attackers get first priority - if(enemies[i]->getType()->hasSkillClass(scAttack) == true) { - *rangedPtr = enemies[i]; - enemySeen = enemies[i]; - result = true; - break; + if(enemy->getType()->hasSkillClass(scAttack) == true) { + // Select closest attacking unit + if(distToUnit < 0 || unit->getCenteredPos().dist(enemy->getCenteredPos()) < distToUnit) { + distToUnit = unit->getCenteredPos().dist(enemy->getCenteredPos()); + *rangedPtr = enemies[i]; + enemySeen = enemies[i]; + result = true; + } + //break; } } } @@ -2080,6 +2141,60 @@ bool UnitUpdater::unitOnRange(const Unit *unit, int range, Unit **rangedPtr, return result; } + +//if the unit has any enemy on range +vector UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast) { + int range = unit->getType()->getSight(); + if(ast != NULL) { + range = ast->getTotalAttackRange(unit->getTotalUpgrade()); + } + vector enemies; + //we check command target + const Unit *commandTarget = NULL; +// if(unit->anyCommand()) { +// commandTarget = static_cast(unit->getCurrCommand()->getUnit()); +// } +// if(commandTarget != NULL && commandTarget->isDead()) { +// commandTarget = NULL; +// } + + //aux vars + int size = unit->getType()->getSize(); + Vec2i center = unit->getPos(); + Vec2f floatCenter = unit->getFloatCenteredPos(); + + bool foundInCache = true; + if(findCachedCellsEnemies(center,range,size,enemies,ast, + unit,commandTarget) == false) { + foundInCache = false; + //nearby cells + UnitRangeCellsLookupItem cacheItem; + for(int i = center.x - range; i < center.x + range + size; ++i) { + for(int j = center.y - range; j < center.y + range + size; ++j) { + //cells inside map and in range +#ifdef USE_STREFLOP + if(map->isInside(i, j) && streflop::floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ +#else + if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ +#endif + Cell *cell = map->getCell(i,j); + findEnemiesForCell(ast,cell,unit,commandTarget,enemies); + + cacheItem.rangeCellList.push_back(cell); + } + } + } + + // Ok update our caches with the latest info + if(cacheItem.rangeCellList.size() > 0) { + //cacheItem.UnitRangeCellsLookupItemCacheTimerCountIndex = UnitRangeCellsLookupItemCacheTimerCount++; + UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; + } + } + + return enemies; +} + // ===================================================== // class ParticleDamager // ===================================================== diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index 84db329a..0e30c1ff 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -115,6 +115,10 @@ public: void clearUnitPrecache(Unit *unit); unsigned int getAttackWarningCount() const { return attackWarnings.size(); } + std::pair unitBeingAttacked(const Unit *unit); + void unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast,float *currentDistToUnit=NULL); + vector enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast); + private: //attack diff --git a/source/shared_lib/include/platform/common/simple_threads.h b/source/shared_lib/include/platform/common/simple_threads.h index 588f45cc..8e0fe395 100644 --- a/source/shared_lib/include/platform/common/simple_threads.h +++ b/source/shared_lib/include/platform/common/simple_threads.h @@ -125,13 +125,13 @@ protected: public: LogFileThread(); + virtual ~LogFileThread(); virtual void execute(); void addLogEntry(SystemFlags::DebugType type, string logEntry); std::size_t getLogEntryBufferCount(); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); }; - - }}//end namespace #endif diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index ba9c921c..b8663f90 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -119,12 +119,16 @@ void FileCRCPreCacheThread::execute() { workerThread->start(); consumedWorkers += currentWorkerMax; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Spawning CRC thread, preCacheWorkerThreadList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,(int)preCacheWorkerThreadList.size()); + if(consumedWorkers >= techPaths.size()) { break; } } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Waiting for Spawned CRC threads to complete = preCacheWorkerThreadList.size()\n",__FILE__,__FUNCTION__,__LINE__,(int)preCacheWorkerThreadList.size()); + sleep(0); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Waiting for Spawned CRC threads to complete, preCacheWorkerThreadList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,(int)preCacheWorkerThreadList.size()); bool hasRunningWorkerThread = true; for(;hasRunningWorkerThread == true;) { hasRunningWorkerThread = false; @@ -137,11 +141,13 @@ void FileCRCPreCacheThread::execute() { if(workerThread->getRunningStatus() == true) { hasRunningWorkerThread = true; - if(getQuitStatus() == true) { + if(getQuitStatus() == true && + workerThread->getQuitStatus() == false) { workerThread->signalQuit(); } } else if(workerThread->getRunningStatus() == false) { + sleep(10); delete workerThread; preCacheWorkerThreadList[idx] = NULL; } @@ -211,7 +217,8 @@ void FileCRCPreCacheThread::execute() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] FILE CRC PreCache thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] FILE CRC PreCache thread is exiting, getDeleteSelfOnExecutionDone() = %d\n",__FILE__,__FUNCTION__,__LINE__,getDeleteSelfOnExecutionDone()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] FILE CRC PreCache thread is exiting, getDeleteSelfOnExecutionDone() = %d\n",__FILE__,__FUNCTION__,__LINE__,getDeleteSelfOnExecutionDone()); } deleteSelfIfRequired(); } @@ -378,11 +385,18 @@ bool SimpleTaskThread::getTaskSignalled() { LogFileThread::LogFileThread() : BaseThread() { logList.clear(); lastSaveToDisk = time(NULL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + mutexLogList.setOwnerId(mutexOwnerId); +} + +LogFileThread::~LogFileThread() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 In [%s::%s Line: %d] LogFile thread is deleting\n",__FILE__,__FUNCTION__,__LINE__); } void LogFileThread::addLogEntry(SystemFlags::DebugType type, string logEntry) { static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(&mutexLogList,mutexOwnerId); + mutexLogList.setOwnerId(mutexOwnerId); LogFileEntry entry; entry.type = type; entry.entry = logEntry; @@ -398,7 +412,6 @@ bool LogFileThread::checkSaveCurrentLogBufferToDisk() { bool ret = false; if(difftime(time(NULL),lastSaveToDisk) >= 5 || LogFileThread::getLogEntryBufferCount() >= 1000000) { - //LogFileThread::getLogEntryBufferCount() >= 10000) { lastSaveToDisk = time(NULL); ret = true; } @@ -409,6 +422,7 @@ void LogFileThread::execute() { bool mustDeleteSelf = false; { RunningStatusSafeWrapper runningStatus(this); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(getQuitStatus() == true) { @@ -416,9 +430,11 @@ void LogFileThread::execute() { return; } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"LogFile thread is running\n"); try { + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); for(;this->getQuitStatus() == false;) { while(this->getQuitStatus() == false && checkSaveCurrentLogBufferToDisk() == true) { @@ -430,7 +446,9 @@ void LogFileThread::execute() { } // Ensure remaining entryies are logged to disk on shutdown + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); saveToDisk(true,false); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } catch(const exception &ex) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); @@ -439,28 +457,43 @@ void LogFileThread::execute() { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is starting to exit\n",__FILE__,__FUNCTION__,__LINE__); mustDeleteSelf = getDeleteSelfOnExecutionDone(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is exiting, mustDeleteSelf = %d\n",__FILE__,__FUNCTION__,__LINE__,mustDeleteSelf); } if(mustDeleteSelf == true) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is deleting self\n",__FILE__,__FUNCTION__,__LINE__); delete this; + return; } } std::size_t LogFileThread::getLogEntryBufferCount() { static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(&mutexLogList,mutexOwnerId); + mutexLogList.setOwnerId(mutexOwnerId); std::size_t logCount = logList.size(); safeMutex.ReleaseLock(); return logCount; } +bool LogFileThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if(ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + signalQuit(); + } + + return ret; +} + void LogFileThread::saveToDisk(bool forceSaveAll,bool logListAlreadyLocked) { static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(NULL,mutexOwnerId); if(logListAlreadyLocked == false) { safeMutex.setMutex(&mutexLogList); + mutexLogList.setOwnerId(mutexOwnerId); } std::size_t logCount = logList.size(); @@ -480,7 +513,14 @@ void LogFileThread::saveToDisk(bool forceSaveAll,bool logListAlreadyLocked) { } safeMutex.Lock(); - logList.erase(logList.begin(),logList.begin() + logCount); + if(logList.size() > 0) { + if(logList.size() <= logCount) { + char szBuf[1024]=""; + sprintf(szBuf,"logList.size() <= logCount [%lld][%lld]",(long long int)logList.size(),(long long int)logCount); + throw runtime_error(szBuf); + } + logList.erase(logList.begin(),logList.begin() + logCount); + } safeMutex.ReleaseLock(); } } diff --git a/source/shared_lib/sources/platform/posix/miniftpserver.cpp b/source/shared_lib/sources/platform/posix/miniftpserver.cpp index ac4b0866..42e3be88 100644 --- a/source/shared_lib/sources/platform/posix/miniftpserver.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpserver.cpp @@ -67,12 +67,16 @@ FTPServerThread::FTPServerThread(std::pair mapsPath, } FTPServerThread::~FTPServerThread() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); ftpShutdown(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); // Remove any UPNP port forwarded ports UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort()); for(int clientIndex = 1; clientIndex <= maxPlayers; ++clientIndex) { UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort() + clientIndex); } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void FTPServerThread::signalQuit() { @@ -227,6 +231,7 @@ void FTPServerThread::execute() { } if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] FTP Server thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] FTP Server thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); } } diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index 8b2a95c4..94fa2123 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -69,7 +69,7 @@ bool SystemFlags::getThreadedLoggerRunning() { std::size_t SystemFlags::getLogEntryBufferCount() { std::size_t ret = 0; - if(threadLogger != NULL) { + if(threadLogger != NULL && threadLogger->getRunningStatus() == true) { ret = threadLogger->getLogEntryBufferCount(); } return ret; @@ -187,7 +187,18 @@ CURL *SystemFlags::initHTTP() { SystemFlags::SystemFlagsType & SystemFlags::getSystemSettingType(DebugType type) { if(SystemFlags::debugLogFileList == NULL) { - SystemFlags::init(false); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { + //throw runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n",__FILE__,__FUNCTION__,__LINE__); + static SystemFlagsType *result = new SystemFlagsType(); + result->enabled = SystemFlags::VERBOSE_MODE_ENABLED; + return *result; + } + else { + SystemFlags::init(false); + } } return (*debugLogFileList)[type]; @@ -195,8 +206,15 @@ SystemFlags::SystemFlagsType & SystemFlags::getSystemSettingType(DebugType type) void SystemFlags::init(bool haveSpecialOutputCommandLineOption) { SystemFlags::haveSpecialOutputCommandLineOption = haveSpecialOutputCommandLineOption; - //if(SystemFlags::debugLogFileList.size() == 0) { if(SystemFlags::debugLogFileList == NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { + //throw runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n",__FILE__,__FUNCTION__,__LINE__); + return; + } + SystemFlags::debugLogFileList = new std::map(); (*SystemFlags::debugLogFileList)[SystemFlags::debugSystem] = SystemFlags::SystemFlagsType(SystemFlags::debugSystem); @@ -211,6 +229,7 @@ void SystemFlags::init(bool haveSpecialOutputCommandLineOption) { } if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == false) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); threadLogger = new LogFileThread(); threadLogger->start(); sleep(1); @@ -219,7 +238,7 @@ void SystemFlags::init(bool haveSpecialOutputCommandLineOption) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); if(curl_handle == NULL) { - + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); curl_handle = SystemFlags::initHTTP(); @@ -265,20 +284,40 @@ void SystemFlags::cleanupHTTP(CURL **handle, bool globalCleanup) { SystemFlags::~SystemFlags() { SystemFlags::Close(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(curl_handle != NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::cleanupHTTP(&curl_handle, true); curl_handle = NULL; } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void SystemFlags::Close() { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(threadLogger != NULL) { SystemFlags::ENABLE_THREADED_LOGGING = false; //SystemFlags::SHUTDOWN_PROGRAM_MODE=true; + time_t elapsed = time(NULL); threadLogger->signalQuit(); - threadLogger->shutdownAndWait(); - delete threadLogger; - threadLogger = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //threadLogger->shutdownAndWait(); + for(;threadLogger->canShutdown(false) == false && + difftime(time(NULL),elapsed) <= 15;) { + //sleep(150); + } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(threadLogger->canShutdown(true)) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + delete threadLogger; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + threadLogger = NULL; + //delete threadLogger; + //threadLogger = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } if(SystemFlags::debugLogFileList != NULL) { @@ -295,6 +334,8 @@ void SystemFlags::Close() { delete SystemFlags::debugLogFileList; SystemFlags::debugLogFileList = NULL; } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::lockFile != -1) { #ifndef WIN32 close(SystemFlags::lockFile); @@ -310,18 +351,31 @@ void SystemFlags::Close() { } } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(SystemFlags::debugLogFileList != NULL) { if(SystemFlags::haveSpecialOutputCommandLineOption == false) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("END Closing logfiles\n"); } } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) { if(SystemFlags::debugLogFileList == NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { + //throw runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n",__FILE__,__FUNCTION__,__LINE__); + //return; + } + SystemFlags::init(false); } - SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; + //SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; + SystemFlags::SystemFlagsType ¤tDebugLog =getSystemSettingType(type); if(currentDebugLog.enabled == false) { return; } @@ -355,9 +409,11 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) { void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugTime) { if(SystemFlags::debugLogFileList == NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::init(false); } - SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; + //SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; + SystemFlags::SystemFlagsType ¤tDebugLog =getSystemSettingType(type); if(currentDebugLog.enabled == false) { return; }