X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=c8580105cfcef25a13b193902a9c8fa8d0732c9c;hb=564a563aee2c9fdb37116d41342b36eda63c1f6a;hp=40cdbcf4274549672be9cc57f8571f607028df82;hpb=b764179e9f5cbe4ebdfc1b76b9947c2660e34b07;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 40cdbcf4..c8580105 100644 --- a/src/files.c +++ b/src/files.c @@ -29,7 +29,7 @@ #define CHUNK_SIZE_NONE -1 /* do not write chunk size */ #define FILE_VERS_CHUNK_SIZE 8 /* size of file version chunk */ #define LEVEL_HEADER_SIZE 80 /* size of level file header */ -#define LEVEL_HEADER_UNUSED 13 /* unused level header bytes */ +#define LEVEL_HEADER_UNUSED 8 /* unused level header bytes */ #define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */ #define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */ #define LEVEL_CHUNK_CNT3_HEADER 16 /* size of level CNT3 header */ @@ -141,15 +141,25 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->time = 100; level->gems_needed = 0; + level->amoeba_speed = 10; + level->time_magic_wall = 10; level->time_wheel = 10; level->time_light = 10; level->time_timegate = 10; + level->amoeba_content = EL_DIAMOND; + level->double_speed = FALSE; level->initial_gravity = FALSE; level->em_slippery_gems = FALSE; + level->block_last_field = FALSE; + level->sp_block_last_field = TRUE; + + level->use_spring_bug = FALSE; + + level->can_move_into_acid = ~0; /* everything can move into acid */ level->use_custom_template = FALSE; @@ -206,6 +216,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) if (IS_CUSTOM_ELEMENT(element)) { + element_info[element].access_direction = MV_ALL_DIRECTIONS; + element_info[element].collect_score = 10; /* special default */ element_info[element].collect_count = 1; /* special default */ @@ -215,7 +227,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) element_info[element].move_delay_random = 0; element_info[element].move_pattern = MV_ALL_DIRECTIONS; - element_info[element].move_direction_initial = MV_AUTOMATIC; + element_info[element].move_direction_initial = MV_START_AUTOMATIC; element_info[element].move_stepsize = TILEX / 8; element_info[element].move_enter_element = EL_EMPTY_SPACE; element_info[element].move_leave_element = EL_EMPTY_SPACE; @@ -223,12 +235,16 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) element_info[element].slippery_type = SLIPPERY_ANY_RANDOM; + element_info[element].explosion_delay = 18; + element_info[element].ignition_delay = 8; + for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) element_info[element].content[x][y] = EL_EMPTY_SPACE; element_info[element].access_type = 0; element_info[element].access_layer = 0; + element_info[element].access_protected = 0; element_info[element].walk_to_action = 0; element_info[element].smash_targets = 0; element_info[element].deadliness = 0; @@ -244,6 +260,9 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) for (j = 0; j < NUM_EP_BITFIELDS; j++) Properties[element][j] = EP_BITMASK_DEFAULT; + /* now set default properties */ + SET_PROPERTY(element, EP_CAN_MOVE_INTO_ACID, TRUE); + element_info[element].modified_settings = FALSE; } else if (IS_GROUP_ELEMENT(element) || element == EL_INTERNAL_EDITOR) @@ -566,7 +585,7 @@ int getMappedElement(int element) { Error(ERR_WARN, "invalid level element %d", element); - element = EL_CHAR_QUESTION; + element = EL_UNKNOWN; } break; } @@ -575,7 +594,7 @@ int getMappedElement(int element) { Error(ERR_WARN, "invalid level element %d", element); - element = EL_CHAR_QUESTION; + element = EL_UNKNOWN; } else if (element == EL_PLAYER_OBSOLETE) element = EL_PLAYER_1; @@ -628,6 +647,13 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) level->use_custom_template = (getFile8Bit(file) == 1 ? TRUE : FALSE); + level->block_last_field = (getFile8Bit(file) == 1 ? TRUE : FALSE); + level->sp_block_last_field = (getFile8Bit(file) == 1 ? TRUE : FALSE); + + level->use_spring_bug = (getFile8Bit(file) == 1 ? TRUE : FALSE); + + level->can_move_into_acid = getFile16BitBE(file); + ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED); return chunk_size; @@ -982,6 +1008,7 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) ei->move_delay_fixed = getFile16BitBE(file); ei->move_delay_random = getFile16BitBE(file); + /* bits 0 - 15 of "move_pattern" ... */ ei->move_pattern = getFile16BitBE(file); ei->move_direction_initial = getFile8Bit(file); ei->move_stepsize = getFile8Bit(file); @@ -996,8 +1023,16 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) ei->move_leave_element = getMappedElement(getFile16BitBE(file)); ei->move_leave_type = getFile8Bit(file); + /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */ + ei->move_pattern |= (getFile16BitBE(file) << 16); + + ei->access_direction = getFile8Bit(file); + + ei->explosion_delay = getFile8Bit(file); + ei->ignition_delay = getFile8Bit(file); + /* some free bytes for future custom property values and padding */ - ReadUnusedBytesFromFile(file, 7); + ReadUnusedBytesFromFile(file, 2); /* read change property values */ @@ -1272,7 +1307,7 @@ static int map_em_element_yam(int element) default: Error(ERR_WARN, "invalid level element %d", element); - return EL_CHAR_QUESTION; + return EL_UNKNOWN; } } @@ -1286,10 +1321,13 @@ static int map_em_element_field(int element) switch (element) { case 0x00: return EL_ROCK; + case 0x01: return EL_ROCK; /* EMC */ case 0x02: return EL_DIAMOND; case 0x03: return EL_DIAMOND; case 0x04: return EL_ROBOT; case 0x05: return EL_ROBOT; /* EMC */ + case 0x06: return EL_EMPTY_SPACE; /* EMC */ + case 0x07: return EL_EMPTY_SPACE; /* EMC */ case 0x08: return EL_SPACESHIP_UP; case 0x09: return EL_SPACESHIP_RIGHT; case 0x0a: return EL_SPACESHIP_DOWN; @@ -1298,7 +1336,9 @@ static int map_em_element_field(int element) case 0x0d: return EL_SPACESHIP_RIGHT; case 0x0e: return EL_SPACESHIP_DOWN; case 0x0f: return EL_SPACESHIP_LEFT; + case 0x10: return EL_BOMB; + case 0x11: return EL_BOMB; /* EMC */ case 0x12: return EL_EMERALD; case 0x13: return EL_EMERALD; case 0x14: return EL_BUG_UP; @@ -1310,34 +1350,115 @@ static int map_em_element_field(int element) case 0x1a: return EL_BUG_DOWN; case 0x1b: return EL_BUG_LEFT; case 0x1c: return EL_AMOEBA_DROP; + case 0x1d: return EL_AMOEBA_DROP; /* EMC */ + case 0x1e: return EL_AMOEBA_DROP; /* EMC */ + case 0x1f: return EL_AMOEBA_DROP; /* EMC */ + case 0x20: return EL_ROCK; + case 0x21: return EL_BOMB; /* EMC */ + case 0x22: return EL_DIAMOND; /* EMC */ + case 0x23: return EL_EMERALD; /* EMC */ case 0x24: return EL_MAGIC_WALL; case 0x25: return EL_NUT; + case 0x26: return EL_NUT; /* EMC */ + case 0x27: return EL_NUT; /* EMC */ /* looks like magic wheel, but is _always_ activated */ case 0x28: return EL_ROBOT_WHEEL; /* EMC */ - case 0x29: return EL_YAMYAM; - case 0x2a: return EL_YAMYAM; - case 0x2b: return EL_YAMYAM; /* EMC */ - case 0x2c: return EL_YAMYAM; /* EMC */ + case 0x29: return EL_YAMYAM; /* up */ + case 0x2a: return EL_YAMYAM; /* down */ + case 0x2b: return EL_YAMYAM; /* left */ /* EMC */ + case 0x2c: return EL_YAMYAM; /* right */ /* EMC */ case 0x2d: return EL_QUICKSAND_FULL; + case 0x2e: return EL_EMPTY_SPACE; /* EMC */ + case 0x2f: return EL_EMPTY_SPACE; /* EMC */ + + case 0x30: return EL_EMPTY_SPACE; /* EMC */ + case 0x31: return EL_SAND; /* EMC */ + case 0x32: return EL_SAND; /* EMC */ + case 0x33: return EL_SAND; /* EMC */ + case 0x34: return EL_QUICKSAND_FULL; /* EMC */ + case 0x35: return EL_QUICKSAND_FULL; /* EMC */ + case 0x36: return EL_QUICKSAND_FULL; /* EMC */ + case 0x37: return EL_SAND; /* EMC */ + case 0x38: return EL_ROCK; /* EMC */ case 0x39: return EL_EXPANDABLE_WALL_HORIZONTAL; /* EMC */ case 0x3a: return EL_EXPANDABLE_WALL_VERTICAL; /* EMC */ - case 0x3b: return EL_DYNAMITE_ACTIVE; - case 0x3c: return EL_DYNAMITE_ACTIVE; - case 0x3d: return EL_DYNAMITE_ACTIVE; - case 0x3e: return EL_DYNAMITE_ACTIVE; + case 0x3b: return EL_DYNAMITE_ACTIVE; /* 1 */ + case 0x3c: return EL_DYNAMITE_ACTIVE; /* 2 */ + case 0x3d: return EL_DYNAMITE_ACTIVE; /* 3 */ + case 0x3e: return EL_DYNAMITE_ACTIVE; /* 4 */ case 0x3f: return EL_ACID_POOL_BOTTOM; - case 0x40: return EL_EXIT_OPEN; - case 0x41: return EL_EXIT_OPEN; - case 0x42: return EL_EXIT_OPEN; - case 0x43: return EL_BALLOON; - case 0x4e: return EL_INVISIBLE_WALL; - case 0x65: return EL_ACID; /* EMC */ - case 0x73: return EL_SAND; /* EMC */ + + case 0x40: return EL_EXIT_OPEN; /* 1 */ + case 0x41: return EL_EXIT_OPEN; /* 2 */ + case 0x42: return EL_EXIT_OPEN; /* 3 */ + case 0x43: return EL_BALLOON; /* EMC */ + case 0x44: return EL_UNKNOWN; /* EMC ("plant") */ + case 0x45: return EL_SPRING; /* EMC */ + case 0x46: return EL_SPRING; /* falling */ /* EMC */ + case 0x47: return EL_SPRING; /* left */ /* EMC */ + case 0x48: return EL_SPRING; /* right */ /* EMC */ + case 0x49: return EL_UNKNOWN; /* EMC ("ball 1") */ + case 0x4a: return EL_UNKNOWN; /* EMC ("ball 2") */ + case 0x4b: return EL_UNKNOWN; /* EMC ("android") */ + case 0x4c: return EL_EMPTY_SPACE; /* EMC */ + case 0x4d: return EL_UNKNOWN; /* EMC ("android") */ + case 0x4e: return EL_INVISIBLE_WALL; /* EMC (? "android") */ + case 0x4f: return EL_UNKNOWN; /* EMC ("android") */ + + case 0x50: return EL_UNKNOWN; /* EMC ("android") */ + case 0x51: return EL_UNKNOWN; /* EMC ("android") */ + case 0x52: return EL_UNKNOWN; /* EMC ("android") */ + case 0x53: return EL_UNKNOWN; /* EMC ("android") */ + case 0x54: return EL_UNKNOWN; /* EMC ("android") */ + case 0x55: return EL_EMPTY_SPACE; /* EMC */ + case 0x56: return EL_EMPTY_SPACE; /* EMC */ + case 0x57: return EL_EMPTY_SPACE; /* EMC */ + case 0x58: return EL_EMPTY_SPACE; /* EMC */ + case 0x59: return EL_EMPTY_SPACE; /* EMC */ + case 0x5a: return EL_EMPTY_SPACE; /* EMC */ + case 0x5b: return EL_EMPTY_SPACE; /* EMC */ + case 0x5c: return EL_EMPTY_SPACE; /* EMC */ + case 0x5d: return EL_EMPTY_SPACE; /* EMC */ + case 0x5e: return EL_EMPTY_SPACE; /* EMC */ + case 0x5f: return EL_EMPTY_SPACE; /* EMC */ + + case 0x60: return EL_EMPTY_SPACE; /* EMC */ + case 0x61: return EL_EMPTY_SPACE; /* EMC */ + case 0x62: return EL_EMPTY_SPACE; /* EMC */ + case 0x63: return EL_SPRING; /* left */ /* EMC */ + case 0x64: return EL_SPRING; /* right */ /* EMC */ + case 0x65: return EL_ACID; /* 1 */ /* EMC */ + case 0x66: return EL_ACID; /* 2 */ /* EMC */ + case 0x67: return EL_ACID; /* 3 */ /* EMC */ + case 0x68: return EL_ACID; /* 4 */ /* EMC */ + case 0x69: return EL_ACID; /* 5 */ /* EMC */ + case 0x6a: return EL_ACID; /* 6 */ /* EMC */ + case 0x6b: return EL_ACID; /* 7 */ /* EMC */ + case 0x6c: return EL_ACID; /* 8 */ /* EMC */ + case 0x6d: return EL_EMPTY_SPACE; /* EMC */ + case 0x6e: return EL_EMPTY_SPACE; /* EMC */ + case 0x6f: return EL_EMPTY_SPACE; /* EMC */ + + case 0x70: return EL_EMPTY_SPACE; /* EMC */ + case 0x71: return EL_EMPTY_SPACE; /* EMC */ + case 0x72: return EL_NUT; /* left */ /* EMC */ + case 0x73: return EL_SAND; /* EMC (? "nut") */ case 0x74: return EL_STEELWALL; - case 0x7b: return EL_ACID; + case 0x75: return EL_EMPTY_SPACE; /* EMC */ + case 0x76: return EL_EMPTY_SPACE; /* EMC */ + case 0x77: return EL_BOMB; /* left */ /* EMC */ + case 0x78: return EL_BOMB; /* right */ /* EMC */ + case 0x79: return EL_ROCK; /* left */ /* EMC */ + case 0x7a: return EL_ROCK; /* right */ /* EMC */ + case 0x7b: return EL_ACID; /* (? EMC "blank") */ + case 0x7c: return EL_EMPTY_SPACE; /* EMC */ + case 0x7d: return EL_EMPTY_SPACE; /* EMC */ + case 0x7e: return EL_EMPTY_SPACE; /* EMC */ + case 0x7f: return EL_EMPTY_SPACE; /* EMC */ + case 0x80: return EL_EMPTY; case 0x81: return EL_WALL_SLIPPERY; case 0x82: return EL_SAND; @@ -1351,63 +1472,101 @@ static int map_em_element_field(int element) case 0x8a: return EL_EM_GATE_2; case 0x8b: return EL_EM_GATE_4; case 0x8c: return EL_EM_GATE_3; - case 0x8d: return EL_INVISIBLE_WALL; /* EMC */ + case 0x8d: return EL_INVISIBLE_WALL; /* EMC (? "dripper") */ case 0x8e: return EL_EM_GATE_1_GRAY; case 0x8f: return EL_EM_GATE_2_GRAY; + case 0x90: return EL_EM_GATE_4_GRAY; case 0x91: return EL_EM_GATE_3_GRAY; case 0x92: return EL_MAGIC_WALL; - case 0x94: return EL_QUICKSAND_EMPTY; + case 0x93: return EL_ROBOT_WHEEL; + case 0x94: return EL_QUICKSAND_EMPTY; /* (? EMC "sand") */ case 0x95: return EL_ACID_POOL_TOPLEFT; case 0x96: return EL_ACID_POOL_TOPRIGHT; case 0x97: return EL_ACID_POOL_BOTTOMLEFT; case 0x98: return EL_ACID_POOL_BOTTOMRIGHT; - case 0x99: return EL_ACID; - case 0x9a: return EL_AMOEBA_DEAD; - case 0x9b: return EL_AMOEBA_DEAD; - case 0x9c: return EL_AMOEBA_DEAD; - case 0x9d: return EL_AMOEBA_DEAD; + case 0x99: return EL_ACID; /* (? EMC "fake blank") */ + case 0x9a: return EL_AMOEBA_DEAD; /* 1 */ + case 0x9b: return EL_AMOEBA_DEAD; /* 2 */ + case 0x9c: return EL_AMOEBA_DEAD; /* 3 */ + case 0x9d: return EL_AMOEBA_DEAD; /* 4 */ case 0x9e: return EL_EXIT_CLOSED; - case 0x9f: return EL_CHAR_LESS; /* EMC */ - case 0x93: return EL_ROBOT_WHEEL; - - /* looks like normal dust, but behaves like wall */ - case 0xa0: return EL_WALL; /* EMC */ - - case 0xa8: return EL_EMC_WALL_1; /* EMC */ - case 0xa9: return EL_EMC_WALL_2; /* EMC */ - case 0xaa: return EL_EMC_WALL_3; /* EMC */ - case 0xab: return EL_EMC_WALL_7; /* EMC */ + case 0x9f: return EL_CHAR_LESS; /* arrow left */ + + /* looks like normal sand, but behaves like wall */ + case 0xa0: return EL_UNKNOWN; /* EMC ("fake grass") */ + case 0xa1: return EL_UNKNOWN; /* EMC ("lenses") */ + case 0xa2: return EL_UNKNOWN; /* EMC ("magnify") */ + case 0xa3: return EL_UNKNOWN; /* EMC ("fake blank") */ + case 0xa4: return EL_UNKNOWN; /* EMC ("fake grass") */ + case 0xa5: return EL_UNKNOWN; /* EMC ("switch") */ + case 0xa6: return EL_UNKNOWN; /* EMC ("switch") */ + case 0xa7: return EL_EMPTY_SPACE; /* EMC */ + case 0xa8: return EL_EMC_WALL_1; /* EMC ("decor 8") */ + case 0xa9: return EL_EMC_WALL_2; /* EMC ("decor 9") */ + case 0xaa: return EL_EMC_WALL_3; /* EMC ("decor 10") */ + case 0xab: return EL_EMC_WALL_7; /* EMC ("decor 5") */ + case 0xac: return EL_CHAR_COMMA; /* EMC */ + case 0xad: return EL_CHAR_QUOTEDBL; /* EMC */ case 0xae: return EL_CHAR_MINUS; /* EMC */ case 0xaf: return EL_DYNAMITE; - case 0xb0: return EL_EMC_STEELWALL_1; /* EMC */ - case 0xb1: return EL_EMC_WALL_8; /* EMC */ - - /* (exact steel wall) */ - case 0xb3: return EL_STEELWALL; /* EMC */ - case 0xb4: return EL_WALL_SLIPPERY; /* EMC */ - case 0xb5: return EL_EMC_WALL_6; /* EMC */ - case 0xb6: return EL_EMC_WALL_5; /* EMC */ - case 0xb7: return EL_EMC_WALL_4; /* EMC */ + case 0xb0: return EL_EMC_STEELWALL_1; /* EMC ("steel 3") */ + case 0xb1: return EL_EMC_WALL_8; /* EMC ("decor 6") */ + case 0xb2: return EL_UNKNOWN; /* EMC ("decor 7") */ + case 0xb3: return EL_STEELWALL; /* 2 */ /* EMC */ + case 0xb4: return EL_WALL_SLIPPERY; /* 2 */ /* EMC */ + case 0xb5: return EL_EMC_WALL_6; /* EMC ("decor 2") */ + case 0xb6: return EL_EMC_WALL_5; /* EMC ("decor 4") */ + case 0xb7: return EL_EMC_WALL_4; /* EMC ("decor 3") */ case 0xb8: return EL_BALLOON_SWITCH_ANY; /* EMC */ case 0xb9: return EL_BALLOON_SWITCH_RIGHT; /* EMC */ case 0xba: return EL_BALLOON_SWITCH_DOWN; /* EMC */ case 0xbb: return EL_BALLOON_SWITCH_LEFT; /* EMC */ case 0xbc: return EL_BALLOON_SWITCH_UP; /* EMC */ - case 0xbd: return EL_SAND; /* EMC */ + case 0xbd: return EL_SAND; /* EMC ("dirt") */ + case 0xbe: return EL_UNKNOWN; /* EMC ("plant") */ + case 0xbf: return EL_UNKNOWN; /* EMC ("key 5") */ + + case 0xc0: return EL_UNKNOWN; /* EMC ("key 6") */ + case 0xc1: return EL_UNKNOWN; /* EMC ("key 7") */ + case 0xc2: return EL_UNKNOWN; /* EMC ("key 8") */ + case 0xc3: return EL_UNKNOWN; /* EMC ("door 5") */ + case 0xc4: return EL_UNKNOWN; /* EMC ("door 6") */ + case 0xc5: return EL_UNKNOWN; /* EMC ("door 7") */ + case 0xc6: return EL_UNKNOWN; /* EMC ("door 8") */ + case 0xc7: return EL_UNKNOWN; /* EMC ("bumper") */ + + /* characters: see above */ + case 0xec: return EL_CHAR_PERIOD; case 0xed: return EL_CHAR_EXCLAM; case 0xee: return EL_CHAR_COLON; case 0xef: return EL_CHAR_QUESTION; - case 0xf0: return EL_CHAR_GREATER; - case 0xf1: return EL_CHAR_COPYRIGHT; - case 0xfe: return EL_PLAYER_1; - case 0xff: return EL_PLAYER_2; + + case 0xf0: return EL_CHAR_GREATER; /* arrow right */ + case 0xf1: return EL_CHAR_COPYRIGHT; /* EMC: "decor 1" */ + case 0xf2: return EL_UNKNOWN; /* EMC ("fake door 5") */ + case 0xf3: return EL_UNKNOWN; /* EMC ("fake door 6") */ + case 0xf4: return EL_UNKNOWN; /* EMC ("fake door 7") */ + case 0xf5: return EL_UNKNOWN; /* EMC ("fake door 8") */ + case 0xf6: return EL_EMPTY_SPACE; /* EMC */ + case 0xf7: return EL_EMPTY_SPACE; /* EMC */ + + case 0xf8: return EL_EMPTY_SPACE; /* EMC */ + case 0xf9: return EL_EMPTY_SPACE; /* EMC */ + case 0xfa: return EL_EMPTY_SPACE; /* EMC */ + case 0xfb: return EL_EMPTY_SPACE; /* EMC */ + case 0xfc: return EL_EMPTY_SPACE; /* EMC */ + case 0xfd: return EL_EMPTY_SPACE; /* EMC */ + + case 0xfe: return EL_PLAYER_1; /* EMC: "blank" */ + case 0xff: return EL_PLAYER_2; /* EMC: "blank" */ default: + /* should never happen (all 8-bit value cases should be handled) */ Error(ERR_WARN, "invalid level element %d", element); - return EL_CHAR_QUESTION; + return EL_UNKNOWN; } } @@ -1556,7 +1715,7 @@ static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level, Error(ERR_WARN, "in level %d, at position %d, %d:", nr, x, y); Error(ERR_WARN, "invalid level element %d", element_old); - element_new = EL_CHAR_QUESTION; + element_new = EL_UNKNOWN; } level->field[x][y] = element_new; @@ -1877,6 +2036,24 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) /* Default behaviour for EM style gems was "slippery" only in 2.0.1 */ if (level->game_version == VERSION_IDENT(2,0,1,0)) level->em_slippery_gems = TRUE; + + if (level->game_version < VERSION_IDENT(2,2,0,0)) + level->use_spring_bug = TRUE; + + if (level->game_version < VERSION_IDENT(3,0,9,0)) + { + int i; + + level->can_move_into_acid = 0; /* nothing can move into acid */ + + setMoveIntoAcidProperty(level, EL_ROBOT, TRUE); + setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE); + setMoveIntoAcidProperty(level, EL_PENGUIN, TRUE); + setMoveIntoAcidProperty(level, EL_BALLOON, TRUE); + + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE); + } } else { @@ -1981,6 +2158,15 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } + /* correct field access direction (for old levels without this option) */ + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + if (element_info[element].access_direction == MV_NO_MOVING) + element_info[element].access_direction = MV_ALL_DIRECTIONS; + } + #if 0 /* set default push delay values (corrected since version 3.0.7-1) */ if (level->game_version < VERSION_IDENT(3,0,7,1)) @@ -2140,6 +2326,13 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) putFile8Bit(file, (level->use_custom_template ? 1 : 0)); + putFile8Bit(file, (level->block_last_field ? 1 : 0)); + putFile8Bit(file, (level->sp_block_last_field ? 1 : 0)); + + putFile8Bit(file, (level->use_spring_bug ? 1 : 0)); + + putFile16BitBE(file, level->can_move_into_acid); + WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED); } @@ -2422,7 +2615,8 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) putFile16BitBE(file, ei->move_delay_fixed); putFile16BitBE(file, ei->move_delay_random); - putFile16BitBE(file, ei->move_pattern); + /* bits 0 - 15 of "move_pattern" ... */ + putFile16BitBE(file, ei->move_pattern & 0xffff); putFile8Bit(file, ei->move_direction_initial); putFile8Bit(file, ei->move_stepsize); @@ -2436,8 +2630,16 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) putFile16BitBE(file, ei->move_leave_element); putFile8Bit(file, ei->move_leave_type); + /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */ + putFile16BitBE(file, (ei->move_pattern >> 16) & 0xffff); + + putFile8Bit(file, ei->access_direction); + + putFile8Bit(file, ei->explosion_delay); + putFile8Bit(file, ei->ignition_delay); + /* some free bytes for future custom property values and padding */ - WriteUnusedBytesToFile(file, 7); + WriteUnusedBytesToFile(file, 2); /* write change property values */ @@ -2638,24 +2840,27 @@ void DumpLevel(struct LevelInfo *level) level->file_version, level->game_version); printf_line("-", 79); - printf("Level Author: '%s'\n", level->author); - printf("Level Title: '%s'\n", level->name); + printf("Level author: '%s'\n", level->author); + printf("Level title: '%s'\n", level->name); printf("\n"); - printf("Playfield Size: %d x %d\n", level->fieldx, level->fieldy); + printf("Playfield size: %d x %d\n", level->fieldx, level->fieldy); printf("\n"); - printf("Level Time: %d seconds\n", level->time); + printf("Level time: %d seconds\n", level->time); printf("Gems needed: %d\n", level->gems_needed); printf("\n"); - printf("Time for Magic Wall: %d seconds\n", level->time_magic_wall); - printf("Time for Wheel: %d seconds\n", level->time_wheel); - printf("Time for Light: %d seconds\n", level->time_light); - printf("Time for Timegate: %d seconds\n", level->time_timegate); + printf("Time for magic wall: %d seconds\n", level->time_magic_wall); + printf("Time for wheel: %d seconds\n", level->time_wheel); + printf("Time for light: %d seconds\n", level->time_light); + printf("Time for timegate: %d seconds\n", level->time_timegate); printf("\n"); - printf("Amoeba Speed: %d\n", level->amoeba_speed); + printf("Amoeba speed: %d\n", level->amoeba_speed); printf("\n"); - printf("Gravity: %s\n", (level->initial_gravity ? "yes" : "no")); - printf("Double Speed Movement: %s\n", (level->double_speed ? "yes" : "no")); - printf("EM style slippery gems: %s\n", (level->em_slippery_gems ? "yes" : "no")); + printf("Initial gravity: %s\n", (level->initial_gravity ? "yes" : "no")); + printf("Double speed movement: %s\n", (level->double_speed ? "yes" : "no")); + printf("EM style slippery gems: %s\n", (level->em_slippery_gems ? "yes" : "no")); + printf("Player blocks last field: %s\n", (level->block_last_field ? "yes" : "no")); + printf("SP player blocks last field: %s\n", (level->sp_block_last_field ? "yes" : "no")); + printf("use spring bug: %s\n", (level->use_spring_bug ? "yes" : "no")); printf_line("-", 79); }