X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Feditor.c;h=761ff632485f8ebc44968c35d883ca5cf42e6dc0;hp=68dcf25612655fa089dd52c0aebc40bc72df89b0;hb=f92a51e4612e0720519440bf3aaee117c10a7952;hpb=01732be3e0e75dbeebc5272b96a2d8dac127c4db diff --git a/src/editor.c b/src/editor.c index 68dcf256..761ff632 100644 --- a/src/editor.c +++ b/src/editor.c @@ -627,66 +627,73 @@ /* checkbuttons/radiobuttons for level/element properties */ #define GADGET_ID_CHECKBUTTON_FIRST (GADGET_ID_SCROLLING_LIST_FIRST + 3) -#define GADGET_ID_RANDOM_PERCENTAGE (GADGET_ID_CHECKBUTTON_FIRST + 0) -#define GADGET_ID_RANDOM_QUANTITY (GADGET_ID_CHECKBUTTON_FIRST + 1) -#define GADGET_ID_RANDOM_RESTRICTED (GADGET_ID_CHECKBUTTON_FIRST + 2) -#define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 3) -#define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 4) -#define GADGET_ID_EM_EXPLODES_BY_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 5) -#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 6) -#define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7) -#define GADGET_ID_RANDOM_BALL_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 8) -#define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_AUTO_EXIT_SOKOBAN (GADGET_ID_CHECKBUTTON_FIRST + 11) -#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_SHIFTED_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_LAZY_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 41) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 42) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 43) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CUSTOM_USE_TEMPLATE_1 (GADGET_ID_CHECKBUTTON_FIRST + 45) -#define GADGET_ID_CUSTOM_USE_TEMPLATE_2 (GADGET_ID_CHECKBUTTON_FIRST + 46) -#define GADGET_ID_CUSTOM_USE_TEMPLATE_3 (GADGET_ID_CHECKBUTTON_FIRST + 47) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 48) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 49) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 50) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 51) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 52) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 53) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 54) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 55) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 56) +#define GADGET_ID_AUTO_COUNT_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 0) +#define GADGET_ID_RANDOM_PERCENTAGE (GADGET_ID_CHECKBUTTON_FIRST + 1) +#define GADGET_ID_RANDOM_QUANTITY (GADGET_ID_CHECKBUTTON_FIRST + 2) +#define GADGET_ID_RANDOM_RESTRICTED (GADGET_ID_CHECKBUTTON_FIRST + 3) +#define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 4) +#define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 5) +#define GADGET_ID_EM_EXPLODES_BY_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 6) +#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7) +#define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 8) +#define GADGET_ID_RANDOM_BALL_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 9) +#define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_AUTO_EXIT_SOKOBAN (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_SHIFTED_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_LAZY_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_MM_LASER_RED (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_MM_LASER_GREEN (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_MM_LASER_BLUE (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_DF_LASER_RED (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_DF_LASER_GREEN (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_DF_LASER_BLUE (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 43) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 44) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 47) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 48) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 51) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_1 (GADGET_ID_CHECKBUTTON_FIRST + 52) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_2 (GADGET_ID_CHECKBUTTON_FIRST + 53) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_3 (GADGET_ID_CHECKBUTTON_FIRST + 54) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 55) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 56) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 57) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 58) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 59) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 60) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 61) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 62) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 63) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 57) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 64) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -825,7 +832,7 @@ #define ED_NUM_SELECTBOX 29 #define ED_SELECTBOX_ID_LEVEL_FIRST ED_SELECTBOX_ID_TIME_OR_STEPS -#define ED_SELECTBOX_ID_LEVEL_LAST ED_SELECTBOX_ID_WIND_DIRECTION +#define ED_SELECTBOX_ID_LEVEL_LAST ED_SELECTBOX_ID_GAME_ENGINE_TYPE #define ED_SELECTBOX_ID_CUSTOM1_FIRST ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE #define ED_SELECTBOX_ID_CUSTOM1_LAST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION @@ -873,63 +880,73 @@ #define ED_GRAPHICBUTTON_ID_CHANGE_LAST ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE /* values for checkbutton gadgets */ -#define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 0 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3 1 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 2 -#define ED_CHECKBUTTON_ID_STICK_ELEMENT 3 -#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 4 -#define ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE 5 -#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 6 -#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 7 -#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 8 -#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 9 -#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 10 -#define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 11 -#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 12 -#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 13 -#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 14 -#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 15 -#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 16 -#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 17 -#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 18 -#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 19 -#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 20 -#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 21 -#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 22 -#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 23 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 24 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 25 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 26 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 27 -#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 28 -#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 29 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 30 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 31 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 32 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 33 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 34 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 35 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 36 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 37 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 38 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 39 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 40 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 41 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 42 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 43 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 44 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 45 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 46 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 47 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 48 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 49 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 50 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 51 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 52 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 53 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 54 - -#define ED_NUM_CHECKBUTTONS 55 +#define ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS 0 +#define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 1 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3 2 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 3 +#define ED_CHECKBUTTON_ID_STICK_ELEMENT 4 +#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 5 +#define ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE 6 +#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 7 +#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 8 +#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 9 +#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 10 +#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 11 +#define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 12 +#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 13 +#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 14 +#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 15 +#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 16 +#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 17 +#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 18 +#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 19 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 20 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 21 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 22 +#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 23 +#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 24 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 25 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 26 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 27 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 28 +#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 29 +#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 30 +#define ED_CHECKBUTTON_ID_MM_LASER_RED 31 +#define ED_CHECKBUTTON_ID_MM_LASER_GREEN 32 +#define ED_CHECKBUTTON_ID_MM_LASER_BLUE 33 +#define ED_CHECKBUTTON_ID_DF_LASER_RED 34 +#define ED_CHECKBUTTON_ID_DF_LASER_GREEN 35 +#define ED_CHECKBUTTON_ID_DF_LASER_BLUE 36 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 37 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 38 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 39 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 40 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 41 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 42 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 43 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 44 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 45 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 46 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 47 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 48 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 49 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 50 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 51 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 52 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 53 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 54 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 55 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 56 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 57 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 58 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 59 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 60 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 61 + +#define ED_NUM_CHECKBUTTONS 62 + +#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_EDITOR_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED #define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 @@ -1299,7 +1316,7 @@ static struct NULL, "number of gems to collect:", NULL }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7), + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(8), 0, 9999, GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP, GADGET_ID_LEVEL_TIMELIMIT_TEXT, GADGET_ID_NONE, @@ -1307,7 +1324,7 @@ static struct "time or step limit to solve level:", NULL, NULL }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(9), + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), 0, 999, GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE, @@ -2316,18 +2333,18 @@ static struct int size; /* char size of selectbox or '-1' (dynamically determined) */ struct ValueTextInfo *options; int *value; - char *text_left, *text_right, *infotext; + char *text_above, *text_left, *text_right, *infotext; } selectbox_info[ED_NUM_SELECTBOX] = { /* ---------- level and editor settings ---------------------------------- */ { - -1, ED_LEVEL_SETTINGS_YPOS(7), + -1, ED_LEVEL_SETTINGS_YPOS(8), GADGET_ID_TIME_OR_STEPS, GADGET_ID_LEVEL_TIMELIMIT_UP, -1, options_time_or_steps, &level.use_step_counter, - NULL, "(0 => no limit)", "time or step limit" + NULL, NULL, "(0 => no limit)", "time or step limit" }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), @@ -2335,26 +2352,26 @@ static struct -1, options_game_engine_type, &level.game_engine_type, - "game engine:", NULL, "game engine" + NULL, "game engine:", NULL, "game engine" }, + + /* ---------- element settings: configure (several elements) ------------- */ + { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), GADGET_ID_WIND_DIRECTION, GADGET_ID_NONE, -1, options_wind_direction, &level.wind_direction_initial, - "initial wind direction:", NULL, "initial wind direction" + NULL, "initial wind direction:", NULL, "initial wind direction" }, - - /* ---------- element settings: configure (several elements) ------------- */ - { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, -1, options_player_speed, &level.initial_player_stepsize[0], - "initial player speed:", NULL, "initial player speed" + NULL, "initial player speed:", NULL, "initial player speed" }, /* ---------- element settings: configure 1 (custom elements) ------------ */ @@ -2365,7 +2382,7 @@ static struct -1, options_access_type, &custom_element.access_type, - NULL, NULL, "type of access to this field" + NULL, NULL, NULL, "type of access to this field" }, { -1, ED_ELEMENT_SETTINGS_YPOS(2), @@ -2373,7 +2390,7 @@ static struct -1, options_access_layer, &custom_element.access_layer, - NULL, NULL, "layer of access for this field" + NULL, NULL, NULL, "layer of access for this field" }, { -1, ED_ELEMENT_SETTINGS_YPOS(2), @@ -2381,7 +2398,7 @@ static struct -1, options_access_protected, &custom_element.access_protected, - NULL, NULL, "protected access for this field" + NULL, NULL, NULL, "protected access for this field" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), @@ -2389,7 +2406,7 @@ static struct -1, options_access_direction, &custom_element.access_direction, - "from", NULL, "access direction for this field" + NULL, "from", NULL, "access direction for this field" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), @@ -2397,7 +2414,7 @@ static struct -1, options_walk_to_action, &custom_element.walk_to_action, - NULL, NULL, "diggable/collectible/pushable" + NULL, NULL, NULL, "diggable/collectible/pushable" }, /* ---------- element settings: configure 2 (custom elements) ------------ */ @@ -2408,7 +2425,7 @@ static struct -1, options_move_pattern, &custom_element.move_pattern, - "can move", NULL, "element move pattern" + NULL, "can move", NULL, "element move pattern" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), @@ -2416,7 +2433,7 @@ static struct -1, options_move_direction, &custom_element.move_direction_initial, - "starts moving", NULL, "initial element move direction" + NULL, "starts moving", NULL, "initial element move direction" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), @@ -2424,7 +2441,7 @@ static struct -1, options_move_stepsize, &custom_element.move_stepsize, - "move/fall speed", NULL, "speed of element movement" + NULL, "move/fall speed", NULL, "speed of element movement" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), @@ -2434,8 +2451,8 @@ static struct &custom_element.move_leave_type, // left text with leading spaces to place gadget next to "can dig" gadget // (needed because drawing area gadgets created after selectbox gadgets) - // "can dig: can", ":", "leave behind or change element" - " can", ":", "leave behind or change element" + // NULL, "can dig: can", ":", "leave behind or change element" + NULL, " can", ":", "leave behind or change element" }, { -1, ED_ELEMENT_SETTINGS_YPOS(7), @@ -2443,7 +2460,7 @@ static struct -1, options_smash_targets, &custom_element.smash_targets, - "can smash", NULL, "elements that can be smashed" + NULL, "can smash", NULL, "elements that can be smashed" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), @@ -2451,7 +2468,7 @@ static struct -1, options_slippery_type, &custom_element.slippery_type, - "slippery", NULL, "where other elements fall down" + NULL, "slippery", NULL, "where other elements fall down" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), @@ -2459,7 +2476,7 @@ static struct -1, options_deadliness, &custom_element.deadliness, - "deadly when", NULL, "deadliness of element" + NULL, "deadly when", NULL, "deadliness of element" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10), @@ -2467,7 +2484,7 @@ static struct -1, options_explosion_type, &custom_element.explosion_type, - "can explode", NULL, "explosion type" + NULL, "can explode", NULL, "explosion type" }, /* ---------- element settings: advanced (custom elements) --------------- */ @@ -2478,7 +2495,7 @@ static struct -1, options_time_units, &custom_element_change.delay_frames, - "delay time given in", NULL, "delay time units for change" + NULL, "delay time given in", NULL, "delay time units for change" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(4), @@ -2486,7 +2503,7 @@ static struct -1, options_change_direct_action, &custom_element_change.direct_action, - NULL, NULL, "type of direct action" + NULL, NULL, NULL, "type of direct action" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(5), @@ -2494,7 +2511,7 @@ static struct -1, options_change_other_action, &custom_element_change.other_action, - NULL, "element:", "type of other element action" + NULL, NULL, "element:", "type of other element action" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(6), @@ -2502,7 +2519,7 @@ static struct -1, options_change_trigger_side, &custom_element_change.trigger_side, - "at", "side", "element side triggering change" + NULL, "at", "side", "element side triggering change" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), @@ -2510,7 +2527,7 @@ static struct -1, options_change_trigger_player, &custom_element_change.trigger_player, - "player:", " ", "player that causes change" + NULL, "player:", " ", "player that causes change" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), @@ -2518,7 +2535,7 @@ static struct -1, options_change_trigger_page, &custom_element_change.trigger_page, - "page:", NULL, "change page that causes change" + NULL, "page:", NULL, "change page that causes change" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(10), @@ -2526,7 +2543,7 @@ static struct -1, options_change_replace_when, &custom_element_change.replace_when, - "replace when", NULL, "which elements can be replaced" + NULL, "replace when", NULL, "which elements can be replaced" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), @@ -2534,7 +2551,7 @@ static struct -1, options_action_type, &custom_element_change.action_type, - NULL, NULL, "action on specified condition" + NULL, NULL, NULL, "action on specified condition" }, { -1, ED_ELEMENT_SETTINGS_YPOS(13), @@ -2542,7 +2559,7 @@ static struct -1, options_action_mode_none, &custom_element_change.action_mode, - NULL, NULL, "action operator" + NULL, NULL, NULL, "action operator" }, { -1, ED_ELEMENT_SETTINGS_YPOS(13), @@ -2550,7 +2567,7 @@ static struct -1, options_action_arg_none, &custom_element_change.action_arg, - NULL, NULL, "action parameter" + NULL, NULL, NULL, "action parameter" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14), @@ -2558,7 +2575,7 @@ static struct 3, options_change_page, &custom_element.current_change_page, - NULL, NULL, "element change page" + NULL, NULL, NULL, "element change page" }, /* ---------- element settings: configure (group elements) --------------- */ @@ -2569,7 +2586,7 @@ static struct -1, options_group_choice_mode, &group_element_info.choice_mode, - "choice type:", NULL, "type of group element choice" + NULL, "choice type:", NULL, "type of group element choice" }, }; @@ -2818,6 +2835,13 @@ static struct { /* ---------- level and editor settings ---------------------------------- */ + { + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6), + GADGET_ID_AUTO_COUNT_GEMS, GADGET_ID_NONE, + &level.auto_count_gems, + NULL, NULL, + "automatically count gems needed", "set counter to number of gems" + }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(1), GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE, @@ -3031,6 +3055,48 @@ static struct NULL, " ", "centered", "automatically center envelope text" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_MM_LASER_RED, GADGET_ID_NONE, + &level.mm_laser_red, + "choose color components for laser:", NULL, + "red", "use red color components in laser" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_MM_LASER_GREEN, GADGET_ID_NONE, + &level.mm_laser_green, + NULL, NULL, + "green", "use green color components in laser" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_MM_LASER_BLUE, GADGET_ID_NONE, + &level.mm_laser_blue, + NULL, NULL, + "blue", "use blue color components in laser" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_DF_LASER_RED, GADGET_ID_NONE, + &level.df_laser_red, + "choose color components for laser:", NULL, + "red", "use red color components in laser" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_DF_LASER_GREEN, GADGET_ID_NONE, + &level.df_laser_green, + NULL, NULL, + "green", "use green color components in laser" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_DF_LASER_BLUE, GADGET_ID_NONE, + &level.df_laser_blue, + NULL, NULL, + "blue", "use blue color components in laser" + }, /* ---------- element settings: configure 1 (custom elements) ----------- */ @@ -3576,6 +3642,8 @@ static void DrawPropertiesWindow(); static void DrawPaletteWindow(); static void UpdateCustomElementGraphicGadgets(); static boolean checkPropertiesConfig(int); +static void SetAutomaticNumberOfGemsNeeded(); +static void ClearEditorGadgetInfoText(); static void CopyLevelToUndoBuffer(int); static void HandleDrawingAreas(struct GadgetInfo *); static void HandleCounterButtons(struct GadgetInfo *); @@ -3590,6 +3658,7 @@ static void HandleControlButtons(struct GadgetInfo *); static void HandleDrawingAreaInfo(struct GadgetInfo *); static void PrintEditorGadgetInfoText(struct GadgetInfo *); static boolean AskToCopyAndModifyLevelTemplate(); +static boolean getDrawModeHiRes(); static int num_editor_gadgets = 0; /* dynamically determined */ @@ -5393,6 +5462,7 @@ static void ReinitializeElementList_EnableSections() setup_editor_el_more = FALSE; setup_editor_el_sokoban = FALSE; setup_editor_el_supaplex = FALSE; + setup_editor_el_diamond_caves = FALSE; setup_editor_el_dx_boulderdash = FALSE; setup_editor_el_mirror_magic = FALSE; setup_editor_el_deflektor = FALSE; @@ -5591,7 +5661,7 @@ static void ReinitializeElementList() void PrintEditorElementList() { - boolean *stop = &setup.editor.el_user_defined; + boolean *stop = &setup_editor_el_user_defined; int i, j; for (i = 0; editor_elements_info[i].setup_value != stop; i++) @@ -5721,6 +5791,11 @@ static void DrawEditorElement(int x, int y, int element) DrawSizedElement(x, y, element, ed_tilesize); } +static void DrawEditorElementThruMask(int x, int y, int element) +{ + DrawSizedElementThruMask(x, y, element, ed_tilesize); +} + static void DrawEditorElementOrWall(int x, int y, int scroll_x, int scroll_y) { DrawSizedElementOrWall(x, y, scroll_x, scroll_y, ed_tilesize); @@ -6207,7 +6282,7 @@ static void CreateDrawingAreas() event_mask = GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING | - GD_EVENT_OFF_BORDERS; + GD_EVENT_OFF_BORDERS | GD_EVENT_PIXEL_PRECISE; /* determine horizontal position to the right of specified gadget */ if (drawingarea_info[i].gadget_id_align != GADGET_ID_NONE) @@ -7039,11 +7114,17 @@ static void MapSelectboxGadget(int id) struct GadgetInfo *gi = level_editor_gadget[selectbox_info[id].gadget_id]; int xoffset_left = getTextWidthForGadget(selectbox_info[id].text_left); int xoffset_right = ED_GADGET_TEXT_DISTANCE; + int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE; int yoffset = (gi->height - font_height) / 2; int x_left = gi->x - xoffset_left; int x_right = gi->x + gi->width + xoffset_right; + int y_above = gi->y - yoffset_above; + int x = gi->x; int y = gi->y + yoffset; + if (selectbox_info[id].text_above) + DrawText(x, y_above, selectbox_info[id].text_above, font_nr); + if (selectbox_info[id].text_left) DrawText(x_left, y, selectbox_info[id].text_left, font_nr); @@ -8075,8 +8156,16 @@ static int getMaxEdFieldY(boolean has_scrollbar) return max_ed_fieldy; } -void InitZoomLevelSettings() +void InitZoomLevelSettings(int zoom_tilesize) { + if (zoom_tilesize == -1) + zoom_tilesize = setup.auto_setup.editor_zoom_tilesize; + + // limit zoom tilesize by upper and lower bound + zoom_tilesize = MIN(MAX(MICRO_TILESIZE, zoom_tilesize), TILESIZE); + + ed_tilesize = setup.auto_setup.editor_zoom_tilesize = zoom_tilesize; + MAX_ED_FIELDX = getMaxEdFieldX(FALSE); MAX_ED_FIELDY = getMaxEdFieldY(FALSE); } @@ -8097,7 +8186,7 @@ void DrawLevelEd() ClearField(); - InitZoomLevelSettings(); + InitZoomLevelSettings(-1); OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2 | DOOR_NO_DELAY); @@ -8431,6 +8520,9 @@ static void PickDrawingElement(int button, int element) if (button < 1 || button > 3) return; + if (IS_MM_WALL(element)) + element = map_mm_wall_element(element); + de = drawing_elements[button - 1]; *de.new_element = element; // update global drawing element variable @@ -8576,6 +8668,10 @@ static void DrawLevelInfoLevel() for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++) MapCounterButtons(i); + /* draw checkbutton gadgets */ + for (i = ED_CHECKBUTTON_ID_LEVEL_FIRST; i<= ED_CHECKBUTTON_ID_LEVEL_LAST; i++) + MapCheckbuttonGadget(i); + /* draw selectbox gadgets */ for (i = ED_SELECTBOX_ID_LEVEL_FIRST; i <= ED_SELECTBOX_ID_LEVEL_LAST; i++) MapSelectboxGadget(i); @@ -8618,6 +8714,8 @@ static void DrawLevelInfoWindow() stick_element_properties_window = FALSE; + SetAutomaticNumberOfGemsNeeded(); + UnmapLevelEditorFieldGadgets(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); @@ -9024,6 +9122,10 @@ static void DrawPropertiesInfo() #define TEXT_CRACKING "Score for cracking" #define TEXT_AMOEBA_SPEED "Speed of amoeba growth" #define TEXT_DURATION "Duration when activated" +#define TEXT_DELAY_ON "Delay before activating" +#define TEXT_DELAY_OFF "Delay before deactivating" +#define TEXT_DELAY_EXPLODING "Delay before exploding" +#define TEXT_DELAY_MOVING "Delay before moving" #define TEXT_BALL_DELAY "Element generation delay" #define TEXT_MOVE_SPEED "Speed of android moving" #define TEXT_CLONE_SPEED "Speed of android cloning" @@ -9105,6 +9207,15 @@ static struct { EL_EMC_KEY_7, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_EMC_KEY_8, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_DC_KEY_WHITE, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_MM_KETTLE, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_DF_CELL, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_MM_KEY, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_MM_LIGHTBALL, &level.score[SC_ELEM_BONUS], TEXT_COLLECTING }, + { EL_MM_PACMAN, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING }, { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, @@ -9140,6 +9251,11 @@ static struct { EL_SPRING, &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 }, + { EL_MM_BOMB, &level.mm_time_bomb, TEXT_DELAY_EXPLODING }, + { EL_MM_GRAY_BALL, &level.mm_time_ball, TEXT_DELAY_ON }, + { EL_MM_STEEL_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING }, + { EL_MM_WOODEN_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING }, { -1, NULL, NULL } }; @@ -9151,7 +9267,10 @@ static boolean checkPropertiesConfig(int element) if (IS_GEM(element) || IS_CUSTOM_ELEMENT(element) || IS_GROUP_ELEMENT(element) || + IS_BALLOON_ELEMENT(element) || IS_ENVELOPE(element) || + IS_MM_MCDUFFIN(element) || + IS_DF_LASER(element) || ELEM_IS_PLAYER(element) || HAS_EDITOR_CONTENT(element) || CAN_GROW(element) || @@ -9169,6 +9288,31 @@ static boolean checkPropertiesConfig(int element) return FALSE; } +static void SetAutomaticNumberOfGemsNeeded() +{ + int x, y; + + if (!level.auto_count_gems) + return; + + level.gems_needed = 0; + + for (x = 0; x < lev_fieldx; x++) + { + for (y = 0; y < lev_fieldy; y++) + { + int element = Feld[x][y]; + + if (IS_GEM(element) || + element == EL_MM_KETTLE || + element == EL_DF_CELL) + level.gems_needed++; + } + } + + ModifyEditorCounterValue(ED_COUNTER_ID_LEVEL_GEMSLIMIT, level.gems_needed); +} + static void DrawPropertiesConfig() { boolean draw_footer_line = FALSE; @@ -9337,7 +9481,8 @@ static void DrawPropertiesConfig() 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 : - HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); + IS_BALLOON_ELEMENT(properties_element) || + HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID); } @@ -9364,6 +9509,9 @@ static void DrawPropertiesConfig() properties_element == EL_SOKOBAN_FIELD_FULL) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN); + if (IS_BALLOON_ELEMENT(properties_element)) + MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION); + if (IS_ENVELOPE(properties_element)) { int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE; @@ -9389,6 +9537,20 @@ static void DrawPropertiesConfig() DrawEnvelopeTextArea(envelope_nr); } + if (IS_MM_MCDUFFIN(properties_element)) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_MM_LASER_RED); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_MM_LASER_GREEN); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_MM_LASER_BLUE); + } + + if (IS_DF_LASER(properties_element)) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DF_LASER_RED); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DF_LASER_GREEN); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DF_LASER_BLUE); + } + if (IS_CUSTOM_ELEMENT(properties_element)) { /* draw stickybutton gadget */ @@ -10136,10 +10298,33 @@ static int getClosedChip(int x, int y) return getChipFromOpenDirectionNotEmpty(direction_new, element_old); } -static void SetElementSimple(int x, int y, int element, boolean change_level) +static void SetElementSimpleExt(int x, int y, int dx, int dy, int element, + boolean change_level) { int sx = x - level_xpos; int sy = y - level_ypos; + int old_element = Feld[x][y]; + int new_element = element; + unsigned int new_bitmask = (getDrawModeHiRes() ? (dx + 1) << (dy * 2) : 0x0f); + boolean draw_masked = FALSE; + + if (IS_MM_WALL_EDITOR(element)) + { + element = map_mm_wall_element_editor(element) | new_bitmask; + + if (IS_MM_WALL(old_element)) + element |= MM_WALL_BITS(old_element); + + if (!change_level) + draw_masked = TRUE; + } + else if (IS_MM_WALL(old_element) && element == EL_EMPTY) + { + int element_changed = old_element & ~new_bitmask; + + if (MM_WALL_BITS(element_changed) != 0) + element = element_changed; + } IntelliDrawBuffer[x][y] = element; @@ -10147,7 +10332,19 @@ static void SetElementSimple(int x, int y, int element, boolean change_level) Feld[x][y] = element; if (IN_ED_FIELD(sx, sy)) - DrawEditorElement(sx, sy, element); + { + if (IS_MM_WALL(old_element) && new_element == EL_EMPTY) + DrawSizedWallParts_MM(sx, sy, EL_EMPTY, ed_tilesize, FALSE, new_bitmask); + else if (draw_masked) + DrawEditorElementThruMask(sx, sy, element); + else + DrawEditorElement(sx, sy, element); + } +} + +static void SetElementSimple(int x, int y, int element, boolean change_level) +{ + SetElementSimpleExt(x, y, 0, 0, element, change_level); } static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, @@ -10521,10 +10718,14 @@ static void SetElementIntelliDraw(int x, int y, int new_element, { EL_EM_EXIT_CLOSED, EL_EM_EXIT_OPEN }, { EL_EM_STEEL_EXIT_CLOSED, EL_EM_STEEL_EXIT_OPEN }, { EL_QUICKSAND_FAST_EMPTY, EL_QUICKSAND_FAST_FULL }, + { EL_MM_EXIT_CLOSED, EL_MM_EXIT_OPEN }, + { EL_MM_FUSE, EL_MM_FUSE_ACTIVE }, + { EL_MM_LIGHTBULB, EL_MM_LIGHTBULB_ACTIVE }, + { EL_MM_FUEL_EMPTY, EL_MM_FUEL_FULL }, { -1, -1 }, }; - static int rotatable_elements[][4] = + static int rotatable_elements_4[][4] = { { EL_BUG_UP, @@ -10532,95 +10733,344 @@ static void SetElementIntelliDraw(int x, int y, int new_element, EL_BUG_DOWN, EL_BUG_LEFT }, - { EL_SPACESHIP_UP, EL_SPACESHIP_RIGHT, EL_SPACESHIP_DOWN, EL_SPACESHIP_LEFT }, - { EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_RIGHT, EL_BD_BUTTERFLY_DOWN, EL_BD_BUTTERFLY_LEFT }, - { EL_BD_FIREFLY_UP, EL_BD_FIREFLY_RIGHT, EL_BD_FIREFLY_DOWN, EL_BD_FIREFLY_LEFT }, - { EL_PACMAN_UP, EL_PACMAN_RIGHT, EL_PACMAN_DOWN, EL_PACMAN_LEFT }, - { EL_YAMYAM_UP, EL_YAMYAM_RIGHT, EL_YAMYAM_DOWN, EL_YAMYAM_LEFT }, - { EL_ARROW_UP, EL_ARROW_RIGHT, EL_ARROW_DOWN, EL_ARROW_LEFT }, - { EL_SP_PORT_UP, EL_SP_PORT_RIGHT, EL_SP_PORT_DOWN, EL_SP_PORT_LEFT }, - { EL_SP_GRAVITY_PORT_UP, EL_SP_GRAVITY_PORT_RIGHT, EL_SP_GRAVITY_PORT_DOWN, EL_SP_GRAVITY_PORT_LEFT }, - { EL_SP_GRAVITY_ON_PORT_UP, EL_SP_GRAVITY_ON_PORT_RIGHT, EL_SP_GRAVITY_ON_PORT_DOWN, EL_SP_GRAVITY_ON_PORT_LEFT }, - { EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_DOWN, EL_SP_GRAVITY_OFF_PORT_LEFT }, - { EL_MOLE_UP, EL_MOLE_RIGHT, EL_MOLE_DOWN, EL_MOLE_LEFT }, - { EL_BALLOON_SWITCH_UP, EL_BALLOON_SWITCH_RIGHT, EL_BALLOON_SWITCH_DOWN, EL_BALLOON_SWITCH_LEFT }, + { + EL_MM_MCDUFFIN_UP, + EL_MM_MCDUFFIN_RIGHT, + EL_MM_MCDUFFIN_DOWN, + EL_MM_MCDUFFIN_LEFT + }, + { + EL_MM_MIRROR_FIXED_1, + EL_MM_MIRROR_FIXED_4, + EL_MM_MIRROR_FIXED_3, + EL_MM_MIRROR_FIXED_2 + }, + { + EL_MM_STEEL_GRID_FIXED_1, + EL_MM_STEEL_GRID_FIXED_4, + EL_MM_STEEL_GRID_FIXED_2, + EL_MM_STEEL_GRID_FIXED_3 + }, + { + EL_MM_WOODEN_GRID_FIXED_1, + EL_MM_WOODEN_GRID_FIXED_4, + EL_MM_WOODEN_GRID_FIXED_2, + EL_MM_WOODEN_GRID_FIXED_3 + }, + { + EL_MM_POLARISATOR_CROSS_1, + EL_MM_POLARISATOR_CROSS_4, + EL_MM_POLARISATOR_CROSS_3, + EL_MM_POLARISATOR_CROSS_2 + }, + { + EL_MM_PACMAN_UP, + EL_MM_PACMAN_RIGHT, + EL_MM_PACMAN_DOWN, + EL_MM_PACMAN_LEFT + }, + { + EL_DF_LASER_UP, + EL_DF_LASER_RIGHT, + EL_DF_LASER_DOWN, + EL_DF_LASER_LEFT + }, + { + EL_DF_RECEIVER_UP, + EL_DF_RECEIVER_RIGHT, + EL_DF_RECEIVER_DOWN, + EL_DF_RECEIVER_LEFT + }, { -1, + }, + }; + static int rotatable_elements_8[][8] = + { + { + EL_DF_STEEL_GRID_FIXED_1, + EL_DF_STEEL_GRID_FIXED_8, + EL_DF_STEEL_GRID_FIXED_7, + EL_DF_STEEL_GRID_FIXED_6, + EL_DF_STEEL_GRID_FIXED_5, + EL_DF_STEEL_GRID_FIXED_4, + EL_DF_STEEL_GRID_FIXED_3, + EL_DF_STEEL_GRID_FIXED_2 + }, + { + EL_DF_WOODEN_GRID_FIXED_1, + EL_DF_WOODEN_GRID_FIXED_8, + EL_DF_WOODEN_GRID_FIXED_7, + EL_DF_WOODEN_GRID_FIXED_6, + EL_DF_WOODEN_GRID_FIXED_5, + EL_DF_WOODEN_GRID_FIXED_4, + EL_DF_WOODEN_GRID_FIXED_3, + EL_DF_WOODEN_GRID_FIXED_2 + }, + { + EL_DF_STEEL_GRID_ROTATING_1, + EL_DF_STEEL_GRID_ROTATING_8, + EL_DF_STEEL_GRID_ROTATING_7, + EL_DF_STEEL_GRID_ROTATING_6, + EL_DF_STEEL_GRID_ROTATING_5, + EL_DF_STEEL_GRID_ROTATING_4, + EL_DF_STEEL_GRID_ROTATING_3, + EL_DF_STEEL_GRID_ROTATING_2 + }, + { + EL_DF_WOODEN_GRID_ROTATING_1, + EL_DF_WOODEN_GRID_ROTATING_8, + EL_DF_WOODEN_GRID_ROTATING_7, + EL_DF_WOODEN_GRID_ROTATING_6, + EL_DF_WOODEN_GRID_ROTATING_5, + EL_DF_WOODEN_GRID_ROTATING_4, + EL_DF_WOODEN_GRID_ROTATING_3, + EL_DF_WOODEN_GRID_ROTATING_2 + }, + + { -1, - -1, + }, + }; + static int rotatable_elements_16[][16] = + { + { + EL_MM_MIRROR_1, + EL_MM_MIRROR_16, + EL_MM_MIRROR_15, + EL_MM_MIRROR_14, + EL_MM_MIRROR_13, + EL_MM_MIRROR_12, + EL_MM_MIRROR_11, + EL_MM_MIRROR_10, + EL_MM_MIRROR_9, + EL_MM_MIRROR_8, + EL_MM_MIRROR_7, + EL_MM_MIRROR_6, + EL_MM_MIRROR_5, + EL_MM_MIRROR_4, + EL_MM_MIRROR_3, + EL_MM_MIRROR_2 + }, + { + EL_MM_BEAMER_5, + EL_MM_BEAMER_4, + EL_MM_BEAMER_3, + EL_MM_BEAMER_2, + EL_MM_BEAMER_1, + EL_MM_BEAMER_16, + EL_MM_BEAMER_15, + EL_MM_BEAMER_14, + EL_MM_BEAMER_13, + EL_MM_BEAMER_12, + EL_MM_BEAMER_11, + EL_MM_BEAMER_10, + EL_MM_BEAMER_9, + EL_MM_BEAMER_8, + EL_MM_BEAMER_7, + EL_MM_BEAMER_6 + }, + { + EL_MM_BEAMER_RED_5, + EL_MM_BEAMER_RED_4, + EL_MM_BEAMER_RED_3, + EL_MM_BEAMER_RED_2, + EL_MM_BEAMER_RED_1, + EL_MM_BEAMER_RED_16, + EL_MM_BEAMER_RED_15, + EL_MM_BEAMER_RED_14, + EL_MM_BEAMER_RED_13, + EL_MM_BEAMER_RED_12, + EL_MM_BEAMER_RED_11, + EL_MM_BEAMER_RED_10, + EL_MM_BEAMER_RED_9, + EL_MM_BEAMER_RED_8, + EL_MM_BEAMER_RED_7, + EL_MM_BEAMER_RED_6 + }, + { + EL_MM_BEAMER_YELLOW_5, + EL_MM_BEAMER_YELLOW_4, + EL_MM_BEAMER_YELLOW_3, + EL_MM_BEAMER_YELLOW_2, + EL_MM_BEAMER_YELLOW_1, + EL_MM_BEAMER_YELLOW_16, + EL_MM_BEAMER_YELLOW_15, + EL_MM_BEAMER_YELLOW_14, + EL_MM_BEAMER_YELLOW_13, + EL_MM_BEAMER_YELLOW_12, + EL_MM_BEAMER_YELLOW_11, + EL_MM_BEAMER_YELLOW_10, + EL_MM_BEAMER_YELLOW_9, + EL_MM_BEAMER_YELLOW_8, + EL_MM_BEAMER_YELLOW_7, + EL_MM_BEAMER_YELLOW_6 + }, + { + EL_MM_BEAMER_GREEN_5, + EL_MM_BEAMER_GREEN_4, + EL_MM_BEAMER_GREEN_3, + EL_MM_BEAMER_GREEN_2, + EL_MM_BEAMER_GREEN_1, + EL_MM_BEAMER_GREEN_16, + EL_MM_BEAMER_GREEN_15, + EL_MM_BEAMER_GREEN_14, + EL_MM_BEAMER_GREEN_13, + EL_MM_BEAMER_GREEN_12, + EL_MM_BEAMER_GREEN_11, + EL_MM_BEAMER_GREEN_10, + EL_MM_BEAMER_GREEN_9, + EL_MM_BEAMER_GREEN_8, + EL_MM_BEAMER_GREEN_7, + EL_MM_BEAMER_GREEN_6 + }, + { + EL_MM_BEAMER_BLUE_5, + EL_MM_BEAMER_BLUE_4, + EL_MM_BEAMER_BLUE_3, + EL_MM_BEAMER_BLUE_2, + EL_MM_BEAMER_BLUE_1, + EL_MM_BEAMER_BLUE_16, + EL_MM_BEAMER_BLUE_15, + EL_MM_BEAMER_BLUE_14, + EL_MM_BEAMER_BLUE_13, + EL_MM_BEAMER_BLUE_12, + EL_MM_BEAMER_BLUE_11, + EL_MM_BEAMER_BLUE_10, + EL_MM_BEAMER_BLUE_9, + EL_MM_BEAMER_BLUE_8, + EL_MM_BEAMER_BLUE_7, + EL_MM_BEAMER_BLUE_6 + }, + { + EL_MM_POLARISATOR_1, + EL_MM_POLARISATOR_16, + EL_MM_POLARISATOR_15, + EL_MM_POLARISATOR_14, + EL_MM_POLARISATOR_13, + EL_MM_POLARISATOR_12, + EL_MM_POLARISATOR_11, + EL_MM_POLARISATOR_10, + EL_MM_POLARISATOR_9, + EL_MM_POLARISATOR_8, + EL_MM_POLARISATOR_7, + EL_MM_POLARISATOR_6, + EL_MM_POLARISATOR_5, + EL_MM_POLARISATOR_4, + EL_MM_POLARISATOR_3, + EL_MM_POLARISATOR_2 + }, + { + EL_DF_MIRROR_1, + EL_DF_MIRROR_16, + EL_DF_MIRROR_15, + EL_DF_MIRROR_14, + EL_DF_MIRROR_13, + EL_DF_MIRROR_12, + EL_DF_MIRROR_11, + EL_DF_MIRROR_10, + EL_DF_MIRROR_9, + EL_DF_MIRROR_8, + EL_DF_MIRROR_7, + EL_DF_MIRROR_6, + EL_DF_MIRROR_5, + EL_DF_MIRROR_4, + EL_DF_MIRROR_3, + EL_DF_MIRROR_2 + }, + { + EL_DF_MIRROR_ROTATING_1, + EL_DF_MIRROR_ROTATING_16, + EL_DF_MIRROR_ROTATING_15, + EL_DF_MIRROR_ROTATING_14, + EL_DF_MIRROR_ROTATING_13, + EL_DF_MIRROR_ROTATING_12, + EL_DF_MIRROR_ROTATING_11, + EL_DF_MIRROR_ROTATING_10, + EL_DF_MIRROR_ROTATING_9, + EL_DF_MIRROR_ROTATING_8, + EL_DF_MIRROR_ROTATING_7, + EL_DF_MIRROR_ROTATING_6, + EL_DF_MIRROR_ROTATING_5, + EL_DF_MIRROR_ROTATING_4, + EL_DF_MIRROR_ROTATING_3, + EL_DF_MIRROR_ROTATING_2 + }, + + { -1, }, }; @@ -10635,19 +11085,61 @@ static void SetElementIntelliDraw(int x, int y, int new_element, new_element = (old_element == element1 ? element2 : element1); } - for (i = 0; rotatable_elements[i][0] != -1; i++) + for (i = 0; rotatable_elements_4[i][0] != -1; i++) { for (j = 0; j < 4; j++) { - int element = rotatable_elements[i][j]; + int element = rotatable_elements_4[i][j]; if (old_element == element) - new_element = (button == 1 ? rotatable_elements[i][(j + 3) % 4] : - button == 2 ? rotatable_elements[i][0] : - button == 3 ? rotatable_elements[i][(j + 1) % 4] : + new_element = (button == 1 ? rotatable_elements_4[i][(j + 3) % 4] : + button == 2 ? rotatable_elements_4[i][0] : + button == 3 ? rotatable_elements_4[i][(j + 1) % 4] : old_element); } } + + for (i = 0; rotatable_elements_8[i][0] != -1; i++) + { + for (j = 0; j < 8; j++) + { + int element = rotatable_elements_8[i][j]; + + if (old_element == element) + new_element = (button == 1 ? rotatable_elements_8[i][(j + 7) % 8] : + button == 2 ? rotatable_elements_8[i][0] : + button == 3 ? rotatable_elements_8[i][(j + 1) % 8] : + old_element); + } + } + + for (i = 0; rotatable_elements_16[i][0] != -1; i++) + { + for (j = 0; j < 16; j++) + { + int element = rotatable_elements_16[i][j]; + + if (old_element == element) + new_element = (button == 1 ? rotatable_elements_16[i][(j + 15) % 16] : + button == 2 ? rotatable_elements_16[i][0] : + button == 3 ? rotatable_elements_16[i][(j + 1) % 16] : + old_element); + } + } + + if (old_element != new_element) + { + int max_infotext_len = getMaxInfoTextLength(); + char infotext[MAX_OUTPUT_LINESIZE + 1]; + + strncpy(infotext, getElementInfoText(new_element), max_infotext_len); + infotext[max_infotext_len] = '\0'; + + ClearEditorGadgetInfoText(); + + DrawTextS(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, INFOTEXT_FONT, + infotext); + } } SetElementSimple(x, y, new_element, change_level); @@ -10667,33 +11159,95 @@ static void ResetIntelliDraw() SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1); } -static void SetElementExt(int x, int y, int element, boolean change_level, - int button) +static boolean draw_mode_hires = FALSE; + +static void SetDrawModeHiRes(int element) +{ + draw_mode_hires = + (level.game_engine_type == GAME_ENGINE_TYPE_MM && + (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY)); +} + +static boolean getDrawModeHiRes() +{ + return draw_mode_hires; +} + +static int getLoResScreenPos(int pos) +{ + return (getDrawModeHiRes() ? pos / 2 : pos); +} + +static int getLoResScreenMod(int pos) +{ + return (getDrawModeHiRes() ? pos % 2 : 0); +} + +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); - else if (GetKeyModState() & KMOD_Shift) + else if (GetKeyModState() & KMOD_Shift && !IS_MM_WALL_EDITOR(element)) SetElementIntelliDraw(x, y, element, change_level, button); else - SetElementSimple(x, y, element, change_level); + SetElementSimpleExt(x, y, dx, dy, element, change_level); } static void SetElement(int x, int y, int element) { - SetElementExt(x, y, element, TRUE, -1); + SetElementExt(x, y, 0, 0, element, TRUE, -1); } -static void SetElementButton(int x, int y, int element, int button) +static void SetElementButton(int x, int y, int dx, int dy, int element, + int button) { - SetElementExt(x, y, element, TRUE, button); + SetElementExt(x, y, dx, dy, element, TRUE, button); } -static void DrawLineElement(int sx, int sy, int element, boolean change_level) +static void SetElementHiRes(int sx2, int sy2, int element, boolean change_level) { - int lx = sx + level_xpos; - int ly = sy + level_ypos; + int lx = getLoResScreenPos(sx2) + level_xpos; + int ly = getLoResScreenPos(sy2) + level_ypos; + int dx = getLoResScreenMod(sx2); + int dy = getLoResScreenMod(sy2); + + SetElementExt(lx, ly, dx, dy, element, change_level, -1); +} + +static void SetLevelElementHiRes(int lx2, int ly2, int element) +{ + int lx = lx2 / 2; + int ly = ly2 / 2; + int dx = lx2 % 2; + int dy = ly2 % 2; + + SetElementExt(lx, ly, dx, dy, element, TRUE, -1); +} + +static int getLevelElementHiRes(int lx2, int ly2) +{ + int lx = lx2 / 2; + int ly = ly2 / 2; + int dx = lx2 % 2; + int dy = ly2 % 2; + int element = Feld[lx][ly]; + unsigned int bitmask = (dx + 1) << (dy * 2); - SetElementExt(lx, ly, element, change_level, -1); + if (IS_MM_WALL(element)) + { + if (element & bitmask) + return map_mm_wall_element(element); + else + return EL_EMPTY; + } + + return element; +} + +static void DrawLineElement(int x, int y, int element, boolean change_level) +{ + SetElementHiRes(x, y, element, change_level); } static void DrawLine(int from_x, int from_y, int to_x, int to_y, @@ -10781,32 +11335,36 @@ static void DrawArcExt(int from_x, int from_y, int to_x2, int to_y2, for (x = 0; x <= radius; x++) { - int sx, sy, lx, ly; + int sx, sy, sx2, sy2, lx, ly; y = (int)(sqrt((float)(radius * radius - x * x)) + 0.5); - sx = from_x + x * (from_x < to_x2 ? +1 : -1); - sy = from_y + y * (from_y < to_y2 ? +1 : -1); + sx2 = from_x + x * (from_x < to_x2 ? +1 : -1); + sy2 = from_y + y * (from_y < to_y2 ? +1 : -1); + sx = getLoResScreenPos(sx2); + sy = getLoResScreenPos(sy2); lx = sx + level_xpos; ly = sy + level_ypos; if (IN_ED_FIELD(sx, sy) && IN_LEV_FIELD(lx, ly)) - DrawLineElement(sx, sy, element, change_level); + DrawLineElement(sx2, sy2, element, change_level); } for (y = 0; y <= radius; y++) { - int sx, sy, lx, ly; + int sx, sy, sx2, sy2, lx, ly; x = (int)(sqrt((float)(radius * radius - y * y)) + 0.5); - sx = from_x + x * (from_x < to_x2 ? +1 : -1); - sy = from_y + y * (from_y < to_y2 ? +1 : -1); + sx2 = from_x + x * (from_x < to_x2 ? +1 : -1); + sy2 = from_y + y * (from_y < to_y2 ? +1 : -1); + sx = getLoResScreenPos(sx2); + sy = getLoResScreenPos(sy2); lx = sx + level_xpos; ly = sy + level_ypos; if (IN_ED_FIELD(sx, sy) && IN_LEV_FIELD(lx, ly)) - DrawLineElement(sx, sy, element, change_level); + DrawLineElement(sx2, sy2, element, change_level); } } @@ -10864,11 +11422,17 @@ static void DrawAreaBorder(int from_x, int from_y, int to_x, int to_y) redraw_mask |= REDRAW_FIELD; } +static void DrawAreaBox(int from_x, int from_y, int to_x, int to_y, + int element, boolean change_level) +{ + DrawBox(from_x, from_y, to_x, to_y, element, change_level); +} + static void SelectArea(int from_x, int from_y, int to_x, int to_y, int element, boolean change_level) { if (element == -1 || change_level) - DrawBox(from_x, from_y, to_x, to_y, -1, FALSE); + DrawAreaBox(from_x, from_y, to_x, to_y, -1, FALSE); else DrawAreaBorder(from_x, from_y, to_x, to_y); } @@ -10881,6 +11445,11 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, #define CB_DUMP_BRUSH 4 #define CB_DUMP_BRUSH_SMALL 5 +static void DrawBrushElement(int sx, int sy, int element, boolean change_level) +{ + DrawLineElement(sx, sy, element, change_level); +} + static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, int button, int mode) { @@ -10953,7 +11522,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, brush_buffer[x][y] = Feld[from_lx + x][from_ly + y]; if (button != 1) - DrawLineElement(from_x + x, from_y + y, new_element, TRUE); + DrawBrushElement(from_x + x, from_y + y, new_element, TRUE); } } @@ -11006,7 +11575,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, else if (sy > border_to_y) border_to_y = sy; - DrawLineElement(sx, sy, element, change_level); + DrawBrushElement(sx, sy, element, change_level); } } } @@ -11056,6 +11625,28 @@ static void FloodFill(int from_x, int from_y, int fill_element) FloodFillLevel(from_x, from_y, fill_element, Feld, lev_fieldx, lev_fieldy); } +static void FloodFillWall_MM(int from_sx2, int from_sy2, int fill_element) +{ + int from_x = from_sx2 + 2 * level_xpos; + 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]; + int x, y; + + for (x = 0; x < max_fillx; x++) + for (y = 0; y < max_filly; y++) + FillFeld[x][y] = getLevelElementHiRes(x, y); + + FloodFillLevelExt(from_x, from_y, fill_element, max_fillx, max_filly, + FillFeld, 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]); +} + /* values for DrawLevelText() modes */ #define TEXT_INIT 0 #define TEXT_SETCURSOR 1 @@ -11322,6 +11913,8 @@ void WrapLevel(int dx, int dy) static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; + static int last_sx = -1, last_sy = -1; + static int last_sx2 = -1, last_sy2 = -1; int id = gi->custom_id; int type_id = gi->custom_type_id; boolean button_press_event; @@ -11335,14 +11928,16 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) int min_sx = 0, min_sy = 0; int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1; int item_xsize = gi->drawing.item_xsize, item_ysize = gi->drawing.item_ysize; + int mini_item_xsize = item_xsize / 2, mini_item_ysize = item_ysize / 2; + int sx2 = gi->event.mx / mini_item_xsize; + int sy2 = gi->event.my / mini_item_ysize; + int dx = sx2 % 2; + int dy = sy2 % 2; int lx = 0, ly = 0; int min_lx = 0, min_ly = 0; int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; int x, y; - /* handle info callback for each invocation of action callback */ - gi->callback_info(gi); - button_press_event = (gi->event.type == GD_EVENT_PRESSED); button_release_event = (gi->event.type == GD_EVENT_RELEASED); @@ -11368,6 +11963,39 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) sy = ly - level_ypos; } + /* also correct MM wall-sized (double) drawing area positions accordingly */ + if (sx2 / 2 < sx || sx2 / 2 > sx) + { + dx = (sx2 / 2 < sx ? 0 : 1); + sx2 = sx * 2 + dx; + } + if (sy2 / 2 < sy || sy2 / 2 > sy) + { + dy = (sy2 / 2 < sy ? 0 : 1); + sy2 = sy * 2 + dy; + } + + if (button_release_event) + { + last_sx = -1; + last_sy = -1; + last_sx2 = -1; + last_sy2 = -1; + } + else if (!button_press_event) + { + /* prevent handling events for every pixel position when moving mouse */ + if ((sx == last_sx && sy == last_sy && + !IS_MM_WALL_EDITOR(new_element) && new_element != EL_EMPTY) || + (sx2 == last_sx2 && sy2 == last_sy2)) + return; + } + + last_sx = sx; + last_sy = sy; + last_sx2 = sx2; + last_sy2 = sy2; + if (button_press_event) started_inside_drawing_area = inside_drawing_area; @@ -11380,6 +12008,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!button && !button_release_event) return; + /* handle info callback for each invocation of action callback */ + gi->callback_info(gi); + /* automatically switch to 'single item' drawing mode, if needed */ actual_drawing_function = (draw_level || drawing_function == GADGET_ID_PICK_ELEMENT ? @@ -11398,6 +12029,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) ResetIntelliDraw(); } + SetDrawModeHiRes(-1); /* reset to normal draw mode */ + switch (actual_drawing_function) { case GADGET_ID_SINGLE_ITEMS: @@ -11421,6 +12054,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) } else { + SetDrawModeHiRes(new_element); + if (new_element == EL_PLAYER_1) { /* remove player at old position */ @@ -11430,7 +12065,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) SetElement(x, y, EL_EMPTY); } - SetElementButton(lx, ly, new_element, button); + SetElementButton(lx, ly, dx, dy, new_element, button); } } else if (!button_release_event) @@ -11474,6 +12109,14 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (button) { + SetDrawModeHiRes(new_element); + + if (getDrawModeHiRes()) + { + sx = sx2; + sy = sy2; + } + if (!button_press_event) DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); @@ -11487,6 +12130,14 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) case GADGET_ID_ARC: case GADGET_ID_RECTANGLE: case GADGET_ID_FILLED_BOX: + SetDrawModeHiRes(new_element); + + if (getDrawModeHiRes()) + { + sx = sx2; + sy = sy2; + } + /* FALLTHROUGH */ case GADGET_ID_GRAB_BRUSH: case GADGET_ID_TEXT: { @@ -11537,6 +12188,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) else if (last_sx != sx || last_sy != sy) { draw_func(start_sx, start_sy, last_sx, last_sy, -1, FALSE); + if (IS_MM_WALL_EDITOR(new_element)) /* clear wall background */ + draw_func(start_sx, start_sy, sx, sy, EL_EMPTY, FALSE); draw_func(start_sx, start_sy, sx, sy, new_element, FALSE); last_sx = sx; last_sy = sy; @@ -11547,7 +12200,11 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) case GADGET_ID_FLOOD_FILL: if (button_press_event && Feld[lx][ly] != new_element) { - FloodFill(lx, ly, new_element); + if (IS_MM_WALL_EDITOR(new_element)) + FloodFillWall_MM(sx2, sy2, new_element); + else + FloodFill(lx, ly, new_element); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_IMMEDIATE); } @@ -11573,6 +12230,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) /* do not mark level as modified for certain non-level-changing gadgets */ if ((type_id >= ED_DRAWING_ID_EDITOR_FIRST && type_id <= ED_DRAWING_ID_EDITOR_LAST) || + actual_drawing_function == GADGET_ID_GRAB_BRUSH || actual_drawing_function == GADGET_ID_PICK_ELEMENT) return; @@ -11614,17 +12272,26 @@ static void HandleCounterButtons(struct GadgetInfo *gi) if (counter_id == ED_COUNTER_ID_SELECT_LEVEL) { - LoadLevel(level_nr); - LoadScore(level_nr); + int last_game_engine_type = level.game_engine_type; + + LoadLevel(level_nr); + LoadScore(level_nr); - SaveLevelSetup_SeriesInfo(); + SaveLevelSetup_SeriesInfo(); - TapeErase(); + TapeErase(); - ResetUndoBuffer(); - DrawEditModeWindow(); + ResetUndoBuffer(); + DrawEditModeWindow(); - return; + if (level.game_engine_type != last_game_engine_type) + { + /* update element selection list */ + ReinitializeElementList(); + ModifyEditorElementList(); + } + + return; } switch (counter_id) @@ -11740,8 +12407,6 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) } CopyElementPropertiesToGame(properties_element); - - level.changed = TRUE; } else if (type_id == ED_SELECTBOX_ID_GAME_ENGINE_TYPE) { @@ -11749,6 +12414,12 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) ReinitializeElementList(); ModifyEditorElementList(); } + + /* do not mark level as modified for certain non-level-changing gadgets */ + if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE) + return; + + level.changed = TRUE; } static void HandleTextbuttonGadgets(struct GadgetInfo *gi) @@ -11994,6 +12665,10 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) ResetUndoBuffer(); DrawEditModeWindow(); } + else if (type_id == ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS) + { + SetAutomaticNumberOfGemsNeeded(); + } /* do not mark level as modified for certain non-level-changing gadgets */ if ((type_id >= ED_CHECKBUTTON_ID_EDITOR_FIRST && @@ -12251,11 +12926,19 @@ static void HandleControlButtons(struct GadgetInfo *gi) // limit zoom level by upper and lower bound ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE); - InitZoomLevelSettings(); + InitZoomLevelSettings(ed_tilesize); if (edit_mode == ED_MODE_DRAWING) + { DrawDrawingWindow(); + /* redraw zoom gadget info text */ + PrintEditorGadgetInfoText(level_editor_gadget[id]); + } + + /* save current editor zoom tilesize */ + SaveSetup_AutoSetup(); + break; case GADGET_ID_CUSTOM_COPY_FROM: @@ -12274,6 +12957,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_UNDO: + if (button == 1 && GetKeyModState() & (KMOD_Shift|KMOD_Control)) + button = 3; + if (button == 1 && undo_buffer_steps == 0) { Request("Undo buffer empty!", REQ_CONFIRM); @@ -12342,8 +13028,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (edit_mode != ED_MODE_DRAWING) ChangeEditModeWindow(ED_MODE_DRAWING); - for (x = 0; x < MAX_LEV_FIELDX; x++) - for (y = 0; y < MAX_LEV_FIELDY; y++) + 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); CopyLevelToUndoBuffer(GADGET_ID_CLEAR); @@ -12373,6 +13059,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (leveldir_former->readonly) ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name); + SetAutomaticNumberOfGemsNeeded(); + CopyPlayfield(Feld, level.field); SaveLevel(level_nr); @@ -12709,7 +13397,7 @@ void HandleLevelEditorIdle() FrameCounter++; /* increase animation frame counter */ } -void ClearEditorGadgetInfoText() +static void ClearEditorGadgetInfoText() { DrawBackground(INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE); } @@ -12741,7 +13429,7 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) else if (gi->custom_id == GADGET_ID_UNDO) sprintf(shortcut, " ('%c/Shift-U')", key); else if (gi->custom_id == GADGET_ID_ZOOM) - sprintf(shortcut, " ('%c', '0', '+')", key); + sprintf(shortcut, " ('%c', '0', '-')", key); else sprintf(shortcut, " ('%s%c')", (key >= 'A' && key <= 'Z' ? "Shift-" : ""), key);