X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=ac4bd38a2e7c1e85290dcda36b8358207794c39a;hb=b4865a65808ffd72a4f98d09cdb332582e464500;hp=38b19f83c58c1429a246a833fef20bcdac685407;hpb=03a51cffeae04186383ded4280b3ebb923cdbc6f;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 38b19f83..ac4bd38a 100644 --- a/src/files.c +++ b/src/files.c @@ -327,6 +327,11 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] = TYPE_BOOLEAN, CONF_VALUE_8_BIT(16), &li.finish_dig_collect, TRUE }, + { + EL_PLAYER_1, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(17), + &li.keep_walkable_ce, FALSE + }, // (these values are different for each player) { @@ -3637,7 +3642,7 @@ static void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) // initialize player positions and delete players from the playfield for (y = 0; y < cav->height; y++) for (x = 0; x < cav->width; x++) { - if (ELEM_IS_PLAYER(level->field[x][y])) + if (IS_PLAYER_ELEMENT(level->field[x][y])) { int player_nr = GET_PLAYER_NR(level->field[x][y]); @@ -6126,6 +6131,7 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level, level->time = 0; level->use_step_counter = TRUE; + level->auto_exit_sokoban = TRUE; if (load_xsb_to_ces) { @@ -6463,6 +6469,36 @@ static void LoadLevel_InitVersion(struct LevelInfo *level) // CE actions were triggered by unfinished digging/collecting up to 4.2.2.0 if (level->game_version <= VERSION_IDENT(4,2,2,0)) level->finish_dig_collect = FALSE; + + // CE changing to player was kept under the player if walkable up to 4.2.3.1 + if (level->game_version <= VERSION_IDENT(4,2,3,1)) + level->keep_walkable_ce = TRUE; +} + +static void LoadLevel_InitSettings_SB(struct LevelInfo *level) +{ + boolean is_sokoban_level = TRUE; // unless non-Sokoban elements found + int x, y; + + // check if this level is (not) a Sokoban level + for (y = 0; y < level->fieldy; y++) + for (x = 0; x < level->fieldx; x++) + if (!IS_SB_ELEMENT(Tile[x][y])) + is_sokoban_level = FALSE; + + if (is_sokoban_level) + { + // set special level settings for Sokoban levels + level->time = 0; + level->use_step_counter = TRUE; + level->auto_exit_sokoban = TRUE; + } +} + +static void LoadLevel_InitSettings(struct LevelInfo *level) +{ + // adjust level settings for (non-native) Sokoban-style levels + LoadLevel_InitSettings_SB(level); } static void LoadLevel_InitStandardElements(struct LevelInfo *level) @@ -6691,6 +6727,7 @@ static void LoadLevelTemplate_LoadAndInit(void) LoadLevel_InitVersion(&level_template); LoadLevel_InitElements(&level_template); + LoadLevel_InitSettings(&level_template); ActivateLevelTemplate(); } @@ -6731,6 +6768,7 @@ static void LoadLevel_LoadAndInit(struct NetworkLevelInfo *network_level) LoadLevel_InitVersion(&level); LoadLevel_InitElements(&level); LoadLevel_InitPlayfield(&level); + LoadLevel_InitSettings(&level); LoadLevel_InitNativeEngines(&level); } @@ -7656,10 +7694,33 @@ void DumpLevel(struct LevelInfo *level) Print("SP player blocks last field: %s\n", (level->sp_block_last_field ? "yes" : "no")); Print("use spring bug: %s\n", (level->use_spring_bug ? "yes" : "no")); Print("use step counter: %s\n", (level->use_step_counter ? "yes" : "no")); + Print("rate time over score: %s\n", (level->rate_time_over_score ? "yes" : "no")); PrintLine("-", 79); } +void DumpLevels(void) +{ + static LevelDirTree *dumplevel_leveldir = NULL; + + dumplevel_leveldir = getTreeInfoFromIdentifier(leveldir_first, + global.dumplevel_leveldir); + + if (dumplevel_leveldir == NULL) + Fail("no such level identifier: '%s'", global.dumplevel_leveldir); + + if (global.dumplevel_level_nr < dumplevel_leveldir->first_level || + global.dumplevel_level_nr > dumplevel_leveldir->last_level) + Fail("no such level number: %d", global.dumplevel_level_nr); + + leveldir_current = dumplevel_leveldir; + + LoadLevel(global.dumplevel_level_nr); + DumpLevel(&level); + + CloseAllAndExit(0); +} + // ============================================================================ // tape file functions @@ -8419,6 +8480,32 @@ void DumpTape(struct TapeInfo *tape) PrintLine("-", 79); } +void DumpTapes(void) +{ + static LevelDirTree *dumptape_leveldir = NULL; + + dumptape_leveldir = getTreeInfoFromIdentifier(leveldir_first, + global.dumptape_leveldir); + + if (dumptape_leveldir == NULL) + Fail("no such level identifier: '%s'", global.dumptape_leveldir); + + if (global.dumptape_level_nr < dumptape_leveldir->first_level || + global.dumptape_level_nr > dumptape_leveldir->last_level) + Fail("no such level number: %d", global.dumptape_level_nr); + + leveldir_current = dumptape_leveldir; + + if (options.mytapes) + LoadTape(global.dumptape_level_nr); + else + LoadSolutionTape(global.dumptape_level_nr); + + DumpTape(&tape); + + CloseAllAndExit(0); +} + // ============================================================================ // score file functions @@ -8441,6 +8528,7 @@ static void setScoreInfoToDefaultsExt(struct ScoreInfo *scores) scores->last_added_local = -1; scores->updated = FALSE; + scores->force_last_added = FALSE; } static void setScoreInfoToDefaults(void) @@ -8742,7 +8830,6 @@ void LoadScore(int nr) void SaveScore_OLD(int nr) { int i; - int permissions = (program.global_scores ? PERMS_PUBLIC : PERMS_PRIVATE); char *filename = getScoreFilename(nr); FILE *file; @@ -8763,7 +8850,7 @@ void SaveScore_OLD(int nr) fclose(file); - SetFilePermissions(filename, permissions); + SetFilePermissions(filename, PERMS_PRIVATE); } #endif @@ -8832,7 +8919,6 @@ static void SaveScore_TAPE(FILE *file, struct ScoreInfo *scores) static void SaveScoreToFilename(char *filename) { FILE *file; - int permissions = (program.global_scores ? PERMS_PUBLIC : PERMS_PRIVATE); int info_chunk_size; int name_chunk_size; int scor_chunk_size; @@ -8875,7 +8961,7 @@ static void SaveScoreToFilename(char *filename) fclose(file); - SetFilePermissions(filename, permissions); + SetFilePermissions(filename, PERMS_PRIVATE); } void SaveScore(int nr) @@ -8929,7 +9015,7 @@ static void DownloadServerScoreToCacheExt(struct HttpRequest *request, struct HttpResponse *response, int nr) { - request->hostname = API_SERVER_HOSTNAME; + request->hostname = setup.api_server_hostname; request->port = API_SERVER_PORT; request->method = API_SERVER_METHOD; request->uri = API_SERVER_URI_GET; @@ -9094,7 +9180,7 @@ void LoadServerScore(int nr, boolean download_score) // (this should prevent reading it while the thread is writing to it) LoadServerScoreFromCache(nr); - if (download_score) + if (download_score && runtime.api_server) { // 2nd step: download server scores from score server to cache file // (as thread, as it might time out if the server is not reachable) @@ -9162,7 +9248,7 @@ static void UploadScoreToServerExt(struct HttpRequest *request, { struct ScoreEntry *score_entry = &scores.entry[scores.last_added]; - request->hostname = API_SERVER_HOSTNAME; + request->hostname = setup.api_server_hostname; request->port = API_SERVER_PORT; request->method = API_SERVER_METHOD; request->uri = API_SERVER_URI_ADD; @@ -9253,7 +9339,7 @@ static void UploadScoreToServerAsThread(int nr) void SaveServerScore(int nr) { - if (!setup.api_server) + if (!runtime.api_server) return; UploadScoreToServerAsThread(nr); @@ -9268,7 +9354,7 @@ void LoadLocalAndServerScore(int nr, boolean download_score) // restore last added local score entry (before merging server scores) scores.last_added = scores.last_added_local = last_added_local; - if (setup.api_server) + if (setup.api_server && !setup.only_show_local_scores) { // load server scores from cache file and trigger update from server LoadServerScore(nr, download_score); @@ -9464,6 +9550,10 @@ static struct TokenInfo global_setup_tokens[] = TYPE_SWITCH, &setup.show_snapshot_buttons, "show_snapshot_buttons" }, + { + TYPE_SWITCH, + &setup.only_show_local_scores, "only_show_local_scores" + }, { TYPE_STRING, &setup.graphics_set, "graphics_set" @@ -10136,6 +10226,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->sp_show_border_elements = FALSE; si->small_game_graphics = FALSE; si->show_snapshot_buttons = FALSE; + si->only_show_local_scores = FALSE; si->graphics_set = getStringCopy(GFX_CLASSIC_SUBDIR); si->sounds_set = getStringCopy(SND_CLASSIC_SUBDIR); @@ -13033,8 +13124,8 @@ void CreateLevelSketchImages(void) sprintf(basename1, "%04d.bmp", i); sprintf(basename2, "%04ds.bmp", i); - filename1 = getPath2(global.create_images_dir, basename1); - filename2 = getPath2(global.create_images_dir, basename2); + filename1 = getPath2(global.create_sketch_images_dir, basename1); + filename2 = getPath2(global.create_sketch_images_dir, basename2); DrawSizedElement(0, 0, element, TILESIZE); BlitBitmap(drawto, bitmap1, SX, SY, TILEX, TILEY, 0, 0); @@ -13078,6 +13169,104 @@ void CreateLevelSketchImages(void) } +// ---------------------------------------------------------------------------- +// create and save images for element collecting animations (raw BMP format) +// ---------------------------------------------------------------------------- + +static boolean createCollectImage(int element) +{ + return (IS_COLLECTIBLE(element) && !IS_SP_ELEMENT(element)); +} + +void CreateCollectElementImages(void) +{ + int i, j; + int num_steps = 8; + int anim_frames = num_steps - 1; + int tile_size = TILESIZE; + int anim_width = tile_size * anim_frames; + int anim_height = tile_size; + int num_collect_images = 0; + int pos_collect_images = 0; + + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + if (createCollectImage(i)) + num_collect_images++; + + Info("Creating %d element collecting animation images ...", + num_collect_images); + + int dst_width = anim_width * 2; + int dst_height = anim_height * num_collect_images / 2; + Bitmap *dst_bitmap = CreateBitmap(dst_width, dst_height, DEFAULT_DEPTH); + char *basename = "RocksCollect.bmp"; + char *filename = getPath2(global.create_collect_images_dir, basename); + + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + { + if (!createCollectImage(i)) + continue; + + int dst_x = (pos_collect_images / (num_collect_images / 2)) * anim_width; + int dst_y = (pos_collect_images % (num_collect_images / 2)) * anim_height; + int graphic = el2img(i); + char *token_name = element_info[i].token_name; + Bitmap *tmp_bitmap = CreateBitmap(tile_size, tile_size, DEFAULT_DEPTH); + Bitmap *src_bitmap; + int src_x, src_y; + + Info("- creating collecting image for '%s' ...", token_name); + + getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y); + + BlitBitmap(src_bitmap, tmp_bitmap, src_x, src_y, + tile_size, tile_size, 0, 0); + + tmp_bitmap->surface_masked = tmp_bitmap->surface; + + for (j = 0; j < anim_frames; j++) + { + int frame_size_final = tile_size * (anim_frames - j) / num_steps; + int frame_size = frame_size_final * num_steps; + int offset = (tile_size - frame_size_final) / 2; + Bitmap *frame_bitmap = ZoomBitmap(tmp_bitmap, frame_size, frame_size); + + while (frame_size > frame_size_final) + { + frame_size /= 2; + + Bitmap *half_bitmap = ZoomBitmap(frame_bitmap, frame_size, frame_size); + + FreeBitmap(frame_bitmap); + + frame_bitmap = half_bitmap; + } + + BlitBitmap(frame_bitmap, dst_bitmap, 0, 0, + frame_size_final, frame_size_final, + dst_x + j * tile_size + offset, dst_y + offset); + + FreeBitmap(frame_bitmap); + } + + tmp_bitmap->surface_masked = NULL; + + FreeBitmap(tmp_bitmap); + + pos_collect_images++; + } + + if (SDL_SaveBMP(dst_bitmap->surface, filename) != 0) + Fail("cannot save element collecting image file '%s'", filename); + + FreeBitmap(dst_bitmap); + + Info("Done."); + + CloseAllAndExit(0); +} + + // ---------------------------------------------------------------------------- // create and save images for custom and group elements (raw BMP format) // ----------------------------------------------------------------------------