static void end_of_month_update(void) { //update queque of polluted tiles scan_pollution(); //fetch remaining textures in order loader thread can exit if(getGameView()->textures_ready && getGameView()->remaining_images) { getGameView()->fetchTextures(); } housed_population = (tpopulation / NUMOF_DAYS_IN_MONTH); total_housing = (thousing / NUMOF_DAYS_IN_MONTH); if ((housed_population + people_pool) > max_pop_ever) max_pop_ever = housed_population + people_pool; if (people_pool > 100) { if (rand() % 1000 < people_pool) people_pool -= 10; } if (people_pool < 0) { people_pool = 0; } if (tech_level > TECH_LEVEL_LOSS_START) { tech_level -= (int)(tech_level * (1. / TECH_LEVEL_LOSS) * (1 + (tpopulation * (1. / NUMOF_DAYS_IN_MONTH / 120 / (TECH_LEVEL_LOSS - 200))))); } else { tech_level += TECH_LEVEL_UNAIDED; } /* we can go over 100, but it's even more difficult */ if (tech_level > MAX_TECH_LEVEL) { tech_level -= (int)((tech_level - MAX_TECH_LEVEL) * (1. / TECH_LEVEL_LOSS) * (1 + (tpopulation * (1. / NUMOF_DAYS_IN_MONTH / 120 / (TECH_LEVEL_LOSS - 100))))); } if (highest_tech_level < tech_level) { highest_tech_level = tech_level; } deaths_cost += tunnat_deaths * UNNAT_DEATHS_COST; for (int i = 0; i < constructionCount.size(); i++) { if (constructionCount[i]) { constructionCount[i]->report_commodities(); } } update_pbars_monthly(); }
void Game::quickLoad(){ closeAllDialogs(); //load file getGameView()->printStatusMessage( "quick load..."); std::string filename; filename.append( "quicksave.scn" ); if( loadCityNG( filename ) ){ getGameView()->printStatusMessage( "quick load successful."); } else { getGameView()->printStatusMessage( "quick load failed!"); } }
void Game::testAllHelpFiles(){ getGameView()->printStatusMessage( "Testing Help Files..."); std::string filename; std::string directory = "help/en"; std::string fullname; char **rc = PHYSFS_enumerateFiles( directory.c_str() ); char **i; size_t pos; for (i = rc; *i != NULL; i++) { fullname = directory; fullname.append( *i ); filename.assign( *i ); if(PHYSFS_isDirectory(fullname.c_str())) continue; pos = filename.rfind( ".xml" ); if( pos != std::string::npos ){ filename.replace( pos, 4 ,""); std::cerr << "--- Examining " << filename << "\n"; helpWindow->showTopic( filename ); std::cerr << "\n"; } } PHYSFS_freeList(rc); }
void updateDate() { std::ostringstream dateText; int day = total_time % NUMOF_DAYS_IN_MONTH +1; // 1..NUMOF_DAYS_IN_MONTH day = 1 + ( 29 * day / NUMOF_DAYS_IN_MONTH ); // 1..30 dateText << day << ". "; dateText << current_month( total_time ); dateText << " "<< current_year( total_time ); Component* root = getGameView(); if( !root ) return; while( root->getParent() ) root = root->getParent(); if( dateText.str() == lastDateText ){ return; } Component* dateParagraphComponent = 0; dateParagraphComponent = root->findComponent( "dateParagraph" ); if( dateParagraphComponent == 0 ) { return;} Paragraph* dateParagraph = getParagraph( *root, "dateParagraph"); if( !dateParagraph ) { return;} dateParagraph->setText( dateText.str() ); lastDateText = dateText.str(); }
/* * Update Message in Message Window */ void updateMessageText( const std::string text ) { //Dialog Test Component* root = getGameView(); if(!root) { //happens while in menu. std::cerr << "Root not found.\n"; return; } while( root->getParent() ) root = root->getParent(); Desktop* desktop = dynamic_cast<Desktop*> (root); if(!desktop) { std::cerr << "Root not a desktop!?!\n"; return; } try { //test if message Windows is open Component* messageTextComponent = 0; messageTextComponent = root->findComponent( "messageText" ); if(messageTextComponent == 0) { messageTextComponent = loadGUIFile("gui/messagearea.xml"); assert(messageTextComponent != 0); desktop->addChildComponent(messageTextComponent); } Paragraph* messageText = getParagraph(*messageTextComponent, "messageText"); messageText->setText( text ); } catch(std::exception& e) { std::cerr << "Couldn't display message '" << text << "': " << e.what() << "\n"; return; } }
void execute_timestep () { static Uint32 oldTime = SDL_GetTicks(); Uint32 now=SDL_GetTicks(); Uint32 mStepTime=( lincitySpeed *1000/NUMOF_DAYS_IN_YEAR); if( lincitySpeed == 0 || blockingDialogIsOpen || ( (now - oldTime < (mStepTime-10)) && (lincitySpeed != FAST_TIME_FOR_YEAR)) ) { SDL_Delay(10); //don't burn cpu in active loop return; } if ( (now - oldTime < mStepTime) && lincitySpeed != FAST_TIME_FOR_YEAR ) return; // skip frame oldTime = now; // TRACE; do_time_step(); //draw the updated city //in FAST-Mode, update at the last day in Month, so print_stats will work. if( ( lincitySpeed != FAST_TIME_FOR_YEAR ) || ( total_time % ( NUMOF_DAYS_IN_MONTH * getConfig()->skipMonthsFast ) == (NUMOF_DAYS_IN_MONTH - 1) ) ){ //update_main_screen (0); //does nothing in NG print_stats (); updateDate(); print_total_money(); getGameView()->requestRedraw(); } }
/** * Either create selected random terrain or load a scenario. **/ void MainMenu::newGameStartButtonClicked(Button* ) { if( mFilename.empty() ){ // std::cout << "nothing selected\n"; return; } getSound()->playSound( "Click" ); int with_village = (getCheckButton(*currentMenu,"WithVillage")->state == CheckButton::STATE_CHECKED)?1:0; if( baseName == "RiverDelta" ){ new_city( &main_screen_originx, &main_screen_originy, with_village ); GameView* gv = getGameView(); if( gv ){ gv->readOrigin(); } quitState = INGAME; running = false; } else if( baseName == "DesertArea" ){ new_desert_city( &main_screen_originx, &main_screen_originy, with_village ); GameView* gv = getGameView(); if( gv ){ gv->readOrigin(); } quitState = INGAME; running = false; } else if( baseName == "TemperateArea" ){ new_temperate_city( &main_screen_originx, &main_screen_originy, with_village ); GameView* gv = getGameView(); if( gv ){ gv->readOrigin(); } quitState = INGAME; running = false; } else if( baseName == "SwampArea" ){ new_swamp_city( &main_screen_originx, &main_screen_originy, with_village ); GameView* gv = getGameView(); if( gv ){ gv->readOrigin(); } quitState = INGAME; running = false; } else { if( loadCityNG( mFilename ) ){ strcpy (given_scene, baseName.c_str()); quitState = INGAME; running = false; } } mFilename = "empty"; //don't erase scenarios later }
/* * Load City and do setup for Lincity NG. */ bool loadCityNG( std::string filename ){ if( file_exists( const_cast<char*>( filename.c_str()) ) ){ load_city(const_cast<char*>(filename.c_str())); update_avail_modules(0); GameView* gv = getGameView(); if( gv ){ gv->readOrigin(); } return true; } return false; }
void Dialog::initDialog( int x /*= -1*/, int y /*= -1*/ ){ Component* root = getGameView(); desktop = 0; myDialogComponent = 0; pointX = x; pointY = y; iAmBlocking = false; if( root ) { while( root->getParent() ) root = root->getParent(); desktop = dynamic_cast<Desktop*> (root); if(!desktop) std::cerr << "Root not a desktop!?!\n"; } else { std::cerr << "Dialog: Root not found.\n"; } }
void updateMoney() { if( lastMoney == total_money ){ return; } //Prevent overflow if (total_money > 2000000000) total_money = 2000000000; else if (total_money < -2000000000) total_money = -2000000000; std::ostringstream moneyText; int money = total_money; if( abs(money) > 100000000 ){ moneyText << money/1000000 << _("M"); } else { if( abs(money) > 1000000 ){ moneyText << money/1000000 << " "; money %= 1000000; money = abs(money); moneyText << std::setw(6); moneyText << std::setfill('0'); } moneyText << money; } moneyText << _("$"); Component* root = getGameView(); if( !root ) return; while( root->getParent() ) root = root->getParent(); Component* moneyParagraphComponent = 0; moneyParagraphComponent = root->findComponent( "moneyParagraph" ); if( moneyParagraphComponent == 0 ) { return; } Paragraph* moneyParagraph = getParagraph( *root, "moneyParagraph"); if( !moneyParagraph ) return; moneyParagraph->setText( moneyText.str() ); lastMoney = total_money; }
void Dialog::gotoButtonClicked( Button* ){ getGameView()->show( MapPoint( pointX, pointY ) ); }
MainState Game::run() { SDL_Event event; running = true; Uint32 fpsTicks = SDL_GetTicks(); Uint32 lastticks = fpsTicks; Desktop* desktop = dynamic_cast<Desktop*> (gui.get()); if(!desktop) { throw std::runtime_error("Toplevel component is not a Desktop");} gui->resize(getConfig()->videoX, getConfig()->videoY); int frame = 0; while(running) { getGameView()->scroll(); while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_VIDEORESIZE: initVideo(event.resize.w, event.resize.h); gui->resize(event.resize.w, event.resize.h); getConfig()->videoX = event.resize.w; getConfig()->videoY = event.resize.h; break; case SDL_KEYUP: { Event gui_event(event); if( gui_event.keysym.sym == SDLK_ESCAPE ){ getButtonPanel()->selectQueryTool(); break; } if( gui_event.keysym.sym == SDLK_b ){ getButtonPanel()->toggleBulldozeTool(); break; } /* //FIXME hack for monitoring constructionCount if( gui_event.keysym.sym == SDLK_c ){ std::cout << "ConstructionCount.size() = " << constructionCount.size() << std::endl; int i, j; for (i = 0, j = 0; i < constructionCount.size(); i++) {constructionCount[i]?j++:j;} std::cout << "for a total of " << j << " active constructions" << std::endl; break; } */ if( gui_event.keysym.sym == SDLK_p ){ static int i = 0; while(i < constructionCount.size() && !constructionCount[i]) {i++;} if (i < constructionCount.size()) { main_screen_originx = constructionCount[i]->x; main_screen_originy = constructionCount[i]->y; getGameView()->readOrigin(true); mps_set( main_screen_originx, main_screen_originy, MPS_MAP); mps_update(); mps_refresh(); i++; } else { i = 0; } break; } if( gui_event.keysym.sym == SDLK_F1 ){ helpWindow->showTopic("help"); break; } if( gui_event.keysym.sym == SDLK_F12 ){ quickSave(); break; } if( gui_event.keysym.sym == SDLK_F9 ){ quickLoad(); break; } #ifdef DEBUG if( gui_event.keysym.sym == SDLK_F5 ){ testAllHelpFiles(); break; } #endif int need_break=true; switch(gui_event.keysym.sym) { case SDLK_BACKQUOTE: getMiniMap()->mapViewChangeDisplayMode(MiniMap::NORMAL); break; case SDLK_1: getMiniMap()->mapViewChangeDisplayMode(MiniMap::STARVE); break; case SDLK_2: getMiniMap()->mapViewChangeDisplayMode(MiniMap::UB40); break; case SDLK_3: getMiniMap()->mapViewChangeDisplayMode(MiniMap::POWER); break; case SDLK_4: getMiniMap()->mapViewChangeDisplayMode(MiniMap::FIRE); break; case SDLK_5: getMiniMap()->mapViewChangeDisplayMode(MiniMap::CRICKET); break; case SDLK_6: getMiniMap()->mapViewChangeDisplayMode(MiniMap::HEALTH); break; case SDLK_7: getMiniMap()->mapViewChangeDisplayMode(MiniMap::TRAFFIC); break; case SDLK_8: getMiniMap()->mapViewChangeDisplayMode(MiniMap::POLLUTION); break; case SDLK_9: getMiniMap()->mapViewChangeDisplayMode(MiniMap::COAL); break; case SDLK_0: getMiniMap()->mapViewChangeDisplayMode(MiniMap::COMMODITIES); break; default: need_break=false; } if (need_break) break; gui->event(gui_event); break; } case SDL_MOUSEMOTION: case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: case SDL_KEYDOWN: { Event gui_event(event); gui->event(gui_event); break; } case SDL_ACTIVEEVENT: if( event.active.gain == 1 ){ gui->resize( gui->getWidth(), gui->getHeight() ); } break; case SDL_VIDEOEXPOSE: gui->resize( gui->getWidth(), gui->getHeight() ); break; case SDL_QUIT: saveCityNG( "9_currentGameNG.scn" ); running = false; quitState = QUIT; break; default: break; } } // create update Event Uint32 ticks = SDL_GetTicks(); float elapsedTime = ((float) (ticks - lastticks)) / 1000.0; gui->event(Event(elapsedTime)); lastticks = ticks; helpWindow->update(); if(desktop->needsRedraw()) { desktop->draw(*painter); flipScreenBuffer(); } frame++; // Slow down cpu consumption in pause mode if(ticks - fpsTicks > 1000 && lincitySpeed) { #ifdef DEBUG_FPS printf("FPS: %d.\n", (frame*1000) / (ticks - fpsTicks)); #endif getEconomyGraph()->newFPS( frame ); frame = 0; fpsTicks = ticks; } else if(!lincitySpeed) { frame = 0;} /* SDL_Delay is done in execute_timestep */ execute_timestep (); } return quitState; }
void Game::quickSave(){ //save file getGameView()->printStatusMessage( "quick save..."); saveCityNG( "quicksave.scn" ); }
void editMap (MapPoint point, int button) { if( !getGameView()->inCity( point ) ){ return; } int x = point.x; int y = point.y; int selected_module_group = get_group_of_type(selected_module_type); int size; // int x, y; /* mappoint */ int mod_x, mod_y; /* upper left coords of module clicked on */ int mps_result; if (MP_TYPE(x,y) == CST_USED) { mod_x = MP_INFO(x,y).int_1; mod_y = MP_INFO(x,y).int_2; } else { mod_x = x; mod_y = y; } /* Bring up mappoint_stats for any right mouse click */ if (button == SDL_BUTTON_RIGHT) { mps_set( x, y, MPS_ENV); return; } /* Handle bulldozing */ if (selected_module_type == CST_GREEN && button != SDL_BUTTON_RIGHT) { check_bulldoze_area (x, y); mps_result = mps_set( mod_x, mod_y, MPS_MAP ); // Update mps on bulldoze #ifdef DEBUG DBG_TileInfo(x, y); #endif return; } /* Bring up mappoint_stats for certain left mouse clicks */ /* Check market and port double-clicks here */ /* Check rocket launches */ if( !GROUP_IS_BARE(MP_GROUP( x,y )) ) { if(mapMPS) mapMPS->playBuildingSound( mod_x, mod_y ); mps_result = mps_set( mod_x, mod_y, MPS_MAP ); //query Tool #ifdef DEBUG DBG_TileInfo(x, y); #endif if( mps_result >= 1 ){ if( MP_GROUP( mod_x,mod_y ) == GROUP_MARKET ){ clicked_market_cb (mod_x, mod_y); return; } else if (MP_GROUP(mod_x,mod_y) == GROUP_PORT) { clicked_port_cb (mod_x, mod_y); return; } else if (MP_TYPE(mod_x,mod_y) >= CST_ROCKET_5 && MP_TYPE(mod_x,mod_y) <= CST_ROCKET_7){ //Dialogs delete themself new Dialog( ASK_LAUNCH_ROCKET, mod_x,mod_y ); return; } } //to be here we are not in bulldoze-mode and the tile //under the cursor is not empty. //to allow up/downgrading of Tracks,Roads,Rails and bridges we can't always return. if( ( selected_module_type != CST_TRACK_LR ) && ( selected_module_type != CST_ROAD_LR ) && ( selected_module_type != CST_RAIL_LR ) ) { return; //not building a transport } if( ( MP_GROUP(x,y) != GROUP_WATER ) && ( !( MP_INFO(x,y).flags & FLAG_IS_TRANSPORT ))){ return; //target area is neither water not a transport } if( selected_module_type == CST_TRACK_LR ) { if( MP_GROUP( x, y ) == GROUP_TRACK || MP_GROUP( x, y ) == GROUP_TRACK_BRIDGE || MP_GROUP( x, y ) == GROUP_ROAD || MP_GROUP( x, y ) == GROUP_ROAD_BRIDGE || MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE ) return; } else if( selected_module_type == CST_ROAD_LR ) { if ( MP_GROUP( x, y ) == GROUP_ROAD || MP_GROUP( x, y ) == GROUP_ROAD_BRIDGE || MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE ) return; } else if( selected_module_type == CST_RAIL_LR ) { if( MP_GROUP( x, y ) == GROUP_RAIL || MP_GROUP( x, y ) == GROUP_RAIL_BRIDGE ) return; } } //query Tool if(selected_module_type==CST_NONE) { if (mapMPS) { mapMPS->playBuildingSound( mod_x, mod_y ); mapMPS->setView(MapPoint( mod_x, mod_y )); } mps_result = mps_set( mod_x, mod_y, MPS_MAP ); //query Tool on CST_NONE #ifdef DEBUG DBG_TileInfo(x, y); #endif return; } /* OK, by now we are certain that the user wants to place the item. Set the origin based on the size of the selected_module_type, and see if the selected item will fit. */ size = main_groups[selected_module_group].size; /* if (px > (mw->x + mw->w) - size*16) px = (mw->x + mw->w) - size*16; if (py > (mw->y + mw->h) - size*16) py = (mw->y + mw->h) - size*16; pixel_to_mappoint(px, py, &x, &y); */ //Check if we are too close to the border if( x + size > WORLD_SIDE_LEN - 1 || y + size > WORLD_SIDE_LEN - 1 || x < 1 || y < 1 ) return; if (size >= 2) { if (!GROUP_IS_BARE(MP_GROUP(x + 1,y)) || !GROUP_IS_BARE(MP_GROUP(x,y + 1)) || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 1))) return; } if (size >= 3) { if (!GROUP_IS_BARE(MP_GROUP(x + 2,y)) || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 1)) || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 2)) || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 2)) || !GROUP_IS_BARE(MP_GROUP(x,y + 2))) return; } if (size == 4) { if (!GROUP_IS_BARE(MP_GROUP(x + 3,y)) || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 1)) || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 2)) || !GROUP_IS_BARE(MP_GROUP(x + 3,y + 3)) || !GROUP_IS_BARE(MP_GROUP(x + 2,y + 3)) || !GROUP_IS_BARE(MP_GROUP(x + 1,y + 3)) || !GROUP_IS_BARE(MP_GROUP(x,y + 3))) return; } //how to build a lake in the park? //just hold 'W' key on build ;-) if( selected_module_group == GROUP_PARKLAND ){ Uint8 *keystate = SDL_GetKeyState(NULL); if ( keystate[SDLK_w] ) selected_module_type = CST_PARKLAND_LAKE; else selected_module_type = CST_PARKLAND_PLANE; } /* Place the selected item . Warning messages are managed by place_item(...) */ last_message_group = place_item (x, y, selected_module_type); switch (last_message_group) { case 0: /* Success */ getSound()->playSound( "Build" ); mps_result = mps_set( mod_x, mod_y, MPS_MAP ); // Update mps on well-built #ifdef DEBUG DBG_TileInfo(x, y); #endif break; case -1000: /* ouch group does not exist */ case -1: /* Not enough money */ case -2: /* Improper port placement */ case -3: /* too many windmills/substations */ case -4: /* too many market */ case -5: /* previous tip here, cannot build tip here */ case -6: /* previous tip here, cannot build oremine */ case -7: /* no ore reserve. cannot build oremine here */ default: /* warning messages are managed by place item */ last_message_group = 0; } }
/* * get Data form Lincity NG and Save City */ void saveCityNG( std::string newFilename ){ GameView* gv = getGameView(); if( gv ){ gv->writeOrigin(); } save_city(const_cast<char*>( newFilename.c_str() ) ); }