X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=080c1761d73095360dd92d84a65b0a66c5f2be0e;hb=fb8bb677ad12b6b837192cb32a395b9e9c2bcdb6;hp=9fb3157e1f0bc922e6a0c0eee212335fdfca4d82;hpb=ad67feea72c2db12d75bb34b27193eacc00bbaef;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 9fb3157e..080c1761 100644 --- a/src/editor.c +++ b/src/editor.c @@ -2009,6 +2009,9 @@ static struct ValueTextInfo options_change_direct_action[] = { CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" }, { CE_CLICKED_BY_MOUSE, "clicked by mouse" }, { CE_PRESSED_BY_MOUSE, "pressed by mouse" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" }, + { CE_NEXT_TO_PLAYER, "next to player" }, { -1, NULL } }; @@ -2042,6 +2045,10 @@ static struct ValueTextInfo options_change_other_action[] = { CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" }, { CE_MOUSE_CLICKED_ON_X, "mouse clicked on" }, { CE_MOUSE_PRESSED_ON_X, "mouse pressed on" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" }, + { CE_PLAYER_NEXT_TO_X, "player next to" }, + { CE_NEXT_TO_X, "next to" }, { -1, NULL } }; @@ -2072,38 +2079,38 @@ static struct ValueTextInfo options_change_trigger_player[] = static struct ValueTextInfo options_change_trigger_page[] = { - { (1 << 0), "1" }, - { (1 << 1), "2" }, - { (1 << 2), "3" }, - { (1 << 3), "4" }, - { (1 << 4), "5" }, - { (1 << 5), "6" }, - { (1 << 6), "7" }, - { (1 << 7), "8" }, - { (1 << 8), "9" }, - { (1 << 9), "10" }, - { (1 << 10), "11" }, - { (1 << 11), "12" }, - { (1 << 12), "13" }, - { (1 << 13), "14" }, - { (1 << 14), "15" }, - { (1 << 15), "16" }, - { (1 << 16), "17" }, - { (1 << 17), "18" }, - { (1 << 18), "19" }, - { (1 << 19), "20" }, - { (1 << 20), "21" }, - { (1 << 21), "22" }, - { (1 << 22), "23" }, - { (1 << 23), "24" }, - { (1 << 24), "25" }, - { (1 << 25), "26" }, - { (1 << 26), "27" }, - { (1 << 27), "28" }, - { (1 << 28), "29" }, - { (1 << 29), "30" }, - { (1 << 30), "31" }, - { (1 << 31), "32" }, + { (1u << 0), "1" }, + { (1u << 1), "2" }, + { (1u << 2), "3" }, + { (1u << 3), "4" }, + { (1u << 4), "5" }, + { (1u << 5), "6" }, + { (1u << 6), "7" }, + { (1u << 7), "8" }, + { (1u << 8), "9" }, + { (1u << 9), "10" }, + { (1u << 10), "11" }, + { (1u << 11), "12" }, + { (1u << 12), "13" }, + { (1u << 13), "14" }, + { (1u << 14), "15" }, + { (1u << 15), "16" }, + { (1u << 16), "17" }, + { (1u << 17), "18" }, + { (1u << 18), "19" }, + { (1u << 19), "20" }, + { (1u << 20), "21" }, + { (1u << 21), "22" }, + { (1u << 22), "23" }, + { (1u << 23), "24" }, + { (1u << 24), "25" }, + { (1u << 25), "26" }, + { (1u << 26), "27" }, + { (1u << 27), "28" }, + { (1u << 28), "29" }, + { (1u << 29), "30" }, + { (1u << 30), "31" }, + { (1u << 31), "32" }, { CH_PAGE_ANY, "any" }, { -1, NULL } @@ -5265,6 +5272,41 @@ static int *editor_el_group_ptr = editor_el_group; static int num_editor_hl_group = ARRAY_SIZE(editor_hl_group); static int num_editor_el_group = ARRAY_SIZE(editor_el_group); +static int editor_hl_empty_space[] = +{ + EL_INTERNAL_CASCADE_ES_ACTIVE, + EL_CHAR('E'), + EL_CHAR('S'), + EL_EMPTY, +}; + +static int editor_el_empty_space[] = +{ + EL_EMPTY_SPACE_1, + EL_EMPTY_SPACE_2, + EL_EMPTY_SPACE_3, + EL_EMPTY_SPACE_4, + + EL_EMPTY_SPACE_5, + EL_EMPTY_SPACE_6, + EL_EMPTY_SPACE_7, + EL_EMPTY_SPACE_8, + + EL_EMPTY_SPACE_9, + EL_EMPTY_SPACE_10, + EL_EMPTY_SPACE_11, + EL_EMPTY_SPACE_12, + + EL_EMPTY_SPACE_13, + EL_EMPTY_SPACE_14, + EL_EMPTY_SPACE_15, + EL_EMPTY_SPACE_16 +}; +static int *editor_hl_empty_space_ptr = editor_hl_empty_space; +static int *editor_el_empty_space_ptr = editor_el_empty_space; +static int num_editor_hl_empty_space = ARRAY_SIZE(editor_hl_empty_space); +static int num_editor_el_empty_space = ARRAY_SIZE(editor_el_empty_space); + static int editor_hl_reference[] = { EL_INTERNAL_CASCADE_REF_ACTIVE, @@ -5477,6 +5519,12 @@ editor_elements_info[] = &editor_hl_group_ptr, &num_editor_hl_group, &editor_el_group_ptr, &num_editor_el_group }, + { + &setup_editor_el_custom, + &setup.editor_cascade.el_es, + &editor_hl_empty_space_ptr, &num_editor_hl_empty_space, + &editor_el_empty_space_ptr, &num_editor_el_empty_space + }, { &setup_editor_el_custom, &setup.editor_cascade.el_ref, @@ -5509,6 +5557,14 @@ editor_elements_info[] = } }; +static struct XY xy_directions[] = +{ + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } +}; + // ---------------------------------------------------------------------------- // functions @@ -5562,7 +5618,7 @@ static char *getElementInfoText(int element) static char *getElementDescriptionFilenameExt(char *basename) { - char *elements_subdir = "elements"; + char *elements_subdir = ELEMENTS_DIRECTORY; static char *elements_subdir2 = NULL; static char *filename = NULL; @@ -5603,6 +5659,11 @@ static char *getElementDescriptionFilename(int element) if (filename != NULL) return filename; + // 3rd try: look for generic fallback text file for any element + filename = getElementDescriptionFilenameExt(FALLBACK_TEXT_FILENAME); + if (filename != NULL) + return filename; + return NULL; } @@ -5831,10 +5892,10 @@ static void ReinitializeElementList(void) // determine size of element list for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { - boolean found_inactive_cascade = FALSE; - if (*editor_elements_info[i].setup_value) { + boolean found_inactive_cascade = FALSE; + if (setup.editor.el_headlines) { // required for correct padding of palette headline buttons @@ -6441,11 +6502,9 @@ static void CreateCounterButtons(void) int graphic; struct GraphicInfo *gd; int gd_x1, gd_x2, gd_y1, gd_y2; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; char infotext[max_infotext_len + 1]; - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; - if (i == ED_COUNTER_ID_SELECT_LEVEL) { graphic = (j == 0 ? @@ -6585,7 +6644,6 @@ static void CreateDrawingAreas(void) for (i = 0; i < ED_NUM_DRAWING_AREAS; i++) { struct GadgetInfo *gi; - unsigned int event_mask; int id = drawingarea_info[i].gadget_id; int x = SX + ED_AREA_SETTINGS_X(drawingarea_info[i]); int y = SY + ED_AREA_SETTINGS_Y(drawingarea_info[i]); @@ -6593,8 +6651,7 @@ static void CreateDrawingAreas(void) int area_ysize = drawingarea_info[i].area_ysize; int item_size = (id == GADGET_ID_DRAWING_LEVEL ? ed_tilesize : ED_DRAWINGAREA_TILE_SIZE); - - event_mask = + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS | GD_EVENT_PIXEL_PRECISE; @@ -6641,7 +6698,7 @@ static void CreateTextInputGadgets(void) int gd_x2 = gd->src_x + gd->active_xoffset; int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textinput_info[i].gadget_id; int x, y; @@ -6668,8 +6725,6 @@ static void CreateTextInputGadgets(void) y = ED_SETTINGS_Y(textinput_info[i].y); } - event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; - sprintf(infotext, "Enter %s", textinput_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6712,14 +6767,12 @@ static void CreateTextAreaGadgets(void) int gd_x2 = gd->src_x + gd->active_xoffset; int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_TEXT_LEAVING; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textarea_info[i].gadget_id; int area_xsize = textarea_info[i].xsize; int area_ysize = textarea_info[i].ysize; - event_mask = GD_EVENT_TEXT_LEAVING; - sprintf(infotext, "Enter %s", textarea_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6763,11 +6816,12 @@ static void CreateSelectboxGadgets(void) int gd_y2 = gd->src_y + gd->active_yoffset; int selectbox_button_xsize = gd2->width; struct GadgetInfo *gi; - unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = selectbox_info[i].gadget_id; int x = SX + ED_SETTINGS_X(selectbox_info[i].x); int y = SY + ED_SETTINGS_Y(selectbox_info[i].y); + unsigned int event_mask = + GD_EVENT_RELEASED | GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; if (selectbox_info[i].size == -1) // dynamically determine size { @@ -6783,9 +6837,6 @@ static void CreateSelectboxGadgets(void) selectbox_info[i].size++; // add one character empty space } - event_mask = GD_EVENT_RELEASED | - GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; - // determine horizontal position to the right of specified gadget if (selectbox_info[i].gadget_id_align != GADGET_ID_NONE) x = (right_gadget_border[selectbox_info[i].gadget_id_align] + @@ -6854,7 +6905,7 @@ static void CreateTextbuttonGadgets(void) int border_xsize = gd->border_size + gd->draw_xoffset; int border_ysize = gd->border_size; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_RELEASED; char infotext[MAX_OUTPUT_LINESIZE + 1]; int x = SX + ED_SETTINGS_X(textbutton_info[i].x); int y = SY + ED_SETTINGS_Y(textbutton_info[i].y); @@ -6862,8 +6913,6 @@ static void CreateTextbuttonGadgets(void) if (textbutton_info[i].size == -1) // dynamically determine size textbutton_info[i].size = strlen(textbutton_info[i].text); - event_mask = GD_EVENT_RELEASED; - sprintf(infotext, "%s", textbutton_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6916,7 +6965,6 @@ static void CreateTextbuttonGadgets(void) static void CreateGraphicbuttonGadgets(void) { struct GadgetInfo *gi; - unsigned int event_mask; int i; // create buttons for scrolling of drawing area and element list @@ -6931,8 +6979,7 @@ static void CreateGraphicbuttonGadgets(void) int gd_y1 = gd->src_y; int gd_x2 = gd->src_x + gd->pressed_xoffset; int gd_y2 = gd->src_y + gd->pressed_yoffset; - - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; // determine horizontal position to the right of specified gadget if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -7024,7 +7071,7 @@ static void CreateScrollbarGadgets(void) int gd_y2 = gd->src_y + gd->pressed_yoffset; struct GadgetInfo *gi; int items_max, items_visible, item_position; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; if (i == ED_SCROLLBAR_ID_LIST_VERTICAL) { @@ -7048,8 +7095,6 @@ static void CreateScrollbarGadgets(void) } } - event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; - gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_IMAGE_ID, graphic, @@ -7085,11 +7130,8 @@ static void CreateScrollbarGadgets(void) static void CreateCheckbuttonGadgets(void) { struct GadgetInfo *gi; - unsigned int event_mask; int i; - event_mask = GD_EVENT_PRESSED; - for (i = 0; i < ED_NUM_CHECKBUTTONS; i++) { int id = checkbutton_info[i].gadget_id; @@ -7106,6 +7148,7 @@ static void CreateCheckbuttonGadgets(void) int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; int x = SX + ED_SETTINGS_X(checkbutton_info[i].x); int y = SY + ED_SETTINGS_Y(checkbutton_info[i].y); + unsigned int event_mask = GD_EVENT_PRESSED; // determine horizontal position to the right of specified gadget if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -7157,16 +7200,14 @@ static void CreateRadiobuttonGadgets(void) int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset; int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; int i; - event_mask = GD_EVENT_PRESSED; - for (i = 0; i < ED_NUM_RADIOBUTTONS; i++) { int id = radiobutton_info[i].gadget_id; int x = SX + ED_SETTINGS_X(radiobutton_info[i].x); int y = SY + ED_SETTINGS_Y(radiobutton_info[i].y); + unsigned int event_mask = GD_EVENT_PRESSED; int checked = (*radiobutton_info[i].value == radiobutton_info[i].checked_value); @@ -8205,7 +8246,8 @@ static void CopyCustomElementPropertiesToEditor(int element) // set "change by direct action" selectbox help value custom_element_change.direct_action = - (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : + (HAS_CHANGE_EVENT(element, CE_NEXT_TO_PLAYER) ? CE_NEXT_TO_PLAYER : + HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_SWITCHED_BY_PLAYER) ? CE_SWITCHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_SNAPPED_BY_PLAYER) ? CE_SNAPPED_BY_PLAYER : @@ -8229,7 +8271,8 @@ static void CopyCustomElementPropertiesToEditor(int element) // set "change by other element action" selectbox help value custom_element_change.other_action = - (HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X : + (HAS_CHANGE_EVENT(element, CE_PLAYER_NEXT_TO_X) ? CE_PLAYER_NEXT_TO_X : + HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_PRESSES_X) ? CE_PLAYER_PRESSES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_SWITCHES_X) ? CE_PLAYER_SWITCHES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_SNAPS_X) ? CE_PLAYER_SNAPS_X : @@ -8239,6 +8282,7 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_PLAYER_DIGS_X) ? CE_PLAYER_DIGS_X : HAS_CHANGE_EVENT(element, CE_PLAYER_COLLECTS_X) ? CE_PLAYER_COLLECTS_X : HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_X : + HAS_CHANGE_EVENT(element, CE_NEXT_TO_X) ? CE_NEXT_TO_X : HAS_CHANGE_EVENT(element, CE_TOUCHING_X) ? CE_TOUCHING_X : HAS_CHANGE_EVENT(element, CE_HITTING_X) ? CE_HITTING_X : HAS_CHANGE_EVENT(element, CE_DIGGING_X) ? CE_DIGGING_X : @@ -8263,9 +8307,14 @@ static void CopyGroupElementPropertiesToEditor(int element) custom_element = element_info[element]; // needed for description } +static void CopyEmptyElementPropertiesToEditor(int element) +{ + custom_element = element_info[element]; +} + static void CopyClassicElementPropertiesToEditor(int element) { - if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element)) + if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element)) custom_element_properties[EP_CAN_MOVE_INTO_ACID] = getMoveIntoAcidProperty(&level, element); @@ -8280,6 +8329,8 @@ static void CopyElementPropertiesToEditor(int element) CopyCustomElementPropertiesToEditor(element); else if (IS_GROUP_ELEMENT(element)) CopyGroupElementPropertiesToEditor(element); + else if (IS_EMPTY_ELEMENT(element)) + CopyEmptyElementPropertiesToEditor(element); else CopyClassicElementPropertiesToEditor(element); } @@ -8367,6 +8418,7 @@ static void CopyCustomElementPropertiesToGame(int element) // ---------- element settings: advanced (custom elements) ------------------ // set player change event from checkbox and selectbox + custom_element_change_events[CE_NEXT_TO_PLAYER] = FALSE; custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE; custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE; custom_element_change_events[CE_SWITCHED_BY_PLAYER] = FALSE; @@ -8391,6 +8443,7 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_BY_DIRECT_ACTION]; // set other element action change event from checkbox and selectbox + custom_element_change_events[CE_PLAYER_NEXT_TO_X] = FALSE; custom_element_change_events[CE_PLAYER_TOUCHES_X] = FALSE; custom_element_change_events[CE_PLAYER_PRESSES_X] = FALSE; custom_element_change_events[CE_PLAYER_SWITCHES_X] = FALSE; @@ -8401,6 +8454,7 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_PLAYER_DIGS_X] = FALSE; custom_element_change_events[CE_PLAYER_COLLECTS_X] = FALSE; custom_element_change_events[CE_PLAYER_DROPS_X] = FALSE; + custom_element_change_events[CE_NEXT_TO_X] = FALSE; custom_element_change_events[CE_TOUCHING_X] = FALSE; custom_element_change_events[CE_HITTING_X] = FALSE; custom_element_change_events[CE_DIGGING_X] = FALSE; @@ -8449,9 +8503,24 @@ static void CopyGroupElementPropertiesToGame(int element) InitElementPropertiesGfxElement(); } +static void CopyEmptyElementPropertiesToGame(int element) +{ + // mark that this empty element has been modified + custom_element.modified_settings = TRUE; + level.changed = TRUE; + + if (level.use_custom_template) + AskToCopyAndModifyLevelTemplate(); + + element_info[element] = custom_element; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); +} + static void CopyClassicElementPropertiesToGame(int element) { - if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element)) + if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element)) setMoveIntoAcidProperty(&level, element, custom_element_properties[EP_CAN_MOVE_INTO_ACID]); @@ -8466,6 +8535,8 @@ static void CopyElementPropertiesToGame(int element) CopyCustomElementPropertiesToGame(element); else if (IS_GROUP_ELEMENT(element)) CopyGroupElementPropertiesToGame(element); + else if (IS_EMPTY_ELEMENT(element)) + CopyEmptyElementPropertiesToGame(element); else CopyClassicElementPropertiesToGame(element); } @@ -9121,7 +9192,7 @@ static void DrawPropertiesTabulatorGadgets(void) int i; // draw two config tabulators for player elements - if (ELEM_IS_PLAYER(properties_element)) + if (IS_PLAYER_ELEMENT(properties_element)) id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2; // draw two config and one "change" tabulator for custom elements @@ -9136,7 +9207,7 @@ static void DrawPropertiesTabulatorGadgets(void) // use "config 1" and "config 2" instead of "config" for players and CEs if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG && - (ELEM_IS_PLAYER(properties_element) || + (IS_PLAYER_ELEMENT(properties_element) || IS_CUSTOM_ELEMENT(properties_element))) continue; @@ -9829,11 +9900,12 @@ static boolean checkPropertiesConfig(int element) if (IS_GEM(element) || IS_CUSTOM_ELEMENT(element) || IS_GROUP_ELEMENT(element) || + IS_EMPTY_ELEMENT(element) || IS_BALLOON_ELEMENT(element) || IS_ENVELOPE(element) || IS_MM_MCDUFFIN(element) || IS_DF_LASER(element) || - ELEM_IS_PLAYER(element) || + IS_PLAYER_ELEMENT(element) || HAS_EDITOR_CONTENT(element) || CAN_GROW(element) || COULD_MOVE_INTO_ACID(element) || @@ -9990,7 +10062,7 @@ static void DrawPropertiesConfig(void) DrawAndroidElementArea(properties_element); } - if (ELEM_IS_PLAYER(properties_element)) + if (IS_PLAYER_ELEMENT(properties_element)) { int player_nr = GET_PLAYER_NR(properties_element); @@ -10070,7 +10142,7 @@ static void DrawPropertiesConfig(void) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE); if (COULD_MOVE_INTO_ACID(properties_element) && - !ELEM_IS_PLAYER(properties_element) && + !IS_PLAYER_ELEMENT(properties_element) && (!IS_CUSTOM_ELEMENT(properties_element) || edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2)) { @@ -10252,6 +10324,23 @@ static void DrawPropertiesConfig(void) draw_footer_line = TRUE; } + else if (IS_EMPTY_ELEMENT(properties_element)) + { + // draw stickybutton gadget + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); + + // draw checkbutton gadgets + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1); + + // draw textbutton gadgets + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); + + // draw drawing area gadgets + MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC); + + draw_footer_line = TRUE; + } // draw little footer border line above CE/GE use/save template gadgets if (draw_footer_line) @@ -10342,12 +10431,12 @@ static void DrawEditorElementName(int x, int y, int font_nr) int font_height = getFontHeight(font_nr); int max_text_width = SXSIZE - x - ED_ELEMENT_SETTINGS_X(0); int max_chars_per_line = max_text_width / font_width; - char buffer[max_chars_per_line + 1]; if (strlen(element_name) <= max_chars_per_line) DrawTextS(x, y, font_nr, element_name); else { + char buffer[max_chars_per_line + 1]; int next_pos = max_chars_per_line; strncpy(buffer, element_name, max_chars_per_line); @@ -10408,12 +10497,12 @@ static void DrawPropertiesWindow(void) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_2; if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG && - !ELEM_IS_PLAYER(properties_element) && + !IS_PLAYER_ELEMENT(properties_element) && !IS_CUSTOM_ELEMENT(properties_element)) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG; if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG && - (ELEM_IS_PLAYER(properties_element) || + (IS_PLAYER_ELEMENT(properties_element) || IS_CUSTOM_ELEMENT(properties_element))) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_1; @@ -10734,13 +10823,7 @@ static int getChipFromOpenDirectionNotEmpty(int direction, int element_old) static int getClosedTube(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromTube(element_old); int direction_new = MV_NONE; @@ -10748,8 +10831,8 @@ static int getClosedTube(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10764,13 +10847,7 @@ static int getClosedTube(int x, int y) static int getClosedBelt(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int nr = getBeltNrFromBeltElement(element_old); int direction_old = getOpenDirectionFromBelt(element_old); @@ -10779,8 +10856,8 @@ static int getClosedBelt(int x, int y) for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10795,13 +10872,7 @@ static int getClosedBelt(int x, int y) static int getClosedPool(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromPool(element_old); int direction_new = MV_NONE; @@ -10809,8 +10880,8 @@ static int getClosedPool(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10826,13 +10897,7 @@ static int getClosedPool(int x, int y) static int getClosedPillar(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromPillar(element_old); int direction_new = MV_NONE; @@ -10840,8 +10905,8 @@ static int getClosedPillar(int x, int y) for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10856,13 +10921,7 @@ static int getClosedPillar(int x, int y) static int getClosedSteel2(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromSteel2(element_old); int direction_new = MV_NONE; @@ -10870,8 +10929,8 @@ static int getClosedSteel2(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10886,13 +10945,7 @@ static int getClosedSteel2(int x, int y) static int getClosedChip(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromChip(element_old); int direction_new = MV_NONE; @@ -10900,8 +10953,8 @@ static int getClosedChip(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10984,13 +11037,7 @@ static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, static void SetElementIntelliDraw(int x, int y, int new_element, boolean change_level, int button) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; static int last_x = -1; static int last_y = -1; @@ -11016,8 +11063,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_TUBE(IntelliDrawBuffer[last_x][last_y])) @@ -11054,8 +11101,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_BELT(IntelliDrawBuffer[last_x][last_y])) @@ -11092,8 +11139,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[last_x][last_y])) @@ -11135,8 +11182,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_EMC_PILLAR(IntelliDrawBuffer[last_x][last_y])) @@ -11172,8 +11219,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y])) @@ -11207,8 +11254,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y])) @@ -11268,8 +11315,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element)) @@ -12321,7 +12368,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, { int element = Tile[x][y]; - if (!IS_EM_ELEMENT(element) && !ELEM_IS_PLAYER(element)) + if (!IS_EM_ELEMENT(element) && !IS_PLAYER_ELEMENT(element)) use_em_engine = FALSE; if (!IS_SP_ELEMENT(element)) @@ -12554,7 +12601,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) static int start_sx; static int last_sx, last_sy; static boolean typing = FALSE; - int letter_element = EL_CHAR_ASCII0 + letter; + int letter_element; int lx = 0, ly = 0; // map lower case letters to upper case and convert special characters @@ -12857,8 +12904,6 @@ static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir) static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; - static int last_sx = -1, last_sy = -1; - static int last_sx2 = -1, last_sy2 = -1; int id = gi->custom_id; int type_id = gi->custom_type_id; boolean button_press_event; @@ -12878,8 +12923,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) int dx = sx2 % 2; int dy = sy2 % 2; int lx = 0, ly = 0; - int min_lx = 0, min_ly = 0; - int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; int x, y; button_press_event = (gi->event.type == GD_EVENT_PRESSED); @@ -12891,6 +12934,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (draw_level) { + int min_lx = 0, min_ly = 0; + int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; + // get positions inside level field lx = sx + level_xpos; ly = sy + level_ypos; @@ -12919,15 +12965,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) sy2 = sy * 2 + dy; } - if (button_release_event) - { - last_sx = -1; - last_sy = -1; - last_sx2 = -1; - last_sy2 = -1; - } - else if (!button_press_event) + if (!button_press_event && !button_release_event) { + static int last_sx = -1; + static int last_sy = -1; + static int last_sx2 = -1; + static int last_sy2 = -1; int old_element = (IN_LEV_FIELD(lx, ly) ? Tile[lx][ly] : EL_UNDEFINED); boolean hires_drawing = (level.game_engine_type == GAME_ENGINE_TYPE_MM && isHiresTileElement(old_element) && @@ -12937,12 +12980,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if ((sx == last_sx && sy == last_sy && !hires_drawing) || (sx2 == last_sx2 && sy2 == last_sy2)) return; - } - last_sx = sx; - last_sy = sy; - last_sx2 = sx2; - last_sy2 = sy2; + last_sx = sx; + last_sy = sy; + last_sx2 = sx2; + last_sy2 = sy2; + } if (button_press_event) started_inside_drawing_area = inside_drawing_area; @@ -12953,9 +12996,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!IS_VALID_BUTTON(button)) return; - if (!button && !button_release_event) - return; - // handle info callback for each invocation of action callback gi->callback_info(gi); @@ -12991,10 +13031,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !inside_drawing_area) DeleteBrushFromCursor(); - } - if (!button || button_release_event) break; + } if (draw_with_brush) { @@ -13004,7 +13043,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { SetDrawModeHiRes(new_element); - if (ELEM_IS_PLAYER(new_element)) + if (IS_PLAYER_ELEMENT(new_element)) { // remove player at old position for (y = 0; y < lev_fieldy; y++) @@ -13013,7 +13052,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { int old_element = Tile[x][y]; - if (ELEM_IS_PLAYER(old_element)) + if (IS_PLAYER_ELEMENT(old_element)) { int replaced_with_element = (old_element == EL_SOKOBAN_FIELD_PLAYER && @@ -13079,22 +13118,19 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (button_release_event) CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - if (button) - { - SetDrawModeHiRes(new_element); + SetDrawModeHiRes(new_element); - if (getDrawModeHiRes()) - { - sx = sx2; - sy = sy2; - } + if (getDrawModeHiRes()) + { + sx = sx2; + sy = sy2; + } - if (!button_press_event) - DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); + if (!button_press_event) + DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); - last_sx = sx; - last_sy = sy; - } + last_sx = sx; + last_sy = sy; } break; @@ -13644,9 +13680,11 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) boolean template_related_changes_found = FALSE; int i; - // check if any custom or group elements have been changed + // check if any custom, group or empty elements have been changed for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if ((IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)) && + if ((IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i)) && element_info[i].modified_settings) template_related_changes_found = TRUE; @@ -14181,7 +14219,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) id <= GADGET_ID_ELEMENTLIST_LAST) { int element_position = id - GADGET_ID_ELEMENTLIST_FIRST; - int new_element = editor_elements[element_position + element_shift]; + + new_element = editor_elements[element_position + element_shift]; if (IS_EDITOR_CASCADE(new_element)) { @@ -14421,11 +14460,12 @@ static void HandleLevelEditorIdle_Properties(void) int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size; int x = editor.settings.element_graphic.x + element_border; int y = editor.settings.element_graphic.y + element_border; - static unsigned int action_delay = 0; - unsigned int action_delay_value = GameFrameDelay; + static DelayCounter action_delay = { 0 }; int i; - if (!DelayReached(&action_delay, action_delay_value)) + action_delay.value = GameFrameDelay; + + if (!DelayReached(&action_delay)) return; for (i = 0; i < ED_NUM_SELECTBOX; i++) @@ -14474,7 +14514,6 @@ static void ClearEditorGadgetInfoText(void) void PrintEditorGadgetInfoText(struct GadgetInfo *gi) { char infotext[MAX_OUTPUT_LINESIZE + 1]; - char shortcut[MAX_OUTPUT_LINESIZE + 1]; int max_infotext_len = getMaxInfoTextLength(); if (gi == NULL || strlen(gi->info_text) == 0) @@ -14489,6 +14528,8 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) if (key) { + char shortcut[MAX_OUTPUT_LINESIZE + 1]; + if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) sprintf(shortcut, " ('.' or '%c')", key); else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) @@ -14532,7 +14573,6 @@ void HandleEditorGadgetInfoText(void *ptr) static void HandleDrawingAreaInfo(struct GadgetInfo *gi) { - static int start_lx, start_ly; int id = gi->custom_id; int type_id = gi->custom_type_id; int sx = gi->event.x; @@ -14545,7 +14585,6 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) int actual_drawing_function = drawing_function; int max_infotext_len = getMaxInfoTextLength(); char infotext[MAX_OUTPUT_LINESIZE + 1]; - char *text; infotext[0] = '\0'; // start with empty info text @@ -14586,6 +14625,10 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) { if (button_status) // if (gi->state == GD_BUTTON_PRESSED) { + static int start_lx = 0; + static int start_ly = 0; + char *text; + if (gi->event.type == GD_EVENT_PRESSED) { start_lx = lx;