X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=2ba8e9e6126e867d8f5c7edc6b92479707e1711f;hb=d01e22a131aef25baab99c9478faf9e94531c4fd;hp=e387efc789eab8e6cfb9fedf6e033a8ab28a533f;hpb=1a5c85211f0a5b74366d264260d464266afb208d;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index e387efc7..2ba8e9e6 100644 --- a/src/files.c +++ b/src/files.c @@ -244,6 +244,12 @@ static struct LevelFileConfigInfo chunk_config_INFO[] = &li.auto_exit_sokoban, FALSE }, + { + -1, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(10), + &li.auto_count_gems, FALSE + }, + { -1, -1, -1, -1, @@ -800,6 +806,44 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] = &li.num_ball_contents, 4, MAX_ELEMENT_CONTENTS }, + { + EL_MM_MCDUFFIN, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(1), + &li.mm_laser_red, FALSE + }, + { + EL_MM_MCDUFFIN, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(2), + &li.mm_laser_green, FALSE + }, + { + EL_MM_MCDUFFIN, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(3), + &li.mm_laser_blue, TRUE + }, + + { + EL_DF_LASER, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(1), + &li.df_laser_red, TRUE + }, + { + EL_DF_LASER, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(2), + &li.df_laser_green, TRUE + }, + { + EL_DF_LASER, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(3), + &li.df_laser_blue, FALSE + }, + + { + EL_MM_FUSE, -1, + TYPE_INTEGER, CONF_VALUE_16_BIT(1), + &li.mm_time_fuse, 0 + }, + /* ---------- unused values ----------------------------------------------- */ { @@ -1319,6 +1363,8 @@ filetype_id_list[] = { LEVEL_FILE_TYPE_DX, "DX" }, { LEVEL_FILE_TYPE_SB, "SB" }, { LEVEL_FILE_TYPE_DC, "DC" }, + { LEVEL_FILE_TYPE_MM, "MM" }, + { LEVEL_FILE_TYPE_MM, "DF" }, { -1, NULL }, }; @@ -1601,6 +1647,7 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level) setLevelInfoToDefaults_EM(); setLevelInfoToDefaults_SP(); + setLevelInfoToDefaults_MM(); level->native_em_level = &native_em_level; level->native_sp_level = &native_sp_level; @@ -1635,6 +1682,9 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level) BorderElement = EL_STEELWALL; + /* detect custom elements when loading them */ + level->file_has_custom_elements = FALSE; + /* set all bug compatibility flags to "false" => do not emulate this bug */ level->use_action_after_change_bug = FALSE; @@ -1916,6 +1966,26 @@ static int getFileTypeFromBasename(char *basename) return LEVEL_FILE_TYPE_UNKNOWN; } +static int getFileTypeFromMagicBytes(char *filename, int type) +{ + File *file; + + if ((file = openFile(filename, MODE_READ))) + { + char chunk_name[CHUNK_ID_LEN + 1]; + + getFileChunkBE(file, chunk_name, NULL); + + if (strEqual(chunk_name, "MMII") || + strEqual(chunk_name, "MIRR")) + type = LEVEL_FILE_TYPE_MM; + + closeFile(file); + } + + return type; +} + static boolean checkForPackageFromBasename(char *basename) { /* !!! WON'T WORK ANYMORE IF getFileTypeFromBasename() ALSO DETECTS !!! @@ -2120,6 +2190,16 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) if (fileExists(lfi->filename)) return; } + else if (leveldir_current->level_filetype != NULL) + { + int filetype = getFiletypeFromID(leveldir_current->level_filetype); + + /* check for specified native level file with standard file name */ + setLevelFileInfo_FormatLevelFilename(lfi, filetype, + "%03d.%s", nr, LEVELFILE_EXTENSION); + if (fileExists(lfi->filename)) + return; + } /* check for native Rocks'n'Diamonds level file */ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND, @@ -2172,6 +2252,9 @@ static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi) { if (lfi->type == LEVEL_FILE_TYPE_UNKNOWN) lfi->type = getFileTypeFromBasename(lfi->basename); + + if (lfi->type == LEVEL_FILE_TYPE_RND) + lfi->type = getFileTypeFromMagicBytes(lfi->filename, lfi->type); } static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr) @@ -2546,6 +2629,8 @@ static int LoadLevel_CUS1(File *file, int chunk_size, struct LevelInfo *level) element_info[element].push_delay_random = 8; } + level->file_has_custom_elements = TRUE; + return chunk_size; } @@ -2572,6 +2657,8 @@ static int LoadLevel_CUS2(File *file, int chunk_size, struct LevelInfo *level) Error(ERR_WARN, "invalid custom element number %d", element); } + level->file_has_custom_elements = TRUE; + return chunk_size; } @@ -2663,6 +2750,8 @@ static int LoadLevel_CUS3(File *file, int chunk_size, struct LevelInfo *level) ei->modified_settings = TRUE; } + level->file_has_custom_elements = TRUE; + return chunk_size; } @@ -2811,6 +2900,8 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level) /* mark this custom element as modified */ ei->modified_settings = TRUE; + level->file_has_custom_elements = TRUE; + return chunk_size; } @@ -2855,6 +2946,8 @@ static int LoadLevel_GRP1(File *file, int chunk_size, struct LevelInfo *level) /* mark this group element as modified */ element_info[element].modified_settings = TRUE; + level->file_has_custom_elements = TRUE; + return chunk_size; } @@ -3147,6 +3240,8 @@ static int LoadLevel_CUSX(File *file, int chunk_size, struct LevelInfo *level) break; } + level->file_has_custom_elements = TRUE; + return real_chunk_size; } @@ -3172,6 +3267,8 @@ static int LoadLevel_GRPX(File *file, int chunk_size, struct LevelInfo *level) *ei = xx_ei; *group = xx_group; + level->file_has_custom_elements = TRUE; + return real_chunk_size; } @@ -3884,14 +3981,15 @@ void CopyNativeLevel_RND_to_MM(struct LevelInfo *level) level_mm->encoding_16bit_field = level->encoding_16bit_field; level_mm->fieldx = MIN(level->fieldx, MM_MAX_PLAYFIELD_WIDTH); - level_mm->fieldy = MIN(level->fieldx, MM_MAX_PLAYFIELD_HEIGHT); + level_mm->fieldy = MIN(level->fieldy, MM_MAX_PLAYFIELD_HEIGHT); level_mm->time = level->time; level_mm->kettles_needed = level->gems_needed; - level_mm->auto_count_kettles = FALSE; - level_mm->laser_red = FALSE; - level_mm->laser_green = FALSE; - level_mm->laser_blue = TRUE; + level_mm->auto_count_kettles = level->auto_count_gems; + + level_mm->laser_red = level->mm_laser_red; + level_mm->laser_green = level->mm_laser_green; + level_mm->laser_blue = level->mm_laser_blue; strcpy(level_mm->name, level->name); strcpy(level_mm->author, level->author); @@ -3901,11 +3999,12 @@ void CopyNativeLevel_RND_to_MM(struct LevelInfo *level) level_mm->score[SC_TIME_BONUS] = level->score[SC_TIME_BONUS]; level_mm->amoeba_speed = level->amoeba_speed; - level_mm->time_fuse = 0; + level_mm->time_fuse = level->mm_time_fuse; - for (y = 0; y < level_mm->fieldx; y++) - for (x = 0; x < level_mm->fieldy; x++) - level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]); + for (x = 0; x < level->fieldx; x++) + for (y = 0; y < level->fieldy; y++) + Ur[x][y] = + level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]); } void CopyNativeLevel_MM_to_RND(struct LevelInfo *level) @@ -3918,22 +4017,31 @@ void CopyNativeLevel_MM_to_RND(struct LevelInfo *level) level->encoding_16bit_field = level_mm->encoding_16bit_field; level->fieldx = MIN(level_mm->fieldx, MAX_LEV_FIELDX); - level->fieldy = MIN(level_mm->fieldx, MAX_LEV_FIELDY); + level->fieldy = MIN(level_mm->fieldy, MAX_LEV_FIELDY); level->time = level_mm->time; level->gems_needed = level_mm->kettles_needed; + level->auto_count_gems = level_mm->auto_count_kettles; + + level->mm_laser_red = level_mm->laser_red; + level->mm_laser_green = level_mm->laser_green; + level->mm_laser_blue = level_mm->laser_blue; strcpy(level->name, level_mm->name); - strcpy(level->author, level_mm->author); + + /* only overwrite author from 'levelinfo.conf' if author defined in level */ + if (!strEqual(level_mm->author, ANONYMOUS_NAME)) + strcpy(level->author, level_mm->author); level->score[SC_PACMAN] = level_mm->score[SC_PACMAN]; level->score[SC_KEY] = level_mm->score[SC_PACMAN]; level->score[SC_TIME_BONUS] = level_mm->score[SC_TIME_BONUS]; level->amoeba_speed = level_mm->amoeba_speed; + level->mm_time_fuse = level_mm->time_fuse; - for (y = 0; y < level->fieldx; y++) - for (x = 0; x < level->fieldy; x++) + for (x = 0; x < level->fieldx; x++) + for (y = 0; y < level->fieldy; y++) level->field[x][y] = map_element_MM_to_RND(level_mm->field[x][y]); } @@ -6253,9 +6361,25 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) level->em_explodes_by_fire = TRUE; } -static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) +static void LoadLevel_InitStandardElements(struct LevelInfo *level) { - int i, j, x, y; + int i, x, y; + + /* map elements that have changed in newer versions */ + level->amoeba_content = getMappedElementByVersion(level->amoeba_content, + level->game_version); + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) + for (x = 0; x < 3; x++) + for (y = 0; y < 3; y++) + level->yamyam_content[i].e[x][y] = + getMappedElementByVersion(level->yamyam_content[i].e[x][y], + level->game_version); + +} + +static void LoadLevel_InitCustomElements(struct LevelInfo *level) +{ + int i, j; /* map custom element change events that have changed in newer versions (these following values were accidentally changed in version 3.0.1) @@ -6369,19 +6493,30 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } - /* map elements that have changed in newer versions */ - level->amoeba_content = getMappedElementByVersion(level->amoeba_content, - level->game_version); - for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) - for (x = 0; x < 3; x++) - for (y = 0; y < 3; y++) - level->yamyam_content[i].e[x][y] = - getMappedElementByVersion(level->yamyam_content[i].e[x][y], - level->game_version); + /* set some other uninitialized values of custom elements in older levels */ + if (level->game_version < VERSION_IDENT(3,1,0,0)) + { + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + element_info[element].access_direction = MV_ALL_DIRECTIONS; + + element_info[element].explosion_delay = 17; + element_info[element].ignition_delay = 8; + } + } +} + +static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) +{ + LoadLevel_InitStandardElements(level); + + if (level->file_has_custom_elements) + LoadLevel_InitCustomElements(level); /* initialize element properties for level editor etc. */ InitElementPropertiesEngine(level->game_version); - InitElementPropertiesAfterLoading(level->game_version); InitElementPropertiesGfxElement(); } @@ -8331,6 +8466,8 @@ static struct TokenInfo editor_cascade_setup_tokens[] = { TYPE_SWITCH, &seci.el_sp, "editor.cascade.el_sp" }, { TYPE_SWITCH, &seci.el_dc, "editor.cascade.el_dc" }, { TYPE_SWITCH, &seci.el_dx, "editor.cascade.el_dx" }, + { TYPE_SWITCH, &seci.el_mm, "editor.cascade.el_mm" }, + { TYPE_SWITCH, &seci.el_df, "editor.cascade.el_df" }, { TYPE_SWITCH, &seci.el_chars, "editor.cascade.el_chars" }, { TYPE_SWITCH, &seci.el_steel_chars, "editor.cascade.el_steel_chars" }, { TYPE_SWITCH, &seci.el_ce, "editor.cascade.el_ce" }, @@ -8524,6 +8661,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->editor.el_supaplex = TRUE; si->editor.el_diamond_caves = TRUE; si->editor.el_dx_boulderdash = TRUE; + + si->editor.el_mirror_magic = TRUE; + si->editor.el_deflektor = TRUE; + si->editor.el_chars = TRUE; si->editor.el_steel_chars = TRUE; @@ -8659,6 +8800,9 @@ static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si) si->editor_cascade.el_dc = TRUE; si->editor_cascade.el_dx = TRUE; + si->editor_cascade.el_mm = TRUE; + si->editor_cascade.el_df = TRUE; + si->editor_cascade.el_chars = FALSE; si->editor_cascade.el_steel_chars = FALSE; si->editor_cascade.el_ce = FALSE;