/* 정인호. 11/14 현재 Base의 상황을 체크하여 게임 종료 여부를 체크. 불타입으로 변경, 스테이지 관련 부분 구현 후 내용추가할 필요가 있어보임 */ bool CPlayScene::CheckGameOver() { if (m_pPlayer->GetPlayerStatus() == PLAYER_ON_PLAYING ) { if(m_pMapCreator->GetPoliceBase()->GetHP() <= 0) { m_pPlayer->SetPlayerStatus(PLAYER_WIN); if (m_pPlayer->GetClearedStage() == m_pPlayer->GetPlayingStage() ) { m_pPlayer->IncreaseClearedStage(); } m_pPlayer->ReadyToSave(); SaveGame(); ShowResult(L"WIN"); printf_s("WIN!\n"); } else if(m_pMapCreator->GetZombieBase()->GetHP() <= 0) { m_pPlayer->SetPlayerStatus(PLAYER_LOSE); m_pPlayer->ReadyToSave(); SaveGame(); ShowResult(L"LOSE"); printf_s("LOSE!\n"); } else { return false; } } else // when the game is over { if( NNInputSystem::GetInstance()->GetKeyState(VK_LBUTTON) && m_pResultOKButton->CheckButtonArea() ) { NNSceneDirector::GetInstance()->ChangeScene(CStageSelectScene::Create()); m_pInstance = nullptr; } } return true; }
void EndGameScene::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) { CCTouch *touch = (CCTouch*)(pTouches->anyObject()); CCPoint pointTouched = touch->getLocationInView(); pointTouched = CCDirector::sharedDirector()->convertToGL(pointTouched); //handle reset button if(resetGame->boundingBox().containsPoint(pointTouched)){ SaveGame(); CCScene* reset = GamePlayLayer::scene(); CCDirector::sharedDirector()->replaceScene(reset); } //handle quit button if (quitGame->boundingBox().containsPoint(pointTouched)) { SaveGame(); CCScene* main_menu = MainMenuLayer::scene(); CCDirector::sharedDirector()->replaceScene(main_menu); } //handle when user touch at nameField if (nameField->boundingBox().containsPoint(pointTouched)) { nameField->attachWithIME(); }else{ nameField->detachWithIME(); } }
void gpOverwriteYes(char *name, featom *atom) { dbgAssertOrIgnore(overwritefilename[0] != 0); if (overwriteRecGame) { overwriteRecGame = FALSE; recPackInGameStartCB(overwritefilename); feAllScreensDelete(); if (!multiPlayerGame) { universePause = FALSE; // unpause game } } else { if (SaveGame(overwritefilename)) clCommandMessage(strGetString(strSavedGame)); else clCommandMessage(strGetString(strPatchUnableWriteFile)); feAllScreensDelete(); if (!multiPlayerGame) { universePause = FALSE; // unpause game } } }
BOOLEAN CheckIfGameCdromIsInCDromDrive() { CHAR8 zVolumeNameBuffer[512]; UINT32 uiVolumeSerialNumber=0; UINT32 uiMaxComponentLength=0; UINT32 uiFileSystemFlags=0; CHAR8 zFileSystemNameBuffer[512]; CHAR8 zCdLocation[ SGPFILENAME_LEN ]; CHAR8 zCdFile[ SGPFILENAME_LEN ]; CHAR8 zCdromRootDrive[512]; BOOLEAN fFailed = FALSE; UINT32 uiVolumeReturnValue; UINT32 uiLastError = ERROR_SUCCESS; if( !GetCdromLocationFromIniFile( zCdromRootDrive ) ) return( FALSE ); uiVolumeReturnValue = GetVolumeInformation( zCdromRootDrive, zVolumeNameBuffer, 512, &uiVolumeSerialNumber, &uiMaxComponentLength, &uiFileSystemFlags, zFileSystemNameBuffer, 512 ); if( !uiVolumeReturnValue ) { uiLastError = GetLastError(); } // OK, build filename sprintf( zCdFile, "%s%s", zCdLocation, gCheckFilenames[ Random( 2 ) ] ); //If the cdrom drive is no longer in the drive if( uiLastError == ERROR_NOT_READY || ( !FileExists( zCdFile ) ) ) { CHAR8 sString[512]; //if a game has been started, add the msg about saving the game to a different entry if( gTacticalStatus.fHasAGameBeenStarted ) { sprintf( sString, "%S %S", pMessageStrings[ MSG_INTEGRITY_WARNING ], pMessageStrings[ MSG_CDROM_SAVE_GAME ] ); SaveGame( SAVE__ERROR_NUM, pMessageStrings[ MSG_CDROM_SAVE ] ); } else { sprintf( sString, "%S", pMessageStrings[ MSG_INTEGRITY_WARNING ] ); } // ATE: These are ness. due to reference counting // in showcursor(). I'm not about to go digging in low level stuff at this // point in the game development, so keep these here, as this works... ShowCursor(TRUE); ShowCursor(TRUE); ShutdownWithErrorBox( sString ); //DoTester( ); //MessageBox(NULL, sString, "Error", MB_OK | MB_ICONERROR ); return( FALSE ); } return( TRUE ); }
void SaveGameMenu::KeyDown(int Key) { switch(Key) { case SDLK_UP: if(highlightedSave != savesList.begin()) highlightedSave--; break; case SDLK_DOWN: if(highlightedSave != savesList.end()) highlightedSave++; break; case SDLK_RETURN: SaveGame(); break; case SDLK_ESCAPE: engine->SetState("MainMenu"); break; default: break; } };
UFlareSimulatedSector* AFlareGame::DeactivateSector() { if (!ActiveSector) { return NULL; } UFlareSimulatedSector* Sector = ActiveSector->GetSimulatedSector(); FLOGV("AFlareGame::DeactivateSector : %s", *Sector->GetSectorName().ToString()); World->Save(); // Set last flown ship UFlareSimulatedSpacecraft* PlayerShip = NULL; if (GetPC()->GetPlayerShip()) { PlayerShip = GetPC()->GetPlayerShip(); } // Destroy the active sector DebrisFieldSystem->Reset(); UnloadStreamingLevel(ActiveSector->GetSimulatedSector()->GetDescription()->LevelName); ActiveSector->DestroySector(); ActiveSector = NULL; // Update the PC GetPC()->OnSectorDeactivated(); SaveGame(GetPC()); return Sector; }
static void Command_Sync(uint8_t *data) { if (!IsReplay()) { uint8_t *sync_data = &*bw::sync_data + 0x10c * (data[1] >> 4); if (sync_data[8] != data[5] || !Command_Sync_Main(data)) { if (*bw::desync_happened == 0) { LogSyncData(); // Saving is kind of pointless as the game cannot be reloaded with all players // but it might give some info if (Debug) { char buf[260]; char timestr[50]; auto now = std::chrono::system_clock::now(); auto timet = std::chrono::system_clock::to_time_t(now); std::strftime(timestr, sizeof timestr, "%m-%d %H-%M", std::localtime(&timet)); snprintf(buf, sizeof buf, "%s.%s", bw::net_players[*bw::self_net_player].name, timestr); auto time = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count(); SaveGame(buf, time); } } *bw::desync_happened = 1; bw::net_player_flags[*bw::lobby_command_user] = 0x10000; // Jep, ei or } }
void Designer::OnKeyDown(SDL_Keycode sym, SDL_Keymod mod) { WombatEngine::OnKeyDown(sym, mod); switch(sym) { case SDLK_ESCAPE: if(MainMap != nullptr) { SaveGame(""); } OnExit(); break; case SDLK_RIGHT: MainCamera->CameraRotation = (Rotation)((MainCamera->CameraRotation + 1)%4); TileSelector->CameraRotation = MainCamera->CameraRotation; break; case SDLK_LEFT: if(MainCamera->CameraRotation == 0) { MainCamera->CameraRotation = (Rotation)(3); } else { MainCamera->CameraRotation = (Rotation)((MainCamera->CameraRotation - 1)%4); } TileSelector->CameraRotation = MainCamera->CameraRotation; break; } };
int AGS_EngineOnEvent(int event, int data) { if (event == AGSE_PREGUIDRAW) { Draw(true); } else if (event == AGSE_PRESCREENDRAW) { Draw(false); } else if (event == AGSE_ENTERROOM) { // Reset all sprites Initialize(); } else if (event == AGSE_PRESCREENDRAW) { // Get screen size once here engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); engine->UnrequestEventHook(AGSE_PRESCREENDRAW); } #if defined(ENABLE_SAVING) else if (event == AGSE_RESTOREGAME) { RestoreGame((FILE*)data); } else if (event == AGSE_SAVEGAME) { SaveGame((FILE*)data); } #endif return 0; }
// Callback interface VOVERRIDE void OnHandleCallback(IVisCallbackDataObject_cl *pData) { if (pData->m_pSender == &Vision::Callbacks.OnBeforeSwapBuffers) { if (m_bSavePending) { // Perform Save if (SaveGame(m_iGameNum) == TRUE) { g_SaveSlot[m_iGameNum-1].ResetErrorState(); Vision::Message.Add(1, "Saved game in slot %d.", m_iGameNum); UpdateSlotStatus(-1); } else { g_SaveSlot[m_iGameNum-1].SetErrorState(); Vision::Message.Add(1, "ERROR: Couldn't save game in slot %d!", m_iGameNum); UpdateSlotStatus(-1); } // Re-set m_bSavePending = false; } } }
Common::Error TinselEngine::saveGameState(int slot, const char *desc) { Common::String saveName = _vm->getSavegameFilename((int16)(slot + 1)); char saveDesc[SG_DESC_LEN]; Common::strlcpy(saveDesc, desc, SG_DESC_LEN); SaveGame((char *)saveName.c_str(), saveDesc); ProcessSRQueue(); // This shouldn't be needed, but for some reason it is... return Common::kNoError; // TODO: return success/failure }
int SaveAll(void) { Bool save_ok; int save_time; char save_name[MAX_PATH+FILENAME_MAX]; char time_str[100]; /* Note: You must call GarbageCollect() right before SaveAll() */ /* charlie: machine sets the local time from a time synch server its potentially dangerous, but only if the time has been changed between either server startup or last save, which is unlikely to have drifted by much, things will only start to freak out if the difference is more than say a minute behind, meaning the all the timers will run for an extra minute.. its better this way as the time is going to be corrected every (currently) 4 hours , even the worst PC clocks aren`t going to degrade that much in 4 hours */ /* The current time is used as a suffix to the save filenames. We make our own copy since the time functions use a static buffer. */ save_time = GetTime(); sprintf(time_str,"%i",save_time); save_ok = True; lprintf("Saving game (time stamp %s)...\n", time_str); sprintf(save_name,"%s%s%s",ConfigStr(PATH_LOADSAVE),GAME_FILE_SAVE,time_str); if (SaveGame(save_name) == False) save_ok = False; sprintf(save_name,"%s%s%s",ConfigStr(PATH_LOADSAVE),STRING_FILE_SAVE,time_str); if (SaveStrings(save_name) == False) save_ok = False; sprintf(save_name,"%s%s%s",ConfigStr(PATH_LOADSAVE),ACCOUNT_FILE_SAVE,time_str); if (SaveAccounts(save_name) == False) save_ok = False; sprintf(save_name,"%s%s%s",ConfigStr(PATH_LOADSAVE),DYNAMIC_RSC_FILE_SAVE,time_str); if (!SaveDynamicRsc(save_name)) save_ok = False; if (save_ok) SaveControlFile(save_time); lprintf("Save game successful (time stamp %s).\n", time_str); if (save_ok) return save_time; return 0; }
void CTileEngine::End() { SetTitle( "TileEngine - Quiting..." ); SaveGame( "savegame.xml" ); if ( g_pGame != 0 ) delete g_pGame; g_pGame = 0; }
void gpSaveGivenGame(char* gamename) { if (SaveGame(gamename)) clCommandMessage(strGetString(strQuickSave)); else clCommandMessage(strGetString(strPatchUnableWriteFile)); if (!multiPlayerGame) { universePause = FALSE; } }
void AFlareGame::Logout(AController* Player) { FLOG("AFlareGame::Logout"); // Save the world, literally AFlarePlayerController* PC = Cast<AFlarePlayerController>(Player); DeactivateSector(); SaveGame(PC); PC->PrepareForExit(); Super::Logout(Player); }
/* save game */ static PyObject * engine_savegame(PyObject *self, PyObject *args) { char *filename; char *sfen; if (!PyArg_ParseTuple(args, "ss", &filename, &sfen)) return NULL; SaveGame(filename, sfen); Py_RETURN_NONE; }
size_t GameDatabase::UpdateGame(const size_t index, const StringPairArray &rulesets, const StringPairArray& options, const ISerialize& stats, const Game &game) { // If this is the last game in the list, no need to reload the database. bool reload = (index != mGames.size() - 1); // Delete the game and then resave it. DeleteGame(index, false); return SaveGame(game, rulesets, options, stats, reload); }
void CDromEjectionErrorMessageBoxCallBack( UINT8 bExitValue ) { if( bExitValue == MSG_BOX_RETURN_OK ) { guiPreviousOptionScreen = GAME_SCREEN; //if we are in a game, save the game if( gTacticalStatus.fHasAGameBeenStarted ) { SaveGame( SAVE__ERROR_NUM, pMessageStrings[ MSG_CDROM_SAVE ] ); } //quit the game gfProgramIsRunning = FALSE; } }
void InGameMenuKey() { while (true) { if (_kbhit()) { char mainMenuKey = _getch(); switch (mainMenuKey) { case CREDITS_CONTINUE_CHAR: start = true; break; case SAVE_CHAR: SaveGame(); break; case OPTIONS_CHAR: Options(); break; case FAME_CHAR: HallOfFame(); break; case INSTRUCTIONS_CHAR: Instructions(); break; case MENU_CHAR: Reset(); quit = true; start = true; break; case QUIT_CHAR: quit = true; break; default: toBreak = false; } if (toBreak) { break; } else { toBreak = true; } } } }
// Todo: Frame calling v-blank 195-196x per frame?? std::pair<sf::Image, bool> GameBoy::RenderFrame() { bool running = (input.PollEvents())?true:false; cpu.frame_clock = cpu.clock + 17556; // Number of cycles/4 for one frame before v-blank bool v_blank = false; do { if (cpu.halt) { cpu.clock += 1; } else { cpu.ExecuteNextInstruction(); } uint8_t if_memory_value = mmu.ReadByte(0xFF0F); if (mmu.interrupt_enable and cpu.interrupt_master_enable and if_memory_value) { cpu.halt = 0; cpu.interrupt_master_enable = 0; uint8_t interrupt_fired = mmu.interrupt_enable & if_memory_value; if (interrupt_fired & 0x01) {if_memory_value &= 0XFE; mmu.WriteByte(0xFF0F, if_memory_value); cpu.RST40();} else if (interrupt_fired & 0x02) {if_memory_value &= 0XFD; mmu.WriteByte(0xFF0F, if_memory_value); cpu.RST48();} else if (interrupt_fired & 0x04) {if_memory_value &= 0XFB; mmu.WriteByte(0xFF0F, if_memory_value); cpu.RST50();} else if (interrupt_fired & 0x08) {if_memory_value &= 0XF7; mmu.WriteByte(0xFF0F, if_memory_value); cpu.RST58();} else if (interrupt_fired & 0x10) {if_memory_value &= 0XEF; mmu.WriteByte(0xFF0F, if_memory_value); cpu.RST60();} else {cpu.interrupt_master_enable = 1;} mmu.WriteByte(0xFF0F, if_memory_value); } timer.Increment(); } while(cpu.clock < cpu.frame_clock); if (!v_blank) { frame = display.RenderFrame(); } // Update the .SAV file if flagged (once per second) if (++frame_counter >= 60) { frame_counter = 0; if (mmu.updateSaveFile) { SaveGame(); mmu.updateSaveFile = false; } } return std::make_pair(frame, running); }
void SaveGameMenu::MouseButtonDown(int Button, Vector2 Location) { MouseMotion(Location); switch(selectedButton) { case 0: SaveGame(); break; case 1: engine->SetState("MainMenu"); break; default: //selected save change break; } };
void CNextStageScene::Update( float dTime ) { // zombie upgrade NNScene::Update(dTime); if ( NNInputSystem::GetInstance()->GetKeyState(VK_LBUTTON) ) { // 업그레이드 버튼 처리 for ( int i=0 ; i<NUMBER_OF_ZOMBIE_TYPES ; ++i ) { if ( m_pUpgradeButtons[i]->CheckButtonArea() && (m_pPlayer->GetGlobalMoney() >= m_UpgradeCost[i]) ) { m_pPlayer->SetGlobalMoney( m_pPlayer->GetGlobalMoney() - m_UpgradeCost[i] ); m_pPlayer->IncreaseZombieLevel(static_cast<ZombieType>(i)); SetUpgradeText(static_cast<ZombieType>(i)); // global money 표시용 임시 나중에 적당한 위치에 라벨로 빼는 것이 좋겠음. swprintf_s( m_ResultBuffer, _countof(m_ResultBuffer), L"Results\nGlobalMoney : %d \nTotal Kill : %d \nTotal Loss : %d \nStage Kill : %d \nStage Loss : %d \n", m_pPlayer->GetGlobalMoney(), m_pPlayer->GetTotalKill(), m_pPlayer->GetTotalLoss(), m_pPlayer->GetNumberOfKillInStage(), m_pPlayer->GetNumberOfLossInStage() ); } } // 세이브 버튼 클릭시 if ( m_pGameSaveButton->CheckButtonArea() ) { SaveGame(); } // 다음 스테이지 버튼 클릭시 if ( m_pNextStageButton->CheckButtonArea() ) { NNSceneDirector::GetInstance()->ChangeScene(CPlayScene::GetInstance()); } } if( NNInputSystem::GetInstance()->GetKeyState(VK_RETURN) == KEY_DOWN ) { NNSceneDirector::GetInstance()->ChangeScene(CPlayScene::GetInstance()); } }
void Engine::play() { while (mode != QUIT && engine->hasScreen()) switch (mode) { case START: Animation(); break; case MENU: Menu(); break; case GAME: Game(); break; case MENU_GAME: MenuInGame(); break; case LOAD: LoadSave(); break; case SAVE: SaveGame(); break; case NEW_GAME: LoadGame(); break; case LAUNCH_GAME: NewGame(); break; case OPTION_MENU: OptionMenu(); break; case OPTION_GAME: MenuInGame(); break; case HIGHSCORE: Highscore(); break; default: mode = QUIT; } }
int tetris_exec( int fdfb, int fdrc, int fdlcd, char *cfgfile ) { struct timeval tv; int x; int i; int fd; FILE *fp; char *line; char *p; if ( FBInitialize( 720, 576, 8, fdfb ) < 0 ) return -1; setup_colors(); if ( RcInitialize( fdrc ) < 0 ) return -1; /* load setup */ fp = fopen( CONFIGDIR "/games.cfg", "r" ); if ( fp ) { line=malloc(128); isalloc=1; #ifdef HAVE_CURL proxy_addr=0; proxy_user=0; #endif hscore=0; while( fgets( line, 128, fp ) ) { if ( *line == '#' ) continue; if ( *line == ';' ) continue; p=strchr(line,'\n'); if ( p ) *p=0; p=strchr(line,'='); if ( !p ) continue; *p=0; p++; #ifdef HAVE_CURL if ( !strcmp(line,"proxy") ) proxy_addr=strdup(p); else if ( !strcmp(line,"proxy_user") ) proxy_user=strdup(p); else if ( !strcmp(line,"hscore") ) hscore=strdup(p); #endif } fclose(fp); free(line); } fd = open( GAMESDIR "/tetris.hscore", O_RDONLY ); if ( fd == -1 ) { mkdir( GAMESDIR, 567 ); for( i=0; i < 8; i++ ) { strcpy(hsc[i].name,"nobody"); hsc[i].points=30; } } else { read( fd, hsc, sizeof(hsc) ); close(fd); } #ifdef HAVE_CURL if ( hscore ) { LoadHScore(); } #endif #if defined(HAVE_DBOX_HARDWARE) || defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) Fx2ShowPig( 480, 400, 176, 144 ); #endif while( doexit != 3 ) { BoardInitialize(); DrawBoard( ); /* 0 = all */ NextItem(); #ifdef HAVE_DREAMBOX_HARDWARE Fx2ShowPig(480, 400, 176, 144 ); #endif doexit=0; while( !doexit ) { tv.tv_sec = 0; tv.tv_usec = 10000; x = select( 0, 0, 0, 0, &tv ); /* 10ms pause */ RcGetActCode( ); if ( doexit ) break; tv.tv_sec = 0; tv.tv_usec = 10000; x = select( 0, 0, 0, 0, &tv ); /* 10ms pause */ RcGetActCode( ); if ( doexit ) break; MoveSide(); if ( !FallDown() ) { RemoveCompl(); if ( !NextItem() ) doexit=1; } #if defined(USEX) || defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) FBFlushGrafic(); #endif RcGetActCode( ); } if ( doexit != 3 ) { actcode=0xee; DrawGameOver(); #if defined(USEX) || defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) FBFlushGrafic(); #endif doexit=0; SaveGame(); #ifdef HAVE_CURL if ( use_ihsc ) ShowIHScore(); #endif ShowHScore(hsc); Fx2PigPause(); #if defined(USEX) || defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) FBFlushGrafic(); #endif i=0; actcode=0xee; while(( actcode != RC_OK ) && !doexit ) { tv.tv_sec = 0; tv.tv_usec = 100000; x = select( 0, 0, 0, 0, &tv ); /* 100ms pause */ RcGetActCode( ); i++; if ( i == 50 ) { FBDrawString( 190, 480, 48, "press OK for new game",GRAY,0); #if defined(USEX) || defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) FBFlushGrafic(); #endif } } Fx2PigResume(); } } Fx2StopPig(); #if defined(HAVE_DBOX_HARDWARE) || defined(HAVE_SPARK_HARDWARE) || defined(HAVE_DUCKBOX_HARDWARE) /* fx2 */ /* buffer leeren, damit neutrino nicht rumspinnt */ realcode = RC_0; while( realcode != 0xee ) { tv.tv_sec = 0; tv.tv_usec = 300000; x = select( 0, 0, 0, 0, &tv ); /* 300ms pause */ RcGetActCode( ); } #endif RcClose(); FBClose(); /* save hscore */ fd = open( GAMESDIR "/tetris.hscore", O_CREAT|O_WRONLY, 438 ); if ( fd != -1 ) { write( fd, hsc, sizeof(hsc) ); close(fd); } if ( isalloc ) { #ifdef HAVE_CURL if ( proxy_addr ) free ( proxy_addr ); if ( proxy_user ) free ( proxy_user ); #endif if ( hscore ) free ( hscore ); } return 0; }
void _FailMessage(const char* message, unsigned lineNum, const char * functionName, const char* sourceFileName) { // This function shouldn't recurse static bool alreadyInThisFunction = false; if (alreadyInThisFunction) return; alreadyInThisFunction = true; sgp::dumpStackTrace(message); std::stringstream basicInformation; basicInformation << "Assertion Failure [Line " << lineNum; if (functionName) { basicInformation << " in function " << functionName; } basicInformation << " in file " << sourceFileName << "]"; std::stringstream outputString; outputString << "{ " << GetTickCount() << " } " << basicInformation.str(); //Build the output strings if( message ) sprintf( gubAssertString, message ); else sprintf( gubAssertString, "" ); //Output to debugger if (gfRecordToDebugger) OutputDebugString( outputString.str().c_str() ); DbgMessage( TOPIC_GAME, DBG_LEVEL_1, outputString.str().c_str()); //This will actually bring up a screen that prints out the assert message //until the user hits esc or alt-x. // WDS - Automatically try to save when an assertion failure occurs if (gGameExternalOptions.autoSaveOnAssertionFailure && !alreadySaving) { sprintf( gubErrorText, "%s. Attempting to do a debug save as SaveGame%d.sav (this may fail)", basicInformation.str().c_str(), SAVE__ASSERTION_FAILURE ); } else { sprintf( gubErrorText, "%s", basicInformation.str().c_str()); } SetPendingNewScreen( ERROR_SCREEN ); SetCurrentScreen( ERROR_SCREEN ); // WDS - Automatically try to save when an assertion failure occurs if (gGameExternalOptions.autoSaveOnAssertionFailure && !alreadySaving) { SaveGame( SAVE__ASSERTION_FAILURE, L"Assertion Failure Auto Save" ); } MSG Message; while (gfProgramIsRunning) { if (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE)) { // We have a message on the WIN95 queue, let's get it if (!GetMessage(&Message, NULL, 0, 0)) { // It's quitting time continue; } // Ok, now that we have the message, let's handle it TranslateMessage(&Message); DispatchMessage(&Message); } else { // Windows hasn't processed any messages, therefore we handle the rest GameLoop(); gfSGPInputReceived = FALSE; } } alreadyInThisFunction = false; exit(0); }
uint32 CFolderSave::OnCommand(uint32 dwCommand, uint32 dwParam1, uint32 dwParam2) { if (dwCommand >= FOLDER_CMD_CUSTOM && dwCommand <= FOLDER_CMD_CUSTOM+kMaxSave) { uint32 slot = dwCommand - FOLDER_CMD_CUSTOM; char strSaveGameSetting[256]; char strKey[32]; sprintf (strKey, "SaveGame%02d", slot); CWinUtil::WinGetPrivateProfileString (GAME_NAME, strKey, "", strSaveGameSetting, 256, SAVEGAMEINI_FILENAME); char strFilename[128]; sprintf (strFilename, "Save\\Slot%02d.sav", slot); g_nSaveSlot = slot; g_nSaveIndex = (int)dwParam1; if (strlen (strSaveGameSetting) > 0 && CWinUtil::FileExist(strFilename)) { HSTRING hString = g_pLTClient->FormatString(IDS_CONFIRMSAVE); g_pInterfaceMgr->ShowMessageBox(hString,LTMB_YESNO,OverwriteCallBack,this); g_pLTClient->FreeString(hString); return 1; } if (dwCommand > FOLDER_CMD_CUSTOM) { m_szSaveName[0] = LTNULL; NameSaveGame(g_nSaveSlot,g_nSaveIndex); } else if (!SaveGame(g_nSaveSlot)) { HSTRING hString = g_pLTClient->FormatString(IDS_SAVEGAMEFAILED); g_pInterfaceMgr->ShowMessageBox(hString,LTMB_OK,LTNULL,LTNULL); g_pLTClient->FreeString(hString); } } else if (dwCommand == CMD_OVERWRITE) { NameSaveGame(g_nSaveSlot,g_nSaveIndex); } else if (dwCommand == CMD_EDIT_NAME) { if (GetCapture()) { m_pEdit->Select(LTFALSE); UpdateData(LTTRUE); SetCapture(LTNULL); RemoveFixedControl(m_pEdit); ForceMouseUpdate(); if (!SaveGame(g_nSaveSlot)) { HSTRING hString = g_pLTClient->FormatString(IDS_SAVEGAMEFAILED); g_pInterfaceMgr->ShowMessageBox(hString,LTMB_OK,LTNULL,LTNULL); g_pLTClient->FreeString(hString); return 0; } } } else return CBaseFolder::OnCommand(dwCommand,dwParam1,dwParam2); return 1; };
INT16 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT16 sDesGrid, INT8 bReserveAPs, INT8 bAction, INT8 fFlags ) { INT16 sLoop,sAPCost; INT16 sTempDest,sGoToGrid; INT16 sOrigin; UINT16 usMaxDist; UINT8 ubDirection,ubDirsLeft,ubDirChecked[8],fFound = FALSE; INT8 bAPsLeft, fPathFlags; UINT8 ubRoomRequired = 0, ubTempRoom; if ( bReserveAPs == -1 ) { // default reserve points if ( CREATURE_OR_BLOODCAT( pSoldier ) ) { bReserveAPs = 0; } else { bReserveAPs = MAX_AP_CARRIED; } } sTempDest = -1; // obtain maximum roaming distance from soldier's sOrigin usMaxDist = RoamingRange(pSoldier,&sOrigin); if ( pSoldier->bOrders <= CLOSEPATROL && (pSoldier->bTeam == CIV_TEAM || pSoldier->ubProfile != NO_PROFILE ) ) { if ( InARoom( pSoldier->usPatrolGrid[0], &ubRoomRequired ) ) { // make sure this doesn't interfere with pathing for scripts if ( pSoldier->sAbsoluteFinalDestination != NOWHERE ) { ubRoomRequired = 0; } } } pSoldier->usUIMovementMode = DetermineMovementMode(pSoldier, bAction ); if ( pSoldier->usUIMovementMode == RUNNING && fFlags & FLAG_CAUTIOUS ) { pSoldier->usUIMovementMode = WALKING; } #ifdef DEBUGDECISIONS sprintf(tempstr,"%s wants to go towards %d (has range %d)",pSoldier->name,sDesGrid,usMaxDist); AIPopMessage(tempstr); #endif // if soldier is ALREADY at the desired destination, quit right away if (sDesGrid == pSoldier->sGridNo) { return(NOWHERE); } // don't try to approach go after noises or enemies actually in water // would be too easy to throw rocks in water, etc. & distract the AI if (Water(sDesGrid)) { return(NOWHERE); } fPathFlags = 0; if ( CREATURE_OR_BLOODCAT( pSoldier ) ) { /* if ( PythSpacesAway( pSoldier->sGridNo, sDesGrid ) <= PATH_CLOSE_RADIUS ) { // then do a limited range path search and see if we can get there gubNPCDistLimit = 10; if ( !LegalNPCDestination( pSoldier, sDesGrid, ENSURE_PATH, NOWATER, fPathFlags) ) { gubNPCDistLimit = 0; return( NOWHERE ); } else { // allow attempt to path without 'good enough' flag on gubNPCDistLimit = 0; } } else { */ fPathFlags = PATH_CLOSE_GOOD_ENOUGH; //} } // first step: try to find an OK destination at or near the desired gridno if (!LegalNPCDestination(pSoldier,sDesGrid,ENSURE_PATH,NOWATER,fPathFlags)) { #ifdef DEBUGDECISIONS AIPopMessage("destination Grid # itself not valid, looking around it"); #endif if ( CREATURE_OR_BLOODCAT( pSoldier ) ) { // we tried to get close, failed; abort! return( NOWHERE ); } else { // else look at the 8 nearest gridnos to sDesGrid for a valid destination // clear ubDirChecked flag for all 8 directions for (ubDirection = 0; ubDirection < 8; ubDirection++) ubDirChecked[ubDirection] = FALSE; ubDirsLeft = 8; // examine all 8 spots around 'sDesGrid' // keep looking while directions remain and a satisfactory one not found for (ubDirsLeft = 8; ubDirsLeft != 0; ubDirsLeft--) { if (fFound) { break; } // randomly select a direction which hasn't been 'checked' yet do { ubDirection = (UINT8) Random(8); } while (ubDirChecked[ubDirection]); ubDirChecked[ubDirection] = TRUE; // determine the gridno 1 tile away from current friend in this direction sTempDest = NewGridNo(sDesGrid,DirectionInc( (INT16)(ubDirection + 1) )); // if that's out of bounds, ignore it & check next direction if (sTempDest == sDesGrid) continue; if (LegalNPCDestination(pSoldier,sTempDest,ENSURE_PATH,NOWATER,0)) { fFound = TRUE; // found a spot #ifdef DEBUGDECISIONS AINumMessage("Found a spot! ubDirection = ",ubDirection + 1); #endif break; // stop checking in other directions } } if (!fFound) { #ifdef DEBUGDECISIONS AINumMessage("Couldn't find OK destination around grid #",sDesGrid); #endif return(NOWHERE); } // found a good grid #, this becomes our actual desired grid # sDesGrid = sTempDest; } } // HAVE FOUND AN OK destination AND PLOTTED A VALID BEST PATH TO IT #ifdef DEBUGDECISIONS AINumMessage("Chosen legal destination is gridno ",sDesGrid); AINumMessage("Tracing along path, pathRouteToGo = ",pSoldier->pathRouteToGo); #endif sGoToGrid = pSoldier->sGridNo; // start back where soldier is standing now sAPCost = 0; // initialize path cost counter // we'll only go as far along the plotted route as is within our // permitted roaming range, and we'll stop as soon as we're down to <= 5 APs for (sLoop = 0; sLoop < (pSoldier->usPathDataSize - pSoldier->usPathIndex); sLoop++) { // what is the next gridno in the path? //sTempDest = NewGridNo( sGoToGrid,DirectionInc( (INT16) (pSoldier->usPathingData[sLoop] + 1) ) ); sTempDest = NewGridNo( sGoToGrid,DirectionInc( (INT16) (pSoldier->usPathingData[sLoop]) ) ); //NumMessage("sTempDest = ",sTempDest); // this should NEVER be out of bounds if (sTempDest == sGoToGrid) { #ifdef BETAVERSION sprintf(tempstr,"GoAsFarAsPossibleTowards: ERROR - gridno along valid route is invalid! guynum %d, sTempDest = %d",pSoldier->ubID,sTempDest); #ifdef RECORDNET fprintf(NetDebugFile,"\n\t%s\n",tempstr); #endif PopMessage(tempstr); SaveGame(ERROR_SAVE); #endif break; // quit here, sGoToGrid is where we are going } // if this takes us beyond our permitted "roaming range" if (SpacesAway(sOrigin,sTempDest) > usMaxDist) break; // quit here, sGoToGrid is where we are going if ( ubRoomRequired ) { if ( !( InARoom( sTempDest, &ubTempRoom ) && ubTempRoom == ubRoomRequired ) ) { // quit here, limited by room! break; } } if ( (fFlags & FLAG_STOPSHORT) && SpacesAway( sDesGrid, sTempDest ) <= STOPSHORTDIST ) { break; // quit here, sGoToGrid is where we are going } // if this gridno is NOT a legal NPC destination // DONT'T test path again - that would replace the traced path! - Ian // NOTE: It's OK to go *THROUGH* water to try and get to the destination! if (!LegalNPCDestination(pSoldier,sTempDest,IGNORE_PATH,WATEROK,0)) break; // quit here, sGoToGrid is where we are going // CAN'T CALL PathCost() HERE! IT CALLS findBestPath() and overwrites // pathRouteToGo !!! Gotta calculate the cost ourselves - Ian // //ubAPsLeft = pSoldier->bActionPoints - PathCost(pSoldier,sTempDest,FALSE,FALSE,FALSE,FALSE,FALSE); if (gfTurnBasedAI) { // if we're just starting the "costing" process (first gridno) if (sLoop == 0) { /* // first, add any additional costs - such as intermediate animations, etc. switch(pSoldier->anitype[pSoldier->anim]) { // in theory, no NPC should ever be in one of these animations as // things stand (they don't medic anyone), but leave it for robustness case START_AID : case GIVING_AID : sAnimCost = AP_STOP_FIRST_AID; break; case TWISTOMACH : case COLLAPSED : sAnimCost = AP_GET_UP; break; case TWISTBACK : case UNCONSCIOUS : sAnimCost = (AP_ROLL_OVER + AP_GET_UP); break; default : sAnimCost = 0; } // this is our first cost sAPCost += sAnimCost; */ if (pSoldier->usUIMovementMode == RUNNING) { sAPCost += AP_START_RUN_COST; } } // ATE: Direction here? sAPCost += EstimateActionPointCost( pSoldier, sTempDest, (INT8) pSoldier->usPathingData[sLoop], pSoldier->usUIMovementMode, (INT8) sLoop, (INT8) pSoldier->usPathDataSize ); bAPsLeft = pSoldier->bActionPoints - sAPCost; } // if after this, we have <= 5 APs remaining, that's far enough, break out // (the idea is to preserve APs so we can crouch or react if // necessary, and benefit from the carry-over next turn if not needed) // This routine is NOT used by any GREEN AI, so such caution is warranted! if ( gfTurnBasedAI && (bAPsLeft < bReserveAPs) ) break; else { sGoToGrid = sTempDest; // we're OK up to here // if exactly 5 APs left, don't bother checking any further if ( gfTurnBasedAI && (bAPsLeft == bReserveAPs) ) break; } } // if it turned out we couldn't go even 1 tile towards the desired gridno if (sGoToGrid == pSoldier->sGridNo) { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s will go NOWHERE, path doesn't meet criteria",pSoldier->name); AIPopMessage(tempstr); #endif return(NOWHERE); // then go nowhere } else { // possible optimization - stored path IS good if we're going all the way if (sGoToGrid == sDesGrid) { pSoldier->bPathStored = TRUE; pSoldier->sFinalDestination = sGoToGrid; } else if ( pSoldier->usPathIndex == 0 ) { // we can hack this surely! -- CJC pSoldier->bPathStored = TRUE; pSoldier->sFinalDestination = sGoToGrid; pSoldier->usPathDataSize = sLoop + 1; } #ifdef DEBUGDECISIONS ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"%d to %d with %d APs left", pSoldier->ubID, sGoToGrid, pSoldier->bActionPoints ); #endif return( sGoToGrid ); } }
int TryToResumeMovement(SOLDIERTYPE *pSoldier, INT16 sGridno) { UINT8 ubGottaCancel = FALSE; UINT8 ubSuccess = FALSE; // have to make sure the old destination is still legal (somebody may // have occupied the destination gridno in the meantime!) if (LegalNPCDestination(pSoldier,sGridno,ENSURE_PATH,WATEROK,0)) { #ifdef DEBUGDECISIONS DebugAI( String( "%d CONTINUES MOVEMENT to gridno %d...\n",pSoldier->ubID,gridno ) ); #endif pSoldier->bPathStored = TRUE; // optimization - Ian // make him go to it (needed to continue movement across multiple turns) NewDest(pSoldier,sGridno); ubSuccess = TRUE; // make sure that it worked (check that pSoldier->sDestination == pSoldier->sGridNo) if (pSoldier->sDestination == sGridno) { ubSuccess = TRUE; } else { #ifdef BETAVERSION sprintf(tempstr,"TryToResumeMovement: ERROR - NewDest failed for %s, action CANCELED",pSoldier->name); #ifdef RECORDNET fprintf(NetDebugFile,"\n\t%s\n",tempstr); #endif PopMessage(tempstr); SaveGame(ERROR_SAVE); #endif // must work even for escorted civs, can't just set the flag CancelAIAction(pSoldier,FORCE); } } else { // don't black-list anything here, this situation can come up quite // legally if another soldier gets in the way between turns #ifdef BETAVERSION sprintf(tempstr,"TryToResumeMovement: %d can't continue to gridno %d, no longer legal!",pSoldier->ubID,gridno); #ifdef RECORDNET fprintf(NetDebugFile,"\n\t%s\n",tempstr); #endif #ifdef DEBUGDECISIONS AIPopMessage(tempstr); #endif #endif if (!pSoldier->bUnderEscort) { CancelAIAction(pSoldier,DONTFORCE); // no need to force this } else { // this is an escorted NPC, don't want to just completely stop // moving, try to find a nearby "next best" destination if possible pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sGridno,pSoldier->bAction); // if it's not possible to get any closer if (pSoldier->usActionData == NOWHERE) { ubGottaCancel = TRUE; } else { // change his desired destination to this new one sGridno = pSoldier->usActionData; // GoAsFar... sets pathStored TRUE only if he could go all the way // make him go to it (needed to continue movement across multiple turns) NewDest(pSoldier,sGridno); // make sure that it worked (check that pSoldier->sDestination == pSoldier->sGridNo) if (pSoldier->sDestination == sGridno) ubSuccess = TRUE; else ubGottaCancel = TRUE; } if (ubGottaCancel) { // can't get close, gotta abort the movement! CancelAIAction(pSoldier,FORCE); // tell the player doing the escorting that civilian has stopped //EscortedMoveCanceled(pSoldier,COMMUNICATE); } } } return(ubSuccess); }
static int PerformLine(int ct) { int continuation=0; int param[5],pptr=0; int act[4]; int cc=0; while(cc<5) { int cv,dv; cv=Actions[ct].Condition[cc]; dv=cv/20; cv%=20; switch(cv) { case 0: param[pptr++]=dv; break; case 1: if(Items[dv].Location!=CARRIED) return(0); break; case 2: if(Items[dv].Location!=MyLoc) return(0); break; case 3: if(Items[dv].Location!=CARRIED&& Items[dv].Location!=MyLoc) return(0); break; case 4: if(MyLoc!=dv) return(0); break; case 5: if(Items[dv].Location==MyLoc) return(0); break; case 6: if(Items[dv].Location==CARRIED) return(0); break; case 7: if(MyLoc==dv) return(0); break; case 8: if((BitFlags&(1<<dv))==0) return(0); break; case 9: if(BitFlags&(1<<dv)) return(0); break; case 10: if(CountCarried()==0) return(0); break; case 11: if(CountCarried()) return(0); break; case 12: if(Items[dv].Location==CARRIED||Items[dv].Location==MyLoc) return(0); break; case 13: if(Items[dv].Location==0) return(0); break; case 14: if(Items[dv].Location) return(0); break; case 15: if(CurrentCounter>dv) return(0); break; case 16: if(CurrentCounter<=dv) return(0); break; case 17: if(Items[dv].Location!=Items[dv].InitialLoc) return(0); break; case 18: if(Items[dv].Location==Items[dv].InitialLoc) return(0); break; case 19:/* Only seen in Brian Howarth games so far */ if(CurrentCounter!=dv) return(0); break; } cc++; } /* Actions */ act[0]=Actions[ct].Action[0]; act[2]=Actions[ct].Action[1]; act[1]=act[0]%150; act[3]=act[2]%150; act[0]/=150; act[2]/=150; cc=0; pptr=0; while(cc<4) { if(act[cc]>=1 && act[cc]<52) { Output(Messages[act[cc]]); Output("\n"); } else if(act[cc]>101) { Output(Messages[act[cc]-50]); Output("\n"); } else switch(act[cc]) { case 0:/* NOP */ break; case 52: if(CountCarried()==GameHeader.MaxCarry) { if(Options&YOUARE) Output("You are carrying too much. "); else Output("I've too much to carry! "); break; } Items[param[pptr++]].Location= CARRIED; break; case 53: Items[param[pptr++]].Location=MyLoc; break; case 54: MyLoc=param[pptr++]; break; case 55: Items[param[pptr++]].Location=0; break; case 56: BitFlags|=1<<DARKBIT; break; case 57: BitFlags&=~(1<<DARKBIT); break; case 58: BitFlags|=(1<<param[pptr++]); break; case 59: Items[param[pptr++]].Location=0; break; case 60: BitFlags&=~(1<<param[pptr++]); break; case 61: if(Options&YOUARE) Output("You are dead.\n"); else Output("I am dead.\n"); BitFlags&=~(1<<DARKBIT); MyLoc=GameHeader.NumRooms;/* It seems to be what the code says! */ break; case 62: { /* Bug fix for some systems - before it could get parameters wrong */ int i=param[pptr++]; Items[i].Location=param[pptr++]; break; } case 63: doneit: Output("The game is now over.\n"); glk_exit(); case 64: break; case 65: { int i=0; int n=0; while(i<=GameHeader.NumItems) { if(Items[i].Location==GameHeader.TreasureRoom && *Items[i].Text=='*') n++; i++; } if(Options&YOUARE) Output("You have stored "); else Output("I've stored "); OutputNumber(n); Output(" treasures. On a scale of 0 to 100, that rates "); OutputNumber((n*100)/GameHeader.Treasures); Output(".\n"); if(n==GameHeader.Treasures) { Output("Well done.\n"); goto doneit; } break; } case 66: { int i=0; int f=0; if(Options&YOUARE) Output("You are carrying:\n"); else Output("I'm carrying:\n"); while(i<=GameHeader.NumItems) { if(Items[i].Location==CARRIED) { if(f==1) { if (Options & TRS80_STYLE) Output(". "); else Output(" - "); } f=1; Output(Items[i].Text); } i++; } if(f==0) Output("Nothing"); Output(".\n"); break; } case 67: BitFlags|=(1<<0); break; case 68: BitFlags&=~(1<<0); break; case 69: GameHeader.LightTime=LightRefill; Items[LIGHT_SOURCE].Location=CARRIED; BitFlags&=~(1<<LIGHTOUTBIT); break; case 70: ClearScreen(); /* pdd. */ break; case 71: SaveGame(); break; case 72: { int i1=param[pptr++]; int i2=param[pptr++]; int t=Items[i1].Location; Items[i1].Location=Items[i2].Location; Items[i2].Location=t; break; } case 73: continuation=1; break; case 74: Items[param[pptr++]].Location= CARRIED; break; case 75: { int i1,i2; i1=param[pptr++]; i2=param[pptr++]; Items[i1].Location=Items[i2].Location; break; } case 76: /* Looking at adventure .. */ break; case 77: if(CurrentCounter>=0) CurrentCounter--; break; case 78: OutputNumber(CurrentCounter); break; case 79: CurrentCounter=param[pptr++]; break; case 80: { int t=MyLoc; MyLoc=SavedRoom; SavedRoom=t; break; } case 81: { /* This is somewhat guessed. Claymorgue always seems to do select counter n, thing, select counter n, but uses one value that always seems to exist. Trying a few options I found this gave sane results on ageing */ int t=param[pptr++]; int c1=CurrentCounter; CurrentCounter=Counters[t]; Counters[t]=c1; break; } case 82: CurrentCounter+=param[pptr++]; break; case 83: CurrentCounter-=param[pptr++]; if(CurrentCounter< -1) CurrentCounter= -1; /* Note: This seems to be needed. I don't yet know if there is a maximum value to limit too */ break; case 84: Output(NounText); break; case 85: Output(NounText); Output("\n"); break; case 86: Output("\n"); break; case 87: { /* Changed this to swap location<->roomflag[x] not roomflag 0 and x */ int p=param[pptr++]; int sr=MyLoc; MyLoc=RoomSaved[p]; RoomSaved[p]=sr; break; } case 88: delay(2); break; case 89: pptr++; /* SAGA draw picture n */ /* Spectrum Seas of Blood - start combat ? */ /* Poking this into older spectrum games causes a crash */ break; default: fprintf(stderr,"Unknown action %d [Param begins %d %d]\n", act[cc],param[pptr],param[pptr+1]); break; } cc++; } return(1+continuation); }
void HumanClientApp::Autosave() { // autosave only on appropriate turn numbers, and when enabled for current // game type (single vs. multiplayer) int autosave_turns = GetOptionsDB().Get<int>("autosave.turns"); if (autosave_turns < 1) return; // avoid divide by zero if (CurrentTurn() % autosave_turns != 0 && CurrentTurn() != 1) return; // turns divisible by autosave_turns, and first turn, have autosaves done if (m_single_player_game && !GetOptionsDB().Get<bool>("autosave.single-player")) return; if (!m_single_player_game && !GetOptionsDB().Get<bool>("autosave.multiplayer")) return; const char* legal_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-"; // get empire name, filtered for filename acceptability int client_empire_id = EmpireID(); const Empire* empire = GetEmpire(client_empire_id); std::string empire_name; if (empire) empire_name = empire->Name(); else empire_name = UserString("OBSERVER"); std::string::size_type first_good_empire_char = empire_name.find_first_of(legal_chars); if (first_good_empire_char == std::string::npos) { empire_name.clear(); } else { std::string::size_type first_bad_empire_char = empire_name.find_first_not_of(legal_chars, first_good_empire_char); empire_name = empire_name.substr(first_good_empire_char, first_bad_empire_char - first_good_empire_char); } // get player name, also filtered std::string player_name; if (empire) player_name = empire->PlayerName(); std::string::size_type first_good_player_char = player_name.find_first_of(legal_chars); if (first_good_player_char == std::string::npos) { player_name.clear(); } else { std::string::size_type first_bad_player_char = player_name.find_first_not_of(legal_chars, first_good_player_char); player_name = player_name.substr(first_good_player_char, first_bad_player_char - first_good_player_char); } // select filename extension std::string extension; if (m_single_player_game) extension = SP_SAVE_FILE_EXTENSION; else extension = MP_SAVE_FILE_EXTENSION; // Add timestamp to autosave generated files std::string datetime_str = FilenameTimestamp(); boost::filesystem::path autosave_dir_path(GetSaveDir() / "auto"); std::string save_filename = boost::io::str(boost::format("FreeOrion_%s_%s_%04d_%s%s") % player_name % empire_name % CurrentTurn() % datetime_str % extension); boost::filesystem::path save_path(autosave_dir_path / save_filename); std::string path_string = PathString(save_path); try { // ensure autosave directory exists if (!exists(autosave_dir_path)) boost::filesystem::create_directories(autosave_dir_path); } catch (const std::exception& e) { ErrorLogger() << "Autosave unable to check / create autosave directory: " << e.what(); std::cerr << "Autosave unable to check / create autosave directory: " << e.what() << std::endl; } // check for and remove excess oldest autosaves int max_autosaves = GetOptionsDB().Get<int>("autosave.limit"); RemoveOldestFiles(max_autosaves, autosave_dir_path); // create new save DebugLogger() << "Autosaving to: " << path_string; try { SaveGame(path_string); } catch (const std::exception& e) { ErrorLogger() << "Autosave failed: " << e.what(); std::cerr << "Autosave failed: " << e.what() << std::endl; } }