#define LEVEL_CHUNK_CNT3_UNUSED 10 /* unused CNT3 chunk bytes */
#define LEVEL_CPART_CUS3_SIZE 134 /* size of CUS3 chunk part */
#define LEVEL_CPART_CUS3_UNUSED 15 /* unused CUS3 bytes / part */
+#define LEVEL_CHUNK_GRP1_SIZE 74 /* size of level GRP1 chunk */
#define TAPE_HEADER_SIZE 20 /* size of tape file header */
#define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */
+#define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x))
#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE)
#define LEVEL_CHUNK_CUS4_SIZE(x) (48 + 48 + (x) * 48)
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
{
- setElementChangePages(&element_info[i], 1);
- setElementChangeInfoToDefaults(element_info[i].change);
- }
-
- for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
+ int element = i;
- for (j = 0; j < MAX_ELEMENT_NAME_LEN + 1; j++)
- element_info[element].description[j] = '\0';
- if (element_info[element].custom_description != NULL)
- strncpy(element_info[element].description,
- element_info[element].custom_description, MAX_ELEMENT_NAME_LEN);
- else
- strcpy(element_info[element].description,
- element_info[element].editor_description);
+ setElementChangePages(&element_info[element], 1);
+ setElementChangeInfoToDefaults(element_info[element].change);
- element_info[element].use_gfx_element = FALSE;
- element_info[element].gfx_element = EL_EMPTY_SPACE;
+ if (IS_CUSTOM_ELEMENT(element) || IS_GROUP_ELEMENT(element))
+ {
+ for (j = 0; j < MAX_ELEMENT_NAME_LEN + 1; j++)
+ element_info[element].description[j] = '\0';
- element_info[element].collect_score = 10; /* special default */
- element_info[element].collect_count = 1; /* special default */
+ if (element_info[element].custom_description != NULL)
+ strncpy(element_info[element].description,
+ element_info[element].custom_description,MAX_ELEMENT_NAME_LEN);
+ else
+ strcpy(element_info[element].description,
+ element_info[element].editor_description);
- element_info[element].push_delay_fixed = -1; /* initialize later */
- element_info[element].push_delay_random = -1; /* initialize later */
- element_info[element].move_delay_fixed = 0;
- element_info[element].move_delay_random = 0;
+ element_info[element].use_gfx_element = FALSE;
+ element_info[element].gfx_element = EL_EMPTY_SPACE;
+ }
- element_info[element].move_pattern = MV_ALL_DIRECTIONS;
- element_info[element].move_direction_initial = MV_NO_MOVING;
- element_info[element].move_stepsize = TILEX / 8;
+ if (IS_CUSTOM_ELEMENT(element))
+ {
+ element_info[element].collect_score = 10; /* special default */
+ element_info[element].collect_count = 1; /* special default */
- element_info[element].slippery_type = SLIPPERY_ANY_RANDOM;
+ element_info[element].push_delay_fixed = -1; /* initialize later */
+ element_info[element].push_delay_random = -1; /* initialize later */
+ element_info[element].move_delay_fixed = 0;
+ element_info[element].move_delay_random = 0;
- for (x = 0; x < 3; x++)
- for (y = 0; y < 3; y++)
- element_info[element].content[x][y] = EL_EMPTY_SPACE;
+ element_info[element].move_pattern = MV_ALL_DIRECTIONS;
+ element_info[element].move_direction_initial = MV_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;
+ element_info[element].move_leave_type = LEAVE_TYPE_UNLIMITED;
- element_info[element].access_type = 0;
- element_info[element].access_layer = 0;
- element_info[element].walk_to_action = 0;
- element_info[element].smash_targets = 0;
- element_info[element].deadliness = 0;
- element_info[element].consistency = 0;
+ element_info[element].slippery_type = SLIPPERY_ANY_RANDOM;
- element_info[element].can_explode_by_fire = FALSE;
- element_info[element].can_explode_smashed = FALSE;
- element_info[element].can_explode_impact = FALSE;
+ for (x = 0; x < 3; x++)
+ for (y = 0; y < 3; y++)
+ element_info[element].content[x][y] = EL_EMPTY_SPACE;
- element_info[element].current_change_page = 0;
+ element_info[element].access_type = 0;
+ element_info[element].access_layer = 0;
+ element_info[element].walk_to_action = 0;
+ element_info[element].smash_targets = 0;
+ element_info[element].deadliness = 0;
+ element_info[element].consistency = 0;
- /* start with no properties at all */
- for (j = 0; j < NUM_EP_BITFIELDS; j++)
- Properties[element][j] = EP_BITMASK_DEFAULT;
+ element_info[element].can_explode_by_fire = FALSE;
+ element_info[element].can_explode_smashed = FALSE;
+ element_info[element].can_explode_impact = FALSE;
- element_info[element].modified_settings = FALSE;
- }
+ element_info[element].current_change_page = 0;
- for (i = 0; i < NUM_GROUP_ELEMENTS; i++)
- {
- int element = EL_GROUP_START + i;
+ /* start with no properties at all */
+ for (j = 0; j < NUM_EP_BITFIELDS; j++)
+ Properties[element][j] = EP_BITMASK_DEFAULT;
- if (element_info[element].group == NULL)
- element_info[element].group =
- checked_malloc(sizeof(struct ElementGroupInfo));
+ element_info[element].modified_settings = FALSE;
+ }
+ else if (IS_GROUP_ELEMENT(element) || element == EL_INTERNAL_EDITOR)
+ {
+ /* initialize memory for list of elements in group */
+ if (element_info[element].group == NULL)
+ element_info[element].group =
+ checked_malloc(sizeof(struct ElementGroupInfo));
- for (j = 0; j < MAX_ELEMENTS_IN_GROUP; j++)
- element_info[element].group->element[j] = EL_EMPTY_SPACE;
+ for (j = 0; j < MAX_ELEMENTS_IN_GROUP; j++)
+ element_info[element].group->element[j] = EL_EMPTY_SPACE;
- element_info[element].group->num_elements = 1;
+ /* default: only one element in group */
+ element_info[element].group->num_elements = 1;
+ }
}
BorderElement = EL_STEELWALL;
ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT3_UNUSED);
- chunk_size_expected = LEVEL_CHUNK_CNT3_HEADER + envelope_len;
-
+ chunk_size_expected = LEVEL_CHUNK_CNT3_SIZE(envelope_len);
if (chunk_size_expected != chunk_size)
{
ReadUnusedBytesFromFile(file, chunk_size - LEVEL_CHUNK_CNT3_HEADER);
{
Error(ERR_WARN, "invalid custom element number %d", element);
- element = EL_DUMMY;
+ element = EL_INTERNAL_DUMMY;
}
for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++)
{
Error(ERR_WARN, "invalid custom element number %d", element);
- element = EL_DUMMY;
+ ReadUnusedBytesFromFile(file, chunk_size - 2);
+ return chunk_size;
}
ei = &element_info[element];
for (x = 0; x < 3; x++)
ei->content[x][y] = checkLevelElement(getFile16BitBE(file));
+ ei->move_enter_element = checkLevelElement(getFile16BitBE(file));
+ ei->move_leave_element = checkLevelElement(getFile16BitBE(file));
+ ei->move_leave_type = getFile8Bit(file);
+
/* some free bytes for future custom property values and padding */
- ReadUnusedBytesFromFile(file, 12);
+ ReadUnusedBytesFromFile(file, 7);
/* read change property values */
return chunk_size;
}
+static int LoadLevel_GRP1(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ struct ElementInfo *ei;
+ struct ElementGroupInfo *group;
+ int element;
+ int i;
+
+ element = getFile16BitBE(file);
+
+ if (!IS_GROUP_ELEMENT(element))
+ {
+ Error(ERR_WARN, "invalid group element number %d", element);
+
+ ReadUnusedBytesFromFile(file, chunk_size - 2);
+ return chunk_size;
+ }
+
+ ei = &element_info[element];
+
+ for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
+ ei->description[i] = getFile8Bit(file);
+ ei->description[MAX_ELEMENT_NAME_LEN] = 0;
+
+ group = element_info[element].group;
+
+ group->num_elements = getFile8Bit(file);
+
+ ei->use_gfx_element = getFile8Bit(file);
+ ei->gfx_element = checkLevelElement(getFile16BitBE(file));
+
+ /* some free bytes for future values and padding */
+ ReadUnusedBytesFromFile(file, 4);
+
+ for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
+ group->element[i] = checkLevelElement(getFile16BitBE(file));
+
+ /* mark this group element as modified */
+ element_info[element].modified_settings = TRUE;
+
+ return chunk_size;
+}
+
static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
struct LevelFileInfo *level_file_info)
{
{ "CUS2", -1, LoadLevel_CUS2 },
{ "CUS3", -1, LoadLevel_CUS3 },
{ "CUS4", -1, LoadLevel_CUS4 },
+ { "GRP1", -1, LoadLevel_GRP1 },
{ NULL, 0, NULL }
};
for (x = 0; x < 3; x++)
putFile16BitBE(file, ei->content[x][y]);
+ putFile16BitBE(file, ei->move_enter_element);
+ putFile16BitBE(file, ei->move_leave_element);
+ putFile8Bit(file, ei->move_leave_type);
+
/* some free bytes for future custom property values and padding */
- WriteUnusedBytesToFile(file, 12);
+ WriteUnusedBytesToFile(file, 7);
/* write change property values */
}
}
+static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element)
+{
+ struct ElementInfo *ei = &element_info[element];
+ struct ElementGroupInfo *group = ei->group;
+ int i;
+
+ putFile16BitBE(file, element);
+
+ for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
+ putFile8Bit(file, ei->description[i]);
+
+ putFile8Bit(file, group->num_elements);
+
+ putFile8Bit(file, ei->use_gfx_element);
+ putFile16BitBE(file, ei->gfx_element);
+
+ /* some free bytes for future values and padding */
+ WriteUnusedBytesToFile(file, 4);
+
+ for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
+ putFile16BitBE(file, group->element[i]);
+}
+
static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
{
int body_chunk_size;
{
int envelope_len = strlen(level->envelope_text[i]) + 1;
- putFileChunkBE(file, "CNT3", LEVEL_CHUNK_CNT3_HEADER + envelope_len);
+ putFileChunkBE(file, "CNT3", LEVEL_CHUNK_CNT3_SIZE(envelope_len));
SaveLevel_CNT3(file, level, EL_ENVELOPE_1 + i);
}
}
}
}
+ /* check for non-default group elements (unless using template level) */
+ if (!level->use_custom_template)
+ {
+ for (i = 0; i < NUM_GROUP_ELEMENTS; i++)
+ {
+ int element = EL_GROUP_START + i;
+
+ if (element_info[element].modified_settings)
+ {
+ putFileChunkBE(file, "GRP1", LEVEL_CHUNK_GRP1_SIZE);
+ SaveLevel_GRP1(file, level, element);
+ }
+ }
+ }
+
fclose(file);
SetFilePermissions(filename, PERMS_PRIVATE);