X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Feditor.c;h=226fd56da5b6498677dd2e128dd2dbc6878ec889;hp=3fa42f10eab74c5accddb47ecc8d90872e340f06;hb=61b373e48107ac90eac8c19aa506b1827120cda9;hpb=37580702ec235276fd1bc656c01e5cc9ae48a683 diff --git a/src/editor.c b/src/editor.c index 3fa42f10..226fd56d 100644 --- a/src/editor.c +++ b/src/editor.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // editor.c // ============================================================================ @@ -559,6 +559,7 @@ enum // selectbox identifiers GADGET_ID_TIME_OR_STEPS, + GADGET_ID_TIME_SCORE_BASE, GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_LEVELSET_SAVE_MODE, GADGET_ID_WIND_DIRECTION, @@ -642,12 +643,13 @@ enum GADGET_ID_USE_TIME_ORB_BUG, GADGET_ID_USE_LIFE_BUGS, GADGET_ID_RANDOM_BALL_CONTENT, - GADGET_ID_INITIAL_BALL_STATE, + GADGET_ID_INITIAL_BALL_ACTIVE, GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_SB_FIELDS_NEEDED, GADGET_ID_SB_OBJECTS_NEEDED, GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_SOLVED_BY_ONE_PLAYER, + GADGET_ID_FINISH_DIG_COLLECT, GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_BLOCK_LAST_FIELD, @@ -839,6 +841,7 @@ enum enum { ED_SELECTBOX_ID_TIME_OR_STEPS, + ED_SELECTBOX_ID_TIME_SCORE_BASE, ED_SELECTBOX_ID_GAME_ENGINE_TYPE, ED_SELECTBOX_ID_LEVELSET_SAVE_MODE, ED_SELECTBOX_ID_WIND_DIRECTION, @@ -947,12 +950,13 @@ enum ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG, ED_CHECKBUTTON_ID_USE_LIFE_BUGS, ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT, - ED_CHECKBUTTON_ID_INITIAL_BALL_STATE, + ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE, ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE, ED_CHECKBUTTON_ID_SB_FIELDS_NEEDED, ED_CHECKBUTTON_ID_SB_OBJECTS_NEEDED, ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN, ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER, + ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT, ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING, ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD, ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD, @@ -1408,7 +1412,7 @@ static struct GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE, &level.score[SC_TIME_BONUS], - "score for each second/step left:", NULL, NULL + "score for time or steps left:", NULL, NULL }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12), @@ -1731,6 +1735,14 @@ static struct ValueTextInfo options_time_or_steps[] = { -1, NULL } }; +static struct ValueTextInfo options_time_score_base[] = +{ + { 1, "per second/step" }, + { 10, "per 10 seconds/steps" }, + + { -1, NULL } +}; + static struct ValueTextInfo options_game_engine_type[] = { { GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" }, @@ -1965,6 +1977,10 @@ static struct ValueTextInfo options_change_direct_action[] = #endif { CE_VALUE_GETS_ZERO, "CE value gets 0" }, { CE_SCORE_GETS_ZERO, "CE score gets 0" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" }, + { CE_CLICKED_BY_MOUSE, "clicked by mouse" }, + { CE_PRESSED_BY_MOUSE, "pressed by mouse" }, { -1, NULL } }; @@ -1994,6 +2010,10 @@ static struct ValueTextInfo options_change_other_action[] = { CE_SCORE_CHANGES_OF_X, "CE score changes of" }, { CE_VALUE_GETS_ZERO_OF_X, "CE value gets 0 of" }, { CE_SCORE_GETS_ZERO_OF_X, "CE score gets 0 of" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" }, + { CE_MOUSE_CLICKED_ON_X, "mouse clicked on" }, + { CE_MOUSE_PRESSED_ON_X, "mouse pressed on" }, { -1, NULL } }; @@ -2084,10 +2104,11 @@ static struct ValueTextInfo options_action_type[] = { CA_SET_LEVEL_SCORE, "set score" }, { CA_SET_LEVEL_GEMS, "set gems" }, { CA_SET_LEVEL_WIND, "set wind dir." }, - { CA_SET_LEVEL_RANDOM_SEED, "set rand. seed" }, + { CA_SET_LEVEL_RANDOM_SEED, "set random seed" }, { CA_UNDEFINED, " " }, { CA_HEADLINE_PLAYER_ACTIONS, "[player]" }, { CA_MOVE_PLAYER, "move player" }, + { CA_MOVE_PLAYER_NEW, "move player new" }, { CA_EXIT_PLAYER, "exit player" }, { CA_KILL_PLAYER, "kill player" }, { CA_SET_PLAYER_KEYS, "set keys" }, @@ -2413,6 +2434,7 @@ action_arg_options[] = { CA_EXIT_PLAYER, 0, options_action_arg_player, }, { CA_KILL_PLAYER, 0, options_action_arg_player, }, { CA_MOVE_PLAYER, 0, options_action_arg_direction, }, + { CA_MOVE_PLAYER_NEW, 0, options_action_arg_direction, }, { CA_RESTART_LEVEL, 0, options_action_arg_none, }, { CA_SHOW_ENVELOPE, 0, options_action_arg_envelope, }, { CA_SET_LEVEL_TIME, 3, options_action_arg_number, }, @@ -2455,6 +2477,14 @@ static struct &level.use_step_counter, NULL, NULL, "(0 => no limit)", "time or step limit" }, + { + -1, ED_LEVEL_SETTINGS_YPOS(10), + GADGET_ID_TIME_SCORE_BASE, GADGET_ID_LEVEL_TIMESCORE_UP, + -1, + options_time_score_base, + &level.time_score_base, + NULL, NULL, NULL, "time score for 1 or 10 seconds/steps" + }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE, @@ -2665,7 +2695,7 @@ static struct { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), GADGET_ID_ACTION_TYPE, GADGET_ID_NONE, - -1, + 15, options_action_type, &custom_element_change.action_type, NULL, NULL, NULL, "action on specified condition" @@ -3060,8 +3090,8 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_INITIAL_BALL_STATE, GADGET_ID_NONE, - &level.ball_state_initial, + GADGET_ID_INITIAL_BALL_ACTIVE, GADGET_ID_NONE, + &level.ball_active_initial, NULL, NULL, "magic ball initially activated", "activate magic ball after level start" }, @@ -3100,6 +3130,13 @@ static struct NULL, NULL, "only one player must enter exit", "level solved by first player in exit" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_FINISH_DIG_COLLECT, GADGET_ID_NONE, + &level.finish_dig_collect, + NULL, NULL, + "CE action on finished dig/collect", "only finished dig/collect triggers CE" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, @@ -3462,7 +3499,7 @@ static struct int gadget_id_align; int *value; int area_xsize, area_ysize; - char *text_left, *text_right, *text_below, *infotext; + char *text_left, *text_right, *text_above, *text_below, *infotext; } drawingarea_info[ED_NUM_DRAWING_AREAS] = { // ---------- level playfield content --------------------------------------- @@ -3473,7 +3510,7 @@ static struct GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE, NULL, -1, -1, // these values are not constant, but can change at runtime - NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL }, // ---------- yam yam content ----------------------------------------------- @@ -3483,56 +3520,56 @@ static struct ED_AREA_YAMYAM_CONTENT_XOFF(0), ED_AREA_YAMYAM_CONTENT_YOFF(0), GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE, &level.yamyam_content[0].e[0][0], 3, 3, - NULL, NULL, "1", NULL + NULL, NULL, NULL, "1", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(1), ED_AREA_YAMYAM_CONTENT_YOFF(1), GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE, &level.yamyam_content[1].e[0][0], 3, 3, - NULL, NULL, "2", NULL + NULL, NULL, NULL, "2", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(2), ED_AREA_YAMYAM_CONTENT_YOFF(2), GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE, &level.yamyam_content[2].e[0][0], 3, 3, - NULL, NULL, "3", NULL + NULL, NULL, NULL, "3", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(3), ED_AREA_YAMYAM_CONTENT_YOFF(3), GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE, &level.yamyam_content[3].e[0][0], 3, 3, - NULL, NULL, "4", NULL + NULL, NULL, NULL, "4", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(4), ED_AREA_YAMYAM_CONTENT_YOFF(4), GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE, &level.yamyam_content[4].e[0][0], 3, 3, - NULL, NULL, "5", NULL + NULL, NULL, NULL, "5", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(5), ED_AREA_YAMYAM_CONTENT_YOFF(5), GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE, &level.yamyam_content[5].e[0][0], 3, 3, - NULL, NULL, "6", NULL + NULL, NULL, NULL, "6", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(6), ED_AREA_YAMYAM_CONTENT_YOFF(6), GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE, &level.yamyam_content[6].e[0][0], 3, 3, - NULL, NULL, "7", NULL + NULL, NULL, NULL, "7", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, ED_AREA_YAMYAM_CONTENT_XOFF(7), ED_AREA_YAMYAM_CONTENT_YOFF(7), GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE, &level.yamyam_content[7].e[0][0], 3, 3, - NULL, NULL, "8", NULL + NULL, NULL, NULL, "8", NULL }, // ---------- magic ball content -------------------------------------------- @@ -3542,66 +3579,66 @@ static struct ED_AREA_MAGIC_BALL_CONTENT_XOFF(0), ED_AREA_MAGIC_BALL_CONTENT_YOFF(0), GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE, &level.ball_content[0].e[0][0], 3, 3, - NULL, NULL, "1", NULL + NULL, NULL, NULL, "1", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(1), ED_AREA_MAGIC_BALL_CONTENT_YOFF(1), GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE, &level.ball_content[1].e[0][0], 3, 3, - NULL, NULL, "2", NULL + NULL, NULL, NULL, "2", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(2), ED_AREA_MAGIC_BALL_CONTENT_YOFF(2), GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE, &level.ball_content[2].e[0][0], 3, 3, - NULL, NULL, "3", NULL + NULL, NULL, NULL, "3", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(3), ED_AREA_MAGIC_BALL_CONTENT_YOFF(3), GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE, &level.ball_content[3].e[0][0], 3, 3, - NULL, NULL, "4", NULL + NULL, NULL, NULL, "4", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(4), ED_AREA_MAGIC_BALL_CONTENT_YOFF(4), GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE, &level.ball_content[4].e[0][0], 3, 3, - NULL, NULL, "5", NULL + NULL, NULL, NULL, "5", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(5), ED_AREA_MAGIC_BALL_CONTENT_YOFF(5), GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE, &level.ball_content[5].e[0][0], 3, 3, - NULL, NULL, "6", NULL + NULL, NULL, NULL, "6", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(6), ED_AREA_MAGIC_BALL_CONTENT_YOFF(6), GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE, &level.ball_content[6].e[0][0], 3, 3, - NULL, NULL, "7", NULL + NULL, NULL, NULL, "7", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, ED_AREA_MAGIC_BALL_CONTENT_XOFF(7), ED_AREA_MAGIC_BALL_CONTENT_YOFF(7), GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE, &level.ball_content[7].e[0][0], 3, 3, - NULL, NULL, "8", NULL + NULL, NULL, NULL, "8", NULL }, // ---------- android content ----------------------------------------------- { - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_ANDROID_CONTENT, GADGET_ID_NONE, &level.android_clone_element[0], MAX_ANDROID_ELEMENTS, 1, - "elements:", NULL, NULL, "elements android can clone" + NULL, NULL, "elements:", NULL, "elements android can clone" }, // ---------- amoeba content ------------------------------------------------ @@ -3611,7 +3648,7 @@ static struct ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE, &level.amoeba_content, 1, 1, - "content:", NULL, NULL, "amoeba content" + "content:", NULL, NULL, NULL, "amoeba content" }, // ---------- level start element ------------------------------------------- @@ -3621,7 +3658,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, &level.start_element[0], 1, 1, - NULL, NULL, NULL, "level start element" + NULL, NULL, NULL, NULL, "level start element" }, // ---------- player artwork element ---------------------------------------- @@ -3631,7 +3668,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, &level.artwork_element[0], 1, 1, - NULL, NULL, NULL, "element for player artwork" + NULL, NULL, NULL, NULL, "element for player artwork" }, // ---------- player explosion element -------------------------------------- @@ -3641,7 +3678,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, &level.explosion_element[0], 1, 1, - NULL, NULL, NULL, "element for player explosion" + NULL, NULL, NULL, NULL, "element for player explosion" }, // ---------- player initial inventory -------------------------------------- @@ -3651,7 +3688,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_INVENTORY_CONTENT, GADGET_ID_USE_INITIAL_INVENTORY, &level.initial_inventory_content[0][0], MAX_INITIAL_INVENTORY_SIZE, 1, - NULL, NULL, NULL, "content for initial inventory" + NULL, NULL, NULL, NULL, "content for initial inventory" }, // ---------- element settings: configure 1 (custom elements) --------------- @@ -3663,7 +3700,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC, &custom_element.gfx_element_initial,1, 1, - NULL, NULL, NULL, "custom graphic element" + NULL, NULL, NULL, NULL, "custom graphic element" }, // ---------- element settings: configure 2 (custom elements) --------------- @@ -3675,7 +3712,7 @@ static struct 0, ED_AREA_3X3_SETTINGS_YOFF, GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, // align three rows &custom_element.content.e[0][0], 3, 3, - "content:", NULL, NULL, NULL + "content:", NULL, NULL, NULL, NULL }, // ---------- custom enter and leave element (when moving) ------------------ @@ -3685,14 +3722,14 @@ static struct ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_MOVE_ENTER, GADGET_ID_NONE, &custom_element.move_enter_element, 1, 1, - "can dig:", " ", NULL, "element that can be digged/collected" + "can dig:", " ", NULL, NULL, "element that can be digged/collected" }, { -1, ED_AREA_1X1_SETTINGS_YPOS(3), 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_MOVE_LEAVE, GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, &custom_element.move_leave_element, 1, 1, - NULL, NULL, NULL, "element that will be left behind" + NULL, NULL, NULL, NULL, "element that will be left behind" }, // ---------- element settings: advanced (custom elements) ------------------ @@ -3704,7 +3741,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE, &custom_element_change.target_element, 1, 1, - NULL, "after/when:", NULL, "new target element after change" + NULL, "after/when:", NULL, NULL, "new target element after change" }, // ---------- custom change content (extended change target) ---------------- @@ -3714,7 +3751,7 @@ static struct 0, ED_AREA_3X3_SETTINGS_YOFF, GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, // align three rows &custom_element_change.target_content.e[0][0], 3, 3, - NULL, NULL, NULL, "new extended elements after change" + NULL, NULL, NULL, NULL, "new extended elements after change" }, // ---------- custom change trigger (element causing change) ---------------- @@ -3724,7 +3761,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION, &custom_element_change.initial_trigger_element, 1, 1, - NULL, NULL, NULL, "other element triggering change" + NULL, NULL, NULL, NULL, "other element triggering change" }, // ---------- custom change action (element used for action) ---------------- @@ -3734,7 +3771,7 @@ static struct 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_CHANGE_ACTION, GADGET_ID_ACTION_ARG, &custom_element_change.action_element, 1, 1, - NULL, NULL, NULL, "element used as action parameter" + NULL, NULL, NULL, NULL, "element used as action parameter" }, // ---------- group element content ----------------------------------------- @@ -3744,7 +3781,7 @@ static struct ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE, &group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1, - "content:", NULL, NULL, NULL + "content:", NULL, NULL, NULL, NULL }, // ---------- random background (for random painting) ----------------------- @@ -3754,7 +3791,7 @@ static struct 0, ED_AREA_1X1_LSETTINGS_YOFF, GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED, &random_placement_background_element, 1, 1, - NULL, NULL, NULL, "random placement background" + NULL, NULL, NULL, NULL, "random placement background" }, }; @@ -3846,7 +3883,7 @@ static int last_drawing_function = GADGET_ID_SINGLE_ITEMS; static boolean draw_with_brush = FALSE; static int properties_element = 0; -static short FieldBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +static short TileBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static short IntelliDrawBuffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static int undo_buffer_position = 0; @@ -4046,13 +4083,13 @@ static int editor_el_emerald_mine_club[] = EL_EMC_MAGIC_BALL, EL_EMC_MAGIC_BALL_SWITCH, - EL_SPRING, - EL_EMC_SPRING_BUMPER, - EL_EMC_LENSES, EL_EMC_MAGNIFIER, - EL_EMPTY, - EL_EMPTY, + + EL_SPRING_LEFT, + EL_SPRING, + EL_SPRING_RIGHT, + EL_EMC_SPRING_BUMPER, EL_BALLOON, EL_YAMYAM_UP, @@ -5546,8 +5583,8 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements) // find all elements used in current level for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] < NUM_FILE_ELEMENTS) // should always be true - element_found[Feld[x][y]] = TRUE; + if (Tile[x][y] < NUM_FILE_ELEMENTS) // should always be true + element_found[Tile[x][y]] = TRUE; *num_elements = 0; @@ -5739,10 +5776,10 @@ static void ReinitializeElementList(void) int element = (*editor_elements_info[i].element_list)[j]; if (element >= NUM_FILE_ELEMENTS) - Error(ERR_WARN, "editor element %d is runtime element", element); + Warn("editor element %d is runtime element", element); if (strEqual(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT)) - Error(ERR_WARN, "no element description text for element %d", element); + Warn("no element description text for element %d", element); } } @@ -6208,7 +6245,7 @@ static void CreateControlButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6274,7 +6311,7 @@ static void CreateControlButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6327,7 +6364,7 @@ static void CreateControlButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6421,7 +6458,7 @@ static void CreateCounterButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6483,7 +6520,7 @@ static void CreateCounterButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6541,7 +6578,7 @@ static void CreateDrawingAreas(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6614,7 +6651,7 @@ static void CreateTextInputGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6663,7 +6700,7 @@ static void CreateTextAreaGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6742,7 +6779,7 @@ static void CreateSelectboxGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6826,7 +6863,7 @@ static void CreateTextbuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6882,7 +6919,7 @@ static void CreateGraphicbuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6997,7 +7034,7 @@ static void CreateScrollbarGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -7057,7 +7094,7 @@ static void CreateCheckbuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -7122,7 +7159,7 @@ static void CreateRadiobuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -7141,7 +7178,7 @@ void CreateLevelEditorGadgets(void) num_editor_gadgets = NUM_EDITOR_GADGETS; - // printf("::: allocating %d gadgets ...\n", num_editor_gadgets); + // Debug("editor", "allocating %d gadgets ...\n", num_editor_gadgets); level_editor_gadget = checked_calloc(num_editor_gadgets * sizeof(struct GadgetInfo *)); @@ -7179,7 +7216,7 @@ void FreeLevelEditorGadgets(void) { int i; - // printf("::: freeing %d gadgets ...\n", num_editor_gadgets); + // Debug("editor", "freeing %d gadgets ...\n", num_editor_gadgets); for (i = 0; i < num_editor_gadgets; i++) { @@ -7293,8 +7330,10 @@ static void MapDrawingArea(int id) int xoffset_below = getTextWidth(drawingarea_info[id].text_below, font_nr); int x_left = gi->x - xoffset_left; int x_right = gi->x + gi->width + ED_DRAWINGAREA_TEXT_DISTANCE; + int x_above = gi->x - ED_DRAWINGAREA_BORDER_SIZE; int x_below = gi->x + (gi->width - xoffset_below) / 2; int y_side = gi->y + (gi->height - font_height) / 2; + int y_above = gi->y - font_height - ED_DRAWINGAREA_TEXT_DISTANCE; int y_below = gi->y + gi->height + ED_DRAWINGAREA_TEXT_DISTANCE; if (drawingarea_info[id].text_left) @@ -7303,6 +7342,9 @@ static void MapDrawingArea(int id) if (drawingarea_info[id].text_right) DrawText(x_right, y_side, drawingarea_info[id].text_right, font_nr); + if (drawingarea_info[id].text_above) + DrawText(x_above, y_above, drawingarea_info[id].text_above, font_nr); + if (drawingarea_info[id].text_below) DrawText(x_below, y_below, drawingarea_info[id].text_below, font_nr); @@ -7679,7 +7721,7 @@ static boolean LevelChanged(void) for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] != level.field[x][y]) + if (Tile[x][y] != level.field[x][y]) field_changed = TRUE; return (level.changed || field_changed); @@ -7707,7 +7749,7 @@ static boolean PrepareSavingIntoPersonalLevelSet(void) return TRUE; } - if (!Request("This level is read only! " + if (!Request("This level is read-only! " "Save into personal level set?", REQ_ASK)) return FALSE; @@ -7715,6 +7757,17 @@ static boolean PrepareSavingIntoPersonalLevelSet(void) leveldir_current = getTreeInfoFromIdentifier(leveldir_first, getLoginName()); + // this may happen if "setup.internal.create_user_levelset" is FALSE + // or if file "levelinfo.conf" is missing in personal user level set + if (leveldir_current == NULL) + { + Request("Cannot find personal level set?!", REQ_CONFIRM); + + leveldir_current = leveldir_former; + + return FALSE; + } + // find unused level number for (new_level_nr = leveldir_current->first_level; ; new_level_nr++) { @@ -7933,8 +7986,8 @@ static void replace_custom_element_in_playfield(int element_from, 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; + if (Tile[x][y] == element_from) + Tile[x][y] = element_to; } static boolean CopyCustomElement(int element_old, int element_new, @@ -8128,6 +8181,8 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES) ? CE_SCORE_CHANGES : HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO) ? CE_VALUE_GETS_ZERO : HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO) ? CE_SCORE_GETS_ZERO : + HAS_CHANGE_EVENT(element, CE_CLICKED_BY_MOUSE) ? CE_CLICKED_BY_MOUSE : + HAS_CHANGE_EVENT(element, CE_PRESSED_BY_MOUSE) ? CE_PRESSED_BY_MOUSE : custom_element_change.direct_action); // set "change by other element action" selectbox help value @@ -8155,6 +8210,8 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES_OF_X) ? CE_SCORE_CHANGES_OF_X : HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X : HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO_OF_X) ? CE_SCORE_GETS_ZERO_OF_X : + HAS_CHANGE_EVENT(element, CE_MOUSE_CLICKED_ON_X) ? CE_MOUSE_CLICKED_ON_X : + HAS_CHANGE_EVENT(element, CE_MOUSE_PRESSED_ON_X) ? CE_MOUSE_PRESSED_ON_X : custom_element_change.other_action); } @@ -8286,6 +8343,8 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_SCORE_CHANGES] = FALSE; custom_element_change_events[CE_VALUE_GETS_ZERO] = FALSE; custom_element_change_events[CE_SCORE_GETS_ZERO] = FALSE; + custom_element_change_events[CE_CLICKED_BY_MOUSE] = FALSE; + custom_element_change_events[CE_PRESSED_BY_MOUSE] = FALSE; custom_element_change_events[custom_element_change.direct_action] = custom_element_change_events[CE_BY_DIRECT_ACTION]; @@ -8313,6 +8372,8 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_SCORE_CHANGES_OF_X] = FALSE; custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE; custom_element_change_events[CE_SCORE_GETS_ZERO_OF_X] = FALSE; + custom_element_change_events[CE_MOUSE_CLICKED_ON_X] = FALSE; + custom_element_change_events[CE_MOUSE_PRESSED_ON_X] = FALSE; custom_element_change_events[custom_element_change.other_action] = custom_element_change_events[CE_BY_OTHER_ACTION]; @@ -8325,6 +8386,9 @@ static void CopyCustomElementPropertiesToGame(int element) // copy change events also to special level editor variable custom_element = element_info[element]; custom_element_change = *element_info[element].change; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); } static void CopyGroupElementPropertiesToGame(int element) @@ -8338,6 +8402,9 @@ static void CopyGroupElementPropertiesToGame(int element) element_info[element] = custom_element; *element_info[element].group = group_element_info; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); } static void CopyClassicElementPropertiesToGame(int element) @@ -8368,8 +8435,7 @@ static void CheckElementDescriptions(void) for (i = 0; i < NUM_FILE_ELEMENTS; i++) if (getElementDescriptionFilename(i) == NULL && !IS_OBSOLETE(i)) - Error(ERR_WARN, "no element description file for element '%s'", - EL_NAME(i)); + Warn("no element description file for element '%s'", EL_NAME(i)); } #endif @@ -8402,6 +8468,9 @@ static void InitZoomLevelSettings(int zoom_tilesize) ed_tilesize = setup.auto_setup.editor_zoom_tilesize; ed_tilesize_default = DEFAULT_EDITOR_TILESIZE; + // make sure that tile size is always a power of 2 + ed_tilesize = (1 << log_2(ed_tilesize)); + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) { ed_tilesize = DEFAULT_EDITOR_TILESIZE_MM; @@ -8566,8 +8635,8 @@ void DrawLevelEd(void) if (level_editor_test_game) { - CopyPlayfield(level.field, Feld); - CopyPlayfield(FieldBackup, level.field); + CopyPlayfield(level.field, Tile); + CopyPlayfield(TileBackup, level.field); level_editor_test_game = FALSE; } @@ -9512,7 +9581,7 @@ static void DrawPropertiesInfo(void) num_elements_in_level = 0; for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] == properties_element) + if (Tile[x][y] == properties_element) num_elements_in_level++; percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy); @@ -9698,6 +9767,8 @@ static struct { EL_EMC_LENSES, &level.lenses_score, TEXT_COLLECTING }, { EL_EMC_MAGNIFIER, &level.magnify_score, TEXT_COLLECTING }, { EL_SPRING, &level.slurp_score, TEXT_SLURPING }, + { EL_SPRING_LEFT, &level.slurp_score, TEXT_SLURPING }, + { EL_SPRING_RIGHT, &level.slurp_score, TEXT_SLURPING }, { EL_EMC_LENSES, &level.lenses_time, TEXT_DURATION }, { EL_EMC_MAGNIFIER, &level.magnify_time, TEXT_DURATION }, { EL_MM_FUSE_ACTIVE, &level.mm_time_fuse, TEXT_DELAY_OFF }, @@ -9750,7 +9821,7 @@ static void SetAutomaticNumberOfGemsNeeded(void) { for (y = 0; y < lev_fieldy; y++) { - int element = Feld[x][y]; + int element = Tile[x][y]; switch (element) { @@ -9871,7 +9942,7 @@ static void DrawPropertiesConfig(void) DrawMagicBallContentAreas(); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_STATE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE); } else if (properties_element == EL_EMC_ANDROID) DrawAndroidElementArea(properties_element); @@ -9939,6 +10010,7 @@ static void DrawPropertiesConfig(void) // draw checkbutton gadgets MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT); // draw counter gadgets MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE); @@ -9973,7 +10045,9 @@ static void DrawPropertiesConfig(void) if (MAYBE_DONT_COLLIDE_WITH(properties_element)) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH); - if (properties_element == EL_SPRING) + if (properties_element == EL_SPRING || + properties_element == EL_SPRING_LEFT || + properties_element == EL_SPRING_RIGHT) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG); if (properties_element == EL_TIME_ORB_FULL) @@ -10802,7 +10876,7 @@ static void SetElementSimpleExt(int x, int y, int dx, int dy, int element, { int sx = x - level_xpos; int sy = y - level_ypos; - int old_element = Feld[x][y]; + int old_element = Tile[x][y]; int new_element = element; unsigned int new_bitmask = (getDrawModeHiRes() ? (dx + 1) << (dy * 2) : 0x0f); boolean draw_masked = FALSE; @@ -10828,7 +10902,7 @@ static void SetElementSimpleExt(int x, int y, int dx, int dy, int element, IntelliDrawBuffer[x][y] = element; if (change_level) - Feld[x][y] = element; + Tile[x][y] = element; if (IN_ED_FIELD(sx, sy)) { @@ -10876,7 +10950,6 @@ static void SetElementIntelliDraw(int x, int y, int new_element, }; static int last_x = -1; static int last_y = -1; - int old_element = IntelliDrawBuffer[x][y]; if (new_element == EL_UNDEFINED) { @@ -10886,6 +10959,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, return; } + int old_element = IntelliDrawBuffer[x][y]; + if (IS_TUBE(new_element)) { int last_element_new = EL_UNDEFINED; @@ -11653,7 +11728,7 @@ static void ResetIntelliDraw(void) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - IntelliDrawBuffer[x][y] = Feld[x][y]; + IntelliDrawBuffer[x][y] = Tile[x][y]; SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1); } @@ -11696,7 +11771,7 @@ static void SetElementExt(int x, int y, int dx, int dy, int element, boolean change_level, int button) { if (element < 0) - SetElementSimple(x, y, Feld[x][y], change_level); + SetElementSimple(x, y, Tile[x][y], change_level); else if (GetKeyModState() & KMOD_Shift && !IS_MM_WALL_EDITOR(element)) SetElementIntelliDraw(x, y, element, change_level, button); else @@ -11740,7 +11815,7 @@ static int getLevelElementHiRes(int lx2, int ly2) int ly = ly2 / 2; int dx = lx2 % 2; int dy = ly2 % 2; - int element = Feld[lx][ly]; + int element = Tile[lx][ly]; unsigned int bitmask = (dx + 1) << (dy * 2); if (IS_MM_WALL(element)) @@ -11992,27 +12067,28 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, char text[MAX_CB_TEXT_SIZE + 1] = ""; int width = (draw_with_brush ? brush_width : lev_fieldx); int height = (draw_with_brush ? brush_height : lev_fieldy); + char *format = "%s%03d"; + + for (y = 0; y < height; y++) + for (x = 0; x < width; x++) + if ((draw_with_brush ? brush_buffer[x][y] : Tile[x][y]) > 999) + format = "%s%04d"; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { - int element = (draw_with_brush ? brush_buffer[x][y] : Feld[x][y]); - int element_mapped = element; + int element = (draw_with_brush ? brush_buffer[x][y] : Tile[x][y]); char *prefix = (mode == CB_DUMP_BRUSH || mode == CB_BRUSH_TO_CLIPBOARD ? "`" : "¸"); - if (IS_CUSTOM_ELEMENT(element)) - element_mapped = EL_CUSTOM_START; - else if (IS_GROUP_ELEMENT(element)) - element_mapped = EL_GROUP_START; - else if (element >= NUM_FILE_ELEMENTS) - element_mapped = EL_UNKNOWN; + if (element >= NUM_FILE_ELEMENTS) + element = EL_UNKNOWN; // copy brush to level sketch text buffer for the R'n'D forum: - // - large tiles: `xxx (0x60 ASCII) - // - small tiles: ¸xxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8) - snprintf(part, MAX_CB_PART_SIZE + 1, "%s%03d", prefix, element_mapped); + // - large tiles: `xxx or `xxxx (0x60 ASCII) + // - small tiles: ¸xxx or ¸xxxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8) + snprintf(part, MAX_CB_PART_SIZE + 1, format, prefix, element); strcat(text, part); } @@ -12023,7 +12099,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, mode == CB_BRUSH_TO_CLIPBOARD_SMALL) SDL_SetClipboardText(text); else - printf("%s", text); + Print("%s", text); // print brush data to console and log file return; } @@ -12059,11 +12135,13 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, char *clipboard_text = SDL_GetClipboardText(); char *ptr = clipboard_text; + boolean allow_new_row = FALSE; boolean stop = FALSE; while (*ptr && !stop) { boolean prefix_found = FALSE; + boolean start_new_row = FALSE; // level sketch element number prefixes (may be multi-byte characters) char *prefix_list[] = { "`", "¸" }; @@ -12092,19 +12170,10 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, } } - // continue with next character if prefix not found - if (!prefix_found) - { - ptr++; // !!! FIX THIS for real UTF-8 handling !!! - - continue; - } - - // continue with next character if prefix not found - if (strlen(ptr) < 3) - break; - - if (ptr[0] >= '0' && ptr[0] <= '9' && + // check if prefix found and followed by (at least) three digits + if (prefix_found && + strlen(ptr) >= 3 && + ptr[0] >= '0' && ptr[0] <= '9' && ptr[1] >= '0' && ptr[1] <= '9' && ptr[2] >= '0' && ptr[2] <= '9') { @@ -12114,6 +12183,16 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, ptr += 3; + // level sketch element number might consist of four digits + if (ptr[0] >= '0' && ptr[0] <= '9') + { + element = element * 10 + (ptr[0] - '0'); + ptr++; + } + + // remap some (historic, now obsolete) elements + element = getMappedElement(element); + if (element >= NUM_FILE_ELEMENTS) element = EL_UNKNOWN; @@ -12124,14 +12203,28 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, x++; - if (x >= MAX_LEV_FIELDX || *ptr == '\n') - { - x = 0; - y++; + if (x >= MAX_LEV_FIELDX) + start_new_row = TRUE; - if (y >= MAX_LEV_FIELDY) - stop = TRUE; - } + allow_new_row = TRUE; + } + else + { + if ((*ptr == '\n' || *ptr == '\r') && allow_new_row) + start_new_row = TRUE; + + ptr++; // !!! FIX THIS for real UTF-8 handling !!! + } + + if (start_new_row) + { + x = 0; + y++; + + if (y >= MAX_LEV_FIELDY) + stop = TRUE; + + allow_new_row = FALSE; } } @@ -12170,11 +12263,41 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, for (x = 0; x < MAX_LEV_FIELDX; x++) for (y = 0; y < MAX_LEV_FIELDY; y++) - Feld[x][y] = brush_buffer[x][y]; + Tile[x][y] = brush_buffer[x][y]; lev_fieldx = level.fieldx = brush_width; lev_fieldy = level.fieldy = brush_height; + boolean use_em_engine = TRUE; + boolean use_sp_engine = TRUE; + boolean use_mm_engine = TRUE; + + for (x = 0; x < MAX_LEV_FIELDX; x++) + { + for (y = 0; y < MAX_LEV_FIELDY; y++) + { + int element = Tile[x][y]; + + if (!IS_EM_ELEMENT(element) && !ELEM_IS_PLAYER(element)) + use_em_engine = FALSE; + + if (!IS_SP_ELEMENT(element)) + use_sp_engine = FALSE; + + if (!IS_MM_ELEMENT(element) && element != EL_EMPTY) + use_mm_engine = FALSE; + } + } + + level.game_engine_type = (use_em_engine ? GAME_ENGINE_TYPE_EM : + use_sp_engine ? GAME_ENGINE_TYPE_SP : + use_mm_engine ? GAME_ENGINE_TYPE_MM : + GAME_ENGINE_TYPE_RND); + + // update element selection list + ReinitializeElementList(); + ModifyEditorElementList(); + SetBorderElement(); DrawEditModeWindow(); @@ -12207,7 +12330,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, { for (x = 0; x < brush_width; x++) { - brush_buffer[x][y] = Feld[from_lx + x][from_ly + y]; + brush_buffer[x][y] = Tile[from_lx + x][from_ly + y]; if (button != 1) DrawBrushElement(from_x + x, from_y + y, new_element, TRUE); @@ -12336,9 +12459,19 @@ void CopyBrushToClipboard_Small(void) CopyBrushExt(0, 0, 0, 0, 0, CB_BRUSH_TO_CLIPBOARD_SMALL); } +void UndoLevelEditorOperation(void) +{ + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], -1); +} + +void RedoLevelEditorOperation(void) +{ + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); +} + static void FloodFill(int from_x, int from_y, int fill_element) { - FloodFillLevel(from_x, from_y, fill_element, Feld, lev_fieldx, lev_fieldy); + FloodFillLevel(from_x, from_y, fill_element, Tile, lev_fieldx, lev_fieldy); } static void FloodFillWall_MM(int from_sx2, int from_sy2, int fill_element) @@ -12347,20 +12480,20 @@ static void FloodFillWall_MM(int from_sx2, int from_sy2, int fill_element) int from_y = from_sy2 + 2 * level_ypos; int max_fillx = lev_fieldx * 2; int max_filly = lev_fieldy * 2; - short FillFeld[max_fillx][max_filly]; + short Fill[max_fillx][max_filly]; int x, y; for (x = 0; x < max_fillx; x++) for (y = 0; y < max_filly; y++) - FillFeld[x][y] = getLevelElementHiRes(x, y); + Fill[x][y] = getLevelElementHiRes(x, y); FloodFillLevelExt(from_x, from_y, fill_element, max_fillx, max_filly, - FillFeld, max_fillx, max_filly); + Fill, max_fillx, max_filly); for (x = 0; x < max_fillx; x++) for (y = 0; y < max_filly; y++) - if (FillFeld[x][y] == fill_element) - SetLevelElementHiRes(x, y, FillFeld[x][y]); + if (Fill[x][y] == fill_element) + SetLevelElementHiRes(x, y, Fill[x][y]); } // values for DrawLevelText() modes @@ -12424,7 +12557,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) break; case TEXT_SETCURSOR: - DrawEditorElement(last_sx, last_sy, Feld[lx][ly]); + DrawEditorElement(last_sx, last_sy, Tile[lx][ly]); DrawAreaBorder(sx, sy, sx, sy); StartTextInput(SX + sx * ed_tilesize, SY + sy * ed_tilesize, ed_tilesize, ed_tilesize); @@ -12439,8 +12572,8 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) new_element1 <= EL_STEEL_CHAR_END) letter_element = letter_element - EL_CHAR_START + EL_STEEL_CHAR_START; - delete_buffer[sx - start_sx] = Feld[lx][ly]; - Feld[lx][ly] = letter_element; + delete_buffer[sx - start_sx] = Tile[lx][ly]; + Tile[lx][ly] = letter_element; if (sx + 1 < ed_fieldx && lx + 1 < lev_fieldx) DrawLevelText(sx + 1, sy, 0, TEXT_SETCURSOR); @@ -12456,8 +12589,8 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_BACKSPACE: if (sx > start_sx) { - Feld[lx - 1][ly] = delete_buffer[sx - start_sx - 1]; - DrawEditorElement(sx - 1, sy, Feld[lx - 1][ly]); + Tile[lx - 1][ly] = delete_buffer[sx - start_sx - 1]; + DrawEditorElement(sx - 1, sy, Tile[lx - 1][ly]); DrawLevelText(sx - 1, sy, 0, TEXT_SETCURSOR); } break; @@ -12471,7 +12604,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_END: CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - DrawEditorElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Tile[lx][ly]); StopTextInput(); typing = FALSE; break; @@ -12493,7 +12626,7 @@ static void SetTextCursor(int unused_sx, int unused_sy, int sx, int sy, int ly = sy + level_ypos; if (element == -1) - DrawEditorElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Tile[lx][ly]); else DrawAreaBorder(sx, sy, sx, sy); } @@ -12547,7 +12680,7 @@ static void CopyLevelToUndoBuffer(int mode) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - UndoBuffer[undo_buffer_position][x][y] = Feld[x][y]; + UndoBuffer[undo_buffer_position][x][y] = Tile[x][y]; // check if drawing operation forces change of border style CheckLevelBorderElement(TRUE); @@ -12569,8 +12702,8 @@ static void RandomPlacement(int new_element) { free_position[x][y] = (random_placement_background_restricted ? - Feld[x][y] == random_placement_background_element : - Feld[x][y] != new_element); + Tile[x][y] == random_placement_background_element : + Tile[x][y] != new_element); if (free_position[x][y]) num_free_positions++; @@ -12618,17 +12751,54 @@ static void WrapLevel(int dx, int dy) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - FieldBackup[x][y] = Feld[x][y]; + TileBackup[x][y] = Tile[x][y]; for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - Feld[x][y] = - FieldBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy]; + Tile[x][y] = + TileBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy]; DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_ACCUMULATE); } +static void DrawAreaElementHighlight(boolean highlighted) +{ + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + + if (!highlighted) + return; + + int x, y; + + for (x = 0; x < ed_fieldx; x++) + { + for (y = 0; y < ed_fieldy; y++) + { + int lx = x + level_xpos; + int ly = y + level_ypos; + + if (!IN_LEV_FIELD(lx, ly)) + continue; + + if (Tile[lx][ly] != new_element1) + continue; + + int sx = SX + x * ed_tilesize; + int sy = SY + y * ed_tilesize; + int from_sx = sx; + int from_sy = sy; + int to_sx = sx + ed_tilesize - 1; + int to_sy = sy + ed_tilesize - 1; + + DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); + DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); + DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy); + DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy); + } + } +} + static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir) { char *template_filename_old = getLocalLevelTemplateFilename(); @@ -12715,7 +12885,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) } else if (!button_press_event) { - int old_element = (IN_LEV_FIELD(lx, ly) ? Feld[lx][ly] : EL_UNDEFINED); + 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) && isHiresDrawElement(new_element)); @@ -12798,7 +12968,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { for (x = 0; x < lev_fieldx; x++) { - int old_element = Feld[x][y]; + int old_element = Tile[x][y]; if (ELEM_IS_PLAYER(old_element)) { @@ -12957,7 +13127,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) break; case GADGET_ID_FLOOD_FILL: - if (button_press_event && Feld[lx][ly] != new_element) + if (button_press_event && Tile[lx][ly] != new_element) { if (IS_MM_WALL_EDITOR(new_element)) FloodFillWall_MM(sx2, sy2, new_element); @@ -12974,7 +13144,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFTBUTTON); else if (draw_level) - PickDrawingElement(button, Feld[lx][ly]); + PickDrawingElement(button, Tile[lx][ly]); else { int pos = sx * drawingarea_info[type_id].area_ysize + sy; @@ -13218,10 +13388,10 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) boolean new_template = !fileExists(getLocalLevelTemplateFilename()); // backup original "level.field" (needed to track playfield changes) - CopyPlayfield(level.field, FieldBackup); + CopyPlayfield(level.field, TileBackup); // "SaveLevelTemplate()" uses "level.field", so copy editor playfield - CopyPlayfield(Feld, level.field); + CopyPlayfield(Tile, level.field); if (new_template || Request("Save this template and kill the old?", REQ_ASK)) @@ -13231,7 +13401,7 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) Request("Template saved!", REQ_CONFIRM); // restore original "level.field" (needed to track playfield changes) - CopyPlayfield(FieldBackup, level.field); + CopyPlayfield(TileBackup, level.field); } else if (type_id == ED_TEXTBUTTON_ID_SAVE_LEVELSET) { @@ -13240,7 +13410,7 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) if (levelset_save_mode == LEVELSET_SAVE_MODE_UPDATE && leveldir_current->readonly) { - Request("This level set is read only!", REQ_CONFIRM); + Request("This level set is read-only!", REQ_CONFIRM); return; } @@ -13701,7 +13871,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) } else { - ChangeEditModeWindow(last_edit_mode); + ChangeEditModeWindow(ED_MODE_DRAWING); ClickOnGadget(level_editor_gadget[last_level_drawing_function], MB_LEFTBUTTON); @@ -13763,6 +13933,10 @@ static void HandleControlButtons(struct GadgetInfo *gi) button == 2 ? ed_tilesize_default : button == 3 ? ed_tilesize / 2 : ed_tilesize); + // when using touch device, cycle through all zoom tilesizes + if (runtime.uses_touch_device && ed_tilesize > TILESIZE) + ed_tilesize = MICRO_TILESIZE; + // limit zoom level by upper and lower bound ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE); @@ -13797,7 +13971,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_UNDO: - if (button == 1 && GetKeyModState() & (KMOD_Shift|KMOD_Control)) + if (button < 0) // keep button value (even if modifier keys are pressed) + button = -button; + else if (button == 1 && GetKeyModState() & (KMOD_Shift | KMOD_Control)) button = 3; if (button == 1 && undo_buffer_steps == 0) @@ -13842,7 +14018,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - Feld[x][y] = UndoBuffer[undo_buffer_position][x][y]; + Tile[x][y] = UndoBuffer[undo_buffer_position][x][y]; // check if undo operation forces change of border style CheckLevelBorderElement(FALSE); @@ -13860,7 +14036,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) } else { - ChangeEditModeWindow(last_edit_mode); + ChangeEditModeWindow(ED_MODE_DRAWING); } break; @@ -13870,7 +14046,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) for (x = 0; x < MAX_LEV_FIELDX; x++) for (y = 0; y < MAX_LEV_FIELDY; y++) - Feld[x][y] = (button == 1 ? EL_EMPTY : new_element); + Tile[x][y] = (button == 1 ? EL_EMPTY : new_element); CopyLevelToUndoBuffer(GADGET_ID_CLEAR); @@ -13901,7 +14077,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) SetAutomaticNumberOfGemsNeeded(); - CopyPlayfield(Feld, level.field); + CopyPlayfield(Tile, level.field); SaveLevel(level_nr); level.changed = FALSE; @@ -13932,8 +14108,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (LevelChanged()) level.game_version = GAME_VERSION_ACTUAL; - CopyPlayfield(level.field, FieldBackup); - CopyPlayfield(Feld, level.field); + CopyPlayfield(level.field, TileBackup); + CopyPlayfield(Tile, level.field); CopyNativeLevel_RND_to_Native(&level); @@ -14033,13 +14209,13 @@ static void HandleControlButtons(struct GadgetInfo *gi) } #ifdef DEBUG else if (gi->event.type == GD_EVENT_PRESSED) - printf("default: HandleControlButtons: GD_EVENT_PRESSED(%d)\n", id); + Debug("editor", "default: HandleControlButtons: GD_EVENT_PRESSED(%d)", id); else if (gi->event.type == GD_EVENT_RELEASED) - printf("default: HandleControlButtons: GD_EVENT_RELEASED(%d)\n", id); + Debug("editor", "default: HandleControlButtons: GD_EVENT_RELEASED(%d)", id); else if (gi->event.type == GD_EVENT_MOVING) - printf("default: HandleControlButtons: GD_EVENT_MOVING(%d)\n", id); + Debug("editor", "default: HandleControlButtons: GD_EVENT_MOVING(%d)", id); else - printf("default: HandleControlButtons: ? (id == %d)\n", id); + Debug("editor", "default: HandleControlButtons: ? (id == %d)", id); #endif break; } @@ -14048,7 +14224,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) void HandleLevelEditorKeyInput(Key key) { char letter = getCharFromKey(key); - int button = MB_LEFTBUTTON; if (drawing_function == GADGET_ID_TEXT && DrawLevelText(0, 0, 0, TEXT_QUERY_TYPING) == TRUE) @@ -14061,153 +14236,144 @@ void HandleLevelEditorKeyInput(Key key) DrawLevelText(0, 0, 0, TEXT_NEWLINE); else if (key == KSYM_Escape) DrawLevelText(0, 0, 0, TEXT_END); + + return; } - else if (button_status == MB_RELEASED) - { - int id = GADGET_ID_NONE; - int new_element_shift = element_shift; - int step = ED_ELEMENTLIST_BUTTONS_VERT - 1; - int i; - switch (key) - { - case KSYM_Left: - id = GADGET_ID_SCROLL_LEFT; - break; - case KSYM_Right: - id = GADGET_ID_SCROLL_RIGHT; - break; - case KSYM_Up: - id = GADGET_ID_SCROLL_UP; - break; - case KSYM_Down: - id = GADGET_ID_SCROLL_DOWN; - break; + int id = GADGET_ID_NONE; + int new_element_shift = element_shift; + int step = ED_ELEMENTLIST_BUTTONS_VERT - 1; + int button = MB_LEFTBUTTON; + int i; - case KSYM_Page_Up: - case KSYM_Page_Down: - step *= (key == KSYM_Page_Up ? -1 : +1); - element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ; + switch (key) + { + case KSYM_Left: + id = GADGET_ID_SCROLL_LEFT; + break; + case KSYM_Right: + id = GADGET_ID_SCROLL_RIGHT; + break; + case KSYM_Up: + id = GADGET_ID_SCROLL_UP; + break; + case KSYM_Down: + id = GADGET_ID_SCROLL_DOWN; + break; - if (element_shift < 0) - element_shift = 0; - if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) - element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; + case KSYM_Page_Up: + case KSYM_Page_Down: + step *= (key == KSYM_Page_Up ? -1 : +1); + element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ; - ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], - GDI_SCROLLBAR_ITEM_POSITION, - element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); + if (element_shift < 0) + element_shift = 0; + if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) + element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; - ModifyEditorElementList(); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], + GDI_SCROLLBAR_ITEM_POSITION, + element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); - break; + ModifyEditorElementList(); - case KSYM_Home: - case KSYM_End: - element_shift = (key == KSYM_Home ? 0 : - num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS); + break; - ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], - GDI_SCROLLBAR_ITEM_POSITION, - element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); + case KSYM_Home: + case KSYM_End: + element_shift = (key == KSYM_Home ? 0 : + num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS); - ModifyEditorElementList(); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], + GDI_SCROLLBAR_ITEM_POSITION, + element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); - break; + ModifyEditorElementList(); - case KSYM_Insert: - case KSYM_Delete: + break; - // this is needed to prevent interference with running "True X-Mouse" - if (GetKeyModStateFromEvents() & KMOD_Control) - break; + case KSYM_Insert: + case KSYM_Delete: - // check for last or next editor cascade block in element list - for (i = 0; i < num_editor_elements; i++) - { - if ((key == KSYM_Insert && i == element_shift) || - (key == KSYM_Delete && new_element_shift > element_shift)) - break; + // this is needed to prevent interference with running "True X-Mouse" + if (GetKeyModStateFromEvents() & KMOD_Control) + break; - // jump to next cascade block (or to start of element list) - if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i])) - new_element_shift = i; - } + // check for last or next editor cascade block in element list + for (i = 0; i < num_editor_elements; i++) + { + if ((key == KSYM_Insert && i == element_shift) || + (key == KSYM_Delete && new_element_shift > element_shift)) + break; - if (i < num_editor_elements) - element_shift = new_element_shift; + // jump to next cascade block (or to start of element list) + if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i])) + new_element_shift = i; + } - if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) - element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; + if (i < num_editor_elements) + element_shift = new_element_shift; - ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], - GDI_SCROLLBAR_ITEM_POSITION, - element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); + if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) + element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; - ModifyEditorElementList(); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], + GDI_SCROLLBAR_ITEM_POSITION, + element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); - break; + ModifyEditorElementList(); - case KSYM_Escape: - if (edit_mode == ED_MODE_DRAWING) - { - RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE); - } - else if (edit_mode == ED_MODE_INFO) - { - HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]); - } - else if (edit_mode == ED_MODE_PROPERTIES) - { - HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]); - } - else if (edit_mode == ED_MODE_PALETTE) - { - HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]); - } - else // should never happen - { - ChangeEditModeWindow(ED_MODE_DRAWING); - } + break; - break; + case KSYM_Escape: + if (edit_mode == ED_MODE_DRAWING) + RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE); + else if (edit_mode == ED_MODE_INFO) + HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]); + else if (edit_mode == ED_MODE_PROPERTIES) + HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]); + else if (edit_mode == ED_MODE_PALETTE) + HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]); + else // should never happen + ChangeEditModeWindow(ED_MODE_DRAWING); - default: - break; - } + break; - if (id != GADGET_ID_NONE) - ClickOnGadget(level_editor_gadget[id], button); - else if (letter == '1' || letter == '?') - ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button); - else if (letter == '2') - ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button); - else if (letter == '3') - ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button); - else if (letter == '.') - ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button); - else if (letter == 'U') - ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); - else if (letter == '-' || key == KSYM_KP_Subtract) - ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3); - else if (letter == '0' || key == KSYM_KP_0) - ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2); - else if (letter == '+' || key == KSYM_KP_Add || - letter == '=') // ("Shift-=" is "+" on US keyboards) - ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1); - else if (key == KSYM_Return || - key == KSYM_space || - key == setup.shortcut.toggle_pause) - ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button); - else - for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) - if (letter && letter == controlbutton_info[i].shortcut) - if (!anyTextGadgetActive()) - ClickOnGadget(level_editor_gadget[i], button); + default: + break; } + + if (id != GADGET_ID_NONE) + ClickOnGadget(level_editor_gadget[id], button); + else if (letter == '1' || letter == '?') + ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button); + else if (letter == '2') + ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button); + else if (letter == '3') + ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button); + else if (letter == '.') + ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button); + else if (letter == 'U') + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); + else if (letter == '-' || key == KSYM_KP_Subtract) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3); + else if (letter == '0' || key == KSYM_KP_0) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2); + else if (letter == '+' || key == KSYM_KP_Add || + letter == '=') // ("Shift-=" is "+" on US keyboards) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1); + else if (key == KSYM_Return || + key == KSYM_space || + key == setup.shortcut.toggle_pause) + ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button); + else + for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) + if (letter && letter == controlbutton_info[i].shortcut) + if (!anyTextGadgetActive()) + ClickOnGadget(level_editor_gadget[i], button); } -void HandleLevelEditorIdle(void) +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; @@ -14216,9 +14382,6 @@ void HandleLevelEditorIdle(void) unsigned int action_delay_value = GameFrameDelay; int i; - if (edit_mode != ED_MODE_PROPERTIES) - return; - if (!DelayReached(&action_delay, action_delay_value)) return; @@ -14237,6 +14400,29 @@ void HandleLevelEditorIdle(void) FrameCounter++; // increase animation frame counter } +static void HandleLevelEditorIdle_Drawing(void) +{ + static boolean last_highlighted = FALSE; + boolean highlighted = (GetKeyModState() & KMOD_Alt); + + if (highlighted != last_highlighted) + { + DrawAreaElementHighlight(highlighted); + + last_highlighted = highlighted; + + redraw_mask |= REDRAW_FIELD; + } +} + +void HandleLevelEditorIdle(void) +{ + if (edit_mode == ED_MODE_PROPERTIES) + HandleLevelEditorIdle_Properties(); + else if (edit_mode == ED_MODE_DRAWING) + HandleLevelEditorIdle_Drawing(); +} + static void ClearEditorGadgetInfoText(void) { DrawBackground(INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE); @@ -14408,7 +14594,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1); } else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) - strncpy(infotext, getElementInfoText(Feld[lx][ly]), max_infotext_len); + strncpy(infotext, getElementInfoText(Tile[lx][ly]), max_infotext_len); else sprintf(infotext, "Level position: %d, %d", lx, ly); }