void mapbuffer::save() { std::map<tripoint, submap*, pointcomp>::iterator it; std::ofstream fout; fout.open("save/maps.txt"); fout << submap_list.size() << std::endl; int num_saved_submaps = 0; int num_total_submaps = submap_list.size(); for (it = submaps.begin(); it != submaps.end(); it++) { if (num_saved_submaps % 100 == 0) popup_nowait(_("Please wait as the map saves [%d/%d]"), num_saved_submaps, num_total_submaps); fout << it->first.x << " " << it->first.y << " " << it->first.z << std::endl; submap *sm = it->second; fout << sm->turn_last_touched << std::endl; // Dump the terrain. for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) fout << int(sm->ter[i][j]) << " "; fout << std::endl; } // Dump the radiation for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) fout << sm->rad[i][j] << " "; } fout << std::endl; // Furniture for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { if (sm->frn[i][j] != f_null) fout << "f " << i << " " << j << " " << sm->frn[i][j] << std::endl; } } // Items section; designate it with an I. Then check itm[][] for each square // in the grid and print the coords and the item's details. // Designate it with a C if it's contained in the prior item. // Also, this wastes space since we print the coords for each item, when we // could be printing a list of items for each coord (except the empty ones) item tmp; for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { for (int k = 0; k < sm->itm[i][j].size(); k++) { tmp = sm->itm[i][j][k]; fout << "I " << i << " " << j << std::endl; fout << tmp.save_info() << std::endl; for (int l = 0; l < tmp.contents.size(); l++) fout << "C " << std::endl << tmp.contents[l].save_info() << std::endl; } } } // Output the traps for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { if (sm->trp[i][j] != tr_null) fout << "T " << i << " " << j << " " << sm->trp[i][j] << std::endl; } } // Output the fields for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { if (sm->fld[i][j].fieldCount() > 0) { for(std::map<field_id, field_entry*>::iterator it = sm->fld[i][j].getFieldStart(); it != sm->fld[i][j].getFieldEnd(); ++it) { if(it->second != NULL) { fout << "F " << i << " " << j << " " << int(it->second->getFieldType()) << " " << int(it->second->getFieldDensity()) << " " << (it->second->getFieldAge()) << std::endl; } } } } } // Output the spawn points spawn_point tmpsp; for (int i = 0; i < sm->spawns.size(); i++) { tmpsp = sm->spawns[i]; fout << "S " << int(tmpsp.type) << " " << tmpsp.count << " " << tmpsp.posx << " " << tmpsp.posy << " " << tmpsp.faction_id << " " << tmpsp.mission_id << (tmpsp.friendly ? " 1 " : " 0 ") << tmpsp.name << std::endl; } // Output the vehicles for (int i = 0; i < sm->vehicles.size(); i++) { fout << "V "; sm->vehicles[i]->save (fout); } // Output the computer if (sm->comp.name != "") fout << "c " << sm->comp.save_data() << std::endl; // Output base camp if any if (sm->camp.is_valid()) fout << "B " << sm->camp.save_data() << std::endl; // Output the graffiti for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { if (sm->graf[i][j].contents) fout << "G " << i << " " << j << *sm->graf[i][j].contents << std::endl; } } fout << "----" << std::endl; num_saved_submaps++; } // Close the file; that's all we need. fout.close(); }
void defense_game::init_map(game *g) { for (int x = 0; x < OMAPX; x++) { for (int y = 0; y < OMAPY; y++) { g->cur_om->ter(x, y, 0) = ot_field; g->cur_om->seen(x, y, 0) = true; } } g->cur_om->save(); g->levx = 100; g->levy = 100; g->levz = 0; g->u.posx = SEEX; g->u.posy = SEEY; switch (location) { case DEFLOC_HOSPITAL: for (int x = 49; x <= 51; x++) { for (int y = 49; y <= 51; y++) g->cur_om->ter(x, y, 0) = ot_hospital; } g->cur_om->ter(50, 49, 0) = ot_hospital_entrance; break; case DEFLOC_MALL: for (int x = 49; x <= 51; x++) { for (int y = 49; y <= 51; y++) g->cur_om->ter(x, y, 0) = ot_megastore; } g->cur_om->ter(50, 49, 0) = ot_megastore_entrance; break; case DEFLOC_BAR: g->cur_om->ter(50, 50, 0) = ot_bar_north; break; case DEFLOC_MANSION: for (int x = 49; x <= 51; x++) { for (int y = 49; y <= 51; y++) g->cur_om->ter(x, y, 0) = ot_mansion; } g->cur_om->ter(50, 49, 0) = ot_mansion_entrance; break; } // Init the map int old_percent = 0; for (int i = 0; i <= MAPSIZE * 2; i += 2) { for (int j = 0; j <= MAPSIZE * 2; j += 2) { int mx = g->levx - MAPSIZE + i, my = g->levy - MAPSIZE + j; int percent = 100 * ((j / 2 + MAPSIZE * (i / 2))) / ((MAPSIZE) * (MAPSIZE + 1)); if (percent >= old_percent + 1) { popup_nowait("Please wait as the map generates [%s%d%]", (percent < 10 ? " " : ""), percent); old_percent = percent; } // Round down to the nearest even number mx -= mx % 2; my -= my % 2; tinymap tm(&g->itypes, &g->mapitems, &g->traps); tm.generate(g, g->cur_om, mx, my, 0, int(g->turn)); tm.clear_spawns(); tm.clear_traps(); tm.save(g->cur_om, int(g->turn), mx, my, 0); } } g->m.load(g, g->levx, g->levy, g->levz, true); g->update_map(g->u.posx, g->u.posy); monster generator(g->mtypes[mon_generator], g->u.posx + 1, g->u.posy + 1); // Find a valid spot to spawn the generator std::vector<point> valid; for (int x = g->u.posx - 1; x <= g->u.posx + 1; x++) { for (int y = g->u.posy - 1; y <= g->u.posy + 1; y++) { if (generator.can_move_to(g, x, y) && g->is_empty(x, y)) valid.push_back( point(x, y) ); } } if (!valid.empty()) { point p = valid[rng(0, valid.size() - 1)]; generator.spawn(p.x, p.y); } generator.friendly = -1; g->z.push_back(generator); }
void mapbuffer::save( bool delete_after_save ) { std::stringstream map_directory; map_directory << world_generator->active_world->world_path << "/maps"; assure_dir_exist( map_directory.str().c_str() ); int num_saved_submaps = 0; int num_total_submaps = submaps.size(); point map_origin; if( g->cur_om != NULL ) { map_origin = overmapbuffer::sm_to_omt_copy( g->get_abs_levx(), g->get_abs_levy() ); } else { map_origin.x = INT_MIN; map_origin.y = INT_MIN; } // A set of already-saved submaps, in global overmap coordinates. std::set<tripoint, pointcomp> saved_submaps; std::list<tripoint> submaps_to_delete; for( submap_map_t::iterator it = submaps.begin(); it != submaps.end(); ++it ) { if (num_total_submaps > 100 && num_saved_submaps % 100 == 0) { popup_nowait(_("Please wait as the map saves [%d/%d]"), num_saved_submaps, num_total_submaps); } // Whatever the coordinates of the current submap are, // we're saving a 2x2 quad of submaps at a time. // Submaps are generated in quads, so we know if we have one member of a quad, // we have the rest of it, if that assumtion is broken we have REAL problems. const tripoint om_addr = overmapbuffer::sm_to_omt_copy( it->first ); if( saved_submaps.count( om_addr ) != 0 ) { // Already handled this one. continue; } saved_submaps.insert( om_addr ); // A segment is a chunk of 32x32 submap quads. // We're breaking them into subdirectories so there aren't too many files per directory. // Might want to make a set for this one too so it's only checked once per save(). std::stringstream segment_path; tripoint segment_addr = overmapbuffer::omt_to_seg_copy( om_addr ); segment_path << map_directory.str() << "/" << segment_addr.x << "." << segment_addr.y << "." << segment_addr.z; assure_dir_exist( segment_path.str().c_str() ); std::stringstream quad_path; quad_path << segment_path.str() << "/" << om_addr.x << "." << om_addr.y << "." << om_addr.z << ".map"; // delete_on_save deletes everything, otherwise delete submaps // outside the current map. save_quad( quad_path.str(), om_addr, submaps_to_delete, delete_after_save || om_addr.z != g->levz || om_addr.x < map_origin.x || om_addr.y < map_origin.y || om_addr.x > map_origin.x + (MAPSIZE / 2) || om_addr.y > map_origin.y + (MAPSIZE / 2) ); num_saved_submaps += 4; } for( std::list<tripoint>::iterator it = submaps_to_delete.begin(); it != submaps_to_delete.end(); ++it ) { remove_submap( *it ); } }
void mapbuffer::load() { if (!master_game) { debugmsg("Can't load mapbuffer without a master_game"); return; } std::map<tripoint, submap*>::iterator it; std::ifstream fin; fin.open("save/maps.txt"); if (!fin.is_open()) return; int itx, ity, t, d, a, num_submaps, num_loaded = 0; item it_tmp; std::string databuff; fin >> num_submaps; while (!fin.eof()) { if (num_loaded % 100 == 0) popup_nowait(_("Please wait as the map loads [%d/%d]"), num_loaded, num_submaps); int locx, locy, locz, turn; submap* sm = new submap; fin >> locx >> locy >> locz >> turn; sm->turn_last_touched = turn; int turndif = (master_game ? int(master_game->turn) - turn : 0); if (turndif < 0) turndif = 0; // Load terrain for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { int tmpter; fin >> tmpter; sm->ter[i][j] = ter_id(tmpter); sm->frn[i][j] = f_null; sm->itm[i][j].clear(); sm->trp[i][j] = tr_null; //sm->fld[i][j] = field(); //not needed now sm->graf[i][j] = graffiti(); } } // Load irradiation for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { int radtmp; fin >> radtmp; radtmp -= int(turndif / 100); // Radiation slowly decays if (radtmp < 0) radtmp = 0; sm->rad[i][j] = radtmp; } } // Load items and traps and fields and spawn points and vehicles std::string string_identifier; do { fin >> string_identifier; // "----" indicates end of this submap t = 0; if (string_identifier == "I") { fin >> itx >> ity; getline(fin, databuff); // Clear out the endline getline(fin, databuff); it_tmp.load_info(databuff, master_game); sm->itm[itx][ity].push_back(it_tmp); if (it_tmp.active) sm->active_item_count++; } else if (string_identifier == "C") { getline(fin, databuff); // Clear out the endline getline(fin, databuff); int index = sm->itm[itx][ity].size() - 1; it_tmp.load_info(databuff, master_game); sm->itm[itx][ity][index].put_in(it_tmp); if (it_tmp.active) sm->active_item_count++; } else if (string_identifier == "T") { fin >> itx >> ity >> t; sm->trp[itx][ity] = trap_id(t); } else if (string_identifier == "f") {
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int argc = __argc; char **argv = __argv; #else int main(int argc, char *argv[]) { #endif int seed = time(NULL); bool verifyexit = false; bool check_all_mods = false; // Set default file paths #ifdef PREFIX #define Q(STR) #STR #define QUOTE(STR) Q(STR) init_base_path(std::string(QUOTE(PREFIX))); #else PATH_INFO::init_base_path(""); #endif #ifdef USE_HOME_DIR PATH_INFO::init_user_dir(); #else PATH_INFO::init_user_dir("./"); #endif PATH_INFO::set_standart_filenames(); MAP_SHARING::setDefaults(); // Process CLI arguments int saved_argc = --argc; // skip program name char **saved_argv = ++argv; while (argc) { if(std::string(argv[0]) == "--seed") { argc--; argv++; if(argc) { seed = djb2_hash((unsigned char *)argv[0]); argc--; argv++; } } else if(std::string(argv[0]) == "--jsonverify") { argc--; argv++; verifyexit = true; } else if(std::string(argv[0]) == "--check-mods") { argc--; argv++; check_all_mods = true; } else if(std::string(argv[0]) == "--basepath") { argc--; argv++; if(argc) { PATH_INFO::init_base_path(std::string(argv[0])); PATH_INFO::set_standart_filenames(); argc--; argv++; } } else if(std::string(argv[0]) == "--userdir") { argc--; argv++; if (argc) { PATH_INFO::init_user_dir( argv[0] ); PATH_INFO::set_standart_filenames(); argc--; argv++; } } else if(std::string(argv[0]) == "--username") { argc--; argv++; if (argc) { MAP_SHARING::setUsername(std::string(argv[0])); argc--; argv++; } } else if(std::string(argv[0]) == "--addadmin") { argc--; argv++; if (argc) { MAP_SHARING::addAdmin(std::string(argv[0])); argc--; argv++; } } else if(std::string(argv[0]) == "--adddebugger") { argc--; argv++; if (argc) { MAP_SHARING::addDebugger(std::string(argv[0])); argc--; argv++; } } else if(std::string(argv[0]) == "--shared") { argc--; argv++; MAP_SHARING::setSharing(true); MAP_SHARING::setCompetitive(true); MAP_SHARING::setWorldmenu(false); } else if(std::string(argv[0]) == "--competitive") { argc--; argv++; MAP_SHARING::setCompetitive(true); } else { // Skipping other options. argc--; argv++; } } while (saved_argc) { if(std::string(saved_argv[0]) == "--worldmenu") { saved_argc--; saved_argv++; MAP_SHARING::setWorldmenu(true); } else if(std::string(saved_argv[0]) == "--datadir") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("datadir", std::string(saved_argv[0])); PATH_INFO::update_datadir(); saved_argc--; saved_argv++; } } else if(std::string(saved_argv[0]) == "--savedir") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("savedir", std::string(saved_argv[0])); saved_argc--; saved_argv++; } } else if(std::string(saved_argv[0]) == "--configdir") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("config_dir", std::string(saved_argv[0])); PATH_INFO::update_config_dir(); saved_argc--; saved_argv++; } } else if(std::string(saved_argv[0]) == "--optionfile") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("options", std::string(saved_argv[0])); saved_argc--; saved_argv++; } } else if(std::string(saved_argv[0]) == "--keymapfile") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("keymap", std::string(saved_argv[0])); saved_argc--; saved_argv++; } } else if(std::string(saved_argv[0]) == "--autopickupfile") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("autopickup", std::string(saved_argv[0])); saved_argc--; saved_argv++; } } else if(std::string(saved_argv[0]) == "--motdfile") { saved_argc--; saved_argv++; if(saved_argc) { PATH_INFO::update_pathname("motd", std::string(saved_argv[0])); saved_argc--; saved_argv++; } } else { // ignore unknown args. saved_argc--; saved_argv++; } } // setup debug loggind #ifdef ENABLE_LOGGING setupDebug(); #endif // set locale to system default setlocale(LC_ALL, ""); #ifdef LOCALIZE const char *locale_dir; #ifdef __linux__ if (!FILENAMES["base_path"].empty()) { locale_dir = std::string(FILENAMES["base_path"] + "share/locale").c_str(); } else { locale_dir = "lang/mo"; } #else locale_dir = "lang/mo"; #endif // __linux__ bindtextdomain("cataclysm-dda", locale_dir); bind_textdomain_codeset("cataclysm-dda", "UTF-8"); textdomain("cataclysm-dda"); #endif // LOCALIZE // ncurses stuff initOptions(); load_options(); // For getting size options #ifdef LOCALIZE setlocale(LC_ALL, OPTIONS["USE_LANG"].getValue().c_str()); #endif // LOCALIZE if (initscr() == NULL) { // Initialize ncurses DebugLog() << "initscr failed!\n"; return 1; } init_interface(); noecho(); // Don't echo keypresses cbreak(); // C-style breaks (e.g. ^C to SIGINT) keypad(stdscr, true); // Numpad is numbers #if !(defined TILES || defined _WIN32 || defined WINDOWS) // For tiles or windows, this is handled already in initscr(). init_colors(); #endif // curs_set(0); // Invisible cursor set_escdelay(10); // Make escape actually responsive std::srand(seed); g = new game; // First load and initialize everything that does not // depend on the mods. try { if (!assure_dir_exist(FILENAMES["user_dir"].c_str())) { debugmsg("Can't open or create %s. Check permissions.", FILENAMES["user_dir"].c_str()); exit_handler(-999); } g->load_static_data(); if (verifyexit) { if(g->game_error()) { exit_handler(-999); } exit_handler(0); } if (check_all_mods) { // Here we load all the mods and check their // consistency (both is done in check_all_mod_data). g->init_ui(); popup_nowait("checking all mods"); g->check_all_mod_data(); if(g->game_error()) { exit_handler(-999); } // At this stage, the mods (and core game data) // are find and we could start playing, but this // is only for verifying that stage, so we exit. exit_handler(0); } } catch(std::string &error_message) { if(!error_message.empty()) { debugmsg("%s", error_message.c_str()); } exit_handler(-999); } // Now we do the actuall game g->init_ui(); if(g->game_error()) { exit_handler(-999); } curs_set(0); // Invisible cursor here, because MAPBUFFER.load() is crash-prone #if (!(defined _WIN32 || defined WINDOWS)) struct sigaction sigIntHandler; sigIntHandler.sa_handler = exit_handler; sigemptyset(&sigIntHandler.sa_mask); sigIntHandler.sa_flags = 0; sigaction(SIGINT, &sigIntHandler, NULL); #endif bool quit_game = false; do { if(!g->opening_screen()) { quit_game = true; } while (!quit_game && !g->do_turn()) ; if (g->game_quit() || g->game_error()) { quit_game = true; } } while (!quit_game); exit_handler(-999); return 0; }
void mapbuffer::save() { std::map<tripoint, submap*, pointcomp>::iterator it; std::ofstream fout; std::stringstream mapfile; mapfile << world_generator->active_world->world_path << "/maps.txt"; fout.open(mapfile.str().c_str()); fout << "# version " << savegame_version << std::endl; JsonOut jsout(fout); jsout.start_object(); jsout.member("listsize", (unsigned int)submap_list.size()); // To keep load speedy, we're saving ints, but since these are ints // that will change with revisions and loaded mods, we're also // including a rosetta stone. jsout.member("terrain_key"); jsout.start_array(); for (int i=0; i < terlist.size(); i++) { jsout.write(terlist[i].id); } jsout.end_array(); jsout.member("furniture_key"); jsout.start_array(); for (int i=0; i < furnlist.size(); i++) { jsout.write(furnlist[i].id); } jsout.end_array(); jsout.member("trap_key"); jsout.start_array(); for (int i=0; i < g->traps.size(); i++) { jsout.write(g->traps[i]->id); } jsout.end_array(); jsout.end_object(); fout << std::endl; int num_saved_submaps = 0; int num_total_submaps = submap_list.size(); for (it = submaps.begin(); it != submaps.end(); it++) { if (num_saved_submaps % 100 == 0) popup_nowait(_("Please wait as the map saves [%d/%d]"), num_saved_submaps, num_total_submaps); fout << it->first.x << " " << it->first.y << " " << it->first.z << std::endl; submap *sm = it->second; fout << sm->turn_last_touched << std::endl; fout << sm->temperature << std::endl; std::stringstream terout; std::stringstream radout; std::stringstream furnout; std::stringstream itemout; std::stringstream trapout; std::stringstream fieldout; std::stringstream graffout; int count = 0; int lastrad = -1; for(int j = 0; j < SEEY; j++){ for(int i = 0; i < SEEX; i++){ // Save terrains terout << int(sm->ter[i][j]) << " "; // Save radiation, re-examine this because it doesnt look like it works right int r = sm->rad[i][j]; if (r == lastrad) { count++; } else { if (count) { radout << count << " "; } radout << r << " "; lastrad = r; count = 1; } // Save furniture if (sm->frn[i][j] != f_null) { furnout << "f " << i << " " << j << " " << sm->frn[i][j] << std::endl; } // Save items item tmp; for (int k = 0; k < sm->itm[i][j].size(); k++) { tmp = sm->itm[i][j][k]; itemout << "I " << i << " " << j << std::endl; itemout << tmp.save_info() << std::endl; for (int l = 0; l < tmp.contents.size(); l++) { itemout << "C " << std::endl << tmp.contents[l].save_info() << std::endl; } } // Save traps if (sm->trp[i][j] != tr_null) { trapout << "T " << i << " " << j << " " << sm->trp[i][j] << std::endl; } // Save fields if (sm->fld[i][j].fieldCount() > 0){ for(std::map<field_id, field_entry*>::iterator it = sm->fld[i][j].getFieldStart(); it != sm->fld[i][j].getFieldEnd(); ++it){ if(it->second != NULL){ fieldout << "F " << i << " " << j << " " << int(it->second->getFieldType()) << " " << int(it->second->getFieldDensity()) << " " << (it->second->getFieldAge()) << std::endl; } } } // Save graffiti if (sm->graf[i][j].contents) { graffout << "G " << i << " " << j << *sm->graf[i][j].contents << std::endl; } } terout << std::endl; } radout << count << std::endl; fout << terout.str() << radout.str() << furnout.str() << itemout.str() << trapout.str() << fieldout.str() << graffout.str(); // Output the spawn points spawn_point tmpsp; for (int i = 0; i < sm->spawns.size(); i++) { tmpsp = sm->spawns[i]; fout << "S " << (tmpsp.type) << " " << tmpsp.count << " " << tmpsp.posx << " " << tmpsp.posy << " " << tmpsp.faction_id << " " << tmpsp.mission_id << (tmpsp.friendly ? " 1 " : " 0 ") << tmpsp.name << std::endl; } // Output the vehicles for (int i = 0; i < sm->vehicles.size(); i++) { fout << "V "; sm->vehicles[i]->save (fout); } // Output the computer if (sm->comp.name != "") fout << "c " << sm->comp.save_data() << std::endl; // Output base camp if any if (sm->camp.is_valid()) fout << "B " << sm->camp.save_data() << std::endl; fout << "----" << std::endl; num_saved_submaps++; } // Close the file; that's all we need. fout.close(); }
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int argc = __argc; char **argv = __argv; #else int main(int argc, char *argv[]) { #endif int seed = time(NULL); bool verifyexit = false; bool check_all_mods = false; // Set default file paths #ifdef PREFIX #define Q(STR) #STR #define QUOTE(STR) Q(STR) PATH_INFO::init_base_path(std::string(QUOTE(PREFIX))); #else PATH_INFO::init_base_path(""); #endif #if (defined USE_HOME_DIR || defined USE_XDG_DIR) PATH_INFO::init_user_dir(); #else PATH_INFO::init_user_dir("./"); #endif PATH_INFO::set_standard_filenames(); MAP_SHARING::setDefaults(); { const char *section_default = nullptr; const char *section_map_sharing = "Map sharing"; const char *section_user_directory = "User directories"; const arg_handler first_pass_arguments[] = { { "--seed", "<string of letters and or numbers>", "Sets the random number generator's seed value", section_default, [&seed](int num_args, const char **params) -> int { if (num_args < 1) return -1; const unsigned char *hash_input = (const unsigned char *) params[0]; seed = djb2_hash(hash_input); return 1; } }, { "--jsonverify", nullptr, "Checks the cdda json files", section_default, [&verifyexit](int, const char **) -> int { verifyexit = true; return 0; } }, { "--check-mods", nullptr, "Checks the json files belonging to cdda mods", section_default, [&check_all_mods](int, const char **) -> int { check_all_mods = true; return 0; } }, { "--basepath", "<path>", "Base path for all game data subdirectories", section_default, [](int num_args, const char **params) { if (num_args < 1) return -1; PATH_INFO::init_base_path(params[0]); PATH_INFO::set_standard_filenames(); return 1; } }, { "--shared", nullptr, "Activates the map-sharing mode", section_map_sharing, [](int, const char **) -> int { MAP_SHARING::setSharing(true); MAP_SHARING::setCompetitive(true); MAP_SHARING::setWorldmenu(false); return 0; } }, { "--username", "<name>", "Instructs map-sharing code to use this name for your character.", section_map_sharing, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; MAP_SHARING::setUsername(params[0]); return 1; } }, { "--addadmin", "<username>", "Instructs map-sharing code to use this name for your character and give you " "access to the cheat functions.", section_map_sharing, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; MAP_SHARING::addAdmin(params[0]); return 1; } }, { "--adddebugger", "<username>", "Informs map-sharing code that you're running inside a debugger", section_map_sharing, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; MAP_SHARING::addDebugger(params[0]); return 1; } }, { "--competitive", nullptr, "Instructs map-sharing code to disable access to the in-game cheat functions", section_map_sharing, [](int, const char **) -> int { MAP_SHARING::setCompetitive(true); return 0; } }, { "--userdir", "<path>", "Base path for user-overrides to files from the ./data directory and named below", section_user_directory, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::init_user_dir(params[0]); PATH_INFO::set_standard_filenames(); return 1; } } }; // The following arguments are dependent on one or more of the previous flags and are run // in a second pass. const arg_handler second_pass_arguments[] = { { "--worldmenu", nullptr, "Enables the world menu in the map-sharing code", section_map_sharing, [](int, const char **) -> int { MAP_SHARING::setWorldmenu(true); return true; } }, { "--datadir", "<directory name>", "Sub directory from which game data is loaded", nullptr, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("datadir", params[0]); PATH_INFO::update_datadir(); return 1; } }, { "--savedir", "<directory name>", "Subdirectory for game saves", section_user_directory, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("savedir", params[0]); return 1; } }, { "--configdir", "<directory name>", "Subdirectory for game configuration", section_user_directory, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("config_dir", params[0]); PATH_INFO::update_config_dir(); return 1; } }, { "--memorialdir", "<directory name>", "Subdirectory for memorials", section_user_directory, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("memorialdir", params[0]); return 1; } }, { "--optionfile", "<filename>", "Name of the options file within the configdir", section_user_directory, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("options", params[0]); return 1; } }, { "--keymapfile", "<filename>", "Name of the keymap file within the configdir", section_user_directory, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("keymap", params[0]); return 1; } }, { "--autopickupfile", "<filename>", "Name of the autopickup options file within the configdir", nullptr, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("autopickup", params[0]); return 1; } }, { "--motdfile", "<filename>", "Name of the message of the day file within the motd directory", nullptr, [](int num_args, const char **params) -> int { if (num_args < 1) return -1; PATH_INFO::update_pathname("motd", params[0]); return 1; } }, }; // Process CLI arguments. const size_t num_first_pass_arguments = sizeof(first_pass_arguments) / sizeof(first_pass_arguments[0]); const size_t num_second_pass_arguments = sizeof(second_pass_arguments) / sizeof(second_pass_arguments[0]); int saved_argc = --argc; // skip program name const char **saved_argv = (const char **)++argv; while (argc) { if(!strcmp(argv[0], "--help")) { printHelpMessage(first_pass_arguments, num_first_pass_arguments, second_pass_arguments, num_second_pass_arguments); return 0; } else { bool arg_handled = false; for (size_t i = 0; i < num_first_pass_arguments; ++i) { auto &arg_handler = first_pass_arguments[i]; if (!strcmp(argv[0], arg_handler.flag)) { argc--; argv++; int args_consumed = arg_handler.handler(argc, (const char **)argv); if (args_consumed < 0) { printf("Failed parsing parameter '%s'\n", *(argv - 1)); exit(1); } argc -= args_consumed; argv += args_consumed; arg_handled = true; break; } } // Skip other options. if (!arg_handled) { --argc; ++argv; } } } while (saved_argc) { bool arg_handled = false; for (size_t i = 0; i < num_second_pass_arguments; ++i) { auto &arg_handler = second_pass_arguments[i]; if (!strcmp(saved_argv[0], arg_handler.flag)) { --saved_argc; ++saved_argv; int args_consumed = arg_handler.handler(saved_argc, saved_argv); if (args_consumed < 0) { printf("Failed parsing parameter '%s'\n", *(argv - 1)); exit(1); } saved_argc -= args_consumed; saved_argv += args_consumed; arg_handled = true; break; } } // Ingore unknown options. if (!arg_handled) { --saved_argc; ++saved_argv; } } } if (!assure_dir_exist(FILENAMES["user_dir"].c_str())) { printf("Can't open or create %s. Check permissions.\n", FILENAMES["user_dir"].c_str()); exit(1); } setupDebug(); if (setlocale(LC_ALL, "") == NULL) { DebugLog(D_WARNING, D_MAIN) << "Error while setlocale(LC_ALL, '')."; } // Options strings loaded with system locale get_options().init(); get_options().load(); set_language(true); if (initscr() == NULL) { // Initialize ncurses DebugLog( D_ERROR, DC_ALL ) << "initscr failed!"; return 1; } init_interface(); noecho(); // Don't echo keypresses cbreak(); // C-style breaks (e.g. ^C to SIGINT) keypad(stdscr, true); // Numpad is numbers #if !(defined TILES || defined _WIN32 || defined WINDOWS) // For tiles or windows, this is handled already in initscr(). init_colors(); #endif // curs_set(0); // Invisible cursor set_escdelay(10); // Make escape actually responsive std::srand(seed); g = new game; // First load and initialize everything that does not // depend on the mods. try { g->load_static_data(); if (verifyexit) { if(g->game_error()) { exit_handler(-999); } exit_handler(0); } if (check_all_mods) { // Here we load all the mods and check their // consistency (both is done in check_all_mod_data). g->init_ui(); popup_nowait("checking all mods"); g->check_all_mod_data(); if(g->game_error()) { exit_handler(-999); } // At this stage, the mods (and core game data) // are find and we could start playing, but this // is only for verifying that stage, so we exit. exit_handler(0); } } catch( const std::exception &err ) { debugmsg( "%s", err.what() ); exit_handler(-999); } // Now we do the actual game. g->init_ui(); if(g->game_error()) { exit_handler(-999); } curs_set(0); // Invisible cursor here, because MAPBUFFER.load() is crash-prone #if (!(defined _WIN32 || defined WINDOWS)) struct sigaction sigIntHandler; sigIntHandler.sa_handler = exit_handler; sigemptyset(&sigIntHandler.sa_mask); sigIntHandler.sa_flags = 0; sigaction(SIGINT, &sigIntHandler, NULL); #endif bool quit_game = false; do { if(!g->opening_screen()) { quit_game = true; } while (!quit_game && !g->do_turn()) ; if (g->game_quit() || g->game_error()) { quit_game = true; } } while (!quit_game); exit_handler(-999); return 0; }
void defense_game::init_map(game *g) { for (int x = 0; x < OMAPX; x++) { for (int y = 0; y < OMAPY; y++) { g->cur_om.ter(x, y) = ot_field; g->cur_om.seen(x, y) = true; } } g->cur_om.save(g->u.name, 0, 0, DEFENSE_Z); g->levx = 100; g->levy = 100; g->levz = 0; g->u.posx = SEEX; g->u.posy = SEEY; switch (location) { case DEFLOC_HOSPITAL: for (int x = 49; x <= 51; x++) { for (int y = 49; y <= 51; y++) g->cur_om.ter(x, y) = ot_hospital; } g->cur_om.ter(50, 49) = ot_hospital_entrance; break; case DEFLOC_MALL: for (int x = 49; x <= 51; x++) { for (int y = 49; y <= 51; y++) g->cur_om.ter(x, y) = ot_megastore; } g->cur_om.ter(50, 49) = ot_megastore_entrance; break; case DEFLOC_BAR: g->cur_om.ter(50, 50) = ot_bar_north; break; case DEFLOC_MANSION: for (int x = 49; x <= 51; x++) { for (int y = 49; y <= 51; y++) g->cur_om.ter(x, y) = ot_mansion; } g->cur_om.ter(50, 49) = ot_mansion_entrance; break; } // Init the map int old_percent = 0; for (int i = 0; i <= MAPSIZE * 2; i += 2) { for (int j = 0; j <= MAPSIZE * 2; j += 2) { int mx = g->levx - MAPSIZE + i, my = g->levy - MAPSIZE + j; int percent = 100 * ((j / 2 + MAPSIZE * (i / 2))) / ((MAPSIZE + 1) * (MAPSIZE + 1)); if (percent >= old_percent + 1) { popup_nowait("Please wait as the map generates [%s%d%]", (percent < 10 ? " " : ""), percent); old_percent = percent; } // Round down to the nearest even number mx -= mx % 2; my -= my % 2; tinymap tm(&g->itypes, &g->mapitems, &g->traps); tm.generate(g, &(g->cur_om), mx, my, int(g->turn)); tm.clear_spawns(); tm.clear_traps(); tm.save(&g->cur_om, int(g->turn), mx, my); } } g->m.load(g, g->levx, g->levy); g->update_map(g->u.posx, g->u.posy); monster generator(g->mtypes[mon_generator], g->u.posx + 1, g->u.posy + 1); generator.friendly = -1; g->z.push_back(generator); }
void Game::generate_kingdoms() { if (!world) { debugmsg("Game::generate_kingdoms() called with NULL world!"); return; } if (!kingdoms.empty()) { for (int i = 0; i < kingdoms.size(); i++) { delete (kingdoms[i]); } } kingdoms.clear(); bool color_free[c_null]; // c_null is the last color for (int i = 0; i < c_null; i++) { color_free[i] = true; } // One kingdom for each race. Start at 1 to skip RACE_NULL. for (int i = 1; i < RACE_MAX; i++) { popup_nowait("Initializing kingdoms (%d of %d)...", i, RACE_MAX - 1); Kingdom* kingdom = new Kingdom; kingdom->uid = i - 1; kingdom->set_game(this); kingdom->race = Race(i); Race_datum* race_dat = Race_data[i]; // Pick a color - try the official race color first if (race_dat->color < c_dkgray && color_free[ race_dat->color ]) { kingdom->color = race_dat->color; color_free[ race_dat->color ] = false; } else { std::vector<nc_color> colors = race_dat->kingdom_colors; // Remove any already-used colors for (int i = 0; i < colors.size(); i++) { if (!color_free[ colors[i] ]) { colors.erase(colors.begin() + i); i--; } } if (colors.empty()) { // Can't use official colors; use a random one std::vector<nc_color> free_colors; // Start at 1 to skip c_black; stop at c_dkgray to skip bright colors for (int i = 1; i < c_dkgray; i++) { if (color_free[i]) { free_colors.push_back( nc_color(i) ); } } if (free_colors.empty()) { // 8 kingdoms used already! kingdom->color = nc_color( rng(1, c_dkgray - 1) ); } else { int index = rng(0, free_colors.size() - 1); kingdom->color = free_colors[index]; color_free[ free_colors[index] ] = false; } } else { // We can use an official color! int index = rng(0, colors.size() - 1); kingdom->color = colors[index]; color_free[ colors[index] ] = false; } } // if (!color_free[race_dat->color]) // Place the kingdom. if (kingdom->place_capital(world)) { kingdoms.push_back( kingdom ); // ...and add to our list. } } // for (int i = 1; i < RACE_MAX; i++) /* Now, expand the kingdoms by placing duchy seats. To keep things fair, each * kingdom gets to place a single city/duchy at a time. We go through our list, * each kingdom taking a turn, until all kingdoms are out of points. */ std::vector<int> points, kingdom_index; for (int i = 0; i < kingdoms.size(); i++) { points.push_back( KINGDOM_EXPANSION_POINTS ); // Defined in kingdom.h kingdom_index.push_back( i ); } int iteration = 0, max_points = points.size() * KINGDOM_EXPANSION_POINTS; while (!kingdom_index.empty()) { iteration++; int total_points = 0; for (int i = 0; i < points.size(); i++) { total_points += points[i]; } int percent = (100 * (max_points - total_points)) / max_points; popup_nowait("Placing duchies... [%d%%%%%%%%]", percent); for (int i = 0; i < kingdom_index.size(); i++) { Kingdom* kingdom = kingdoms[ kingdom_index[i] ]; if (!kingdom->place_duchy_seat(world, points[i])) { kingdom_index.erase( kingdom_index.begin() + i ); points.erase( points.begin() + i ); } } } // Now each kingdom gets to place minor cities in its duchies. for (int i = 0; i < kingdoms.size(); i++) { int percent = (100 * (i + 1)) / kingdoms.size(); popup_nowait("Placing minor cities... [%d%%%%%%%%] [%d/%d]", percent, i + 1, kingdoms.size()); kingdoms[i]->place_minor_cities(world); } // Build roads from the capital to each duchy. Building roads from the duchy to // its minor cities is handled in place_minor_cities(). for (int i = 0; i < kingdoms.size(); i++) { int percent = (100 * (i + 1)) / kingdoms.size(); popup_nowait("Connecting duchies via road... [%d%%%%%%%%]", percent); for (int n = 0; n < kingdoms[i]->dukes.size(); n++) { City* capital = kingdoms[i]->capital; City* duke = kingdoms[i]->dukes[n]; kingdoms[i]->build_road( world, capital, duke ); } } // Finally, swell the territory claimed by each kingdom. int expansions = 3; for (int n = 0; n < expansions; n++) { for (int i = 0; i < kingdoms.size(); i++) { popup_nowait("Expanding territories... (%d/%d; %d/%d)", n + 1, expansions, i + 1, kingdoms.size()); kingdoms[i]->expand_boundaries(world); } } // And setup trade routes for all cities! for (int i = 0; i < kingdoms.size(); i++) { int base_percent = (100 * i) / kingdoms.size(); kingdoms[i]->setup_trade_routes(base_percent); } }