X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Feditor.c;h=833dce2ec7996d81f106a9d3522178bb274753bc;hp=33f0d5b45388a07df884ebc7e2f419a05b680eb3;hb=13fc9c40050cdd760fd457a9c83d0611f95fcd1e;hpb=47d2e643b787f50db5ac9d8cceae6abe2b1600a6 diff --git a/src/editor.c b/src/editor.c index 33f0d5b4..833dce2e 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 // ============================================================================ @@ -489,6 +489,12 @@ enum GADGET_ID_MOVE_DELAY_RND_DOWN, GADGET_ID_MOVE_DELAY_RND_TEXT, GADGET_ID_MOVE_DELAY_RND_UP, + GADGET_ID_STEP_DELAY_FIX_DOWN, + GADGET_ID_STEP_DELAY_FIX_TEXT, + GADGET_ID_STEP_DELAY_FIX_UP, + GADGET_ID_STEP_DELAY_RND_DOWN, + GADGET_ID_STEP_DELAY_RND_TEXT, + GADGET_ID_STEP_DELAY_RND_UP, GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_EXPLOSION_DELAY_UP, @@ -559,6 +565,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, @@ -630,6 +637,7 @@ enum // checkbuttons/radiobuttons for level/element properties GADGET_ID_AUTO_COUNT_GEMS, + GADGET_ID_RATE_TIME_OVER_SCORE, GADGET_ID_USE_LEVELSET_ARTWORK, GADGET_ID_COPY_LEVEL_TEMPLATE, GADGET_ID_RANDOM_PERCENTAGE, @@ -642,12 +650,14 @@ 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_KEEP_WALKABLE_CE, GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_BLOCK_LAST_FIELD, @@ -750,6 +760,8 @@ enum ED_COUNTER_ID_DROP_DELAY_RND, ED_COUNTER_ID_MOVE_DELAY_FIX, ED_COUNTER_ID_MOVE_DELAY_RND, + ED_COUNTER_ID_STEP_DELAY_FIX, + ED_COUNTER_ID_STEP_DELAY_RND, ED_COUNTER_ID_EXPLOSION_DELAY, ED_COUNTER_ID_IGNITION_DELAY, ED_COUNTER_ID_GROUP_CONTENT, @@ -839,6 +851,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, @@ -935,6 +948,7 @@ enum enum { ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS, + ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE, ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK, ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE, ED_CHECKBUTTON_ID_RANDOM_RESTRICTED, @@ -947,12 +961,14 @@ 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_KEEP_WALKABLE_CE, ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING, ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD, ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD, @@ -1007,7 +1023,7 @@ enum }; #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS -#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS +#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE #define ED_CHECKBUTTON_ID_LEVELSET_FIRST ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK #define ED_CHECKBUTTON_ID_LEVELSET_LAST ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE @@ -1408,10 +1424,10 @@ 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), + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(13), 0, 9999, GADGET_ID_LEVEL_RANDOM_SEED_DOWN, GADGET_ID_LEVEL_RANDOM_SEED_UP, GADGET_ID_LEVEL_RANDOM_SEED_TEXT, GADGET_ID_NONE, @@ -1604,7 +1620,23 @@ static struct NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6), + 0, 999, + GADGET_ID_STEP_DELAY_FIX_DOWN, GADGET_ID_STEP_DELAY_FIX_UP, + GADGET_ID_STEP_DELAY_FIX_TEXT, GADGET_ID_NONE, + &custom_element.step_delay_fixed, + NULL, "step delay", NULL + }, + { + -1, ED_ELEMENT_SETTINGS_YPOS(6), + 0, 999, + GADGET_ID_STEP_DELAY_RND_DOWN, GADGET_ID_STEP_DELAY_RND_UP, + GADGET_ID_STEP_DELAY_RND_TEXT, GADGET_ID_STEP_DELAY_FIX_UP, + &custom_element.step_delay_random, + NULL, "+random", NULL + }, + { + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), 0, 999, GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP, GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE, @@ -1612,7 +1644,7 @@ static struct NULL, "explosion delay", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14), 0, 999, GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP, GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE, @@ -1731,6 +1763,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 +2005,13 @@ 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" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" }, + { CE_NEXT_TO_PLAYER, "next to player" }, { -1, NULL } }; @@ -1994,6 +2041,14 @@ 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" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" }, + { CE_PLAYER_NEXT_TO_X, "player next to" }, + { CE_NEXT_TO_X, "next to" }, { -1, NULL } }; @@ -2024,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 } @@ -2084,10 +2139,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 +2469,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, }, @@ -2456,7 +2513,15 @@ static struct NULL, NULL, "(0 => no limit)", "time or step limit" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), + -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(12), GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE, -1, options_game_engine_type, @@ -2572,7 +2637,7 @@ static struct NULL, " can", ":", "leave behind or change element" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), + -1, ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_CUSTOM_SMASH_TARGETS, GADGET_ID_CUSTOM_CAN_SMASH, -1, options_smash_targets, @@ -2580,7 +2645,7 @@ static struct NULL, "can smash", NULL, "elements that can be smashed" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_SLIPPERY_TYPE, GADGET_ID_NONE, -1, options_slippery_type, @@ -2588,7 +2653,7 @@ static struct NULL, "slippery", NULL, "where other elements fall down" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10), GADGET_ID_CUSTOM_DEADLINESS, GADGET_ID_NONE, -1, options_deadliness, @@ -2596,7 +2661,7 @@ static struct NULL, "deadly when", NULL, "deadliness of element" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11), GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_NONE, -1, options_explosion_type, @@ -2665,7 +2730,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" @@ -2971,6 +3036,13 @@ static struct NULL, NULL, "automatically count gems needed", "set counter to number of gems" }, + { + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), + GADGET_ID_RATE_TIME_OVER_SCORE, GADGET_ID_NONE, + &level.rate_time_over_score, + NULL, NULL, + "rate time/steps used over score", "sort high scores by playing time/steps" + }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7), GADGET_ID_USE_LEVELSET_ARTWORK, GADGET_ID_NONE, @@ -3060,8 +3132,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 +3172,20 @@ 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(4), + GADGET_ID_KEEP_WALKABLE_CE, GADGET_ID_NONE, + &level.keep_walkable_ce, + NULL, NULL, + "keep walkable CE changed to player", "keep CE changing to player if walkable" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, @@ -3331,56 +3417,56 @@ static struct NULL, "element can move with some pattern" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE, &custom_element_properties[EP_CAN_FALL], NULL, NULL, "can fall", "element can fall down" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), + -1, ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_CUSTOM_CAN_SMASH, GADGET_ID_CUSTOM_CAN_FALL, &custom_element_properties[EP_CAN_SMASH], NULL, " ", NULL, "element can smash other elements" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_SLIPPERY, GADGET_ID_NONE, &custom_element_properties[EP_SLIPPERY], NULL, NULL, NULL, "other elements can fall down from it" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), GADGET_ID_CUSTOM_DEADLY, GADGET_ID_NONE, &custom_element_properties[EP_DEADLY], NULL, NULL, NULL, "element can kill the player" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_NONE, &custom_element_properties[EP_CAN_EXPLODE], NULL, NULL, NULL, "element can explode" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11), + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12), GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE, &custom_element_properties[EP_EXPLODES_BY_FIRE], NULL, NULL, "by fire", "element can explode by fire/explosion" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(11), + -1, ED_ELEMENT_SETTINGS_YPOS(12), GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE, &custom_element_properties[EP_EXPLODES_SMASHED], NULL, " ", "smashed", "element can explode when smashed" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(11), + -1, ED_ELEMENT_SETTINGS_YPOS(12), GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH, &custom_element_properties[EP_EXPLODES_IMPACT], NULL, " ", @@ -3462,7 +3548,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 +3559,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 +3569,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 +3628,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 +3697,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 +3707,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 +3717,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 +3727,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 +3737,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 +3749,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) --------------- @@ -3671,11 +3757,11 @@ static struct // ---------- custom content (when exploding) ------------------------------- { - -1, ED_AREA_3X3_SETTINGS_YPOS(10), + -1, ED_AREA_3X3_SETTINGS_YPOS(11), 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 +3771,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 +3790,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 +3800,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 +3810,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 +3820,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 +3830,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 +3840,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 +3932,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 +4132,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, @@ -5186,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, @@ -5398,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, @@ -5430,6 +5557,14 @@ editor_elements_info[] = } }; +static struct XY xy_directions[] = +{ + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } +}; + // ---------------------------------------------------------------------------- // functions @@ -5483,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; @@ -5524,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; } @@ -5546,8 +5686,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 +5879,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 +6348,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 +6414,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 +6467,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 +6561,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 +6623,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 +6681,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 +6754,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 +6803,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 +6882,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 +6966,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 +7022,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 +7137,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 +7197,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 +7262,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 +7281,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 +7319,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 +7433,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 +7445,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 +7824,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 +7852,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; @@ -7944,8 +8089,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, @@ -8121,7 +8266,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 : @@ -8139,11 +8285,14 @@ 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 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 : @@ -8153,6 +8302,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 : @@ -8166,6 +8316,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); } @@ -8175,9 +8327,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); @@ -8192,6 +8349,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); } @@ -8279,6 +8438,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; @@ -8297,10 +8457,13 @@ 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]; // 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; @@ -8311,6 +8474,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; @@ -8324,6 +8488,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]; @@ -8357,9 +8523,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]); @@ -8374,6 +8555,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); } @@ -8385,8 +8568,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 @@ -8586,8 +8768,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; } @@ -9030,7 +9212,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 @@ -9045,7 +9227,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; @@ -9532,7 +9714,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); @@ -9718,6 +9900,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 }, @@ -9736,11 +9920,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) || @@ -9770,7 +9955,7 @@ static void SetAutomaticNumberOfGemsNeeded(void) { for (y = 0; y < lev_fieldy; y++) { - int element = Feld[x][y]; + int element = Tile[x][y]; switch (element) { @@ -9891,13 +10076,13 @@ 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); } - if (ELEM_IS_PLAYER(properties_element)) + if (IS_PLAYER_ELEMENT(properties_element)) { int player_nr = GET_PLAYER_NR(properties_element); @@ -9959,6 +10144,8 @@ static void DrawPropertiesConfig(void) // draw checkbutton gadgets MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE); // draw counter gadgets MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE); @@ -9975,7 +10162,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)) { @@ -9983,7 +10170,7 @@ static void DrawPropertiesConfig(void) checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].x = ED_ELEMENT_SETTINGS_XPOS(IS_CUSTOM_ELEMENT(properties_element) ? 1 : 0); checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].y = - ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 : + ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 7 : IS_BALLOON_ELEMENT(properties_element) || HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); @@ -9993,7 +10180,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) @@ -10155,6 +10344,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) @@ -10311,12 +10517,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; @@ -10637,13 +10843,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; @@ -10651,8 +10851,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); @@ -10667,13 +10867,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); @@ -10682,8 +10876,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); @@ -10698,13 +10892,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; @@ -10712,8 +10900,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); @@ -10729,13 +10917,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; @@ -10743,8 +10925,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); @@ -10759,13 +10941,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; @@ -10773,8 +10949,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); @@ -10789,13 +10965,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; @@ -10803,8 +10973,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); @@ -10822,7 +10992,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; @@ -10848,7 +11018,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)) { @@ -10887,13 +11057,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; @@ -10919,8 +11083,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])) @@ -10957,8 +11121,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])) @@ -10995,8 +11159,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])) @@ -11038,8 +11202,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])) @@ -11075,8 +11239,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])) @@ -11110,8 +11274,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])) @@ -11171,8 +11335,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)) @@ -11674,7 +11838,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); } @@ -11717,7 +11881,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 @@ -11761,7 +11925,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)) @@ -12017,14 +12181,14 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, for (y = 0; y < height; y++) for (x = 0; x < width; x++) - if ((draw_with_brush ? brush_buffer[x][y] : Feld[x][y]) > 999) + 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 = (draw_with_brush ? brush_buffer[x][y] : Tile[x][y]); char *prefix = (mode == CB_DUMP_BRUSH || mode == CB_BRUSH_TO_CLIPBOARD ? "`" : "¸"); @@ -12045,7 +12209,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; } @@ -12136,6 +12300,9 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, ptr++; } + // remap some (historic, now obsolete) elements + element = getMappedElement(element); + if (element >= NUM_FILE_ELEMENTS) element = EL_UNKNOWN; @@ -12206,11 +12373,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) && !IS_PLAYER_ELEMENT(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(); @@ -12243,7 +12440,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); @@ -12384,7 +12581,7 @@ void RedoLevelEditorOperation(void) 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) @@ -12393,20 +12590,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 @@ -12470,7 +12667,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); @@ -12485,8 +12682,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); @@ -12502,8 +12699,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; @@ -12517,7 +12714,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; @@ -12539,7 +12736,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); } @@ -12593,7 +12790,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); @@ -12615,8 +12812,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++; @@ -12664,17 +12861,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(); @@ -12761,7 +12995,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)); @@ -12837,16 +13071,16 @@ 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++) { 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)) + if (IS_PLAYER_ELEMENT(old_element)) { int replaced_with_element = (old_element == EL_SOKOBAN_FIELD_PLAYER && @@ -13003,7 +13237,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); @@ -13020,7 +13254,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; @@ -13264,10 +13498,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)) @@ -13277,7 +13511,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) { @@ -13286,7 +13520,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; } @@ -13477,9 +13711,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; @@ -13747,7 +13983,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); @@ -13894,7 +14130,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); @@ -13912,7 +14148,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) } else { - ChangeEditModeWindow(last_edit_mode); + ChangeEditModeWindow(ED_MODE_DRAWING); } break; @@ -13922,7 +14158,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); @@ -13953,7 +14189,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) SetAutomaticNumberOfGemsNeeded(); - CopyPlayfield(Feld, level.field); + CopyPlayfield(Tile, level.field); SaveLevel(level_nr); level.changed = FALSE; @@ -13984,8 +14220,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); @@ -14085,13 +14321,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; } @@ -14249,19 +14485,17 @@ void HandleLevelEditorKeyInput(Key key) 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; 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 (edit_mode != ED_MODE_PROPERTIES) - return; + action_delay.value = GameFrameDelay; - if (!DelayReached(&action_delay, action_delay_value)) + if (!DelayReached(&action_delay)) return; for (i = 0; i < ED_NUM_SELECTBOX; i++) @@ -14279,6 +14513,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); @@ -14450,7 +14707,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); }