X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=f098b1f5f9b025757e32804e850927f4f05251ba;hb=7892cce9f39489a779f8fad4a3e756b0bb8dbee5;hp=0eea3c6da24218245c1a3c75980280f089e1b789;hpb=c2a639c0b2c1a9a2bd14de86932a47429ae918a4;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 0eea3c6d..f098b1f5 100644 --- a/src/editor.c +++ b/src/editor.c @@ -153,6 +153,9 @@ #define ED_AREA_ELEM_CONTENT6_XPOS (29 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT6_YPOS (ED_SETTINGS_YPOS(10) + \ ED_GADGET_DISTANCE - MINI_TILEY) +/* group element content */ +#define ED_AREA_GROUP_CONTENT_XPOS ED_SETTINGS_XPOS(0) +#define ED_AREA_GROUP_CONTENT_YPOS (22 * MINI_TILEY) /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_YPOS (31 * MINI_TILEY) @@ -375,9 +378,12 @@ #define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 57) #define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 58) #define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 59) +#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 60) +#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 61) +#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 62) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 60) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 63) #define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0) #define GADGET_ID_ELEMENT_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) @@ -394,10 +400,11 @@ #define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 12) #define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 13) #define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 14) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 15) +#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 15) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 16) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 16) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 17) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -523,11 +530,12 @@ #define ED_COUNTER_ID_PUSH_DELAY_RND 14 #define ED_COUNTER_ID_MOVE_DELAY_FIX 15 #define ED_COUNTER_ID_MOVE_DELAY_RND 16 -#define ED_COUNTER_ID_CHANGE_DELAY_FIX 17 -#define ED_COUNTER_ID_CHANGE_DELAY_RND 18 -#define ED_COUNTER_ID_CHANGE_CONT_RND 19 +#define ED_COUNTER_ID_GROUP_CONTENT 17 +#define ED_COUNTER_ID_CHANGE_DELAY_FIX 18 +#define ED_COUNTER_ID_CHANGE_DELAY_RND 19 +#define ED_COUNTER_ID_CHANGE_CONT_RND 20 -#define ED_NUM_COUNTERBUTTONS 20 +#define ED_NUM_COUNTERBUTTONS 21 #define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE #define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM @@ -694,9 +702,10 @@ #define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 12 #define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 13 #define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 14 -#define ED_DRAWING_ID_RANDOM_BACKGROUND 15 +#define ED_DRAWING_ID_GROUP_CONTENT 15 +#define ED_DRAWING_ID_RANDOM_BACKGROUND 16 -#define ED_NUM_DRAWING_AREAS 16 +#define ED_NUM_DRAWING_AREAS 17 /* @@ -795,6 +804,7 @@ static boolean stick_element_properties_window = FALSE; static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES]; static boolean custom_element_change_events[NUM_CHANGE_EVENTS]; static struct ElementChangeInfo custom_element_change; +static struct ElementGroupInfo group_element_info; static struct ElementInfo custom_element; static struct @@ -902,7 +912,7 @@ static struct NULL, " ", "height", }, - /* ---------- element settings: configure (custom elements) ------------- */ + /* ---------- element settings: configure (custom elements) -------------- */ { ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), @@ -953,6 +963,17 @@ static struct NULL, "+random", NULL }, + /* ---------- element settings: configure (group elements) --------------- */ + + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(6), + MIN_ELEMENTS_IN_GROUP, MAX_ELEMENTS_IN_GROUP, + GADGET_ID_GROUP_CONTENT_DOWN, GADGET_ID_GROUP_CONTENT_UP, + GADGET_ID_GROUP_CONTENT_TEXT, GADGET_ID_NONE, + &group_element_info.num_elements, + NULL, NULL, "number of elements in group" + }, + /* ---------- element settings: advanced (custom elements) --------------- */ { @@ -1070,7 +1091,15 @@ static struct ValueTextInfo options_move_pattern[] = { MV_ALONG_RIGHT_SIDE, "along right side" }, { MV_TURNING_LEFT, "turning left" }, { MV_TURNING_RIGHT, "turning right" }, + { MV_TURNING_LEFT_RIGHT, "turning left, right" }, + { MV_TURNING_RIGHT_LEFT, "turning right, left" }, + { MV_TURNING_RANDOM, "turning random" }, { MV_WHEN_PUSHED, "when pushed" }, + { MV_WHEN_DROPPED, "when dropped" }, +#if 1 + { MV_MAZE_RUNNER, "maze runner style" }, + { MV_MAZE_HUNTER, "maze hunter style" }, +#endif { -1, NULL } }; @@ -1125,6 +1154,7 @@ static struct ValueTextInfo options_deadliness[] = static struct ValueTextInfo options_consistency[] = { { EP_CAN_EXPLODE_3X3, "can explode 3x3" }, + { EP_CAN_EXPLODE_DYNA, "can explode 3+3" }, { EP_CAN_EXPLODE_1X1, "can explode 1x1" }, { EP_INDESTRUCTIBLE, "indestructible" }, { -1, NULL } @@ -1146,9 +1176,14 @@ static struct ValueTextInfo options_change_direct_action[] = { CE_LEFT_BY_PLAYER, "left by player ..." }, { CE_DROPPED_BY_PLAYER, "dropped by player" }, { CE_SWITCHED, "switched ..." }, - { CE_COLLISION, "collision ..." }, - { CE_IMPACT, "impact" }, - { CE_SMASHED, "smashed" }, +#if 1 + { CE_HITTING_SOMETHING, "hitting something ..." }, + { CE_HIT_BY_SOMETHING, "hit by something ..." }, +#else + { CE_HITTING_SOMETHING, "collision ..." }, +#endif + { CE_IMPACT, "impact (on something)" }, + { CE_SMASHED, "smashed (from above)" }, { -1, NULL } }; @@ -1163,6 +1198,10 @@ static struct ValueTextInfo options_change_other_action[] = { CE_OTHER_GETS_COLLECTED, "player collects" }, { CE_OTHER_GETS_DROPPED, "player drops" }, { CE_OTHER_IS_TOUCHING, "touching ..." }, +#if 1 + { CE_OTHER_IS_HITTING, "hitting ..." }, + { CE_OTHER_GETS_HIT, "hit by ..." }, +#endif { CE_OTHER_IS_SWITCHING, "switch of ..." }, { CE_OTHER_IS_CHANGING, "change of" }, { CE_OTHER_IS_EXPLODING, "explosion of" }, @@ -1177,7 +1216,7 @@ static struct ValueTextInfo options_change_sides[] = { CH_SIDE_BOTTOM, "bottom side" }, { CH_SIDE_LEFT_RIGHT, "left/right side" }, { CH_SIDE_TOP_BOTTOM, "top/bottom side" }, - { CH_SIDE_ANY, "all sides" }, + { CH_SIDE_ANY, "any side" }, { -1, NULL } }; @@ -1828,6 +1867,15 @@ static struct NULL, NULL, NULL }, + /* ---------- group element content -------------------------------------- */ + + { + ED_AREA_GROUP_CONTENT_XPOS, ED_AREA_GROUP_CONTENT_YPOS, + MAX_ELEMENTS_IN_GROUP, 1, + GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE, + "content:", NULL, NULL + }, + /* ---------- random background (for random painting) -------------------- */ { @@ -1867,6 +1915,7 @@ static int new_element3 = EL_SAND; static void ModifyEditorCounter(int, int); static void ModifyEditorCounterLimits(int, int, int); static void ModifyEditorSelectbox(int, int); +static void ModifyEditorDrawingArea(int, int, int); static void ModifyEditorElementList(); static void RedrawDrawingElements(); static void DrawDrawingWindow(); @@ -2133,7 +2182,11 @@ static int editor_el_more[] = EL_BD_FIREFLY, EL_MOLE_LEFT, +#if 0 + EL_MAZE_RUNNER, +#else EL_EMPTY, +#endif EL_MOLE_RIGHT, EL_PACMAN, @@ -2882,6 +2935,87 @@ static int *editor_el_custom_more_ptr = editor_el_custom_more; static int num_editor_hl_custom_more = SIZEOF_ARRAY_INT(editor_hl_custom_more); static int num_editor_el_custom_more = SIZEOF_ARRAY_INT(editor_el_custom_more); +static int editor_hl_group[] = +{ + EL_CHAR('G'), + EL_CHAR('R'), + EL_CHAR('O'), + EL_CHAR('U'), + + EL_CHAR('P'), + EL_CHAR(' '), + EL_CHAR(' '), + EL_CHAR(' '), + + EL_CHAR('E'), + EL_CHAR('L'), + EL_CHAR('E'), + EL_CHAR('M'), + + EL_CHAR('E'), + EL_CHAR('N'), + EL_CHAR('T'), + EL_CHAR('S'), +}; + +static int editor_el_group[] = +{ + EL_GROUP_START + 0, + EL_GROUP_START + 1, + EL_GROUP_START + 2, + EL_GROUP_START + 3, + + EL_GROUP_START + 4, + EL_GROUP_START + 5, + EL_GROUP_START + 6, + EL_GROUP_START + 7, + + EL_GROUP_START + 8, + EL_GROUP_START + 9, + EL_GROUP_START + 10, + EL_GROUP_START + 11, + + EL_GROUP_START + 12, + EL_GROUP_START + 13, + EL_GROUP_START + 14, + EL_GROUP_START + 15 +}; +static int *editor_hl_group_ptr = editor_hl_group; +static int *editor_el_group_ptr = editor_el_group; +static int num_editor_hl_group = SIZEOF_ARRAY_INT(editor_hl_group); +static int num_editor_el_group = SIZEOF_ARRAY_INT(editor_el_group); + +static int editor_hl_group_more[] = +{ +}; + +static int editor_el_group_more[] = +{ + EL_GROUP_START + 16, + EL_GROUP_START + 17, + EL_GROUP_START + 18, + EL_GROUP_START + 19, + + EL_GROUP_START + 20, + EL_GROUP_START + 21, + EL_GROUP_START + 22, + EL_GROUP_START + 23, + + EL_GROUP_START + 24, + EL_GROUP_START + 25, + EL_GROUP_START + 26, + EL_GROUP_START + 27, + + EL_GROUP_START + 28, + EL_GROUP_START + 29, + EL_GROUP_START + 30, + EL_GROUP_START + 31 +}; +static int *editor_hl_group_more_ptr = editor_hl_group_more; +static int *editor_el_group_more_ptr = editor_el_group_more; +static int num_editor_hl_group_more = SIZEOF_ARRAY_INT(editor_hl_group_more); +static int num_editor_el_group_more = SIZEOF_ARRAY_INT(editor_el_group_more); + static int editor_hl_user_defined[] = { EL_CHAR('U'), @@ -2982,6 +3116,16 @@ editor_elements_info[] = &editor_hl_custom_more_ptr, &num_editor_hl_custom_more, &editor_el_custom_more_ptr, &num_editor_el_custom_more }, + { + &setup.editor.el_custom, + &editor_hl_group_ptr, &num_editor_hl_group, + &editor_el_group_ptr, &num_editor_el_group + }, + { + &setup.editor.el_custom_more, + &editor_hl_group_more_ptr, &num_editor_hl_group_more, + &editor_el_group_more_ptr, &num_editor_el_group_more + }, { &setup.editor.el_user_defined, &editor_hl_user_defined_ptr, &num_editor_hl_user_defined, @@ -3058,8 +3202,7 @@ static void ReinitializeElementList() int pos = 0; int i, j; - if (editor_elements != NULL) - free(editor_elements); + checked_free(editor_elements); if (!initialized) { @@ -3068,13 +3211,13 @@ static void ReinitializeElementList() &num_editor_el_user_defined); /* initialize list of empty elements (used for padding, if needed) */ - for (i=0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) + for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) editor_el_empty[i] = EL_EMPTY; /* do some sanity checks for each element from element list */ - for (i=0; editor_elements_info[i].setup_value != NULL; i++) + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { - for (j=0; j < *editor_elements_info[i].element_list_size; j++) + for (j = 0; j < *editor_elements_info[i].element_list_size; j++) { int element = (*editor_elements_info[i].element_list)[j]; @@ -3093,7 +3236,7 @@ static void ReinitializeElementList() use_el_empty = FALSE; /* determine size of element list */ - for (i=0; editor_elements_info[i].setup_value != NULL; i++) + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { if (*editor_elements_info[i].setup_value) { @@ -3116,15 +3259,15 @@ static void ReinitializeElementList() editor_elements = checked_malloc(num_editor_elements * sizeof(int)); /* fill element list */ - for (i=0; editor_elements_info[i].setup_value != NULL; i++) + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { if (*editor_elements_info[i].setup_value) { if (setup.editor.el_headlines) - for (j=0; j < *editor_elements_info[i].headline_list_size; j++) + for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) editor_elements[pos++] = (*editor_elements_info[i].headline_list)[j]; - for (j=0; j < *editor_elements_info[i].element_list_size; j++) + for (j = 0; j < *editor_elements_info[i].element_list_size; j++) editor_elements[pos++] = (*editor_elements_info[i].element_list)[j]; } } @@ -3141,9 +3284,9 @@ void PrintEditorElementList() boolean *stop = &setup.editor.el_user_defined; int i, j; - for (i=0; editor_elements_info[i].setup_value != stop; i++) + for (i = 0; editor_elements_info[i].setup_value != stop; i++) { - for (j=0; j < *editor_elements_info[i].headline_list_size; j++) + for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) { int element = (*editor_elements_info[i].headline_list)[j]; @@ -3153,7 +3296,7 @@ void PrintEditorElementList() if (j > 0) printf("#\n"); - for (j=0; j < *editor_elements_info[i].element_list_size; j++) + for (j = 0; j < *editor_elements_info[i].element_list_size; j++) { int element = (*editor_elements_info[i].element_list)[j]; @@ -3176,7 +3319,7 @@ static void ReinitializeElementListButtons() if (last_setup_value_headlines != setup.editor.el_headlines) initialization_needed = TRUE; - for (i=0; editor_elements_info[i].setup_value != NULL; i++) + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) if (editor_elements_info[i].last_setup_value != *editor_elements_info[i].setup_value) initialization_needed = TRUE; @@ -3190,7 +3333,7 @@ static void ReinitializeElementListButtons() /* store current setup values for next invocation of this function */ last_setup_value_headlines = setup.editor.el_headlines; - for (i=0; editor_elements_info[i].setup_value != NULL; i++) + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) editor_elements_info[i].last_setup_value = *editor_elements_info[i].setup_value; @@ -3204,14 +3347,14 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, (input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER); Bitmap *src_bitmap; int src_x, src_y; - int num_mini_tilex = width / MINI_TILEX + 1; - int num_mini_tiley = width / MINI_TILEY + 1; + int num_mini_tilex = width / MINI_TILEX + 1; + int num_mini_tiley = height / MINI_TILEY + 1; int x, y; getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y); - for (y=0; y < num_mini_tiley; y++) - for (x=0; x < num_mini_tilex; x++) + for (y = 0; y < num_mini_tiley; y++) + for (x = 0; x < num_mini_tilex; x++) BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, dest_x - MINI_TILEX / 2 + x * MINI_TILEX, dest_y - MINI_TILEY / 2 + y * MINI_TILEY); @@ -3233,8 +3376,8 @@ static void DrawDrawingArea(int id) DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(custom_element.gfx_element)); else if (id == ED_DRAWING_ID_CUSTOM_CONTENT) - for (y=0; y<3; y++) - for (x=0; x<3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, el2edimg(custom_element.content[x][y])); @@ -3242,21 +3385,25 @@ static void DrawDrawingArea(int id) DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(custom_element_change.target_element)); else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT) - for (y=0; y < 3; y++) - for (x=0; x < 3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, el2edimg(custom_element_change.content[x][y])); else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER) DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(custom_element_change.trigger_element)); + else if (id == ED_DRAWING_ID_GROUP_CONTENT) + for (x = 0; x < group_element_info.num_elements; x++) + DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y, + el2edimg(group_element_info.element[x])); else if (id >= ED_DRAWING_ID_ELEMENT_CONTENT_0 && id <= ED_DRAWING_ID_ELEMENT_CONTENT_7) { int nr = id - ED_DRAWING_ID_ELEMENT_CONTENT_0; - for (y=0; y < 3; y++) - for (x=0; x < 3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, el2edimg(level.yamyam_content[nr][x][y])); @@ -3279,13 +3426,13 @@ static void ScrollMiniLevel(int from_x, int from_y, int scroll) if (dx) { x = (dx == 1 ? 0 : ed_fieldx - 1); - for(y=0; y selectbox_info[i].size) selectbox_info[i].size = strlen(selectbox_info[i].options[j].text); @@ -3906,7 +4053,7 @@ static void CreateTextbuttonGadgets() int max_infotext_len = getMaxInfoTextLength(); int i; - for (i=0; ix < SX + SXSIZE) UnmapGadget(level_editor_gadget[i]); } @@ -4622,7 +4769,7 @@ void UnmapLevelEditorGadgets() { int i; - for (i=0; i < NUM_EDITOR_GADGETS; i++) + for (i = 0; i < NUM_EDITOR_GADGETS; i++) UnmapGadget(level_editor_gadget[i]); } @@ -4651,8 +4798,8 @@ static boolean LevelChanged() boolean level_changed = FALSE; int x, y; - for(y=0; ydescription[i] = ei_from->description[i]; /* ---------- copy element properties ---------- */ @@ -4731,8 +4878,8 @@ static void copy_custom_element_settings(int element_from, int element_to) ei_to->slippery_type = ei_from->slippery_type; - for(y=0; y<3; y++) - for(x=0; x<3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) ei_to->content[x][y] = ei_from->content[x][y]; ei_to->num_change_pages = ei_from->num_change_pages; @@ -4764,8 +4911,8 @@ static void copy_custom_element_settings(int element_from, int element_to) change_to->random = change_from->random; change_to->power = change_from->power; - for(y=0; y<3; y++) - for(x=0; x<3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) change_to->content[x][y] = change_from->content[x][y]; change_to->can_change = change_from->can_change; @@ -4782,12 +4929,12 @@ static void replace_custom_element_in_settings(int element_from, { int i, j, x, y; - for (i=0; i < NUM_FILE_ELEMENTS; i++) + for (i = 0; i < NUM_FILE_ELEMENTS; i++) { struct ElementInfo *ei = &element_info[i]; - for(y=0; y<3; y++) - for(x=0; x<3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) if (ei->content[x][y] == element_from) ei->content[x][y] = element_to; @@ -4801,8 +4948,8 @@ static void replace_custom_element_in_settings(int element_from, if (change->trigger_element == element_from) change->trigger_element = element_to; - for(y=0; y<3; y++) - for(x=0; x<3; x++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) if (change->content[x][y] == element_from) change->content[x][y] = element_to; } @@ -4814,8 +4961,8 @@ static void replace_custom_element_in_playfield(int element_from, { int x, y; - for(x=0; x < lev_fieldx; x++) - for(y=0; y < lev_fieldy; y++) + for (x = 0; x < lev_fieldx; x++) + for (y = 0; y < lev_fieldy; y++) if (Feld[x][y] == element_from) Feld[x][y] = element_to; } @@ -4855,7 +5002,7 @@ static void CopyCustomElementPropertiesToEditor(int element) int current_change_page = element_info[element].current_change_page; /* dynamically (re)build selectbox for selecting change page */ - for (i=0; i < element_info[element].num_change_pages; i++) + for (i = 0; i < element_info[element].num_change_pages; i++) { sprintf(options_change_page_strings[i], "%d", i + 1); @@ -4876,13 +5023,13 @@ static void CopyCustomElementPropertiesToEditor(int element) custom_element_change = *element_info[element].change; /* needed to initially set selectbox value variables to reliable defaults */ - for (i=0; i < ED_NUM_SELECTBOX; i++) + for (i = 0; i < ED_NUM_SELECTBOX; i++) setSelectboxValue(i, *selectbox_info[i].value); - for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) + for (i = 0; i < NUM_ELEMENT_PROPERTIES; i++) custom_element_properties[i] = HAS_PROPERTY(element, i); - for (i=0; i < NUM_CHANGE_EVENTS; i++) + for (i = 0; i < NUM_CHANGE_EVENTS; i++) custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i); /* ---------- element settings: configure (custom elements) ------------- */ @@ -4942,11 +5089,13 @@ static void CopyCustomElementPropertiesToEditor(int element) (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE : CAN_EXPLODE_1X1(element) ? EP_CAN_EXPLODE_1X1 : CAN_EXPLODE_3X3(element) ? EP_CAN_EXPLODE_3X3 : + CAN_EXPLODE_DYNA(element) ? EP_CAN_EXPLODE_DYNA : custom_element.consistency); custom_element_properties[EP_EXPLODE_RESULT] = (IS_INDESTRUCTIBLE(element) || CAN_EXPLODE_1X1(element) || - CAN_EXPLODE_3X3(element)); + CAN_EXPLODE_3X3(element) || + CAN_EXPLODE_DYNA(element)); /* special case: sub-settings dependent from main setting */ if (CAN_EXPLODE_BY_FIRE(element)) @@ -4967,7 +5116,8 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_LEFT_BY_PLAYER) ? CE_LEFT_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_DROPPED_BY_PLAYER) ? CE_DROPPED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_SWITCHED) ? CE_SWITCHED : - HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION : + HAS_CHANGE_EVENT(element, CE_HITTING_SOMETHING) ? CE_HITTING_SOMETHING : + HAS_CHANGE_EVENT(element, CE_HIT_BY_SOMETHING) ? CE_HIT_BY_SOMETHING : HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT : HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED : custom_element_change.direct_action); @@ -4983,12 +5133,19 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED : HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DROPPED) ? CE_OTHER_GETS_DROPPED : HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING : + HAS_CHANGE_EVENT(element, CE_OTHER_IS_HITTING) ? CE_OTHER_IS_HITTING : + HAS_CHANGE_EVENT(element, CE_OTHER_GETS_HIT) ? CE_OTHER_GETS_HIT : HAS_CHANGE_EVENT(element, CE_OTHER_IS_SWITCHING) ? CE_OTHER_IS_SWITCHING : HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING : HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING : custom_element_change.other_action); } +static void CopyGroupElementPropertiesToEditor(int element) +{ + group_element_info = *element_info[element].group; +} + static void CopyCustomElementPropertiesToGame(int element) { int i; @@ -4999,7 +5156,7 @@ static void CopyCustomElementPropertiesToGame(int element) if (level.use_custom_template) { - if (Request("Copy and modify level tem- plate ?", REQ_ASK)) + if (Request("Copy and modify level template ?", REQ_ASK)) { level.use_custom_template = FALSE; ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE], @@ -5057,6 +5214,7 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_properties[EP_INDESTRUCTIBLE] = FALSE; custom_element_properties[EP_CAN_EXPLODE_1X1] = FALSE; custom_element_properties[EP_CAN_EXPLODE_3X3] = FALSE; + custom_element_properties[EP_CAN_EXPLODE_DYNA] = FALSE; custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE; custom_element_properties[EP_CAN_EXPLODE_SMASHED] = FALSE; custom_element_properties[EP_CAN_EXPLODE_IMPACT] = FALSE; @@ -5064,8 +5222,9 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_properties[EP_EXPLODE_RESULT]; /* special case: sub-settings dependent from main setting */ - if (custom_element_properties[EP_CAN_EXPLODE_3X3] || - custom_element_properties[EP_CAN_EXPLODE_1X1]) + if (custom_element_properties[EP_CAN_EXPLODE_1X1] || + custom_element_properties[EP_CAN_EXPLODE_3X3] || + custom_element_properties[EP_CAN_EXPLODE_DYNA]) { custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = custom_element.can_explode_by_fire; @@ -5085,7 +5244,8 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_LEFT_BY_PLAYER] = FALSE; custom_element_change_events[CE_DROPPED_BY_PLAYER] = FALSE; custom_element_change_events[CE_SWITCHED] = FALSE; - custom_element_change_events[CE_COLLISION] = FALSE; + custom_element_change_events[CE_HITTING_SOMETHING] = FALSE; + custom_element_change_events[CE_HIT_BY_SOMETHING] = FALSE; custom_element_change_events[CE_IMPACT] = FALSE; custom_element_change_events[CE_SMASHED] = FALSE; custom_element_change_events[custom_element_change.direct_action] = @@ -5101,16 +5261,18 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE; custom_element_change_events[CE_OTHER_GETS_DROPPED] = FALSE; custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE; + custom_element_change_events[CE_OTHER_IS_HITTING] = FALSE; + custom_element_change_events[CE_OTHER_GETS_HIT] = FALSE; custom_element_change_events[CE_OTHER_IS_SWITCHING] = FALSE; custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE; custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE; custom_element_change_events[custom_element_change.other_action] = custom_element_change_events[CE_BY_OTHER_ACTION]; - for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) + for (i = 0; i < NUM_ELEMENT_PROPERTIES; i++) SET_PROPERTY(element, i, custom_element_properties[i]); - for (i=0; i < NUM_CHANGE_EVENTS; i++) + for (i = 0; i < NUM_CHANGE_EVENTS; i++) SET_CHANGE_EVENT(element, i, custom_element_change_events[i]); /* copy change events also to special level editor variable */ @@ -5118,6 +5280,14 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change = *element_info[element].change; } +static void CopyGroupElementPropertiesToGame(int element) +{ + /* mark that this group element has been modified */ + element_info[element].modified_settings = TRUE; + + *element_info[element].group = group_element_info; +} + void DrawLevelEd() { CloseDoor(DOOR_CLOSE_ALL); @@ -5309,11 +5479,19 @@ static void ModifyEditorSelectbox(int selectbox_id, int new_value) ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END); } +static void ModifyEditorDrawingArea(int drawingarea_id, int xsize, int ysize) +{ + int gadget_id = drawingarea_info[drawingarea_id].gadget_id; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + + ModifyGadget(gi, GDI_AREA_SIZE, xsize, ysize, GDI_END); +} + static void ModifyEditorElementList() { int i; - for (i=0; i= max_lines_per_screen) - return 0; - - if (filename == NULL) - return 0; - - if (!(file = fopen(filename, MODE_READ))) - return 0; - - buffer[0] = '\0'; - buffer_len = 0; - - while(!feof(file) && current_line < max_lines_per_screen) - { - char *line_ptr; - boolean last_line_was_empty = TRUE; - - /* read next line of input file */ - if (!fgets(line, MAX_LINE_LEN, file)) - break; - - /* skip comments (lines directly beginning with '#') */ - if (line[0] == '#') - continue; - - /* cut trailing newline from input line */ - for (line_ptr = line; *line_ptr; line_ptr++) - { - if (*line_ptr == '\n' || *line_ptr == '\r') - { - *line_ptr = '\0'; - break; - } - } - - if (strlen(line) == 0) /* special case: force empty line */ - strcpy(line, "\n"); - - line_ptr = line; - - while (*line_ptr && current_line < max_lines_per_screen) - { - boolean buffer_filled = RenderLineToBuffer(&line_ptr, - buffer, &buffer_len, - last_line_was_empty, - max_chars_per_line); - if (buffer_filled) - { - DrawText(sx, sy + current_line * font_height, buffer, font_nr); - current_line++; - - last_line_was_empty = (buffer_len == 0); - - buffer[0] = '\0'; - buffer_len = 0; - } - } - } - - fclose(file); - - if (buffer_len > 0 && current_line < max_lines_per_screen) - { - DrawText(sx, sy + current_line * font_height, buffer, font_nr); - current_line++; - } - - return (current_line - start_line); + return DrawTextFromFile(sx, sy, filename, font_nr, max_chars_per_line, + max_lines_per_screen); } #else @@ -5656,6 +5783,9 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) int buffer_len; FILE *file; + if (current_line >= max_lines_per_screen) + return 0; + if (filename == NULL) return 0; @@ -5665,9 +5795,9 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) buffer[0] = '\0'; buffer_len = 0; - while(!feof(file)) + while (!feof(file) && current_line < max_lines_per_screen) { - char *line_ptr, *word_ptr; + char *line_ptr; boolean last_line_was_empty = TRUE; /* read next line of input file */ @@ -5691,77 +5821,16 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) if (strlen(line) == 0) /* special case: force empty line */ strcpy(line, "\n"); - word_ptr = line; + line_ptr = line; - while (*word_ptr) + while (*line_ptr && current_line < max_lines_per_screen) { - boolean print_buffer = FALSE; - int word_len; - - /* skip leading whitespaces */ - while (*word_ptr == ' ' || *word_ptr == '\t') - word_ptr++; - - line_ptr = word_ptr; - word_len = 0; - - /* look for end of next word */ - while (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0') - { - line_ptr++; - word_len++; - } - - if (word_len == 0) - { - continue; - } - else if (*word_ptr == '\n') /* special case: force empty line */ - { - if (buffer_len == 0) - word_ptr++; - - /* prevent printing of multiple empty lines */ - if (buffer_len > 0 || !last_line_was_empty) - print_buffer = TRUE; - } - else if (word_len < max_chars_per_line - buffer_len) - { - /* word fits into text buffer -- add word */ - - if (buffer_len > 0) - buffer[buffer_len++] = ' '; - - strncpy(&buffer[buffer_len], word_ptr, word_len); - buffer_len += word_len; - buffer[buffer_len] = '\0'; - word_ptr += word_len; - } - else if (buffer_len > 0) - { - /* not enough space left for word in text buffer -- print buffer */ - - print_buffer = TRUE; - } - else - { - /* word does not fit at all into empty text buffer -- cut word */ - - strncpy(buffer, word_ptr, max_chars_per_line); - buffer[max_chars_per_line] = '\0'; - word_ptr += max_chars_per_line; - print_buffer = TRUE; - } - - if (print_buffer) + boolean buffer_filled = RenderLineToBuffer(&line_ptr, + buffer, &buffer_len, + last_line_was_empty, + max_chars_per_line); + if (buffer_filled) { - if (current_line >= max_lines_per_screen) - { - fclose(file); - - return (current_line - start_line); - } - DrawText(sx, sy + current_line * font_height, buffer, font_nr); current_line++; @@ -5769,7 +5838,6 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) buffer[0] = '\0'; buffer_len = 0; - print_buffer = FALSE; } } } @@ -5784,171 +5852,7 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) return (current_line - start_line); } -#endif -#else - -static boolean PrintInfoText(char *text, int font_nr, int screen_line) -{ - int font_height = getFontHeight(font_nr); - int pad_x = ED_SETTINGS_XPOS(0); - int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE; - int sx = SX + pad_x; - int sy = SY + pad_y; - int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1; - - if (screen_line >= max_lines_per_screen) - return FALSE; - - DrawText(sx, sy + screen_line * font_height, text, font_nr); - - return TRUE; -} - -static int PrintElementDescriptionFromFile(char *filename, int screen_line) -{ - int font_nr = FONT_TEXT_2; - int font_width = getFontWidth(font_nr); - int pad_x = ED_SETTINGS_XPOS(0); - int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width; - char line[MAX_LINE_LEN]; - char buffer[max_chars_per_line + 1]; - int buffer_len; - int lines_printed = 0; - FILE *file; - - if (filename == NULL) - return 0; - - if (!(file = fopen(filename, MODE_READ))) - return 0; - - buffer[0] = '\0'; - buffer_len = 0; - - while(!feof(file)) - { - char *line_ptr, *word_ptr; - boolean last_line_was_empty = TRUE; - - /* read next line of input file */ - if (!fgets(line, MAX_LINE_LEN, file)) - break; - - /* skip comments (lines directly beginning with '#') */ - if (line[0] == '#') - continue; - - /* cut trailing newline from input line */ - for (line_ptr = line; *line_ptr; line_ptr++) - { - if (*line_ptr == '\n' || *line_ptr == '\r') - { - *line_ptr = '\0'; - break; - } - } - - if (strlen(line) == 0) /* special case: force empty line */ - strcpy(line, "\n"); - - word_ptr = line; - -#if 0 - printf("::: got line '%s'...\n", line); -#endif - - while (*word_ptr) - { - boolean print_buffer = FALSE; - int word_len; - - /* skip leading whitespaces */ - while (*word_ptr == ' ' || *word_ptr == '\t') - word_ptr++; - - line_ptr = word_ptr; - word_len = 0; - - /* look for end of next word */ - while (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0') - { - line_ptr++; - word_len++; - } - - if (word_len == 0) - { - continue; - } - else if (*word_ptr == '\n') /* special case: force empty line */ - { - if (buffer_len == 0) - word_ptr++; - - /* prevent printing of multiple empty lines */ - if (buffer_len > 0 || !last_line_was_empty) - print_buffer = TRUE; - } - else if (word_len < max_chars_per_line - buffer_len) - { - /* word fits into text buffer -- add word */ - - if (buffer_len > 0) - buffer[buffer_len++] = ' '; - - strncpy(&buffer[buffer_len], word_ptr, word_len); - buffer_len += word_len; - buffer[buffer_len] = '\0'; - word_ptr += word_len; - } - else if (buffer_len > 0) - { - /* not enough space left for word in text buffer -- print buffer */ - - print_buffer = TRUE; - } - else - { - /* word does not fit at all into empty text buffer -- cut word */ - - strncpy(buffer, word_ptr, max_chars_per_line); - buffer[max_chars_per_line] = '\0'; - word_ptr += max_chars_per_line; - print_buffer = TRUE; - } - - if (print_buffer) - { -#if 0 - printf("::: printing '%s'...\n", buffer); -#endif - - if (!PrintInfoText(buffer, font_nr, screen_line + lines_printed)) - { - fclose(file); - - return lines_printed; - } - - last_line_was_empty = (buffer_len == 0); - lines_printed++; - - buffer[0] = '\0'; - buffer_len = 0; - print_buffer = FALSE; - } - } - } - - fclose(file); - - if (buffer_len > 0) - if (PrintInfoText(buffer, font_nr, screen_line + lines_printed)) - lines_printed++; - - return lines_printed; -} #endif static void DrawPropertiesTabulatorGadgets() @@ -5966,7 +5870,7 @@ static void DrawPropertiesTabulatorGadgets() if (IS_CUSTOM_ELEMENT(properties_element)) id_last = ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED; - for (i=id_first; i <= id_last; i++) + for (i = id_first; i <= id_last; i++) { int gadget_id = textbutton_info[i].gadget_id; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; @@ -6070,8 +5974,8 @@ static void DrawPropertiesInfo() /* ----- print number of elements / percentage of this element in level */ num_elements_in_level = 0; - for (y=0; y to_x) swap_numbers(&from_x, &to_x); - for (x=from_x; x<=to_x; x++) + for (x = from_x; x <= to_x; x++) DrawLineElement(x, y, element, change_level); } else if (from_x == to_x) /* vertical line */ @@ -6479,7 +6399,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y, if (from_y > to_y) swap_numbers(&from_y, &to_y); - for (y=from_y; y<=to_y; y++) + for (y = from_y; y <= to_y; y++) DrawLineElement(x, y, element, change_level); } else /* diagonal line */ @@ -6495,7 +6415,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y, if (from_x > to_x) swap_number_pairs(&from_x, &from_y, &to_x, &to_y); - for (x=0; x<=len_x; x++) + for (x = 0; x <= len_x; x++) { y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1); DrawLineElement(from_x + x, from_y + y, element, change_level); @@ -6508,7 +6428,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y, if (from_y > to_y) swap_number_pairs(&from_x, &from_y, &to_x, &to_y); - for (y=0; y<=len_y; y++) + for (y = 0; y <= len_y; y++) { x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1); DrawLineElement(from_x + x, from_y + y, element, change_level); @@ -6534,7 +6454,7 @@ static void DrawFilledBox(int from_x, int from_y, int to_x, int to_y, if (from_y > to_y) swap_number_pairs(&from_x, &from_y, &to_x, &to_y); - for (y=from_y; y<=to_y; y++) + for (y = from_y; y <= to_y; y++) DrawLine(from_x, y, to_x, y, element, change_level); } @@ -6552,7 +6472,7 @@ static void DrawArcExt(int from_x, int from_y, int to_x2, int to_y2, /* not optimal (some points get drawn twice) but simple, and fast enough for the few points we are drawing */ - for (x=0; x<=radius; x++) + for (x = 0; x <= radius; x++) { int sx, sy, lx, ly; @@ -6567,7 +6487,7 @@ static void DrawArcExt(int from_x, int from_y, int to_x2, int to_y2, DrawLineElement(sx, sy, element, change_level); } - for (y=0; y<=radius; y++) + for (y = 0; y <= radius; y++) { int sx, sy, lx, ly; @@ -6680,9 +6600,9 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, from_lx = from_x + level_xpos; from_ly = from_y + level_ypos; - for (y=0; y= num_free_positions) { - for (x=0; x= GADGET_ID_ELEMENT_CONTENT_0 && @@ -7382,6 +7311,11 @@ static void HandleCounterButtons(struct GadgetInfo *gi) DrawElementContentAreas(); break; + case ED_COUNTER_ID_GROUP_CONTENT: + DrawGroupElementArea(properties_element); + CopyGroupElementPropertiesToGame(properties_element); + break; + case ED_COUNTER_ID_ENVELOPE_XSIZE: case ED_COUNTER_ID_ENVELOPE_YSIZE: DrawEnvelopeTextArea(-1); @@ -7466,14 +7400,15 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) } else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE) { - boolean new_template = (!LevelFileExists(-1)); + char *template_filename = getDefaultLevelFilename(-1); + boolean new_template = !fileExists(template_filename); if (new_template || - Request("Save this tem- plate and kill the old ?", REQ_ASK)) + Request("Save this template and kill the old ?", REQ_ASK)) SaveLevelTemplate(); if (new_template) - Request("Tem- plate saved !", REQ_CONFIRM); + Request("Template saved !", REQ_CONFIRM); } else if (type_id == ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE && custom_element.num_change_pages < MAX_CHANGE_PAGES) @@ -7554,9 +7489,11 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) } else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE) { - if (level.use_custom_template && !LevelFileExists(-1)) + char *template_filename = getDefaultLevelFilename(-1); + + if (level.use_custom_template && !fileExists(template_filename)) { - Request("No level tem- plate found !", REQ_CONFIRM); + Request("No level template found !", REQ_CONFIRM); level.use_custom_template = FALSE; ModifyGadget(gi, GDI_CHECKED, FALSE, GDI_END); @@ -7789,8 +7726,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS; undo_buffer_steps--; - for(x=0; x