X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=6a95010a354f054ba20386ed8e4b398cbc6de469;hb=f73fd0cea8ac4e9836ea9a4c12c89be0acef03ba;hp=3030dc091fbf1179425f40ca2edd8f18633804b1;hpb=c5638bbc5bd4a2b412cd86206a69c01252448072;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 3030dc09..6a95010a 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1,15 +1,13 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2006 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* editor.c * -***********************************************************/ +// ============================================================================ +// Rocks'n'Diamonds - McDuffin Strikes Back! +// ---------------------------------------------------------------------------- +// (c) 1995-2014 by Artsoft Entertainment +// Holger Schemel +// info@artsoft.org +// http://www.artsoft.org/ +// ---------------------------------------------------------------------------- +// editor.c +// ============================================================================ #include @@ -33,42 +31,7 @@ ----------------------------------------------------------------------------- */ -/* positions in the level editor */ -#define ED_WIN_MB_LEFT_XPOS 6 -#define ED_WIN_MB_LEFT_YPOS 258 -#define ED_WIN_MB_MIDDLE_XPOS 42 -#define ED_WIN_MB_MIDDLE_YPOS ED_WIN_MB_LEFT_YPOS -#define ED_WIN_MB_RIGHT_XPOS 78 -#define ED_WIN_MB_RIGHT_YPOS ED_WIN_MB_LEFT_YPOS - /* values for the control window */ -#define ED_CTRL_NO_BUTTONS_GFX_XPOS 6 -#define ED_CTRL_NO_BUTTONS_GFX_YPOS 286 -#define ED_CTRL1_BUTTONS_GFX_YPOS 236 -#define ED_CTRL2_BUTTONS_GFX_YPOS 236 -#define ED_CTRL3_BUTTONS_GFX_YPOS 324 -#define ED_CTRL4_BUTTONS_GFX_XPOS 44 -#define ED_CTRL4_BUTTONS_GFX_YPOS 214 -#define ED_CTRL1_BUTTONS_ALT_GFX_YPOS 142 -#define ED_CTRL3_BUTTONS_ALT_GFX_YPOS 302 - -#define ED_CTRL1_BUTTON_XSIZE 22 -#define ED_CTRL1_BUTTON_YSIZE 22 -#define ED_CTRL1_BUTTONS_XPOS 6 -#define ED_CTRL1_BUTTONS_YPOS 6 -#define ED_CTRL2_BUTTON_XSIZE 30 -#define ED_CTRL2_BUTTON_YSIZE 20 -#define ED_CTRL2_BUTTONS_XPOS 5 -#define ED_CTRL2_BUTTONS_YPOS 99 -#define ED_CTRL3_BUTTON_XSIZE 22 -#define ED_CTRL3_BUTTON_YSIZE 22 -#define ED_CTRL3_BUTTONS_XPOS 6 -#define ED_CTRL3_BUTTONS_YPOS 6 -#define ED_CTRL4_BUTTON_XSIZE 22 -#define ED_CTRL4_BUTTON_YSIZE 22 -#define ED_CTRL4_BUTTONS_XPOS 6 -#define ED_CTRL4_BUTTONS_YPOS 6 - #define ED_CTRL1_BUTTONS_HORIZ 4 #define ED_CTRL1_BUTTONS_VERT 4 #define ED_CTRL2_BUTTONS_HORIZ 3 @@ -77,25 +40,26 @@ #define ED_CTRL3_BUTTONS_VERT 1 #define ED_CTRL4_BUTTONS_HORIZ 2 #define ED_CTRL4_BUTTONS_VERT 1 +#define ED_CTRL5_BUTTONS_HORIZ 1 +#define ED_CTRL5_BUTTONS_VERT 1 #define ED_NUM_CTRL1_BUTTONS (ED_CTRL1_BUTTONS_HORIZ * ED_CTRL1_BUTTONS_VERT) #define ED_NUM_CTRL2_BUTTONS (ED_CTRL2_BUTTONS_HORIZ * ED_CTRL2_BUTTONS_VERT) #define ED_NUM_CTRL3_BUTTONS (ED_CTRL3_BUTTONS_HORIZ * ED_CTRL3_BUTTONS_VERT) #define ED_NUM_CTRL4_BUTTONS (ED_CTRL4_BUTTONS_HORIZ * ED_CTRL4_BUTTONS_VERT) +#define ED_NUM_CTRL5_BUTTONS (ED_CTRL5_BUTTONS_HORIZ * ED_CTRL5_BUTTONS_VERT) #define ED_NUM_CTRL1_2_BUTTONS (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS) #define ED_NUM_CTRL1_3_BUTTONS (ED_NUM_CTRL1_2_BUTTONS + ED_NUM_CTRL3_BUTTONS) -#define ED_NUM_CTRL_BUTTONS (ED_NUM_CTRL1_BUTTONS + \ - ED_NUM_CTRL2_BUTTONS + \ - ED_NUM_CTRL3_BUTTONS + \ - ED_NUM_CTRL4_BUTTONS) +#define ED_NUM_CTRL1_4_BUTTONS (ED_NUM_CTRL1_3_BUTTONS + ED_NUM_CTRL4_BUTTONS) +#define ED_NUM_CTRL_BUTTONS (ED_NUM_CTRL1_4_BUTTONS + ED_NUM_CTRL5_BUTTONS) /* values for the element list */ -#define ED_ELEMENTLIST_XPOS 5 -#define ED_ELEMENTLIST_YPOS 30 -#define ED_ELEMENTLIST_XSIZE 20 -#define ED_ELEMENTLIST_YSIZE 20 -#define ED_ELEMENTLIST_BUTTONS_HORIZ 4 -#define ED_ELEMENTLIST_BUTTONS_VERT 11 +#define ED_ELEMENTLIST_XPOS (editor.palette.x) +#define ED_ELEMENTLIST_YPOS (editor.palette.y) +#define ED_ELEMENTLIST_XSIZE (graphic_info[IMG_EDITOR_PALETTE_BUTTON].width) +#define ED_ELEMENTLIST_YSIZE (graphic_info[IMG_EDITOR_PALETTE_BUTTON].height) +#define ED_ELEMENTLIST_BUTTONS_HORIZ (editor.palette.cols) +#define ED_ELEMENTLIST_BUTTONS_VERT (editor.palette.rows) #define ED_NUM_ELEMENTLIST_BUTTONS (ED_ELEMENTLIST_BUTTONS_HORIZ * \ ED_ELEMENTLIST_BUTTONS_VERT) @@ -111,7 +75,7 @@ /* values for the settings windows */ #define ED_LEVEL_SETTINGS_XSTART (3 * MINI_TILEX / 2) -#define ED_LEVEL_SETTINGS_YSTART (5 * MINI_TILEY) +#define ED_LEVEL_SETTINGS_YSTART (7 * MINI_TILEY) #define ED_ELEMENT_SETTINGS_XSTART (3 * MINI_TILEX / 2) #define ED_ELEMENT_SETTINGS_YSTART (10 * MINI_TILEY) @@ -121,6 +85,7 @@ #define ED_SETTINGS_XOFFSET ED_XOFFSET_CHECKBOX #define ED_SETTINGS_YOFFSET (3 * MINI_TILEY / 2) +#define ED_SETTINGS_TAB_XOFFSET 124 #define ED_LEVEL_SETTINGS_XPOS(n) (ED_LEVEL_SETTINGS_XSTART + \ (n) * ED_SETTINGS_XOFFSET) @@ -132,6 +97,16 @@ #define ED_ELEMENT_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YSTART + \ (n) * ED_SETTINGS_YOFFSET) +#define ED_LEVEL_SETTINGS_TABS_XPOS(n) (ED_LEVEL_SETTINGS_XPOS(0) + \ + (n) * ED_SETTINGS_TAB_XOFFSET) +#define ED_LEVEL_SETTINGS_TABS_YPOS(n) (ED_LEVEL_SETTINGS_YSTART - \ + 3 * MINI_TILEY) + +#define ED_ELEMENT_SETTINGS_TABS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(0) + \ + (n) * ED_SETTINGS_TAB_XOFFSET) +#define ED_ELEMENT_SETTINGS_TABS_YPOS(n) (ED_ELEMENT_SETTINGS_YSTART - \ + 2 * MINI_TILEY) + #define ED_SETTINGS1_YPOS MINI_TILEY #define ED_SETTINGS2_XPOS MINI_TILEX #define ED_SETTINGS2_YPOS (ED_SETTINGS1_YPOS + 12 * TILEY - 2) @@ -199,11 +174,13 @@ #define ED_SCROLLBAR2_XPOS 50 #define ED_SCROLLBAR2_YPOS 20 -#define ED_SCROLLBUTTON2_XSIZE 10 -#define ED_SCROLLBUTTON2_YSIZE 10 +#define ED_SCROLLBUTTON2_XSIZE (graphic_info[IMG_EDITOR_PALETTE_SCROLL_UP].width) +#define ED_SCROLLBUTTON2_YSIZE (graphic_info[IMG_EDITOR_PALETTE_SCROLL_UP].height) -#define ED_SCROLL2_UP_XPOS 85 -#define ED_SCROLL2_UP_YPOS 30 +#define ED_SCROLL2_UP_XPOS (ED_ELEMENTLIST_XPOS + \ + ED_ELEMENTLIST_BUTTONS_HORIZ * \ + ED_ELEMENTLIST_XSIZE) +#define ED_SCROLL2_UP_YPOS ED_ELEMENTLIST_YPOS #define ED_SCROLL2_DOWN_XPOS ED_SCROLL2_UP_XPOS #define ED_SCROLL2_DOWN_YPOS (ED_SCROLL2_UP_YPOS + \ ED_ELEMENTLIST_BUTTONS_VERT * \ @@ -240,10 +217,6 @@ #define ED_WIN_COUNT_YPOS ED_BUTTON_COUNT_YPOS #define ED_WIN_COUNT_XSIZE 52 #define ED_WIN_COUNT_YSIZE ED_BUTTON_COUNT_YSIZE -#define ED_WIN_COUNT2_XPOS 27 -#define ED_WIN_COUNT2_YPOS 3 -#define ED_WIN_COUNT2_XSIZE 46 -#define ED_WIN_COUNT2_YSIZE ED_BUTTON_COUNT_YSIZE #define ED_BUTTON_MINUS_XPOS 2 #define ED_BUTTON_MINUS_YPOS ED_BUTTON_COUNT_YPOS @@ -304,7 +277,7 @@ #define GADGET_ID_TEXT (GADGET_ID_TOOLBOX_FIRST + 7) #define GADGET_ID_FLOOD_FILL (GADGET_ID_TOOLBOX_FIRST + 8) #define GADGET_ID_WRAP_LEFT (GADGET_ID_TOOLBOX_FIRST + 9) -#define GADGET_ID_PROPERTIES (GADGET_ID_TOOLBOX_FIRST + 10) +#define GADGET_ID_ZOOM (GADGET_ID_TOOLBOX_FIRST + 10) #define GADGET_ID_WRAP_RIGHT (GADGET_ID_TOOLBOX_FIRST + 11) #define GADGET_ID_RANDOM_PLACEMENT (GADGET_ID_TOOLBOX_FIRST + 12) #define GADGET_ID_GRAB_BRUSH (GADGET_ID_TOOLBOX_FIRST + 13) @@ -324,8 +297,10 @@ #define GADGET_ID_CUSTOM_COPY (GADGET_ID_TOOLBOX_FIRST + 25) #define GADGET_ID_CUSTOM_PASTE (GADGET_ID_TOOLBOX_FIRST + 26) +#define GADGET_ID_PROPERTIES (GADGET_ID_TOOLBOX_FIRST + 27) + /* counter gadget identifiers */ -#define GADGET_ID_COUNTER_FIRST (GADGET_ID_TOOLBOX_FIRST + 27) +#define GADGET_ID_COUNTER_FIRST (GADGET_ID_TOOLBOX_FIRST + 28) #define GADGET_ID_SELECT_LEVEL_DOWN (GADGET_ID_COUNTER_FIRST + 0) #define GADGET_ID_SELECT_LEVEL_TEXT (GADGET_ID_COUNTER_FIRST + 1) @@ -348,84 +323,90 @@ #define GADGET_ID_LEVEL_TIMESCORE_DOWN (GADGET_ID_COUNTER_FIRST + 18) #define GADGET_ID_LEVEL_TIMESCORE_TEXT (GADGET_ID_COUNTER_FIRST + 19) #define GADGET_ID_LEVEL_TIMESCORE_UP (GADGET_ID_COUNTER_FIRST + 20) -#define GADGET_ID_ELEMENT_VALUE1_DOWN (GADGET_ID_COUNTER_FIRST + 21) -#define GADGET_ID_ELEMENT_VALUE1_TEXT (GADGET_ID_COUNTER_FIRST + 22) -#define GADGET_ID_ELEMENT_VALUE1_UP (GADGET_ID_COUNTER_FIRST + 23) -#define GADGET_ID_ELEMENT_VALUE2_DOWN (GADGET_ID_COUNTER_FIRST + 24) -#define GADGET_ID_ELEMENT_VALUE2_TEXT (GADGET_ID_COUNTER_FIRST + 25) -#define GADGET_ID_ELEMENT_VALUE2_UP (GADGET_ID_COUNTER_FIRST + 26) -#define GADGET_ID_ELEMENT_VALUE3_DOWN (GADGET_ID_COUNTER_FIRST + 27) -#define GADGET_ID_ELEMENT_VALUE3_TEXT (GADGET_ID_COUNTER_FIRST + 28) -#define GADGET_ID_ELEMENT_VALUE3_UP (GADGET_ID_COUNTER_FIRST + 29) -#define GADGET_ID_ELEMENT_VALUE4_DOWN (GADGET_ID_COUNTER_FIRST + 30) -#define GADGET_ID_ELEMENT_VALUE4_TEXT (GADGET_ID_COUNTER_FIRST + 31) -#define GADGET_ID_ELEMENT_VALUE4_UP (GADGET_ID_COUNTER_FIRST + 32) -#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 33) -#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 34) -#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 35) -#define GADGET_ID_BALL_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 36) -#define GADGET_ID_BALL_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 37) -#define GADGET_ID_BALL_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 38) -#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 39) -#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 40) -#define GADGET_ID_ANDROID_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 41) -#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 42) -#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 43) -#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 44) -#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 45) -#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 46) -#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 47) -#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 48) -#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 49) -#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 50) -#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 51) -#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 52) -#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 53) -#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 54) -#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 55) -#define GADGET_ID_CUSTOM_VALUE_FIX_UP (GADGET_ID_COUNTER_FIRST + 56) -#define GADGET_ID_CUSTOM_VALUE_RND_DOWN (GADGET_ID_COUNTER_FIRST + 57) -#define GADGET_ID_CUSTOM_VALUE_RND_TEXT (GADGET_ID_COUNTER_FIRST + 58) -#define GADGET_ID_CUSTOM_VALUE_RND_UP (GADGET_ID_COUNTER_FIRST + 59) -#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 60) -#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 61) -#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 62) -#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 63) -#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 64) -#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 65) -#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66) -#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67) -#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68) -#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69) -#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70) -#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71) -#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 72) -#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 73) -#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 74) -#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 75) -#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 76) -#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 77) -#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 78) -#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 79) -#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 80) -#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 81) -#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 82) -#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 83) -#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 84) -#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 85) -#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 86) -#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 87) -#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 88) -#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 89) -#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 90) -#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 91) -#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 92) -#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 93) -#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 94) -#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 95) +#define GADGET_ID_LEVEL_RANDOM_SEED_DOWN (GADGET_ID_COUNTER_FIRST + 21) +#define GADGET_ID_LEVEL_RANDOM_SEED_TEXT (GADGET_ID_COUNTER_FIRST + 22) +#define GADGET_ID_LEVEL_RANDOM_SEED_UP (GADGET_ID_COUNTER_FIRST + 23) +#define GADGET_ID_ELEMENT_VALUE1_DOWN (GADGET_ID_COUNTER_FIRST + 24) +#define GADGET_ID_ELEMENT_VALUE1_TEXT (GADGET_ID_COUNTER_FIRST + 25) +#define GADGET_ID_ELEMENT_VALUE1_UP (GADGET_ID_COUNTER_FIRST + 26) +#define GADGET_ID_ELEMENT_VALUE2_DOWN (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_ELEMENT_VALUE2_TEXT (GADGET_ID_COUNTER_FIRST + 28) +#define GADGET_ID_ELEMENT_VALUE2_UP (GADGET_ID_COUNTER_FIRST + 29) +#define GADGET_ID_ELEMENT_VALUE3_DOWN (GADGET_ID_COUNTER_FIRST + 30) +#define GADGET_ID_ELEMENT_VALUE3_TEXT (GADGET_ID_COUNTER_FIRST + 31) +#define GADGET_ID_ELEMENT_VALUE3_UP (GADGET_ID_COUNTER_FIRST + 32) +#define GADGET_ID_ELEMENT_VALUE4_DOWN (GADGET_ID_COUNTER_FIRST + 33) +#define GADGET_ID_ELEMENT_VALUE4_TEXT (GADGET_ID_COUNTER_FIRST + 34) +#define GADGET_ID_ELEMENT_VALUE4_UP (GADGET_ID_COUNTER_FIRST + 35) +#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 36) +#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 37) +#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 38) +#define GADGET_ID_BALL_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 39) +#define GADGET_ID_BALL_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 40) +#define GADGET_ID_BALL_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 41) +#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 42) +#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 43) +#define GADGET_ID_ANDROID_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 44) +#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 45) +#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 46) +#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 47) +#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 48) +#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 49) +#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 50) +#define GADGET_ID_INVENTORY_SIZE_DOWN (GADGET_ID_COUNTER_FIRST + 51) +#define GADGET_ID_INVENTORY_SIZE_TEXT (GADGET_ID_COUNTER_FIRST + 52) +#define GADGET_ID_INVENTORY_SIZE_UP (GADGET_ID_COUNTER_FIRST + 53) +#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 54) +#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 55) +#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 56) +#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 57) +#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 58) +#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 59) +#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 60) +#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 61) +#define GADGET_ID_CUSTOM_VALUE_FIX_UP (GADGET_ID_COUNTER_FIRST + 62) +#define GADGET_ID_CUSTOM_VALUE_RND_DOWN (GADGET_ID_COUNTER_FIRST + 63) +#define GADGET_ID_CUSTOM_VALUE_RND_TEXT (GADGET_ID_COUNTER_FIRST + 64) +#define GADGET_ID_CUSTOM_VALUE_RND_UP (GADGET_ID_COUNTER_FIRST + 65) +#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66) +#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67) +#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68) +#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69) +#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70) +#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71) +#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 72) +#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 73) +#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 74) +#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 75) +#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 76) +#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 77) +#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 78) +#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 79) +#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 80) +#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 81) +#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 82) +#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 83) +#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 84) +#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 85) +#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 86) +#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 87) +#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 88) +#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 89) +#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 90) +#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 91) +#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 92) +#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 93) +#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 94) +#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 95) +#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 96) +#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 97) +#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 98) +#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 99) +#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 100) +#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 101) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 96) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 102) #define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0) #define GADGET_ID_YAMYAM_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) @@ -449,18 +430,20 @@ #define GADGET_ID_START_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 19) #define GADGET_ID_ARTWORK_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 20) #define GADGET_ID_EXPLOSION_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 21) -#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 22) -#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 23) -#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 24) -#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 25) -#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 26) -#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 27) -#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 28) -#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 29) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 30) +#define GADGET_ID_INVENTORY_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 22) +#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 23) +#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 24) +#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 25) +#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 26) +#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 27) +#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 28) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 29) +#define GADGET_ID_CUSTOM_CHANGE_ACTION (GADGET_ID_DRAWING_AREA_FIRST + 30) +#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 31) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 32) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 31) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 33) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -507,17 +490,19 @@ /* textbutton identifiers */ #define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 29) -#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0) -#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1) -#define GADGET_ID_PROPERTIES_CONFIG_1 (GADGET_ID_TEXTBUTTON_FIRST + 2) -#define GADGET_ID_PROPERTIES_CONFIG_2 (GADGET_ID_TEXTBUTTON_FIRST + 3) -#define GADGET_ID_PROPERTIES_CHANGE (GADGET_ID_TEXTBUTTON_FIRST + 4) -#define GADGET_ID_SAVE_AS_TEMPLATE (GADGET_ID_TEXTBUTTON_FIRST + 5) -#define GADGET_ID_ADD_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 6) -#define GADGET_ID_DEL_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 7) +#define GADGET_ID_LEVELINFO_LEVEL (GADGET_ID_TEXTBUTTON_FIRST + 0) +#define GADGET_ID_LEVELINFO_EDITOR (GADGET_ID_TEXTBUTTON_FIRST + 1) +#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 2) +#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 3) +#define GADGET_ID_PROPERTIES_CONFIG_1 (GADGET_ID_TEXTBUTTON_FIRST + 4) +#define GADGET_ID_PROPERTIES_CONFIG_2 (GADGET_ID_TEXTBUTTON_FIRST + 5) +#define GADGET_ID_PROPERTIES_CHANGE (GADGET_ID_TEXTBUTTON_FIRST + 6) +#define GADGET_ID_SAVE_AS_TEMPLATE (GADGET_ID_TEXTBUTTON_FIRST + 7) +#define GADGET_ID_ADD_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 8) +#define GADGET_ID_DEL_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 9) /* graphicbutton identifiers */ -#define GADGET_ID_GRAPHICBUTTON_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 8) +#define GADGET_ID_GRAPHICBUTTON_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 10) #define GADGET_ID_PREV_CHANGE_PAGE (GADGET_ID_GRAPHICBUTTON_FIRST + 0) #define GADGET_ID_NEXT_CHANGE_PAGE (GADGET_ID_GRAPHICBUTTON_FIRST + 1) @@ -549,54 +534,58 @@ #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_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 5) -#define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 6) -#define GADGET_ID_RANDOM_BALL_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 7) -#define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 8) -#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 11) -#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 41) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 42) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 43) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 45) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 46) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 47) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 48) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 49) +#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_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 43) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 44) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 47) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 48) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 51) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 52) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 53) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 54) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -614,37 +603,41 @@ #define ED_COUNTER_ID_LEVEL_GEMSLIMIT 3 #define ED_COUNTER_ID_LEVEL_TIMELIMIT 4 #define ED_COUNTER_ID_LEVEL_TIMESCORE 5 -#define ED_COUNTER_ID_LEVEL_RANDOM 6 -#define ED_COUNTER_ID_ELEMENT_VALUE1 7 -#define ED_COUNTER_ID_ELEMENT_VALUE2 8 -#define ED_COUNTER_ID_ELEMENT_VALUE3 9 -#define ED_COUNTER_ID_ELEMENT_VALUE4 10 -#define ED_COUNTER_ID_YAMYAM_CONTENT 11 -#define ED_COUNTER_ID_BALL_CONTENT 12 -#define ED_COUNTER_ID_ANDROID_CONTENT 13 -#define ED_COUNTER_ID_ENVELOPE_XSIZE 14 -#define ED_COUNTER_ID_ENVELOPE_YSIZE 15 -#define ED_COUNTER_ID_CUSTOM_SCORE 16 -#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 17 -#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 18 -#define ED_COUNTER_ID_CUSTOM_VALUE_RND 19 -#define ED_COUNTER_ID_PUSH_DELAY_FIX 20 -#define ED_COUNTER_ID_PUSH_DELAY_RND 21 -#define ED_COUNTER_ID_DROP_DELAY_FIX 22 -#define ED_COUNTER_ID_DROP_DELAY_RND 23 -#define ED_COUNTER_ID_MOVE_DELAY_FIX 24 -#define ED_COUNTER_ID_MOVE_DELAY_RND 25 -#define ED_COUNTER_ID_EXPLOSION_DELAY 26 -#define ED_COUNTER_ID_IGNITION_DELAY 27 -#define ED_COUNTER_ID_GROUP_CONTENT 28 -#define ED_COUNTER_ID_CHANGE_DELAY_FIX 29 -#define ED_COUNTER_ID_CHANGE_DELAY_RND 30 -#define ED_COUNTER_ID_CHANGE_CONT_RND 31 - -#define ED_NUM_COUNTERBUTTONS 32 +#define ED_COUNTER_ID_LEVEL_RANDOM_SEED 6 +#define ED_COUNTER_ID_LEVEL_RANDOM 7 +#define ED_COUNTER_ID_ELEMENT_VALUE1 8 +#define ED_COUNTER_ID_ELEMENT_VALUE2 9 +#define ED_COUNTER_ID_ELEMENT_VALUE3 10 +#define ED_COUNTER_ID_ELEMENT_VALUE4 11 +#define ED_COUNTER_ID_YAMYAM_CONTENT 12 +#define ED_COUNTER_ID_BALL_CONTENT 13 +#define ED_COUNTER_ID_ANDROID_CONTENT 14 +#define ED_COUNTER_ID_ENVELOPE_XSIZE 15 +#define ED_COUNTER_ID_ENVELOPE_YSIZE 16 +#define ED_COUNTER_ID_INVENTORY_SIZE 17 +#define ED_COUNTER_ID_CUSTOM_SCORE 18 +#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 19 +#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 20 +#define ED_COUNTER_ID_CUSTOM_VALUE_RND 21 +#define ED_COUNTER_ID_PUSH_DELAY_FIX 22 +#define ED_COUNTER_ID_PUSH_DELAY_RND 23 +#define ED_COUNTER_ID_DROP_DELAY_FIX 24 +#define ED_COUNTER_ID_DROP_DELAY_RND 25 +#define ED_COUNTER_ID_MOVE_DELAY_FIX 26 +#define ED_COUNTER_ID_MOVE_DELAY_RND 27 +#define ED_COUNTER_ID_EXPLOSION_DELAY 28 +#define ED_COUNTER_ID_IGNITION_DELAY 29 +#define ED_COUNTER_ID_GROUP_CONTENT 30 +#define ED_COUNTER_ID_CHANGE_DELAY_FIX 31 +#define ED_COUNTER_ID_CHANGE_DELAY_RND 32 +#define ED_COUNTER_ID_CHANGE_CONT_RND 33 + +#define ED_NUM_COUNTERBUTTONS 34 #define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE -#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM +#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM_SEED +#define ED_COUNTER_ID_EDITOR_FIRST ED_COUNTER_ID_LEVEL_RANDOM +#define ED_COUNTER_ID_EDITOR_LAST ED_COUNTER_ID_LEVEL_RANDOM #define ED_COUNTER_ID_CUSTOM1_FIRST ED_COUNTER_ID_CUSTOM_SCORE #define ED_COUNTER_ID_CUSTOM1_LAST ED_COUNTER_ID_DROP_DELAY_RND @@ -744,16 +737,21 @@ #define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_SELECT_CHANGE_PAGE /* values for textbutton gadgets */ -#define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0 -#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 1 -#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1 2 -#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2 3 -#define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE 4 -#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 5 -#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE 6 -#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE 7 - -#define ED_NUM_TEXTBUTTONS 8 +#define ED_TEXTBUTTON_ID_LEVELINFO_LEVEL 0 +#define ED_TEXTBUTTON_ID_LEVELINFO_EDITOR 1 +#define ED_TEXTBUTTON_ID_PROPERTIES_INFO 2 +#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 3 +#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1 4 +#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2 5 +#define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE 6 +#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 7 +#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE 8 +#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE 9 + +#define ED_NUM_TEXTBUTTONS 10 + +#define ED_TEXTBUTTON_ID_LEVELINFO_FIRST ED_TEXTBUTTON_ID_LEVELINFO_LEVEL +#define ED_TEXTBUTTON_ID_LEVELINFO_LAST ED_TEXTBUTTON_ID_LEVELINFO_EDITOR #define ED_TEXTBUTTON_ID_PROPERTIES_FIRST ED_TEXTBUTTON_ID_PROPERTIES_INFO #define ED_TEXTBUTTON_ID_PROPERTIES_LAST ED_TEXTBUTTON_ID_PROPERTIES_CHANGE @@ -776,56 +774,60 @@ #define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 0 #define ED_CHECKBUTTON_ID_STICK_ELEMENT 1 #define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 2 -#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 3 -#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 4 -#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 5 -#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 6 -#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 7 -#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 8 -#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 9 -#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 10 -#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 11 -#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 12 -#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 13 -#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 14 -#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 15 -#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 16 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 17 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 18 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 19 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 20 -#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 21 -#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 22 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 23 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 24 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 25 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 26 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 27 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 28 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 29 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 30 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 31 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 32 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 33 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 34 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 35 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 36 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 37 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 38 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 39 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 40 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 41 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 42 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 43 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 44 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 45 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 46 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 47 - -#define ED_NUM_CHECKBUTTONS 48 - -#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED -#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED +#define ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE 3 +#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 4 +#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 5 +#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 6 +#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 7 +#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 8 +#define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 9 +#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 10 +#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 11 +#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 12 +#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 13 +#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 14 +#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 15 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 16 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 17 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 18 +#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 19 +#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 20 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 21 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 22 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 23 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 24 +#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 25 +#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 26 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 27 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 28 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 29 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 30 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 31 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 32 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 33 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 34 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 35 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 36 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 37 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 38 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 39 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 40 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 41 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 42 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 43 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 44 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 45 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 46 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 47 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 48 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 49 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 50 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 51 + +#define ED_NUM_CHECKBUTTONS 52 + +#define ED_CHECKBUTTON_ID_EDITOR_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED +#define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED #define ED_CHECKBUTTON_ID_CUSTOM1_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC #define ED_CHECKBUTTON_ID_CUSTOM1_LAST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE @@ -843,8 +845,8 @@ #define ED_NUM_RADIOBUTTONS 2 -#define ED_RADIOBUTTON_ID_LEVEL_FIRST ED_RADIOBUTTON_ID_PERCENTAGE -#define ED_RADIOBUTTON_ID_LEVEL_LAST ED_RADIOBUTTON_ID_QUANTITY +#define ED_RADIOBUTTON_ID_EDITOR_FIRST ED_RADIOBUTTON_ID_PERCENTAGE +#define ED_RADIOBUTTON_ID_EDITOR_LAST ED_RADIOBUTTON_ID_QUANTITY /* values for drawing area gadgets */ #define ED_DRAWING_ID_DRAWING_LEVEL 0 @@ -869,17 +871,19 @@ #define ED_DRAWING_ID_START_ELEMENT 19 #define ED_DRAWING_ID_ARTWORK_ELEMENT 20 #define ED_DRAWING_ID_EXPLOSION_ELEMENT 21 -#define ED_DRAWING_ID_CUSTOM_GRAPHIC 22 -#define ED_DRAWING_ID_CUSTOM_CONTENT 23 -#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 24 -#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 25 -#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 26 -#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 27 -#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 28 -#define ED_DRAWING_ID_GROUP_CONTENT 29 -#define ED_DRAWING_ID_RANDOM_BACKGROUND 30 +#define ED_DRAWING_ID_INVENTORY_CONTENT 22 +#define ED_DRAWING_ID_CUSTOM_GRAPHIC 23 +#define ED_DRAWING_ID_CUSTOM_CONTENT 24 +#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 25 +#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 26 +#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 27 +#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 28 +#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 29 +#define ED_DRAWING_ID_CUSTOM_CHANGE_ACTION 30 +#define ED_DRAWING_ID_GROUP_CONTENT 31 +#define ED_DRAWING_ID_RANDOM_BACKGROUND 32 -#define ED_NUM_DRAWING_AREAS 31 +#define ED_NUM_DRAWING_AREAS 33 /* @@ -904,6 +908,10 @@ #define ED_MODE_INFO 1 #define ED_MODE_PROPERTIES 2 +/* sub-screens in the global settings section */ +#define ED_MODE_LEVELINFO_LEVEL ED_TEXTBUTTON_ID_LEVELINFO_LEVEL +#define ED_MODE_LEVELINFO_EDITOR ED_TEXTBUTTON_ID_LEVELINFO_EDITOR + /* sub-screens in the element properties section */ #define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO #define ED_MODE_PROPERTIES_CONFIG ED_TEXTBUTTON_ID_PROPERTIES_CONFIG @@ -916,19 +924,19 @@ /* values for elements with score for certain actions */ #define MIN_SCORE 0 -#define MAX_SCORE 255 +#define MAX_SCORE 999 /* values for elements with count for collecting */ #define MIN_COLLECT_COUNT 0 -#define MAX_COLLECT_COUNT 255 +#define MAX_COLLECT_COUNT 999 /* values for random placement */ #define RANDOM_USE_PERCENTAGE 0 #define RANDOM_USE_QUANTITY 1 /* maximal size of level editor drawing area */ -#define MAX_ED_FIELDX (2 * SCR_FIELDX) -#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1) +#define MAX_ED_FIELDX (SCR_FIELDX) +#define MAX_ED_FIELDY (SCR_FIELDY - 1) /* @@ -939,43 +947,168 @@ static struct { + int graphic; + int gadget_id; + struct XY *pos; + int gadget_type; + char *infotext; char shortcut; - char *text; -} control_info[ED_NUM_CTRL_BUTTONS] = +} controlbutton_info[ED_NUM_CTRL_BUTTONS] = { /* note: some additional characters are already reserved for "cheat mode" shortcuts (":XYZ" style) -- for details, see "events.c" */ - { 's', "draw single items" }, - { 'd', "draw connected items" }, - { 'l', "draw lines" }, - { 'a', "draw arcs" }, - { 'r', "draw outline rectangles" }, - { 'R', "draw filled rectangles" }, - { '\0', "wrap (rotate) level up" }, - { 't', "enter text elements" }, - { 'f', "flood fill" }, - { '\0', "wrap (rotate) level left" }, - { '?', "properties of drawing element" }, - { '\0', "wrap (rotate) level right" }, - { '\0', "random element placement" }, - { 'b', "grab brush" }, - { '\0', "wrap (rotate) level down" }, - { ',', "pick drawing element" }, - - { 'U', "undo last operation" }, - { 'I', "level properties" }, - { 'S', "save level" }, - { 'C', "clear level" }, - { 'T', "test level" }, - { 'E', "exit level editor" }, - - { '\0', "copy settings from other element" }, - { '\0', "copy settings to other element" }, - { '\0', "exchange element with other element" }, - - { '\0', "copy settings from this element" }, - { '\0', "paste settings to this element" }, + /* ---------- toolbox control buttons ------------------------------------ */ + + { + IMG_EDITOR_BUTTON_GFX_DRAW_SINGLE, GADGET_ID_SINGLE_ITEMS, + &editor.button.draw_single, GD_TYPE_RADIO_BUTTON, + "draw single items", 's' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_CONNECTED, GADGET_ID_CONNECTED_ITEMS, + &editor.button.draw_connected, GD_TYPE_RADIO_BUTTON, + "draw connected items", 'd' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_LINE, GADGET_ID_LINE, + &editor.button.draw_line, GD_TYPE_RADIO_BUTTON, + "draw lines", 'l' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_ARC, GADGET_ID_ARC, + &editor.button.draw_arc, GD_TYPE_RADIO_BUTTON, + "draw arcs", 'a' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_RECTANGLE, GADGET_ID_RECTANGLE, + &editor.button.draw_rectangle, GD_TYPE_RADIO_BUTTON, + "draw outline rectangles", 'r' + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_FILLED_BOX, GADGET_ID_FILLED_BOX, + &editor.button.draw_filled_box, GD_TYPE_RADIO_BUTTON, + "draw filled rectangles", 'R' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_UP, GADGET_ID_WRAP_UP, + &editor.button.rotate_up, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level up", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_TEXT, GADGET_ID_TEXT, + &editor.button.draw_text, GD_TYPE_RADIO_BUTTON, + "enter text elements", 't' + }, + { + IMG_EDITOR_BUTTON_GFX_FLOOD_FILL, GADGET_ID_FLOOD_FILL, + &editor.button.flood_fill, GD_TYPE_RADIO_BUTTON, + "flood fill", 'f' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_LEFT, GADGET_ID_WRAP_LEFT, + &editor.button.rotate_left, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level left", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_ZOOM_LEVEL, GADGET_ID_ZOOM, + &editor.button.zoom_level, GD_TYPE_NORMAL_BUTTON, + "zoom level tile size", 'z' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_RIGHT, GADGET_ID_WRAP_RIGHT, + &editor.button.rotate_right, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level right", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_DRAW_RANDOM, GADGET_ID_RANDOM_PLACEMENT, + &editor.button.draw_random, GD_TYPE_NORMAL_BUTTON, + "random element placement", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_GRAB_BRUSH, GADGET_ID_GRAB_BRUSH, + &editor.button.grab_brush, GD_TYPE_RADIO_BUTTON, + "grab brush", 'b' + }, + { + IMG_EDITOR_BUTTON_GFX_ROTATE_DOWN, GADGET_ID_WRAP_DOWN, + &editor.button.rotate_down, GD_TYPE_NORMAL_BUTTON, + "wrap (rotate) level down", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_PICK_ELEMENT, GADGET_ID_PICK_ELEMENT, + &editor.button.pick_element, GD_TYPE_RADIO_BUTTON, + "pick drawing element", ',' + }, + + /* ---------- level control buttons -------------------------------------- */ + + { + IMG_EDITOR_BUTTON_GFX_UNDO, GADGET_ID_UNDO, + &editor.button.undo, GD_TYPE_NORMAL_BUTTON, + "undo last operation", 'U' + }, + { + IMG_EDITOR_BUTTON_GFX_CONF, GADGET_ID_INFO, + &editor.button.conf, GD_TYPE_NORMAL_BUTTON, + "properties of level", 'I' + }, + { + IMG_EDITOR_BUTTON_GFX_SAVE, GADGET_ID_SAVE, + &editor.button.save, GD_TYPE_NORMAL_BUTTON, + "save level", 'S' + }, + { + IMG_EDITOR_BUTTON_GFX_CLEAR, GADGET_ID_CLEAR, + &editor.button.clear, GD_TYPE_NORMAL_BUTTON, + "clear level", 'C' + }, + { + IMG_EDITOR_BUTTON_GFX_TEST, GADGET_ID_TEST, + &editor.button.test, GD_TYPE_NORMAL_BUTTON, + "test level", 'T' + }, + { + IMG_EDITOR_BUTTON_GFX_EXIT, GADGET_ID_EXIT, + &editor.button.exit, GD_TYPE_NORMAL_BUTTON, + "exit level editor", 'E' + }, + + /* ---------- CE and GE control buttons ---------------------------------- */ + + { + IMG_EDITOR_BUTTON_GFX_CE_COPY_FROM, GADGET_ID_CUSTOM_COPY_FROM, + &editor.button.ce_copy_from, GD_TYPE_RADIO_BUTTON, + "copy settings from other element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_COPY_TO, GADGET_ID_CUSTOM_COPY_TO, + &editor.button.ce_copy_to, GD_TYPE_RADIO_BUTTON, + "copy settings to other element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_SWAP, GADGET_ID_CUSTOM_EXCHANGE, + &editor.button.ce_swap, GD_TYPE_RADIO_BUTTON, + "exchange element with other element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_COPY, GADGET_ID_CUSTOM_COPY, + &editor.button.ce_copy, GD_TYPE_NORMAL_BUTTON, + "copy settings from this element", 0 + }, + { + IMG_EDITOR_BUTTON_GFX_CE_PASTE, GADGET_ID_CUSTOM_PASTE, + &editor.button.ce_paste, GD_TYPE_NORMAL_BUTTON, + "paste settings to this element", 0 + }, + + /* ---------- palette control buttons ------------------------------------ */ + + { + IMG_EDITOR_BUTTON_GFX_PROPERTIES, GADGET_ID_PROPERTIES, + &editor.button.properties, GD_TYPE_NORMAL_BUTTON, + "properties of drawing element", 'p' + } }; static int random_placement_value = 10; @@ -1003,7 +1136,7 @@ static struct /* ---------- current level number --------------------------------------- */ { - DX + 5 - SX, DY + 3 - SY, + -1, -1, /* these values are not constant, but can change at runtime */ 1, 100, GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, GADGET_ID_SELECT_LEVEL_TEXT, GADGET_ID_NONE, @@ -1035,7 +1168,7 @@ static struct GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP, GADGET_ID_LEVEL_GEMSLIMIT_TEXT, GADGET_ID_NONE, &level.gems_needed, - NULL, "number of gems to collect:", NULL + NULL, "number of gems to collect:", NULL }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7), @@ -1047,14 +1180,22 @@ static struct }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(9), - 0, 255, + 0, 999, 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 }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(8), + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12), + 0, 9999, + GADGET_ID_LEVEL_RANDOM_SEED_DOWN, GADGET_ID_LEVEL_RANDOM_SEED_UP, + GADGET_ID_LEVEL_RANDOM_SEED_TEXT, GADGET_ID_NONE, + &level.random_seed, + NULL, "random seed:", "(0 => random)" + }, + { + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), 1, 100, GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP, GADGET_ID_LEVEL_RANDOM_TEXT, GADGET_ID_NONE, @@ -1136,6 +1277,14 @@ static struct NULL, /* will be set when used */ NULL, " ", "height", }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + MIN_INITIAL_INVENTORY_SIZE, MAX_INITIAL_INVENTORY_SIZE, + GADGET_ID_INVENTORY_SIZE_DOWN, GADGET_ID_INVENTORY_SIZE_UP, + GADGET_ID_INVENTORY_SIZE_TEXT, GADGET_ID_NONE, + &level.initial_inventory_size[0], + NULL, NULL, "number of inventory elements" + }, /* ---------- element settings: configure 1 (custom elements) ------------ */ @@ -1173,7 +1322,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), - 0, 255, + 0, 999, GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP, GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.push_delay_fixed, @@ -1181,7 +1330,7 @@ static struct }, { -1, ED_ELEMENT_SETTINGS_YPOS(7), - 0, 255, + 0, 999, GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP, GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP, &custom_element.push_delay_random, @@ -1189,7 +1338,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), - 0, 255, + 0, 999, GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP, GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.drop_delay_fixed, @@ -1197,7 +1346,7 @@ static struct }, { -1, ED_ELEMENT_SETTINGS_YPOS(8), - 0, 255, + 0, 999, GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP, GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP, &custom_element.drop_delay_random, @@ -1224,7 +1373,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12), - 0, 255, + 0, 999, GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP, GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE, &custom_element.explosion_delay, @@ -1232,7 +1381,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), - 0, 255, + 0, 999, GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP, GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE, &custom_element.ignition_delay, @@ -1340,6 +1489,7 @@ static struct ValueTextInfo options_game_engine_type[] = { { GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" }, { GAME_ENGINE_TYPE_EM, "Emerald Mine" }, + { GAME_ENGINE_TYPE_SP, "Supaplex" }, { -1, NULL } }; @@ -1513,6 +1663,7 @@ static struct ValueTextInfo options_deadliness[] = { { EP_DONT_RUN_INTO, "running into" }, { EP_DONT_COLLIDE_WITH, "colliding with" }, + { EP_DONT_GET_HIT_BY, "getting hit by" }, { EP_DONT_TOUCH, "touching" }, { -1, NULL } @@ -1671,15 +1822,16 @@ static struct ValueTextInfo options_action_type[] = { { CA_NO_ACTION, "no action" }, { CA_UNDEFINED, " " }, - { CA_HEADLINE_LEVEL_ACTIONS, "[level actions]" }, + { CA_HEADLINE_LEVEL_ACTIONS, "[level]" }, { CA_RESTART_LEVEL, "restart level" }, { CA_SHOW_ENVELOPE, "show envelope" }, { CA_SET_LEVEL_TIME, "set time" }, { CA_SET_LEVEL_SCORE, "set score" }, - { CA_SET_LEVEL_GEMS, "set needed gems" }, + { CA_SET_LEVEL_GEMS, "set gems" }, { CA_SET_LEVEL_WIND, "set wind dir." }, + { CA_SET_LEVEL_RANDOM_SEED, "set rand. seed" }, { CA_UNDEFINED, " " }, - { CA_HEADLINE_PLAYER_ACTIONS, "[player actions]" }, + { CA_HEADLINE_PLAYER_ACTIONS, "[player]" }, { CA_MOVE_PLAYER, "move player" }, { CA_EXIT_PLAYER, "exit player" }, { CA_KILL_PLAYER, "kill player" }, @@ -1688,12 +1840,14 @@ static struct ValueTextInfo options_action_type[] = { CA_SET_PLAYER_SHIELD, "set shield" }, { CA_SET_PLAYER_GRAVITY, "set gravity" }, { CA_SET_PLAYER_ARTWORK, "set artwork" }, + { CA_SET_PLAYER_INVENTORY, "set inventory" }, { CA_UNDEFINED, " " }, - { CA_HEADLINE_CE_ACTIONS, "[CE actions]" }, + { CA_HEADLINE_CE_ACTIONS, "[CE]" }, { CA_SET_CE_VALUE, "set CE value" }, { CA_SET_CE_SCORE, "set CE score" }, + { CA_SET_CE_ARTWORK, "set CE artwork" }, { CA_UNDEFINED, " " }, - { CA_HEADLINE_ENGINE_ACTIONS, "[engine actions]" }, + { CA_HEADLINE_ENGINE_ACTIONS, "[engine]" }, { CA_SET_ENGINE_SCAN_MODE, "set scan mode" }, { -1, NULL } @@ -1749,6 +1903,7 @@ static struct ValueTextInfo options_action_arg_player[] = { CA_ARG_PLAYER_4, "4" }, { CA_ARG_PLAYER_ANY, "any" }, { CA_ARG_PLAYER_TRIGGER, "trigger" }, + { CA_ARG_PLAYER_ACTION, "action ->" }, { -1, NULL } }; @@ -1782,10 +1937,12 @@ static struct ValueTextInfo options_action_arg_number[] = { CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" }, { CA_ARG_ELEMENT_CV_TARGET, "target" }, { CA_ARG_ELEMENT_CV_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CV_ACTION, "action ->" }, { CA_ARG_UNDEFINED, " " }, { CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" }, { CA_ARG_ELEMENT_CS_TARGET, "target" }, { CA_ARG_ELEMENT_CS_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CS_ACTION, "action ->" }, { -1, NULL } }; @@ -1819,14 +1976,17 @@ static struct ValueTextInfo options_action_arg_value[] = { CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" }, { CA_ARG_ELEMENT_CV_TARGET, "target" }, { CA_ARG_ELEMENT_CV_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CV_ACTION, "action ->" }, { CA_ARG_UNDEFINED, " " }, { CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" }, { CA_ARG_ELEMENT_CS_TARGET, "target" }, { CA_ARG_ELEMENT_CS_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CS_ACTION, "action ->" }, { CA_ARG_UNDEFINED, " " }, { CA_ARG_ELEMENT_NR_HEADLINE, "[element]" }, { CA_ARG_ELEMENT_NR_TARGET, "target" }, { CA_ARG_ELEMENT_NR_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_NR_ACTION, "action ->" }, { -1, NULL } }; @@ -1842,6 +2002,7 @@ static struct ValueTextInfo options_action_arg_envelope[] = { CA_ARG_ELEMENT_HEADLINE, "[element]" }, { CA_ARG_ELEMENT_TARGET, "target" }, { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_ACTION, "action ->" }, { -1, NULL } }; @@ -1861,6 +2022,7 @@ static struct ValueTextInfo options_action_arg_key[] = { CA_ARG_ELEMENT_HEADLINE, "[element]" }, { CA_ARG_ELEMENT_TARGET, "target" }, { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_ACTION, "action ->" }, { -1, NULL } }; @@ -1899,6 +2061,7 @@ static struct ValueTextInfo options_action_arg_artwork[] = { CA_ARG_ELEMENT_HEADLINE, "[element]" }, { CA_ARG_ELEMENT_TARGET, "target" }, { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_ACTION, "action ->" }, { CA_ARG_UNDEFINED, " " }, { CA_ARG_ELEMENT_RESET, "reset" }, @@ -1938,6 +2101,26 @@ static struct ValueTextInfo options_action_arg_scan_mode[] = { -1, NULL } }; +static struct ValueTextInfo options_action_arg_inventory[] = +{ + { CA_ARG_INVENTORY_HEADLINE, "[add]" }, + { CA_ARG_ELEMENT_TARGET, "+ target" }, + { CA_ARG_ELEMENT_TRIGGER, "+ trigger" }, + { CA_ARG_ELEMENT_ACTION, "+ action" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_INVENTORY_RM_HEADLINE,"[remove]" }, + { CA_ARG_INVENTORY_RM_TARGET, "- target" }, + { CA_ARG_INVENTORY_RM_TRIGGER,"- trigger" }, + { CA_ARG_INVENTORY_RM_ACTION, "- action" }, + { CA_ARG_INVENTORY_RM_FIRST, "- first" }, + { CA_ARG_INVENTORY_RM_LAST, "- last" }, + { CA_ARG_INVENTORY_RM_ALL, "- all" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_INVENTORY_RESET, "reset" }, + + { -1, NULL } +}; + static char options_change_page_strings[MAX_CHANGE_PAGES][10]; static struct ValueTextInfo options_change_page[MAX_CHANGE_PAGES + 1] = { @@ -1981,13 +2164,16 @@ action_arg_options[] = { CA_SET_LEVEL_GEMS, 3, options_action_arg_number, }, { CA_SET_LEVEL_SCORE, 3, options_action_arg_number, }, { CA_SET_LEVEL_WIND, 1, options_action_arg_direction, }, + { CA_SET_LEVEL_RANDOM_SEED, 1, options_action_arg_number, }, { CA_SET_PLAYER_KEYS, 2, options_action_arg_key, }, { CA_SET_PLAYER_SPEED, 1, options_action_arg_speed, }, { CA_SET_PLAYER_SHIELD, 1, options_action_arg_shield, }, { CA_SET_PLAYER_GRAVITY, 1, options_action_arg_gravity, }, { CA_SET_PLAYER_ARTWORK, 1, options_action_arg_artwork, }, + { CA_SET_PLAYER_INVENTORY, 0, options_action_arg_inventory, }, { CA_SET_CE_VALUE, 3, options_action_arg_value, }, { CA_SET_CE_SCORE, 3, options_action_arg_value, }, + { CA_SET_CE_ARTWORK, 1, options_action_arg_artwork, }, { CA_SET_ENGINE_SCAN_MODE, 1, options_action_arg_scan_mode, }, { -1, FALSE, NULL } @@ -2034,7 +2220,7 @@ static struct /* ---------- element settings: configure (several elements) ------------- */ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, -1, options_player_speed, @@ -2266,34 +2452,46 @@ static struct } textbutton_info[ED_NUM_TEXTBUTTONS] = { { - ED_ELEMENT_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1), + ED_LEVEL_SETTINGS_TABS_XPOS(0), ED_LEVEL_SETTINGS_TABS_YPOS(0), + GADGET_ID_LEVELINFO_LEVEL, GADGET_ID_NONE, + 8, "Level", + NULL, NULL, "Configure level properties" + }, + { + ED_LEVEL_SETTINGS_TABS_XPOS(1), ED_LEVEL_SETTINGS_TABS_YPOS(0), + GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_NONE, + 8, "Editor", + NULL, NULL, "Configure editor properties" + }, + { + ED_ELEMENT_SETTINGS_TABS_XPOS(0), ED_ELEMENT_SETTINGS_TABS_YPOS(0), GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE, 8, "Info", NULL, NULL, "Show information about element" }, { - ED_ELEMENT_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1), + ED_ELEMENT_SETTINGS_TABS_XPOS(1), ED_ELEMENT_SETTINGS_TABS_YPOS(0), GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE, 8, "Config", NULL, NULL, "Configure element properties" }, { - ED_ELEMENT_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1), + ED_ELEMENT_SETTINGS_TABS_XPOS(1), ED_ELEMENT_SETTINGS_TABS_YPOS(0), GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_NONE, 8, "Config 1", - NULL, NULL, "Configure custom element properties" + NULL, NULL, "Configure element properties, part 1" }, { - ED_ELEMENT_SETTINGS_XPOS(0) + 248, ED_COUNTER_YPOS(1), + ED_ELEMENT_SETTINGS_TABS_XPOS(2), ED_ELEMENT_SETTINGS_TABS_YPOS(0), GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_NONE, 8, "Config 2", - NULL, NULL, "Configure custom element properties" + NULL, NULL, "Configure element properties, part 2" }, { - ED_ELEMENT_SETTINGS_XPOS(0) + 372, ED_COUNTER_YPOS(1), + ED_ELEMENT_SETTINGS_TABS_XPOS(3), ED_ELEMENT_SETTINGS_TABS_YPOS(0), GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_NONE, 8, "Change", - NULL, NULL, "Custom element change configuration" + NULL, NULL, "Configure custom element change pages" }, { -1, ED_ELEMENT_SETTINGS_YPOS(2), @@ -2357,45 +2555,43 @@ static struct static struct { - int gd_x, gd_y; int x, y; +} scrollbutton_pos[ED_NUM_SCROLLBUTTONS]; + +static struct +{ + int graphic; int gadget_id; char *infotext; } scrollbutton_info[ED_NUM_SCROLLBUTTONS] = { { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 0 * ED_SCROLLBUTTON_YSIZE, - ED_SCROLL_UP_XPOS, ED_SCROLL_UP_YPOS, + IMG_EDITOR_PLAYFIELD_SCROLL_UP, GADGET_ID_SCROLL_UP, "scroll level editing area up" }, { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 1 * ED_SCROLLBUTTON_YSIZE, - ED_SCROLL_DOWN_XPOS, ED_SCROLL_DOWN_YPOS, + IMG_EDITOR_PLAYFIELD_SCROLL_DOWN, GADGET_ID_SCROLL_DOWN, "scroll level editing area down" }, { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 2 * ED_SCROLLBUTTON_YSIZE, - ED_SCROLL_LEFT_XPOS, ED_SCROLL_LEFT_YPOS, + IMG_EDITOR_PLAYFIELD_SCROLL_LEFT, GADGET_ID_SCROLL_LEFT, "scroll level editing area left" }, { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 3 * ED_SCROLLBUTTON_YSIZE, - ED_SCROLL_RIGHT_XPOS, ED_SCROLL_RIGHT_YPOS, + IMG_EDITOR_PLAYFIELD_SCROLL_RIGHT, GADGET_ID_SCROLL_RIGHT, "scroll level editing area right" }, { - ED_SCROLLBUTTON2_XPOS, ED_SCROLLBUTTON2_YPOS + 0 * ED_SCROLLBUTTON2_YSIZE, - ED_SCROLL2_UP_XPOS, ED_SCROLL2_UP_YPOS, + IMG_EDITOR_PALETTE_SCROLL_UP, GADGET_ID_SCROLL_LIST_UP, "scroll element list up ('Page Up')" }, { - ED_SCROLLBUTTON2_XPOS, ED_SCROLLBUTTON2_YPOS + 1 * ED_SCROLLBUTTON2_YSIZE, - ED_SCROLL2_DOWN_XPOS, ED_SCROLL2_DOWN_YPOS, + IMG_EDITOR_PALETTE_SCROLL_DOWN, GADGET_ID_SCROLL_LIST_DOWN, "scroll element list down ('Page Down')" }, @@ -2403,63 +2599,41 @@ static struct static struct { - int gd_x, gd_y; int x, y; int width, height; int wheel_x, wheel_y; int wheel_width, wheel_height; +} scrollbar_pos[ED_NUM_SCROLLBARS]; + +static struct +{ + int graphic; int type; int gadget_id; char *infotext; } scrollbar_info[ED_NUM_SCROLLBARS] = { { - ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS, - SX + ED_SCROLL_HORIZONTAL_XPOS, SY + ED_SCROLL_HORIZONTAL_YPOS, - ED_SCROLL_HORIZONTAL_XSIZE, ED_SCROLL_HORIZONTAL_YSIZE, -#if 1 - SX, SY, - SXSIZE, SYSIZE, -#else - 0, 0, - SX + SXSIZE + SX, WIN_YSIZE, -#endif + IMG_EDITOR_PLAYFIELD_SCROLLBAR, GD_TYPE_SCROLLBAR_HORIZONTAL, GADGET_ID_SCROLL_HORIZONTAL, "scroll level editing area horizontally" }, { - ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS, - SX + ED_SCROLL_VERTICAL_XPOS, SY + ED_SCROLL_VERTICAL_YPOS, - ED_SCROLL_VERTICAL_XSIZE, ED_SCROLL_VERTICAL_YSIZE, -#if 1 - SX, SY, - SXSIZE, SYSIZE, -#else - 0, 0, - SX + SXSIZE + SX, WIN_YSIZE, -#endif + IMG_EDITOR_PLAYFIELD_SCROLLBAR, GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_VERTICAL, "scroll level editing area vertically" }, { - ED_SCROLLBAR2_XPOS, ED_SCROLLBAR2_YPOS, - DX + ED_SCROLL2_VERTICAL_XPOS, DY + ED_SCROLL2_VERTICAL_YPOS, - ED_SCROLL2_VERTICAL_XSIZE, ED_SCROLL2_VERTICAL_YSIZE, -#if 1 - DX, DY, - DXSIZE, DYSIZE, -#else - SX + SXSIZE + SX, 0, - WIN_XSIZE - (SX + SXSIZE + SX), WIN_YSIZE, -#endif + IMG_EDITOR_PALETTE_SCROLLBAR, GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_LIST_VERTICAL, "scroll element list vertically" } }; + static struct { int x, y; @@ -2472,14 +2646,14 @@ static struct } radiobutton_info[ED_NUM_RADIOBUTTONS] = { { - -1, ED_COUNTER2_YPOS(8), + -1, ED_LEVEL_SETTINGS_YPOS(0), GADGET_ID_RANDOM_PERCENTAGE, GADGET_ID_LEVEL_RANDOM_UP, RADIO_NR_RANDOM_ELEMENTS, &random_placement_method, RANDOM_USE_PERCENTAGE, " ", "percentage", "use percentage for random elements" }, { - -1, ED_COUNTER2_YPOS(8), + -1, ED_LEVEL_SETTINGS_YPOS(0), GADGET_ID_RANDOM_QUANTITY, GADGET_ID_RANDOM_PERCENTAGE, RADIO_NR_RANDOM_ELEMENTS, &random_placement_method, RANDOM_USE_QUANTITY, @@ -2499,7 +2673,7 @@ static struct /* ---------- level and editor settings ---------------------------------- */ { - ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(9) - MINI_TILEY, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(1), GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE, &random_placement_background_restricted, NULL, @@ -2522,6 +2696,13 @@ static struct NULL, "slip down from certain flat walls","use EM/DC style slipping behaviour" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_EM_EXPLODES_BY_FIRE, GADGET_ID_NONE, + &level.em_explodes_by_fire, + NULL, + "explodes with chain reaction", "use R'n'D style explosion behaviour" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_USE_SPRING_BUG, GADGET_ID_NONE, @@ -2558,14 +2739,21 @@ static struct "can grow into anything diggable", "grow into more than just sand" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_NONE, + &level.auto_exit_sokoban, + NULL, + "exit level if all fields solved", "automatically finish Sokoban levels" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, &level.continuous_snapping, NULL, - "continuos snapping", "use snapping without releasing key" + "continuous snapping", "use snapping without releasing key" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, &level.block_snap_field, NULL, @@ -2593,35 +2781,49 @@ static struct "no scrolling when relocating", "player gets relocated without delay" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_SHIFTED_RELOCATION, GADGET_ID_NONE, + &level.shifted_relocation, + NULL, + "no centering when relocating", "level not centered after relocation" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE, &level.use_start_element[0], NULL, "use level start element:", "start level at this element's position" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, &level.use_artwork_element[0], NULL, "use artwork from element:", "use player artwork from other element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, &level.use_explosion_element[0], NULL, "use explosion from element:", "use explosion properties from element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE, &level.initial_player_gravity[0], NULL, "use initial gravity", "set initial player gravity" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_USE_INITIAL_INVENTORY, GADGET_ID_NONE, + &level.use_initial_inventory[0], + NULL, + "use initial inventory:", "use collected elements on level start" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, &level.can_pass_to_walkable, NULL, @@ -2669,15 +2871,8 @@ static struct ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), GADGET_ID_CUSTOM_USE_GRAPHIC, GADGET_ID_NONE, &custom_element.use_gfx_element, - - /* !!! add separate "use existing element sound" !!! */ -#if 0 - NULL, - "use graphic/sound of element:", "use existing graphic and sound" -#else NULL, "use graphic of element:", "use existing element graphic" -#endif }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), @@ -2870,7 +3065,8 @@ static struct { 0, 0, GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE, - NULL, MAX_ED_FIELDX, MAX_ED_FIELDY, + NULL, + -1, -1, /* these values are not constant, but can change at runtime */ NULL, NULL, NULL, NULL }, @@ -2997,7 +3193,7 @@ static struct /* ---------- level start element ---------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(8), + -1, ED_AREA_1X1_SETTINGS_YPOS(9), GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, &level.start_element[0], 1, 1, NULL, NULL, NULL, "level start element" @@ -3006,7 +3202,7 @@ static struct /* ---------- player artwork element ------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(9), + -1, ED_AREA_1X1_SETTINGS_YPOS(10), GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, &level.artwork_element[0], 1, 1, NULL, NULL, NULL, "element for player artwork" @@ -3015,12 +3211,21 @@ static struct /* ---------- player explosion element ----------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(10), + -1, ED_AREA_1X1_SETTINGS_YPOS(11), GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, &level.explosion_element[0], 1, 1, NULL, NULL, NULL, "element for player explosion" }, + /* ---------- player initial inventory ----------------------------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(1), + 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" + }, + /* ---------- element settings: configure 1 (custom elements) ----------- */ /* ---------- custom graphic --------------------------------------------- */ @@ -3028,7 +3233,7 @@ static struct { -1, ED_AREA_1X1_SETTINGS_YPOS(1), GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC, - &custom_element.gfx_element, 1, 1, + &custom_element.gfx_element_initial,1, 1, NULL, NULL, NULL, "custom graphic element" }, @@ -3083,10 +3288,19 @@ static struct { -1, ED_AREA_1X1_SETTINGS_YPOS(5), GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION, - &custom_element_change.trigger_element, 1, 1, + &custom_element_change.initial_trigger_element, 1, 1, NULL, NULL, NULL, "other element triggering change" }, + /* ---------- custom change action (element used for action) ------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_CHANGE_ACTION, GADGET_ID_ACTION_ARG, + &custom_element_change.action_element, 1, 1, + NULL, NULL, NULL, "element used as action parameter" + }, + /* ---------- group element content -------------------------------------- */ { @@ -3099,7 +3313,7 @@ static struct /* ---------- random background (for random painting) -------------------- */ { - -1, ED_ELEMENT_SETTINGS_YPOS(14), + -1, ED_AREA_1X1_SETTINGS_YPOS(-1), GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED, &random_placement_background_element, 1, 1, NULL, NULL, NULL, "random placement background" @@ -3114,16 +3328,12 @@ static struct */ /* actual size of level editor drawing area */ -static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1; +static int ed_fieldx, ed_fieldy; /* actual position of level editor drawing area in level playfield */ static int level_xpos = -1, level_ypos = -1; -#if 1 #define IN_ED_FIELD(x,y) IN_FIELD(x, y, ed_fieldx, ed_fieldy) -#else -#define IN_ED_FIELD(x,y) ((x)>=0 && (x)=0 &&(y) 0) + num_editor_elements += editor.palette.cols; for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) { @@ -4820,7 +5052,13 @@ static void ReinitializeElementList() if (found_inactive_cascade) continue; - num_editor_elements += *editor_elements_info[i].element_list_size; + // required for correct padding of palette element buttons + int element_list_size = *editor_elements_info[i].element_list_size; + int element_rows = + (element_list_size + editor.palette.cols - 1) / editor.palette.cols; + int element_buttons = editor.palette.cols * element_rows; + + num_editor_elements += element_buttons; } } @@ -4844,9 +5082,16 @@ static void ReinitializeElementList() { if (setup.editor.el_headlines) { - for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) + // required for correct padding of palette headline buttons + int headline_size = (*editor_elements_info[i].headline_list_size > 0 ? + editor.palette.cols : 0); + + for (j = 0; j < headline_size; j++) { - int element = (*editor_elements_info[i].headline_list)[j]; + // use empty elements for padding of palette headline buttons + int element = (j < *editor_elements_info[i].headline_list_size ? + (*editor_elements_info[i].headline_list)[j] : + editor_el_empty[0]); editor_elements[pos++] = element; @@ -4858,8 +5103,19 @@ static void ReinitializeElementList() if (found_inactive_cascade) continue; - for (j = 0; j < *editor_elements_info[i].element_list_size; j++) + // required for correct padding of palette element buttons + int element_list_size = *editor_elements_info[i].element_list_size; + int element_rows = + (element_list_size + editor.palette.cols - 1) / editor.palette.cols; + int element_buttons = editor.palette.cols * element_rows; + + // copy all elements from element list + for (j = 0; j < element_list_size; j++) editor_elements[pos++] = (*editor_elements_info[i].element_list)[j]; + + // use empty elements for padding of palette element buttons + for (j = 0; j < element_buttons - element_list_size; j++) + editor_elements[pos++] = editor_el_empty[0]; } } @@ -4950,27 +5206,40 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, (input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER); Bitmap *src_bitmap; int src_x, src_y; - int num_mini_tilex = width / MINI_TILEX + 1; - int num_mini_tiley = height / MINI_TILEY + 1; - int from_x = dest_x - MINI_TILEX / 2; - int from_y = dest_y - MINI_TILEY / 2; - int to_x = from_x + num_mini_tilex * MINI_TILEX - 1; - int to_y = from_y + num_mini_tiley * MINI_TILEY - 1; - int x, y; - - getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y); + int bx = (input ? 4 : 8); + int by = (input ? 4 : 8); + int bx2 = TILEX - bx; + int by2 = TILEY - by; + int i; - for (y = 0; y < num_mini_tiley; y++) - for (x = 0; x < num_mini_tilex; x++) - BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, - from_x + x * MINI_TILEX, from_y + y * MINI_TILEY); + getFixedGraphicSource(border_graphic, 0, &src_bitmap, &src_x, &src_y); - ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2); + BlitBitmap(src_bitmap, drawto, src_x, src_y, + bx, by, dest_x - bx, dest_y - by); + BlitBitmap(src_bitmap, drawto, src_x + bx2, src_y, + bx, by, dest_x + width, dest_y - by); + BlitBitmap(src_bitmap, drawto, src_x, src_y + by2, + bx, by, dest_x - bx, dest_y + height); + BlitBitmap(src_bitmap, drawto, src_x + bx2, src_y + by2, + bx, by, dest_x + width, dest_y + height); - DrawSimpleBlackLine(drawto, from_x, from_y, to_x, from_y); - DrawSimpleBlackLine(drawto, to_x, from_y, to_x, to_y); - DrawSimpleBlackLine(drawto, to_x, to_y, from_x, to_y); - DrawSimpleBlackLine(drawto, from_x, to_y, from_x, from_y); + for (i = 0; i < width / MINI_TILEX; i++) + { + BlitBitmap(src_bitmap, drawto, src_x + bx, src_y, MINI_TILEX, by, + dest_x + i * MINI_TILEX, dest_y - by); + BlitBitmap(src_bitmap, drawto, src_x + bx, src_y + by2, MINI_TILEX, by, + dest_x + i * MINI_TILEX, dest_y + height); + } + + for (i = 0; i < height / MINI_TILEY; i++) + { + BlitBitmap(src_bitmap, drawto, src_x, src_y + by, bx, MINI_TILEY, + dest_x - bx, dest_y + i * MINI_TILEY); + BlitBitmap(src_bitmap, drawto, src_x + bx2, src_y + by, bx, MINI_TILEY, + dest_x + width, dest_y + i * MINI_TILEY); + } + + ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2); } static void DrawDrawingArea(int id) @@ -4992,7 +5261,7 @@ static void DrawDrawingArea(int id) static void ScrollMiniLevel(int from_x, int from_y, int scroll) { - int x,y; + int x, y; int dx = (scroll == ED_SCROLL_LEFT ? -1 : scroll == ED_SCROLL_RIGHT ? 1 : 0); int dy = (scroll == ED_SCROLL_UP ? -1 : scroll == ED_SCROLL_DOWN ? 1 : 0); @@ -5003,6 +5272,7 @@ static void ScrollMiniLevel(int from_x, int from_y, int scroll) (ed_fieldy * MINI_TILEY) - (dy != 0 ? MINI_TILEY : 0), SX + (dx == +1 ? MINI_TILEX : 0), SY + (dy == +1 ? MINI_TILEY : 0)); + if (dx) { x = (dx == 1 ? 0 : ed_fieldx - 1); @@ -5020,49 +5290,55 @@ static void ScrollMiniLevel(int from_x, int from_y, int scroll) BackToFront(); } +void getElementListGraphicSource(int element, Bitmap **bitmap, int *x, int *y) +{ + int graphic = el2edimg(element); + int tile_size = (editor.palette.tile_size >= TILESIZE ? TILESIZE : + MINI_TILESIZE); + + getSizedGraphicSource(graphic, 0, tile_size, bitmap, x, y); +} + static void CreateControlButtons() { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; - unsigned long event_mask; int i; /* create toolbox buttons */ for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) { - int id = i; - int width, height; - int gd_xoffset, gd_yoffset; - int gd_x1, gd_x2, gd_y1, gd_y2; - int button_type; - int radio_button_nr; - boolean checked; - - if (id == GADGET_ID_SINGLE_ITEMS || - id == GADGET_ID_CONNECTED_ITEMS || - id == GADGET_ID_LINE || - id == GADGET_ID_ARC || - id == GADGET_ID_TEXT || - id == GADGET_ID_RECTANGLE || - id == GADGET_ID_FILLED_BOX || - id == GADGET_ID_FLOOD_FILL || - id == GADGET_ID_GRAB_BRUSH || - id == GADGET_ID_PICK_ELEMENT || - id == GADGET_ID_CUSTOM_COPY_FROM || - id == GADGET_ID_CUSTOM_COPY_TO || - id == GADGET_ID_CUSTOM_EXCHANGE) + int id = controlbutton_info[i].gadget_id; + int type = controlbutton_info[i].gadget_type; + int graphic = controlbutton_info[i].graphic; + struct XY *pos = controlbutton_info[i].pos; + struct GraphicInfo *gd = &graphic_info[graphic]; + Bitmap *gd_bitmap = gd->bitmap; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int gd_x1a = gd->src_x + gd->active_xoffset; + int gd_y1a = gd->src_y + gd->active_yoffset; + int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset; + int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; + int width = gd->width; + int height = gd->height; + int x = pos->x; + int y = pos->y; + unsigned int event_mask; + int radio_button_nr = RADIO_NR_NONE; + boolean checked = FALSE; + + if (type == GD_TYPE_RADIO_BUTTON) { - button_type = GD_TYPE_RADIO_BUTTON; - radio_button_nr = RADIO_NR_DRAWING_TOOLBOX; - checked = (id == drawing_function ? TRUE : FALSE); event_mask = GD_EVENT_PRESSED; + radio_button_nr = RADIO_NR_DRAWING_TOOLBOX; + + if (id == drawing_function) + checked = TRUE; } else { - button_type = GD_TYPE_NORMAL_BUTTON; - radio_button_nr = RADIO_NR_NONE; - checked = FALSE; - if (id == GADGET_ID_WRAP_LEFT || id == GADGET_ID_WRAP_RIGHT || id == GADGET_ID_WRAP_UP || @@ -5072,82 +5348,32 @@ static void CreateControlButtons() event_mask = GD_EVENT_RELEASED; } - if (id < ED_NUM_CTRL1_BUTTONS) - { - int x = i % ED_CTRL1_BUTTONS_HORIZ; - int y = i / ED_CTRL1_BUTTONS_HORIZ; - - gd_xoffset = ED_CTRL1_BUTTONS_XPOS + x * ED_CTRL1_BUTTON_XSIZE; - gd_yoffset = ED_CTRL1_BUTTONS_YPOS + y * ED_CTRL1_BUTTON_YSIZE; - width = ED_CTRL1_BUTTON_XSIZE; - height = ED_CTRL1_BUTTON_YSIZE; - - gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset; - gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset; - gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_GFX_YPOS + gd_yoffset; - gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_ALT_GFX_YPOS + gd_yoffset; - } - else if (id < ED_NUM_CTRL1_2_BUTTONS) - { - int x = (i - ED_NUM_CTRL1_BUTTONS) % ED_CTRL2_BUTTONS_HORIZ; - int y = (i - ED_NUM_CTRL1_BUTTONS) / ED_CTRL2_BUTTONS_HORIZ; - - gd_xoffset = ED_CTRL2_BUTTONS_XPOS + x * ED_CTRL2_BUTTON_XSIZE; - gd_yoffset = ED_CTRL2_BUTTONS_YPOS + y * ED_CTRL2_BUTTON_YSIZE; - width = ED_CTRL2_BUTTON_XSIZE; - height = ED_CTRL2_BUTTON_YSIZE; - - gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset; - gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset; - gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL2_BUTTONS_GFX_YPOS + gd_yoffset; - gd_y2 = 0; /* no alternative graphic for these buttons */ - } - else if (id < ED_NUM_CTRL1_3_BUTTONS) + if (id == GADGET_ID_PROPERTIES) { - int x = (i - ED_NUM_CTRL1_2_BUTTONS) % ED_CTRL3_BUTTONS_HORIZ + 1; - int y = (i - ED_NUM_CTRL1_2_BUTTONS) / ED_CTRL3_BUTTONS_HORIZ; - - gd_xoffset = ED_CTRL3_BUTTONS_XPOS + x * ED_CTRL3_BUTTON_XSIZE; - gd_yoffset = ED_CTRL3_BUTTONS_YPOS + y * ED_CTRL3_BUTTON_YSIZE; - width = ED_CTRL3_BUTTON_XSIZE; - height = ED_CTRL3_BUTTON_YSIZE; - - gd_x1 = DOOR_GFX_PAGEX6 + gd_xoffset; - gd_x2 = DOOR_GFX_PAGEX5 + gd_xoffset; - gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_GFX_YPOS + gd_yoffset; - gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_ALT_GFX_YPOS + gd_yoffset; + x += DX; + y += DY; } else { - int x = (i - ED_NUM_CTRL1_3_BUTTONS) % ED_CTRL4_BUTTONS_HORIZ; - int y = (i - ED_NUM_CTRL1_3_BUTTONS) / ED_CTRL4_BUTTONS_HORIZ + 3; - - gd_xoffset = ED_CTRL4_BUTTONS_XPOS + x * ED_CTRL4_BUTTON_XSIZE; - gd_yoffset = ED_CTRL4_BUTTONS_YPOS + y * ED_CTRL4_BUTTON_YSIZE; - width = ED_CTRL4_BUTTON_XSIZE; - height = ED_CTRL4_BUTTON_YSIZE; - - gd_x1 = DOOR_GFX_PAGEX6 + ED_CTRL4_BUTTONS_GFX_XPOS + gd_xoffset; - gd_x2 = DOOR_GFX_PAGEX5 + ED_CTRL4_BUTTONS_GFX_XPOS + gd_xoffset; - gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL4_BUTTONS_GFX_YPOS + gd_yoffset; - gd_y2 = 0; /* no alternative graphic for these buttons */ + x += EX; + y += EY; } gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, - GDI_INFO_TEXT, control_info[i].text, - GDI_X, EX + gd_xoffset, - GDI_Y, EY + gd_yoffset, + GDI_INFO_TEXT, controlbutton_info[i].infotext, + GDI_X, x, + GDI_Y, y, GDI_WIDTH, width, GDI_HEIGHT, height, - GDI_TYPE, button_type, + GDI_TYPE, type, GDI_STATE, GD_BUTTON_UNPRESSED, GDI_RADIO_NR, radio_button_nr, GDI_CHECKED, checked, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, - GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1, - GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2, - GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, + GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, + GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1a, gd_y1a, + GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2a, gd_y2a, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, @@ -5159,40 +5385,47 @@ static void CreateControlButtons() level_editor_gadget[id] = gi; } + /* these values are not constant, but can change at runtime */ + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_UP].x = ED_SCROLL_UP_XPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_UP].y = ED_SCROLL_UP_YPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_DOWN].x = ED_SCROLL_DOWN_XPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_DOWN].y = ED_SCROLL_DOWN_YPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_LEFT].x = ED_SCROLL_LEFT_XPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_LEFT].y = ED_SCROLL_LEFT_YPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_RIGHT].x = ED_SCROLL_RIGHT_XPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_RIGHT].y = ED_SCROLL_RIGHT_YPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_UP].x = ED_SCROLL2_UP_XPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_UP].y = ED_SCROLL2_UP_YPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_DOWN].x = ED_SCROLL2_DOWN_XPOS; + scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_DOWN].y = ED_SCROLL2_DOWN_YPOS; + /* create buttons for scrolling of drawing area and element list */ for (i = 0; i < ED_NUM_SCROLLBUTTONS; i++) { int id = scrollbutton_info[i].gadget_id; - int x, y, width, height; - int gd_x1, gd_x2, gd_y1, gd_y2; - - x = scrollbutton_info[i].x; - y = scrollbutton_info[i].y; - - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; + int graphic = scrollbutton_info[i].graphic; + struct GraphicInfo *gd = &graphic_info[graphic]; + Bitmap *gd_bitmap = gd->bitmap; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int width = gd->width; + int height = gd->height; + int x = scrollbutton_pos[i].x; + int y = scrollbutton_pos[i].y; + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; if (id == GADGET_ID_SCROLL_LIST_UP || id == GADGET_ID_SCROLL_LIST_DOWN) { x += DX; y += DY; - width = ED_SCROLLBUTTON2_XSIZE; - height = ED_SCROLLBUTTON2_YSIZE; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x; - gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y; - gd_x2 = gd_x1 - ED_SCROLLBUTTON2_XSIZE; - gd_y2 = gd_y1; } else { x += SX; y += SY; - width = ED_SCROLLBUTTON_XSIZE; - height = ED_SCROLLBUTTON_YSIZE; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x; - gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y; - gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE; - gd_y2 = gd_y1; } gi = CreateGadget(GDI_CUSTOM_ID, id, @@ -5220,42 +5453,43 @@ static void CreateControlButtons() /* create buttons for element list */ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) { + int id = GADGET_ID_ELEMENTLIST_FIRST + i; + int graphic = IMG_EDITOR_PALETTE_BUTTON; + struct GraphicInfo *gd = &graphic_info[graphic]; + Bitmap *gd_bitmap = gd->bitmap; Bitmap *deco_bitmap; int deco_x, deco_y, deco_xpos, deco_ypos; - int gd_xoffset, gd_yoffset; - int gd_x1, gd_x2, gd_y; - int x = i % ED_ELEMENTLIST_BUTTONS_HORIZ; - int y = i / ED_ELEMENTLIST_BUTTONS_HORIZ; - int id = GADGET_ID_ELEMENTLIST_FIRST + i; + int gd_x1 = gd->src_x; + int gd_y1 = gd->src_y; + int gd_x2 = gd->src_x + gd->pressed_xoffset; + int gd_y2 = gd->src_y + gd->pressed_yoffset; + int xx = i % ED_ELEMENTLIST_BUTTONS_HORIZ; + int yy = i / ED_ELEMENTLIST_BUTTONS_HORIZ; + int x = DX + ED_ELEMENTLIST_XPOS + xx * gd->width; + int y = DY + ED_ELEMENTLIST_YPOS + yy * gd->height; int element = editor_elements[i]; + int tile_size = (editor.palette.tile_size >= TILESIZE ? TILESIZE : + MINI_TILESIZE); + unsigned int event_mask = GD_EVENT_RELEASED; - event_mask = GD_EVENT_RELEASED; - - gd_xoffset = ED_ELEMENTLIST_XPOS + x * ED_ELEMENTLIST_XSIZE; - gd_yoffset = ED_ELEMENTLIST_YPOS + y * ED_ELEMENTLIST_YSIZE; - - gd_x1 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS + ED_ELEMENTLIST_XSIZE; - gd_x2 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS; - gd_y = DOOR_GFX_PAGEY1 + ED_ELEMENTLIST_YPOS; - - getMiniGraphicSource(el2edimg(element), &deco_bitmap, &deco_x, &deco_y); - deco_xpos = (ED_ELEMENTLIST_XSIZE - MINI_TILEX) / 2; - deco_ypos = (ED_ELEMENTLIST_YSIZE - MINI_TILEY) / 2; + getElementListGraphicSource(element, &deco_bitmap, &deco_x, &deco_y); + deco_xpos = (gd->width - tile_size) / 2; + deco_ypos = (gd->height - tile_size) / 2; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, getElementInfoText(element), - GDI_X, DX + gd_xoffset, - GDI_Y, DY + gd_yoffset, - GDI_WIDTH, ED_ELEMENTLIST_XSIZE, - GDI_HEIGHT, ED_ELEMENTLIST_YSIZE, + GDI_X, x, + GDI_Y, y, + GDI_WIDTH, gd->width, + GDI_HEIGHT, gd->height, GDI_TYPE, GD_TYPE_NORMAL_BUTTON, GDI_STATE, GD_BUTTON_UNPRESSED, - GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y, - GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y, + GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y, GDI_DECORATION_POSITION, deco_xpos, deco_ypos, - GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY, + GDI_DECORATION_SIZE, tile_size, tile_size, GDI_DECORATION_SHIFTING, 1, 1, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, @@ -5297,37 +5531,49 @@ static void CreateCounterButtons() counterbutton_info[i].gadget_id_down : counterbutton_info[i].gadget_id_up); int gd_xoffset; - int gd_x, gd_x1, gd_x2, gd_y; + int gd_x, gd_y, gd_x1, gd_x2, gd_y1, gd_y2; int x_size, y_size; - unsigned long event_mask; + unsigned int event_mask; char infotext[max_infotext_len + 1]; event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; if (i == ED_COUNTER_ID_SELECT_LEVEL) { - int sid = (j == 0 ? - ED_SCROLLBUTTON_ID_AREA_LEFT : - ED_SCROLLBUTTON_ID_AREA_RIGHT); + int graphic = (j == 0 ? + IMG_EDITOR_BUTTON_GFX_PREV_LEVEL : + IMG_EDITOR_BUTTON_GFX_NEXT_LEVEL); + struct GraphicInfo *gd = &graphic_info[graphic]; + + gd_bitmap = gd->bitmap; event_mask |= GD_EVENT_RELEASED; - if (j == 1) - x += 2 * ED_GADGET_DISTANCE; - y += ED_GADGET_DISTANCE; + if (j == 0) + { + x = DX + editor.button.prev_level.x; + y = DY + editor.button.prev_level.y; + } + else + { + x = DX + editor.button.next_level.x; + y = DY + editor.button.next_level.y; + } - gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[sid].gd_x; - gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE; - gd_y = DOOR_GFX_PAGEY1 + scrollbutton_info[sid].gd_y; - x_size = ED_SCROLLBUTTON_XSIZE; - y_size = ED_SCROLLBUTTON_YSIZE; + gd_x1 = gd->src_x; + gd_y1 = gd->src_y; + gd_x2 = gd->src_x + gd->pressed_xoffset; + gd_y2 = gd->src_y + gd->pressed_yoffset; + x_size = gd->width; + y_size = gd->height; } else { gd_xoffset = (j == 0 ? ED_BUTTON_MINUS_XPOS : ED_BUTTON_PLUS_XPOS); gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset; gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset; - gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_COUNT_YPOS; + gd_y1 = DOOR_GFX_PAGEY1 + ED_BUTTON_COUNT_YPOS; + gd_y2 = gd_y1; x_size = ED_BUTTON_COUNT_XSIZE; y_size = ED_BUTTON_COUNT_YSIZE; } @@ -5344,8 +5590,8 @@ static void CreateCounterButtons() GDI_HEIGHT, y_size, GDI_TYPE, GD_TYPE_NORMAL_BUTTON, GDI_STATE, GD_BUTTON_UNPRESSED, - GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y, - GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y, + GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCounterButtons, @@ -5365,24 +5611,28 @@ static void CreateCounterButtons() int font_type = FONT_INPUT_1; int font_type_active = FONT_INPUT_1_ACTIVE; int gd_width = ED_WIN_COUNT_XSIZE; + int border_size = ED_BORDER_SIZE; id = counterbutton_info[i].gadget_id_text; event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; if (i == ED_COUNTER_ID_SELECT_LEVEL) { + int graphic = IMG_EDITOR_INPUT_GFX_LEVEL_NUMBER; + struct GraphicInfo *gd = &graphic_info[graphic]; + + gd_bitmap = gd->bitmap; + + x = DX + editor.input.level_number.x; + y = DY + editor.input.level_number.y; + + gd_x = gd->src_x; + gd_y = gd->src_y; + gd_width = gd->width; + border_size = gd->border_size; + font_type = FONT_LEVEL_NUMBER; -#if 1 font_type_active = FONT_LEVEL_NUMBER_ACTIVE; -#else - font_type_active = FONT_LEVEL_NUMBER; -#endif - x += 2 * ED_GADGET_DISTANCE; - y -= ED_GADGET_DISTANCE; - - gd_x = DOOR_GFX_PAGEX6 + ED_WIN_COUNT2_XPOS; - gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT2_YPOS; - gd_width = ED_WIN_COUNT2_XSIZE; } else { @@ -5404,7 +5654,7 @@ static void CreateCounterButtons() GDI_TEXT_FONT_ACTIVE, font_type_active, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y, - GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE, + GDI_BORDER_SIZE, border_size, border_size, GDI_DESIGN_WIDTH, gd_width, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, @@ -5428,10 +5678,14 @@ static void CreateDrawingAreas() { int i; + /* these values are not constant, but can change at runtime */ + drawingarea_info[ED_DRAWING_ID_DRAWING_LEVEL].area_xsize = MAX_ED_FIELDX; + drawingarea_info[ED_DRAWING_ID_DRAWING_LEVEL].area_ysize = MAX_ED_FIELDY; + for (i = 0; i < ED_NUM_DRAWING_AREAS; i++) { struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; int id = drawingarea_info[i].gadget_id; int x = SX + drawingarea_info[i].x; int y = SY + drawingarea_info[i].y; @@ -5482,7 +5736,7 @@ static void CreateTextInputGadgets() Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int gd_x, gd_y; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textinput_info[i].gadget_id; @@ -5530,7 +5784,7 @@ static void CreateTextAreaGadgets() Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int gd_x, gd_y; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textarea_info[i].gadget_id; int area_xsize = textarea_info[i].xsize; @@ -5579,7 +5833,7 @@ static void CreateSelectboxGadgets() Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int gd_x, gd_y; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = selectbox_info[i].gadget_id; int x = SX + selectbox_info[i].x; @@ -5624,9 +5878,11 @@ static void CreateSelectboxGadgets() GDI_Y, y, GDI_TYPE, GD_TYPE_SELECTBOX, GDI_SELECTBOX_OPTIONS, selectbox_info[i].options, + GDI_SELECTBOX_CHAR_UNSELECTABLE, '[', GDI_TEXT_SIZE, selectbox_info[i].size, GDI_TEXT_FONT, FONT_INPUT_1, GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE, + GDI_TEXT_FONT_UNSELECTABLE, FONT_TEXT_1, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y, GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE, @@ -5656,7 +5912,7 @@ static void CreateTextbuttonGadgets() Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int gd_x1, gd_x2, gd_y1, gd_y2; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textbutton_info[i].gadget_id; int x = SX + textbutton_info[i].x; @@ -5667,7 +5923,8 @@ static void CreateTextbuttonGadgets() event_mask = GD_EVENT_RELEASED; - if (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE) + if ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) || + (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE)) { gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_TAB_XPOS; gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_TAB_XPOS; @@ -5728,7 +5985,7 @@ static void CreateGraphicbuttonGadgets() { Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; int i; /* create buttons for scrolling of drawing area and element list */ @@ -5794,14 +6051,56 @@ static void CreateScrollbarGadgets() { int i; + /* these values are not constant, but can change at runtime */ + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].x = + SX + ED_SCROLL_HORIZONTAL_XPOS; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].y = + SY + ED_SCROLL_HORIZONTAL_YPOS; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width = + ED_SCROLL_HORIZONTAL_XSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].height = + ED_SCROLL_HORIZONTAL_YSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_x = SX; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_y = SY; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_width = SXSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_height = SYSIZE; + + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].x = + SX + ED_SCROLL_VERTICAL_XPOS; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].y = + SY + ED_SCROLL_VERTICAL_YPOS; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].width = + ED_SCROLL_VERTICAL_XSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].height = + ED_SCROLL_VERTICAL_YSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_x = SX; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_y = SY; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_width = SXSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_height = SYSIZE; + + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].x = + DX + ED_SCROLL2_VERTICAL_XPOS; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].y = + DY + ED_SCROLL2_VERTICAL_YPOS; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].width = + ED_SCROLL2_VERTICAL_XSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].height = + ED_SCROLL2_VERTICAL_YSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_x = DX; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_y = DY; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_width = DXSIZE; + scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_height = DYSIZE; + for (i = 0; i < ED_NUM_SCROLLBARS; i++) { int id = scrollbar_info[i].gadget_id; - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; + int graphic = scrollbar_info[i].graphic; + struct GraphicInfo *gd = &graphic_info[graphic]; + Bitmap *gd_bitmap = gd->bitmap; int gd_x1, gd_x2, gd_y1, gd_y2; struct GadgetInfo *gi; int items_max, items_visible, item_position; - unsigned long event_mask; + unsigned int event_mask; if (i == ED_SCROLLBAR_ID_LIST_VERTICAL) { @@ -5827,27 +6126,26 @@ static void CreateScrollbarGadgets() event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbar_info[i].gd_x; - gd_x2 = (gd_x1 - (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL ? - scrollbar_info[i].height : scrollbar_info[i].width)); - gd_y1 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y; - gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y; + gd_x1 = gd->src_x; + gd_y1 = gd->src_y; + gd_x2 = gd->src_x + gd->pressed_xoffset; + gd_y2 = gd->src_y + gd->pressed_yoffset; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, scrollbar_info[i].infotext, - GDI_X, scrollbar_info[i].x, - GDI_Y, scrollbar_info[i].y, - GDI_WIDTH, scrollbar_info[i].width, - GDI_HEIGHT, scrollbar_info[i].height, + GDI_X, scrollbar_pos[i].x, + GDI_Y, scrollbar_pos[i].y, + GDI_WIDTH, scrollbar_pos[i].width, + GDI_HEIGHT, scrollbar_pos[i].height, GDI_TYPE, scrollbar_info[i].type, GDI_SCROLLBAR_ITEMS_MAX, items_max, GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible, GDI_SCROLLBAR_ITEM_POSITION, item_position, - GDI_WHEEL_AREA_X, scrollbar_info[i].wheel_x, - GDI_WHEEL_AREA_Y, scrollbar_info[i].wheel_y, - GDI_WHEEL_AREA_WIDTH, scrollbar_info[i].wheel_width, - GDI_WHEEL_AREA_HEIGHT, scrollbar_info[i].wheel_height, + GDI_WHEEL_AREA_X, scrollbar_pos[i].wheel_x, + GDI_WHEEL_AREA_Y, scrollbar_pos[i].wheel_y, + GDI_WHEEL_AREA_WIDTH, scrollbar_pos[i].wheel_width, + GDI_WHEEL_AREA_HEIGHT, scrollbar_pos[i].wheel_height, GDI_STATE, GD_BUTTON_UNPRESSED, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, @@ -5868,7 +6166,7 @@ static void CreateCheckbuttonGadgets() { Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; int gd_x1, gd_x2, gd_x3, gd_x4, gd_y; int i; @@ -5931,7 +6229,7 @@ static void CreateRadiobuttonGadgets() { Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; struct GadgetInfo *gi; - unsigned long event_mask; + unsigned int event_mask; int gd_x1, gd_x2, gd_x3, gd_x4, gd_y; int i; @@ -5996,6 +6294,22 @@ void CreateLevelEditorGadgets() /* setting 'game_status' is needed to get the right fonts for the editor */ game_status = GAME_MODE_EDITOR; + /* these values are not constant, but can change at runtime */ + ed_fieldx = MAX_ED_FIELDX - 1; + ed_fieldy = MAX_ED_FIELDY - 1; + + num_editor_gadgets = NUM_EDITOR_GADGETS; + + // printf("::: allocating %d gadgets ...\n", num_editor_gadgets); + + level_editor_gadget = + checked_calloc(num_editor_gadgets * sizeof(struct GadgetInfo *)); + right_gadget_border = + checked_calloc(num_editor_gadgets * sizeof(int)); + + editor_el_empty = checked_calloc(ED_NUM_ELEMENTLIST_BUTTONS * sizeof(int)); + editor_el_empty_ptr = editor_el_empty; + ReinitializeElementList(); CreateControlButtons(); @@ -6019,12 +6333,19 @@ void FreeLevelEditorGadgets() { int i; - for (i = 0; i < NUM_EDITOR_GADGETS; i++) + // printf("::: freeing %d gadgets ...\n", num_editor_gadgets); + + for (i = 0; i < num_editor_gadgets; i++) { FreeGadget(level_editor_gadget[i]); level_editor_gadget[i] = NULL; } + + checked_free(level_editor_gadget); + checked_free(right_gadget_border); + + checked_free(editor_el_empty); } static void MapCounterButtons(int id) @@ -6089,6 +6410,9 @@ static void MapControlButtons() for (i = 0; i < ED_NUM_CTRL1_2_BUTTONS; i++) MapGadget(level_editor_gadget[i]); + /* map toolbox buttons (element properties button) */ + MapGadget(level_editor_gadget[ED_NUM_CTRL1_4_BUTTONS]); + /* map buttons to select elements */ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) MapGadget(level_editor_gadget[GADGET_ID_ELEMENTLIST_FIRST + i]); @@ -6346,26 +6670,27 @@ static void UnmapLevelEditorToolboxCustomGadgets() static void MapOrUnmapLevelEditorToolboxDrawingGadgets(boolean map) { - Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int i; for (i = 0; i < ED_NUM_CTRL1_BUTTONS; i++) { if (i != GADGET_ID_SINGLE_ITEMS && - i != GADGET_ID_PROPERTIES && i != GADGET_ID_PICK_ELEMENT) { struct GadgetInfo *gi = level_editor_gadget[i]; if (map) + { MapGadget(gi); + } else { + int graphic = IMG_EDITOR_NO_TOOLBOX_BUTTON; + struct GraphicInfo *gd = &graphic_info[graphic]; + UnmapGadget(gi); - BlitBitmap(gd_bitmap, drawto, - DOOR_GFX_PAGEX6 + ED_CTRL_NO_BUTTONS_GFX_XPOS, - DOOR_GFX_PAGEY1 + ED_CTRL_NO_BUTTONS_GFX_YPOS, + BlitBitmap(gd->bitmap, drawto, gd->src_x, gd->src_y, gi->width, gi->height, gi->x, gi->y); redraw_mask |= REDRAW_DOOR_3; @@ -6389,12 +6714,13 @@ static void UnmapDrawingArea(int id) UnmapGadget(level_editor_gadget[drawingarea_info[id].gadget_id]); } -static void UnmapLevelEditorWindowGadgets() +static void UnmapLevelEditorFieldGadgets() { int i; - for (i = 0; i < NUM_EDITOR_GADGETS; i++) - if (level_editor_gadget[i]->x < SX + SXSIZE) + for (i = 0; i < num_editor_gadgets; i++) + if (IN_GFX_FIELD_FULL(level_editor_gadget[i]->x, + level_editor_gadget[i]->y)) UnmapGadget(level_editor_gadget[i]); } @@ -6402,7 +6728,7 @@ void UnmapLevelEditorGadgets() { int i; - for (i = 0; i < NUM_EDITOR_GADGETS; i++) + for (i = 0; i < num_editor_gadgets; i++) UnmapGadget(level_editor_gadget[i]); } @@ -6433,9 +6759,6 @@ static boolean LevelChanged() boolean field_changed = FALSE; int x, y; - if (leveldir_current->readonly) - return FALSE; - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) if (Feld[x][y] != level.field[x][y]) @@ -6444,21 +6767,151 @@ static boolean LevelChanged() return (level.changed || field_changed); } -static boolean LevelContainsPlayer() +static boolean PrepareSavingIntoPersonalLevelSet() { - boolean player_found = FALSE; - int x, y; + static LevelDirTree *last_copied_leveldir = NULL; + static LevelDirTree *last_written_leveldir = NULL; + static int last_copied_level_nr = -1; + static int last_written_level_nr = -1; + LevelDirTree *leveldir_former = leveldir_current; + int level_nr_former = level_nr; + int new_level_nr; + + // remember last mod/save so that for current session, we write + // back to the same personal copy, asking only about overwrite. + if (leveldir_current == last_copied_leveldir && + level_nr == last_copied_level_nr) + { + // "cd" to personal level set dir (as used when writing last copy) + leveldir_current = last_written_leveldir; + level_nr = last_written_level_nr; + + return TRUE; + } + + if (!Request("This level is read only! " + "Save into personal level set?", REQ_ASK)) + return FALSE; + + // "cd" to personal level set dir (for writing copy the first time) + leveldir_current = + getTreeInfoFromIdentifier(leveldir_first, getLoginName()); + + // find unused level number + for (new_level_nr = leveldir_current->first_level; ; new_level_nr++) + { + static char *level_filename = NULL; + + setString(&level_filename, getDefaultLevelFilename(new_level_nr)); + + if (!fileExists(level_filename)) + break; + } + + last_copied_leveldir = leveldir_former; + last_copied_level_nr = level_nr_former; + + last_written_leveldir = leveldir_current; + last_written_level_nr = level_nr = new_level_nr; - return TRUE; /* !!! CURRENTLY DEACTIVATED !!! */ + return TRUE; +} + +static void ModifyLevelInfoForSavingIntoPersonalLevelSet(char *former_name) +{ + static char *filename_levelinfo = NULL, *mod_name = NULL; + FILE *file; + + // annotate this copy-and-mod in personal levelinfo.conf + setString(&filename_levelinfo, + getPath2(getCurrentLevelDir(), LEVELINFO_FILENAME)); + + if ((file = fopen(filename_levelinfo, MODE_APPEND))) + { + fprintf(file, "\n"); + fprintf(file, "# level %d was modified from:\n", level_nr); + fprintf(file, "# - previous level set name: %s\n", + former_name); + fprintf(file, "# - level within previous set: %d \"%s\"\n", + level.file_info.nr, level.name); + fprintf(file, "# - previous author: %s\n", + level.author); + fprintf(file, "# - previous save date: "); + + if (level.creation_date.src == DATE_SRC_LEVELFILE) + { + fprintf(file, "%04d-%02d-%02d\n", + level.creation_date.year, + level.creation_date.month, + level.creation_date.day); + } + else + { + fprintf(file, "not recorded\n"); + } + + fclose(file); + } - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) + if (level_nr > leveldir_current->last_level) { - if (Feld[x][y] == EL_PLAYER_1 || - Feld[x][y] == EL_SP_MURPHY) - player_found = TRUE; + static char *temp_levelinfo = NULL; + FILE *temp_file = NULL; + char line[MAX_LINE_LEN]; + + setString(&temp_levelinfo, + getPath2(getCurrentLevelDir(), + getStringCat2(LEVELINFO_FILENAME, ".new"))); + + if ((file = fopen(filename_levelinfo, MODE_READ)) && + (temp_file = fopen(temp_levelinfo, MODE_WRITE))) + { + while (fgets(line, MAX_LINE_LEN, file)) + { + if (!strPrefix(line, "levels:")) + fputs(line, temp_file); + else + fprintf(temp_file, "%-32s%d\n", "levels:", level_nr + 9); + } + } + + if (temp_file) + fclose(temp_file); + + if (file) + fclose(file); + + // needs error handling; also, ok on dos/win? + unlink(filename_levelinfo); + rename(temp_levelinfo, filename_levelinfo); } - return player_found; + // else: allow the save even if annotation failed + + // now... spray graffiti on the old level vital statistics + // user can change these; just trying to set a good baseline + + // don't truncate names for fear of making offensive or silly: + // long-named original author only recorded in levelinfo.conf. + // try to fit "Joe after Bob", "Joe (ed.)", then just "Joe" + if (!strEqual(level.author, leveldir_current->author)) + { + setString(&mod_name, getStringCat3(leveldir_current->author, + " after ", level.author)); + + if (strlen(mod_name) > MAX_LEVEL_AUTHOR_LEN) + setString(&mod_name, + getStringCat2(leveldir_current->author, " (ed.)")); + + if (strlen(mod_name) > MAX_LEVEL_AUTHOR_LEN) + setString(&mod_name, leveldir_current->author); + + strncpy(level.author, mod_name, MAX_LEVEL_AUTHOR_LEN); + + // less worried about truncation here + setString(&mod_name, getStringCat2("Mod: ", level.name)); + strncpy(level.name, mod_name, MAX_LEVEL_NAME_LEN); + } } static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY], @@ -6566,8 +7019,11 @@ static void replace_custom_element_in_settings(int element_from, if (change->target_element == element_from) change->target_element = element_to; - if (change->trigger_element == element_from) - change->trigger_element = element_to; + if (change->initial_trigger_element == element_from) + change->initial_trigger_element = element_to; + + if (change->action_element == element_from) + change->action_element = element_to; for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) @@ -6612,13 +7068,13 @@ static boolean CopyCustomElement(int element_old, int element_new, } else if (IS_CUSTOM_ELEMENT(element_old) && !IS_CUSTOM_ELEMENT(element_new)) { - Request("Please choose custom element !", REQ_CONFIRM); + Request("Please choose custom element!", REQ_CONFIRM); return FALSE; } else if (IS_GROUP_ELEMENT(element_old) && !IS_GROUP_ELEMENT(element_new)) { - Request("Please choose group element !", REQ_CONFIRM); + Request("Please choose group element!", REQ_CONFIRM); return FALSE; } @@ -6743,11 +7199,13 @@ static void CopyCustomElementPropertiesToEditor(int element) /* set deadliness selectbox help value */ custom_element.deadliness = (DONT_TOUCH(element) ? EP_DONT_TOUCH : + DONT_GET_HIT_BY(element) ? EP_DONT_GET_HIT_BY : DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH : DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO : custom_element.deadliness); custom_element_properties[EP_DEADLY] = (DONT_TOUCH(element) || + DONT_GET_HIT_BY(element) || DONT_COLLIDE_WITH(element) || DONT_RUN_INTO(element)); @@ -6841,7 +7299,7 @@ static void CopyCustomElementPropertiesToGame(int element) if (level.use_custom_template) { - if (Request("Copy and modify level template ?", REQ_ASK)) + if (Request("Copy and modify level template?", REQ_ASK)) { level.use_custom_template = FALSE; ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE], @@ -6895,6 +7353,7 @@ static void CopyCustomElementPropertiesToGame(int element) /* set deadliness property from checkbox and selectbox */ custom_element_properties[EP_DONT_RUN_INTO] = FALSE; custom_element_properties[EP_DONT_COLLIDE_WITH] = FALSE; + custom_element_properties[EP_DONT_GET_HIT_BY] = FALSE; custom_element_properties[EP_DONT_TOUCH] = FALSE; custom_element_properties[custom_element.deadliness] = custom_element_properties[EP_DEADLY]; @@ -7001,10 +7460,25 @@ void CheckElementDescriptions() Error(ERR_WARN, "no element description for element '%s'", EL_NAME(i)); } +static boolean playfield_area_changed = FALSE; + void DrawLevelEd() { + StopAnimation(); + CloseDoor(DOOR_CLOSE_ALL); - OpenDoor(DOOR_OPEN_2 | DOOR_NO_DELAY); + + FadeOut(REDRAW_FIELD); + + /* needed after playing if editor playfield area has different size */ + ClearRectangle(drawto, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); + + /* needed if different viewport properties defined for editor */ + ChangeViewportPropertiesIfNeeded(); + + playfield_area_changed = DrawingAreaChanged(); + + OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2 | DOOR_NO_DELAY); #if DEBUG CheckElementDescriptions(); @@ -7020,6 +7494,7 @@ void DrawLevelEd() else { edit_mode = ED_MODE_DRAWING; + edit_mode_levelinfo = ED_MODE_LEVELINFO_LEVEL; edit_mode_properties = ED_MODE_PROPERTIES_INFO; ResetUndoBuffer(); @@ -7028,9 +7503,14 @@ void DrawLevelEd() level_ypos = -1; } + /* needed for gadgets drawn on background (like palette scrollbar) */ + SetDoorBackgroundImage(IMG_UNDEFINED); + /* copy default editor door content to main double buffer */ - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY); + BlitBitmap(graphic_info[IMG_BACKGROUND_PALETTE].bitmap, drawto, + graphic_info[IMG_BACKGROUND_PALETTE].src_x, + graphic_info[IMG_BACKGROUND_PALETTE].src_y, + DXSIZE, DYSIZE, DX, DY); /* draw bigger door */ DrawSpecialEditorDoor(); @@ -7039,25 +7519,25 @@ void DrawLevelEd() BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, DOOR_GFX_PAGEX8, 236, EXSIZE, EYSIZE, EX, EY); - redraw_mask |= REDRAW_ALL; + // redraw_mask |= REDRAW_ALL; + + FreeLevelEditorGadgets(); + CreateLevelEditorGadgets(); ReinitializeElementList(); /* update dynamic level element list */ ReinitializeElementListButtons(); /* custom element may look different */ -#if 1 + InitElementPropertiesGfxElement(); + UnmapAllGadgets(); -#else - UnmapTapeButtons(); -#endif MapControlButtons(); DrawEditModeWindow(); - /* copy actual editor door content to door double buffer for OpenDoor() */ - BlitBitmap(drawto, bitmap_db_door, - DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1); + FadeIn(playfield_area_changed ? REDRAW_ALL : REDRAW_FIELD); - OpenDoor(DOOR_OPEN_1); + /* copy actual editor door content to door double buffer for OpenDoor() */ + BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0); } static void AdjustDrawingAreaGadgets() @@ -7095,22 +7575,20 @@ static void AdjustDrawingAreaGadgets() ed_fieldy = (ed_ysize < MAX_ED_FIELDY ? ed_ysize : max_ed_fieldy); ModifyGadget(level_editor_gadget[GADGET_ID_DRAWING_LEVEL], - GDI_WIDTH, ed_fieldx * MINI_TILEX, - GDI_HEIGHT, ed_fieldy * MINI_TILEY, GDI_AREA_SIZE, ed_fieldx, ed_fieldy, GDI_END); xoffset = (ed_fieldx == MAX_ED_FIELDX ? ED_SCROLLBUTTON_XSIZE : 0); yoffset = (ed_fieldy == MAX_ED_FIELDY ? ED_SCROLLBUTTON_YSIZE : 0); - x = SX + scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_RIGHT].x + xoffset; - y = SX + scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_DOWN].y + yoffset; + x = SX + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_RIGHT].x + xoffset; + y = SX + scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_DOWN].y + yoffset; ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_RIGHT], GDI_X, x, GDI_END); ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_DOWN], GDI_Y, y, GDI_END); - width = scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width + xoffset; - height = scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].height + yoffset; + width = scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width + xoffset; + height = scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].height + yoffset; ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL], GDI_WIDTH, width, @@ -7260,39 +7738,41 @@ static void ModifyEditorElementList() UnmapGadget(gi); - getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y); + getElementListGraphicSource(element, &gd->bitmap, &gd->x, &gd->y); + ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END); MapGadget(gi); } } +static void DrawDrawingElement(int element, struct EditorPaletteElementInfo *e) +{ + int graphic = el2edimg(element); + int tile_size = (e->tile_size >= TILESIZE ? TILESIZE : MINI_TILESIZE); + + DrawSizedGraphicExt(drawto, DX + e->x, DY + e->y, graphic, 0, tile_size); +} + static void PickDrawingElement(int button, int element) { + struct + { + int *new_element; + struct EditorPaletteElementInfo *e; + } de, drawing_elements[] = + { + { &new_element1, &editor.palette.element_left }, + { &new_element2, &editor.palette.element_middle }, + { &new_element3, &editor.palette.element_right }, + }; + if (button < 1 || button > 3) return; - if (button == 1) - { - new_element1 = element; - DrawMiniGraphicExt(drawto, - DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS, - el2edimg(new_element1)); - } - else if (button == 2) - { - new_element2 = element; - DrawMiniGraphicExt(drawto, - DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS, - el2edimg(new_element2)); - } - else - { - new_element3 = element; - DrawMiniGraphicExt(drawto, - DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS, - el2edimg(new_element3)); - } + de = drawing_elements[button - 1]; + + DrawDrawingElement((*de.new_element = element), de.e); redraw_mask |= REDRAW_DOOR_1; } @@ -7309,9 +7789,9 @@ static void DrawDrawingWindow() stick_element_properties_window = FALSE; SetMainBackgroundImage(IMG_UNDEFINED); - ClearWindow(); + ClearField(); - UnmapLevelEditorWindowGadgets(); + UnmapLevelEditorFieldGadgets(); UnmapLevelEditorToolboxCustomGadgets(); AdjustDrawingAreaGadgets(); @@ -7325,25 +7805,101 @@ static void DrawDrawingWindow() MapLevelEditorToolboxDrawingGadgets(); } -static void DrawLevelInfoWindow() +static int getTabulatorBarWidth() +{ + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO]; + struct GadgetInfo *gd_gi4 = level_editor_gadget[GADGET_ID_PROPERTIES_CHANGE]; + + return gd_gi4->x - gd_gi1->x + gd_gi4->width; +} + +static void DrawLevelInfoTabulatorGadgets() { + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL]; + struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED]; + int gd_x = gd->x + gd_gi1->border.width / 2; + int gd_y = gd->y + gd_gi1->height - 1; + Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y); + int id_first = ED_TEXTBUTTON_ID_LEVELINFO_LEVEL; + int id_last = ED_TEXTBUTTON_ID_LEVELINFO_EDITOR; int i; - stick_element_properties_window = FALSE; + for (i = id_first; i <= id_last; i++) + { + int gadget_id = textbutton_info[i].gadget_id; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + boolean active = (i != edit_mode_levelinfo); - SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); - ClearWindow(); - UnmapLevelEditorWindowGadgets(); + /* draw background line below tabulator button */ + ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1); -#if 0 - DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Level Settings"); - DrawTextSCentered(ED_SETTINGS2_YPOS, FONT_TITLE_1, "Editor Settings"); -#else - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, - "Level Settings", FONT_TITLE_1); - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS2_YPOS, - "Editor Settings", FONT_TITLE_1); -#endif + /* draw solid line below inactive tabulator buttons */ + if (!active && tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, 1, tab_color); + + ModifyGadget(gi, GDI_ACTIVE, active, GDI_END); + MapTextbuttonGadget(i); + } + + /* draw little border line below tabulator buttons */ + if (tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + 1, + getTabulatorBarWidth(), ED_GADGET_DISTANCE, + tab_color); +} + +static void DrawPropertiesTabulatorGadgets() +{ + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO]; + struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED]; + int gd_x = gd->x + gd_gi1->border.width / 2; + int gd_y = gd->y + gd_gi1->height - 1; + Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y); + int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO; + int id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG; + int i; + + /* draw two config tabulators for player elements */ + if (ELEM_IS_PLAYER(properties_element)) + id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2; + + /* draw two config and one "change" tabulator for custom elements */ + if (IS_CUSTOM_ELEMENT(properties_element)) + id_last = ED_TEXTBUTTON_ID_PROPERTIES_CHANGE; + + for (i = id_first; i <= id_last; i++) + { + int gadget_id = textbutton_info[i].gadget_id; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + boolean active = (i != edit_mode_properties); + + /* 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_CUSTOM_ELEMENT(properties_element))) + continue; + + /* draw background line below tabulator button */ + ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1); + + /* draw solid line below inactive tabulator buttons */ + if (!active && tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, 1, tab_color); + + ModifyGadget(gi, GDI_ACTIVE, active, GDI_END); + MapTextbuttonGadget(i); + } + + /* draw little border line below tabulator buttons */ + if (tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + 1, + getTabulatorBarWidth(), ED_GADGET_DISTANCE, + tab_color); +} + +static void DrawLevelInfoLevel() +{ + int i; /* draw counter gadgets */ for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++) @@ -7353,28 +7909,56 @@ static void DrawLevelInfoWindow() for (i = ED_SELECTBOX_ID_LEVEL_FIRST; i <= ED_SELECTBOX_ID_LEVEL_LAST; i++) MapSelectboxGadget(i); - /* draw checkbutton gadgets */ - for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i <= ED_CHECKBUTTON_ID_LEVEL_LAST; i++) - MapCheckbuttonGadget(i); - - /* draw radiobutton gadgets */ - for (i=ED_RADIOBUTTON_ID_LEVEL_FIRST; i <= ED_RADIOBUTTON_ID_LEVEL_LAST; i++) - MapRadiobuttonGadget(i); - /* draw text input gadgets */ for (i = ED_TEXTINPUT_ID_LEVEL_FIRST; i <= ED_TEXTINPUT_ID_LEVEL_LAST; i++) MapTextInputGadget(i); - - /* draw drawing area */ - MapDrawingArea(ED_DRAWING_ID_RANDOM_BACKGROUND); } -static void DrawCustomContentArea() +static void DrawLevelInfoEditor() { - int id = ED_DRAWING_ID_CUSTOM_CONTENT; - struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id]; - int x1 = right_gadget_border[GADGET_ID_CUSTOM_DEADLINESS]; - int x2 = right_gadget_border[GADGET_ID_CUSTOM_EXPLOSION_TYPE]; + int i; + + /* draw counter gadgets */ + for (i = ED_COUNTER_ID_EDITOR_FIRST; i <= ED_COUNTER_ID_EDITOR_LAST; i++) + MapCounterButtons(i); + + /* draw checkbutton gadgets */ + for (i=ED_CHECKBUTTON_ID_EDITOR_FIRST; i<= ED_CHECKBUTTON_ID_EDITOR_LAST; i++) + MapCheckbuttonGadget(i); + + /* draw radiobutton gadgets */ + for (i=ED_RADIOBUTTON_ID_EDITOR_FIRST; i<= ED_RADIOBUTTON_ID_EDITOR_LAST; i++) + MapRadiobuttonGadget(i); + + /* draw drawing area */ + MapDrawingArea(ED_DRAWING_ID_RANDOM_BACKGROUND); +} + +static void DrawLevelInfoWindow() +{ + stick_element_properties_window = FALSE; + + UnmapLevelEditorFieldGadgets(); + + SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); + ClearField(); + + DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Global Settings"); + + DrawLevelInfoTabulatorGadgets(); + + if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVEL) + DrawLevelInfoLevel(); + else /* (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR) */ + DrawLevelInfoEditor(); +} + +static void DrawCustomContentArea() +{ + int id = ED_DRAWING_ID_CUSTOM_CONTENT; + struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id]; + int x1 = right_gadget_border[GADGET_ID_CUSTOM_DEADLINESS]; + int x2 = right_gadget_border[GADGET_ID_CUSTOM_EXPLOSION_TYPE]; int x3 = right_gadget_border[GADGET_ID_CUSTOM_EXPLODE_IMPACT]; int xoffset = ED_DRAWINGAREA_TEXT_DISTANCE; @@ -7519,6 +8103,35 @@ static void DrawGroupElementArea(int element) MapDrawingArea(id); } +static void DrawPlayerInitialInventoryArea(int element) +{ + int player_nr = GET_PLAYER_NR(element); + int num_elements = level.initial_inventory_size[player_nr]; + int id = ED_DRAWING_ID_INVENTORY_CONTENT; + int sx = SX + drawingarea_info[id].x - MINI_TILEX / 2; + int sy = SY + drawingarea_info[id].y - MINI_TILEY / 2; + int xsize = MAX_INITIAL_INVENTORY_SIZE; + int ysize = 1; + + /* determine horizontal position to the right of specified gadget */ + if (drawingarea_info[id].gadget_id_align != GADGET_ID_NONE) + sx += (right_gadget_border[drawingarea_info[id].gadget_id_align] + + ED_DRAWINGAREA_TEXT_DISTANCE); + + /* determine horizontal offset for leading text */ + if (drawingarea_info[id].text_left != NULL) + sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left); + + UnmapDrawingArea(id); + + ModifyEditorDrawingArea(id, num_elements, 1); + + /* delete content areas in case of reducing number of them */ + DrawBackground(sx, sy, (xsize + 1) * MINI_TILEX, (ysize + 1) * MINI_TILEY); + + MapDrawingArea(id); +} + static void DrawEnvelopeTextArea(int envelope_nr) { int id = ED_TEXTAREA_ID_ENVELOPE_INFO; @@ -7566,66 +8179,13 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) int sy = SY + pad_y + start_line * font_height; int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width; int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1; + int max_lines_drawable = max_lines_per_screen - start_line; - return DrawTextFile(sx, sy, filename, font_nr, max_chars_per_line, -1, - max_lines_per_screen, -1, TRUE, FALSE, FALSE); -} - -static void DrawPropertiesTabulatorGadgets() -{ - struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO]; - struct GadgetInfo *gd_gi4 = level_editor_gadget[GADGET_ID_PROPERTIES_CHANGE]; - struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED]; - int gd_x = gd->x + gd_gi1->border.width / 2; - int gd_y = gd->y + gd_gi1->height - 1; - Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y); - int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO; - int id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG; -#if 1 -#else - int max_tabs = 4; -#endif - int i; - - /* draw additional "change" tabulator for custom elements */ - if (IS_CUSTOM_ELEMENT(properties_element)) - id_last = ED_TEXTBUTTON_ID_PROPERTIES_CHANGE; - - for (i = id_first; i <= id_last; i++) - { - int gadget_id = textbutton_info[i].gadget_id; - struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - boolean active = (i != edit_mode_properties); - - /* use "config 1" and "config 2" instead of "config" */ - if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG && - IS_CUSTOM_ELEMENT(properties_element)) - continue; - - /* draw background line below tabulator button */ - ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1); - - /* draw solid line below inactive tabulator buttons */ - if (!active && tab_color != BLACK_PIXEL) /* black => transparent */ - FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, 1, tab_color); - - ModifyGadget(gi, GDI_ACTIVE, active, GDI_END); - MapTextbuttonGadget(i); - } + if (start_line >= max_lines_per_screen) + return FALSE; -#if 1 - /* draw little border line below tabulator buttons */ - if (tab_color != BLACK_PIXEL) /* black => transparent */ - FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + 1, - gd_gi4->x - gd_gi1->x + gd_gi4->width, ED_GADGET_DISTANCE, - tab_color); -#else - /* draw little border line below tabulator buttons */ - if (tab_color != BLACK_PIXEL) /* black => transparent */ - FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + 1, - max_tabs * gd_gi1->width + (max_tabs -1) * ED_GADGET_DISTANCE, - ED_GADGET_DISTANCE, tab_color); -#endif + return DrawTextFile(sx, sy, filename, font_nr, max_chars_per_line, -1, + max_lines_drawable, 0, -1, TRUE, FALSE, FALSE); } static void DrawPropertiesInfo() @@ -7667,6 +8227,7 @@ static void DrawPropertiesInfo() { EP_DONT_RUN_INTO, "- deadly when running into" }, { EP_DONT_COLLIDE_WITH, "- deadly when colliding with" }, + { EP_DONT_GET_HIT_BY, "- deadly when getting hit by" }, { EP_DONT_TOUCH, "- deadly when touching" }, { EP_INDESTRUCTIBLE, "- indestructible" }, @@ -7688,8 +8249,8 @@ static void DrawPropertiesInfo() { -1, NULL } }; char *filename = getElementDescriptionFilename(properties_element); - char *percentage_text = "In this level:"; - char *properties_text = "Standard properties:"; + char *percentage_text = "In this level: "; + char *properties_text = "Standard properties: "; float percentage; int num_elements_in_level; int num_standard_properties = 0; @@ -7840,6 +8401,7 @@ static struct { EL_EMC_KEY_6, &level.score[SC_KEY], TEXT_COLLECTING }, { 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_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 }, @@ -7891,7 +8453,10 @@ static boolean checkPropertiesConfig(int element) HAS_EDITOR_CONTENT(element) || CAN_GROW(element) || COULD_MOVE_INTO_ACID(element) || - MAYBE_DONT_COLLIDE_WITH(element)) + MAYBE_DONT_COLLIDE_WITH(element) || + element == EL_SOKOBAN_OBJECT || + element == EL_SOKOBAN_FIELD_EMPTY || + element == EL_SOKOBAN_FIELD_FULL) return TRUE; else for (i = 0; elements_with_counter[i].element != -1; i++) @@ -7984,48 +8549,75 @@ static void DrawPropertiesConfig() /* these properties can be set for every player individually */ - drawingarea_info[ED_DRAWING_ID_START_ELEMENT].value = - &level.start_element[player_nr]; - drawingarea_info[ED_DRAWING_ID_ARTWORK_ELEMENT].value = - &level.artwork_element[player_nr]; - drawingarea_info[ED_DRAWING_ID_EXPLOSION_ELEMENT].value = - &level.explosion_element[player_nr]; - - checkbutton_info[ED_CHECKBUTTON_ID_USE_START_ELEMENT].value = - &level.use_start_element[player_nr]; - checkbutton_info[ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT].value = - &level.use_artwork_element[player_nr]; - checkbutton_info[ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT].value = - &level.use_explosion_element[player_nr]; - checkbutton_info[ED_CHECKBUTTON_ID_INITIAL_GRAVITY].value = - &level.initial_player_gravity[player_nr]; - - selectbox_info[ED_SELECTBOX_ID_PLAYER_SPEED].value = - &level.initial_player_stepsize[player_nr]; - - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID); - MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ? - ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD : - ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_GRAVITY); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); - - MapDrawingArea(ED_DRAWING_ID_START_ELEMENT); - MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT); - MapDrawingArea(ED_DRAWING_ID_EXPLOSION_ELEMENT); - - MapSelectboxGadget(ED_SELECTBOX_ID_PLAYER_SPEED); + if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_1) + { + drawingarea_info[ED_DRAWING_ID_START_ELEMENT].value = + &level.start_element[player_nr]; + drawingarea_info[ED_DRAWING_ID_ARTWORK_ELEMENT].value = + &level.artwork_element[player_nr]; + drawingarea_info[ED_DRAWING_ID_EXPLOSION_ELEMENT].value = + &level.explosion_element[player_nr]; + + checkbutton_info[ED_CHECKBUTTON_ID_USE_START_ELEMENT].value = + &level.use_start_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT].value = + &level.use_artwork_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT].value = + &level.use_explosion_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_INITIAL_GRAVITY].value = + &level.initial_player_gravity[player_nr]; + + selectbox_info[ED_SELECTBOX_ID_PLAYER_SPEED].value = + &level.initial_player_stepsize[player_nr]; + + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID); + MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ? + ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD : + ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_SHIFTED_RELOCATION); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_GRAVITY); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); + + MapDrawingArea(ED_DRAWING_ID_START_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_EXPLOSION_ELEMENT); + + MapSelectboxGadget(ED_SELECTBOX_ID_PLAYER_SPEED); + } + else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2) + { + drawingarea_info[ED_DRAWING_ID_INVENTORY_CONTENT].value = + &level.initial_inventory_content[player_nr][0]; + + counterbutton_info[ED_COUNTER_ID_INVENTORY_SIZE].value = + &level.initial_inventory_size[player_nr]; + + checkbutton_info[ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY].value = + &level.use_initial_inventory[player_nr]; + + /* draw checkbutton gadgets */ + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY); + + /* draw counter gadgets */ + MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE); + + /* draw drawing area gadgets */ + DrawPlayerInitialInventoryArea(properties_element); + } } if (IS_GEM(properties_element)) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS); + if (properties_element == EL_EM_DYNAMITE) + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE); + if (COULD_MOVE_INTO_ACID(properties_element) && !ELEM_IS_PLAYER(properties_element) && (!IS_CUSTOM_ELEMENT(properties_element) || @@ -8058,6 +8650,11 @@ static void DrawPropertiesConfig() MapCheckbuttonGadget(ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE); } + if (properties_element == EL_SOKOBAN_OBJECT || + properties_element == EL_SOKOBAN_FIELD_EMPTY || + properties_element == EL_SOKOBAN_FIELD_FULL) + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN); + if (IS_ENVELOPE(properties_element)) { int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE; @@ -8172,6 +8769,7 @@ static void DrawPropertiesChangeDrawingAreas() { MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_TARGET); MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER); + MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_ACTION); DrawCustomChangeContentArea(); } @@ -8226,7 +8824,7 @@ static void DrawEditorElementAnimation(int x, int y) ANIM_MODE(graphic) == ANIM_CE_SCORE ? custom_element.collect_score_initial : FrameCounter); - DrawGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING); + DrawFixedGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING); } static void DrawEditorElementName(int x, int y, int element) @@ -8282,17 +8880,23 @@ static void DrawPropertiesWindow() stick_element_properties_window = FALSE; /* make sure that previous properties edit mode exists for this element */ + if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG_2 && + !IS_CUSTOM_ELEMENT(properties_element)) + edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_2; + if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG && + !ELEM_IS_PLAYER(properties_element) && !IS_CUSTOM_ELEMENT(properties_element)) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG; if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG && - IS_CUSTOM_ELEMENT(properties_element)) + (ELEM_IS_PLAYER(properties_element) || + IS_CUSTOM_ELEMENT(properties_element))) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_1; CopyElementPropertiesToEditor(properties_element); - UnmapLevelEditorWindowGadgets(); + UnmapLevelEditorFieldGadgets(); UnmapLevelEditorToolboxDrawingGadgets(); UnmapLevelEditorToolboxCustomGadgets(); @@ -8301,14 +8905,9 @@ static void DrawPropertiesWindow() MapLevelEditorToolboxCustomGadgets(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); - ClearWindow(); + ClearField(); -#if 0 DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Element Settings"); -#else - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, - "Element Settings", FONT_TITLE_1); -#endif FrameCounter = 0; /* restart animation frame counter */ @@ -8335,8 +8934,12 @@ static void DrawPropertiesWindow() static void UpdateCustomElementGraphicGadgets() { + struct ElementInfo *ei = &element_info[properties_element]; int i; + ei->gfx_element = (ei->use_gfx_element ? ei->gfx_element_initial : + properties_element); + ModifyEditorElementList(); RedrawDrawingElements(); @@ -8350,7 +8953,7 @@ static void UpdateCustomElementGraphicGadgets() } } -static int getDirectionFromTube(int element) +static int getOpenDirectionFromTube(int element) { switch (element) { @@ -8370,7 +8973,7 @@ static int getDirectionFromTube(int element) return MV_NONE; } -static int getTubeFromDirection(int direction) +static int getTubeFromOpenDirection(int direction) { switch (direction) { @@ -8396,14 +8999,209 @@ static int getTubeFromDirection(int direction) return EL_EMPTY; } -static int getTubeFromDirectionNotEmpty(int direction, int element_old) +static int getTubeFromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getTubeFromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromBelt(int element) +{ + int belt_dir = getBeltDirFromBeltElement(element); + + return (belt_dir == MV_LEFT ? MV_RIGHT : + belt_dir == MV_RIGHT ? MV_LEFT : + belt_dir == MV_NONE ? MV_HORIZONTAL : belt_dir); +} + +static int getBeltFromNrAndOpenDirection(int nr, int direction) +{ + int belt_dir = (direction == MV_LEFT ? MV_RIGHT : + direction == MV_RIGHT ? MV_LEFT : + direction == MV_HORIZONTAL ? MV_NONE : direction); + + if (direction == MV_NONE) + return EL_EMPTY; + + return getBeltElementFromBeltNrAndBeltDir(nr, belt_dir); +} + +static int getBeltFromNrAndOpenDirectionNotEmpty(int nr, int direction, + int element_old) +{ + int element_new = getBeltFromNrAndOpenDirection(nr, direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromPool(int element) +{ + switch (element) + { + case EL_ACID_POOL_TOPLEFT: return (MV_DOWN | MV_RIGHT); + case EL_ACID_POOL_TOPRIGHT: return (MV_DOWN | MV_LEFT); + case EL_ACID_POOL_BOTTOMLEFT: return (MV_UP | MV_RIGHT); + case EL_ACID_POOL_BOTTOMRIGHT: return (MV_UP | MV_LEFT); + case EL_ACID_POOL_BOTTOM: return (MV_HORIZONTAL | MV_UP); + case EL_ACID: return (MV_HORIZONTAL | MV_DOWN); + } + + return MV_NONE; +} + +static int getPoolFromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_DOWN | MV_RIGHT): return EL_ACID_POOL_TOPLEFT; + case (MV_DOWN | MV_LEFT): return EL_ACID_POOL_TOPRIGHT; + case (MV_UP | MV_RIGHT): return EL_ACID_POOL_BOTTOMLEFT; + case (MV_UP | MV_LEFT): return EL_ACID_POOL_BOTTOMRIGHT; + case (MV_HORIZONTAL | MV_UP): return EL_ACID_POOL_BOTTOM; + case (MV_HORIZONTAL | MV_DOWN): return EL_ACID; + } + + return EL_EMPTY; +} + +static int getPoolFromOpenDirectionExt(int direction, int help_element) +{ + int element = getPoolFromOpenDirection(direction); + int help_direction = getOpenDirectionFromPool(help_element); + + if (element == EL_EMPTY) + { + int help_direction_vertical = help_direction & MV_VERTICAL; + + element = getPoolFromOpenDirection(direction | help_direction_vertical); + } + + if (element == EL_EMPTY) + { + int help_direction_horizontal = help_direction & MV_HORIZONTAL; + + element = getPoolFromOpenDirection(direction | help_direction_horizontal); + } + + return element; +} + +static int getPoolFromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getPoolFromOpenDirectionExt(direction, element_old); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromPillar(int element) +{ + switch (element) + { + case EL_EMC_WALL_1: return (MV_DOWN); + case EL_EMC_WALL_2: return (MV_VERTICAL); + case EL_EMC_WALL_3: return (MV_UP); + } + + return MV_NONE; +} + +static int getPillarFromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_DOWN): return EL_EMC_WALL_1; + case (MV_VERTICAL): return EL_EMC_WALL_2; + case (MV_UP): return EL_EMC_WALL_3; + } + + return EL_EMPTY; +} + +static int getPillarFromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getPillarFromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromSteel2(int element) +{ + switch (element) + { + case EL_DC_STEELWALL_2_LEFT: return (MV_RIGHT); + case EL_DC_STEELWALL_2_RIGHT: return (MV_LEFT); + case EL_DC_STEELWALL_2_TOP: return (MV_DOWN); + case EL_DC_STEELWALL_2_BOTTOM: return (MV_UP); + case EL_DC_STEELWALL_2_HORIZONTAL: return (MV_HORIZONTAL); + case EL_DC_STEELWALL_2_VERTICAL: return (MV_VERTICAL); + case EL_DC_STEELWALL_2_MIDDLE: return (MV_ANY_DIRECTION); + case EL_DC_STEELWALL_2_SINGLE: return (MV_NONE); + } + + return MV_NONE; +} + +static int getSteel2FromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_RIGHT): return EL_DC_STEELWALL_2_LEFT; + case (MV_LEFT): return EL_DC_STEELWALL_2_RIGHT; + case (MV_DOWN): return EL_DC_STEELWALL_2_TOP; + case (MV_UP): return EL_DC_STEELWALL_2_BOTTOM; + case (MV_HORIZONTAL): return EL_DC_STEELWALL_2_HORIZONTAL; + case (MV_VERTICAL): return EL_DC_STEELWALL_2_VERTICAL; + case (MV_ANY_DIRECTION): return EL_DC_STEELWALL_2_MIDDLE; + case (MV_NONE): return EL_DC_STEELWALL_2_SINGLE; + } + + return EL_EMPTY; +} + +static int getSteel2FromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getSteel2FromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromChip(int element) +{ + switch (element) + { + case EL_SP_CHIP_SINGLE: return (MV_NONE); + case EL_SP_CHIP_LEFT: return (MV_RIGHT); + case EL_SP_CHIP_RIGHT: return (MV_LEFT); + case EL_SP_CHIP_TOP: return (MV_DOWN); + case EL_SP_CHIP_BOTTOM: return (MV_UP); + } + + return MV_NONE; +} + +static int getChipFromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_NONE): return EL_SP_CHIP_SINGLE; + case (MV_LEFT): return EL_SP_CHIP_RIGHT; + case (MV_RIGHT): return EL_SP_CHIP_LEFT; + case (MV_UP): return EL_SP_CHIP_BOTTOM; + case (MV_DOWN): return EL_SP_CHIP_TOP; + } + + return EL_EMPTY; +} + +static int getChipFromOpenDirectionNotEmpty(int direction, int element_old) { - int element_new = getTubeFromDirection(direction); + int element_new = getChipFromOpenDirection(direction); return (element_new != EL_EMPTY ? element_new : element_old); } -static int getMinimalConnectedTube(int x, int y) +static int getClosedTube(int x, int y) { static int xy[4][2] = { @@ -8413,69 +9211,432 @@ static int getMinimalConnectedTube(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int tube_direction_old = getDirectionFromTube(element_old); - int tube_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromTube(element_old); + int direction_new = MV_NONE; int i; - for (i = 0; i < NUM_DIRECTIONS; i++) - { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; - int dir = MV_DIR_FROM_BIT(i); - int dir_opposite = MV_DIR_OPPOSITE(dir); + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_TUBE(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromTube(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getTubeFromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedBelt(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int nr = getBeltNrFromBeltElement(element_old); + int direction_old = getOpenDirectionFromBelt(element_old); + int direction_new = MV_NONE; + int i; + + for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_BELT(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromBelt(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getBeltFromNrAndOpenDirection(nr, direction_new); +} + +static int getClosedPool(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromPool(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && + IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromPool(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getPoolFromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedPillar(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromPillar(element_old); + int direction_new = MV_NONE; + int i; + + for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_EMC_PILLAR(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromPillar(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getPillarFromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedSteel2(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromSteel2(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_DC_STEELWALL_2(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromSteel2(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getSteel2FromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedChip(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromChip(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_SP_CHIP(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromChip(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getChipFromOpenDirectionNotEmpty(direction_new, element_old); +} + +static void SetElementSimple(int x, int y, int element, boolean change_level) +{ + int sx = x - level_xpos; + int sy = y - level_ypos; + + IntelliDrawBuffer[x][y] = element; + + if (change_level) + Feld[x][y] = element; + + if (IN_ED_FIELD(sx, sy)) + DrawMiniElement(sx, sy, element); +} + +static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, + int x2, int y2, int *element2, + int (*close_function)(int, int), + boolean change_level) +{ + /* set neighbour elements to newly determined connections */ + SetElementSimple(x1, y1, *element1, change_level); + SetElementSimple(x2, y2, *element2, change_level); + + /* remove all open connections of neighbour elements */ + *element1 = close_function(x1, y1); + *element2 = close_function(x2, y2); + + /* set neighbour elements to new, minimized connections */ + SetElementSimple(x1, y1, *element1, change_level); + SetElementSimple(x2, y2, *element2, change_level); +} + +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 } + }; + static int last_x = -1; + static int last_y = -1; + int old_element = IntelliDrawBuffer[x][y]; + + if (new_element == EL_UNDEFINED) + { + last_x = -1; + last_y = -1; + + return; + } + + if (IS_TUBE(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if old element is of same kind, keep all existing directions */ + if (IS_TUBE(old_element)) + direction |= getOpenDirectionFromTube(old_element); + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_TUBE(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromTube(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getTubeFromOpenDirection(last_direction_new); + + direction |= dir; + } + } + + new_element = getTubeFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedTube, change_level); + } + else if (IS_BELT(new_element)) + { + int belt_nr = getBeltNrFromBeltElement(new_element); + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if old element is of same kind, keep all existing directions */ + if (IS_BELT(old_element)) + direction |= getOpenDirectionFromBelt(old_element); + + for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_BELT(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_belt_nr = getBeltNrFromBeltElement(last_element_old); + int last_direction_old = getOpenDirectionFromBelt(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getBeltFromNrAndOpenDirection(last_belt_nr, + last_direction_new); + direction |= dir; + } + } + + new_element = getBeltFromNrAndOpenDirectionNotEmpty(belt_nr, direction, + new_element); + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedBelt, change_level); + } + else if (IS_ACID_POOL_OR_ACID(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if old element is of same kind, keep all existing directions */ + if (IS_ACID_POOL_OR_ACID(old_element)) + direction |= getOpenDirectionFromPool(old_element); + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromPool(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getPoolFromOpenDirection(last_direction_new); + + direction |= dir; + } + } + + /* special corrections needed for intuitively correct acid pool drawing */ + if (last_element_new == EL_EMPTY) + last_element_new = new_element; + else if (last_element_new != EL_UNDEFINED) + new_element = last_element_new; + + new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedPool, change_level); + } + else if (IS_EMC_PILLAR(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if old element is of same kind, keep all existing directions */ + if (IS_EMC_PILLAR(old_element)) + direction |= getOpenDirectionFromPillar(old_element); + + for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_EMC_PILLAR(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromPillar(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getPillarFromOpenDirection(last_direction_new); - if (IN_LEV_FIELD(xx, yy) && IS_TUBE(IntelliDrawBuffer[xx][yy]) && - (tube_direction_old & dir) && - (getDirectionFromTube(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - tube_direction_new |= dir; + direction |= dir; + } + } + + new_element = getPillarFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedPillar, change_level); } + else if (IS_DC_STEELWALL_2(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; - return getTubeFromDirectionNotEmpty(tube_direction_new, element_old); -} + /* if old element is of same kind, keep all existing directions */ + if (IS_DC_STEELWALL_2(old_element)) + direction |= getOpenDirectionFromSteel2(old_element); -static void SetElementSimple(int x, int y, int element, boolean change_level) -{ - if (change_level) - Feld[x][y] = element; + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; - IntelliDrawBuffer[x][y] = element; + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromSteel2(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; - if (IN_ED_FIELD(x - level_xpos, y - level_ypos)) - DrawMiniElement(x - level_xpos, y - level_ypos, element); -} + last_element_new = getSteel2FromOpenDirection(last_direction_new); -static void SetElementIntelliDraw(int x, int y, int new_element, - boolean change_level) -{ - static int last_x = -1; - static int last_y = -1; - int old_element = IntelliDrawBuffer[x][y]; + direction |= dir; + } + } - if (new_element == EL_UNDEFINED) - { - last_x = -1; - last_y = -1; + new_element = getSteel2FromOpenDirectionNotEmpty(direction, new_element); - return; + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedSteel2, change_level); } - - if (IS_TUBE(new_element)) + else if (IS_SP_CHIP(new_element)) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; - boolean last_element_is_neighbour = FALSE; - int last_element_new; - int tube_direction = MV_NONE; + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; int i; - /* if existing element is tube, keep all existing tube directions */ - if (IS_TUBE(old_element)) - tube_direction |= getDirectionFromTube(old_element); + /* (do not keep existing directions, regardless of kind of old element) */ for (i = 0; i < NUM_DIRECTIONS; i++) { @@ -8483,37 +9644,256 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int yy = y + xy[i][1]; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && - IS_TUBE(IntelliDrawBuffer[last_x][last_y])) + IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y])) { int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); int last_element_old = IntelliDrawBuffer[last_x][last_y]; - int last_direction_old = getDirectionFromTube(last_element_old); + int last_direction_old = getOpenDirectionFromChip(last_element_old); int last_direction_new = last_direction_old | dir_opposite; - last_element_new = getTubeFromDirection(last_direction_new); - last_element_is_neighbour = TRUE; - - tube_direction |= dir; + if (last_direction_old == MV_NONE) + { + last_element_new = getChipFromOpenDirection(last_direction_new); + direction |= dir; + } + else if (last_direction_old & (dir | dir_opposite)) + { + direction |= MV_DIR_OPPOSITE(last_direction_old); + } + else + { + direction |= MV_DIR_OPPOSITE(dir); + } } } - new_element = getTubeFromDirectionNotEmpty(tube_direction, new_element); + new_element = getChipFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedChip, change_level); + } + else if (IS_SP_HARDWARE_BASE(new_element)) + { + int nr = GetSimpleRandom(6); + + new_element = (nr == 0 ? EL_SP_HARDWARE_BASE_1 : + nr == 1 ? EL_SP_HARDWARE_BASE_2 : + nr == 2 ? EL_SP_HARDWARE_BASE_3 : + nr == 3 ? EL_SP_HARDWARE_BASE_4 : + nr == 4 ? EL_SP_HARDWARE_BASE_5 : EL_SP_HARDWARE_BASE_6); + } + else if (new_element == EL_SP_HARDWARE_GREEN || + new_element == EL_SP_HARDWARE_BLUE || + new_element == EL_SP_HARDWARE_RED) + { + int nr = GetSimpleRandom(3); + + new_element = (nr == 0 ? EL_SP_HARDWARE_GREEN : + nr == 1 ? EL_SP_HARDWARE_BLUE : EL_SP_HARDWARE_RED); + } + else if (IS_GROUP_ELEMENT(new_element)) + { + boolean connected_drawing = FALSE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + 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)) + connected_drawing = TRUE; + } + + if (!connected_drawing) + ResolveGroupElement(new_element); + + new_element = GetElementFromGroupElement(new_element); + } + else if (IS_BELT_SWITCH(old_element)) + { + int belt_nr = getBeltNrFromBeltSwitchElement(old_element); + int belt_dir = getBeltDirFromBeltSwitchElement(old_element); + + belt_dir = (belt_dir == MV_LEFT ? MV_NONE : + belt_dir == MV_NONE ? MV_RIGHT : MV_LEFT); + + new_element = getBeltSwitchElementFromBeltNrAndBeltDir(belt_nr, belt_dir); + } + else + { + static int swappable_elements[][2] = + { + { EL_EXIT_CLOSED, EL_EXIT_OPEN }, + { EL_DYNAMITE, EL_DYNAMITE_ACTIVE }, + { EL_EM_DYNAMITE, EL_EM_DYNAMITE_ACTIVE }, + { EL_QUICKSAND_EMPTY, EL_QUICKSAND_FULL }, + { EL_EMERALD, EL_WALL_EMERALD }, + { EL_EMERALD_YELLOW, EL_WALL_EMERALD_YELLOW }, + { EL_EMERALD_RED, EL_WALL_EMERALD_RED }, + { EL_EMERALD_PURPLE, EL_WALL_EMERALD_PURPLE }, + { EL_DIAMOND, EL_WALL_DIAMOND }, + { EL_BD_DIAMOND, EL_WALL_BD_DIAMOND }, + { EL_GATE_1, EL_GATE_1_GRAY }, + { EL_GATE_2, EL_GATE_2_GRAY }, + { EL_GATE_3, EL_GATE_3_GRAY }, + { EL_GATE_4, EL_GATE_4_GRAY }, + { EL_EM_GATE_1, EL_EM_GATE_1_GRAY }, + { EL_EM_GATE_2, EL_EM_GATE_2_GRAY }, + { EL_EM_GATE_3, EL_EM_GATE_3_GRAY }, + { EL_EM_GATE_4, EL_EM_GATE_4_GRAY }, + { EL_EMC_GATE_5, EL_EMC_GATE_5_GRAY }, + { EL_EMC_GATE_6, EL_EMC_GATE_6_GRAY }, + { EL_EMC_GATE_7, EL_EMC_GATE_7_GRAY }, + { EL_EMC_GATE_8, EL_EMC_GATE_8_GRAY }, + { EL_DC_GATE_WHITE, EL_DC_GATE_WHITE_GRAY }, + { EL_TIME_ORB_EMPTY, EL_TIME_ORB_FULL }, + { EL_LAMP, EL_LAMP_ACTIVE }, + { EL_SOKOBAN_FIELD_EMPTY, EL_SOKOBAN_FIELD_FULL }, + { EL_SP_BASE, EL_SP_BUGGY_BASE }, + { EL_PEARL, EL_WALL_PEARL }, + { EL_CRYSTAL, EL_WALL_CRYSTAL }, + { EL_TIMEGATE_CLOSED, EL_TIMEGATE_OPEN }, + { EL_SWITCHGATE_CLOSED, EL_SWITCHGATE_OPEN }, + { EL_SWITCHGATE_SWITCH_UP, EL_SWITCHGATE_SWITCH_DOWN }, + { EL_DC_SWITCHGATE_SWITCH_UP, EL_DC_SWITCHGATE_SWITCH_DOWN }, + { EL_LIGHT_SWITCH, EL_LIGHT_SWITCH_ACTIVE }, + { EL_LANDMINE, EL_DC_LANDMINE }, + { EL_SHIELD_NORMAL, EL_SHIELD_DEADLY }, + { EL_STEEL_EXIT_CLOSED, EL_STEEL_EXIT_OPEN }, + { 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 }, + + { -1, -1 }, + }; + static int rotatable_elements[][4] = + { + { + EL_BUG_UP, + EL_BUG_RIGHT, + 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 + }, + + { + -1, + -1, + -1, + -1, + }, + }; + int i, j; - /* reduce connections of neighbour tube elements to minimal connections */ - if (last_element_is_neighbour) + for (i = 0; swappable_elements[i][0] != -1; i++) { - /* set neighbour tube elements to newly determined tube connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); + int element1 = swappable_elements[i][0]; + int element2 = swappable_elements[i][1]; - /* remove all open tube connections of neighbour tube elements */ - new_element = getMinimalConnectedTube(x, y); - last_element_new = getMinimalConnectedTube(last_x, last_y); + if (old_element == element1 || old_element == element2) + new_element = (old_element == element1 ? element2 : element1); + } + + for (i = 0; rotatable_elements[i][0] != -1; i++) + { + for (j = 0; j < 4; j++) + { + int element = rotatable_elements[i][j]; - /* set neighbour tube elements to new, minimized tube connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); + 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] : + old_element); + } } } @@ -8531,100 +9911,80 @@ static void ResetIntelliDraw() for (y = 0; y < lev_fieldy; y++) IntelliDrawBuffer[x][y] = Feld[x][y]; - SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE); + SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1); } -static void SetElementExt(int x, int y, int element, boolean change_level) +static void SetElementExt(int x, int y, int element, boolean change_level, + int button) { if (element < 0) - element = IntelliDrawBuffer[x][y] = Feld[x][y]; - - if (GetKeyModState() & KMOD_Shift) - SetElementIntelliDraw(x, y, element, change_level); + SetElementSimple(x, y, Feld[x][y], change_level); + else if (GetKeyModState() & KMOD_Shift) + SetElementIntelliDraw(x, y, element, change_level, button); else SetElementSimple(x, y, element, change_level); } static void SetElement(int x, int y, int element) { - SetElementExt(x, y, element, TRUE); + SetElementExt(x, y, element, TRUE, -1); } -static void DrawLineElement(int sx, int sy, int element, boolean change_level) +static void SetElementButton(int x, int y, int element, int button) { -#if 1 - int lx = sx + level_xpos; - int ly = sy + level_ypos; - - SetElementExt(lx, ly, element, change_level); - -#else + SetElementExt(x, y, element, TRUE, button); +} +static void DrawLineElement(int sx, int sy, int element, boolean change_level) +{ int lx = sx + level_xpos; int ly = sy + level_ypos; - int element_new = (element < 0 ? Feld[lx][ly] : element); - - DrawMiniElement(sx, sy, element_new); - if (change_level) - Feld[lx][ly] = element; -#endif + SetElementExt(lx, ly, element, change_level, -1); } static void DrawLine(int from_x, int from_y, int to_x, int to_y, int element, boolean change_level) { + int xsize = ABS(to_x - from_x); + int ysize = ABS(to_y - from_y); + int dx = (to_x < from_x ? -1 : +1); + int dy = (to_y < from_y ? -1 : +1); + int i; + if (from_y == to_y) /* horizontal line */ { - int x; - int y = from_y; - - if (from_x > to_x) - swap_numbers(&from_x, &to_x); - - for (x = from_x; x <= to_x; x++) - DrawLineElement(x, y, element, change_level); + for (i = 0; i <= xsize; i++) + DrawLineElement(from_x + i * dx, from_y, element, change_level); } else if (from_x == to_x) /* vertical line */ { - int x = from_x; - int y; - - if (from_y > to_y) - swap_numbers(&from_y, &to_y); - - for (y = from_y; y <= to_y; y++) - DrawLineElement(x, y, element, change_level); + for (i = 0; i <= ysize; i++) + DrawLineElement(from_x, from_y + i * dy, element, change_level); } else /* diagonal line */ { - int len_x = ABS(to_x - from_x); - int len_y = ABS(to_y - from_y); - int x, y; - - if (len_y < len_x) /* a < 1 */ + if (ysize < xsize) /* a < 1 */ { - float a = (float)len_y / (float)len_x; - - if (from_x > to_x) - swap_number_pairs(&from_x, &from_y, &to_x, &to_y); + float a = (float)ysize / (float)xsize; - for (x = 0; x <= len_x; x++) + for (i = 0; i <= xsize; i++) { - y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1); + int x = dx * i; + int y = dy * (int)(a * i + 0.5); + DrawLineElement(from_x + x, from_y + y, element, change_level); } } else /* a >= 1 */ { - float a = (float)len_x / (float)len_y; - - if (from_y > to_y) - swap_number_pairs(&from_x, &from_y, &to_x, &to_y); + float a = (float)xsize / (float)ysize; - for (y = 0; y <= len_y; y++) + for (i = 0; i <= ysize; i++) { - x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1); + int x = dx * (int)(a * i + 0.5); + int y = dy * i; + DrawLineElement(from_x + x, from_y + y, element, change_level); } } @@ -8771,7 +10131,7 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, int button, int mode) { - static short brush_buffer[MAX_ED_FIELDX][MAX_ED_FIELDY]; + static short brush_buffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static int brush_width, brush_height; static int last_cursor_x = -1, last_cursor_y = -1; static boolean delete_old_brush; @@ -8802,7 +10162,10 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, else if (element >= NUM_FILE_ELEMENTS) element_mapped = EL_UNKNOWN; - printf("%c%03d", (mode == CB_DUMP_BRUSH ? '`' : '¸'), element_mapped); + // dump brush as level sketch text for the R'n'D forum: + // - large tiles: `xxx (0x60 ASCII) + // - small tiles: ¸xxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8) + printf("%s%03d", (mode == CB_DUMP_BRUSH ? "`" : "¸"), element_mapped); } printf("\n"); @@ -8952,7 +10315,7 @@ static void FloodFill(int from_x, int from_y, int fill_element) static int DrawLevelText(int sx, int sy, char letter, int mode) { static short delete_buffer[MAX_LEV_FIELDX]; - static int start_sx, start_sy; + static int start_sx; static int last_sx, last_sy; static boolean typing = FALSE; int letter_element = EL_CHAR_ASCII0 + letter; @@ -8961,11 +10324,11 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) /* map lower case letters to upper case and convert special characters */ if (letter >= 'a' && letter <= 'z') letter_element = EL_CHAR_ASCII0 + letter + (int)('A' - 'a'); - else if (letter == 'ä' || letter == 'Ä') + else if (letter == CHAR_BYTE_UMLAUT_a || letter == CHAR_BYTE_UMLAUT_A) letter_element = EL_CHAR_AUMLAUT; - else if (letter == 'ö' || letter == 'Ö') + else if (letter == CHAR_BYTE_UMLAUT_o || letter == CHAR_BYTE_UMLAUT_O) letter_element = EL_CHAR_OUMLAUT; - else if (letter == 'ü' || letter == 'Ü') + else if (letter == CHAR_BYTE_UMLAUT_u || letter == CHAR_BYTE_UMLAUT_U) letter_element = EL_CHAR_UUMLAUT; else if (letter == '^') letter_element = EL_CHAR_COPYRIGHT; @@ -8994,8 +10357,9 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) DrawLevelText(0, 0, 0, TEXT_END); typing = TRUE; - start_sx = last_sx = sx; - start_sy = last_sy = sy; + start_sx = sx; + last_sx = sx; + last_sy = sy; DrawLevelText(sx, sy, 0, TEXT_SETCURSOR); break; @@ -9009,6 +10373,10 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_WRITECHAR: if (letter_element >= EL_CHAR_START && letter_element <= EL_CHAR_END) { + if (new_element1 >= EL_STEEL_CHAR_START && + 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; @@ -9125,6 +10493,8 @@ static void RandomPlacement(int new_element) int num_percentage, num_elements; int x, y; + ResetIntelliDraw(); + /* determine number of free positions for randomly placing the new element */ for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) { @@ -9148,20 +10518,20 @@ static void RandomPlacement(int new_element) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) if (free_position[x][y]) - Feld[x][y] = new_element; + SetElement(x, y, new_element); } else { while (num_elements > 0) { - x = RND(lev_fieldx); - y = RND(lev_fieldy); + x = GetSimpleRandom(lev_fieldx); + y = GetSimpleRandom(lev_fieldy); /* don't place element at the same position twice */ if (free_position[x][y]) { free_position[x][y] = FALSE; - Feld[x][y] = new_element; + SetElement(x, y, new_element); num_elements--; } } @@ -9280,10 +10650,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !inside_drawing_area) DeleteBrushFromCursor(); - -#if 0 - ResetIntelliDraw(); -#endif } if (!button || button_release_event) @@ -9291,50 +10657,20 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (draw_with_brush) { -#if 0 - if (!button_release_event) -#endif - CopyBrushToLevel(sx, sy, button); + CopyBrushToLevel(sx, sy, button); } -#if 1 else -#else - else if (new_element != Feld[lx][ly]) -#endif { if (new_element == EL_PLAYER_1) { /* remove player at old position */ for (y = 0; y < lev_fieldy; y++) - { for (x = 0; x < lev_fieldx; x++) - { if (Feld[x][y] == EL_PLAYER_1) - { -#if 1 SetElement(x, y, EL_EMPTY); -#else - Feld[x][y] = EL_EMPTY; -#if 1 - if (IN_ED_FIELD(x - level_xpos, y - level_ypos)) - DrawMiniElement(x - level_xpos, y - level_ypos, EL_EMPTY); -#else - if (x - level_xpos >= 0 && x - level_xpos < ed_fieldx && - y - level_ypos >= 0 && y - level_ypos < ed_fieldy) - DrawMiniElement(x - level_xpos, y - level_ypos, EL_EMPTY); -#endif -#endif - } - } - } } -#if 1 - SetElement(lx, ly, new_element); -#else - Feld[lx][ly] = new_element; - DrawMiniElement(sx, sy, new_element); -#endif + SetElementButton(lx, ly, new_element, button); } } else @@ -9348,10 +10684,10 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) gi->y + sy * MINI_TILEY, el2edimg(new_element)); else - DrawGraphicExt(drawto, - gi->x + sx * TILEX, - gi->y + sy * TILEY, - el2img(new_element), 0); + DrawFixedGraphicExt(drawto, + gi->x + sx * TILEX, + gi->y + sy * TILEY, + el2img(new_element), 0); if (id == GADGET_ID_CUSTOM_GRAPHIC) new_element = GFX_ELEMENT(new_element); @@ -9497,7 +10833,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi) if ((level_changed && pressed) || (!level_changed && released)) return; - if (level_changed && !Request("Level has changed ! Discard changes ?", + if (level_changed && !Request("Level has changed! Discard changes?", REQ_ASK)) { if (gadget_id == counterbutton_info[counter_id].gadget_id_text) @@ -9515,7 +10851,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) if (counter_id == ED_COUNTER_ID_SELECT_LEVEL) { LoadLevel(level_nr); + LoadScore(level_nr); + TapeErase(); + ResetUndoBuffer(); DrawEditModeWindow(); @@ -9541,6 +10880,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) CopyGroupElementPropertiesToGame(properties_element); break; + case ED_COUNTER_ID_INVENTORY_SIZE: + DrawPlayerInitialInventoryArea(properties_element); + break; + case ED_COUNTER_ID_ENVELOPE_XSIZE: case ED_COUNTER_ID_ENVELOPE_YSIZE: DrawEnvelopeTextArea(-1); @@ -9585,14 +10928,9 @@ static void HandleTextAreaGadgets(struct GadgetInfo *gi) { int type_id = gi->custom_type_id; -#if 1 strncpy(textarea_info[type_id].value, gi->textarea.value, MAX_ENVELOPE_TEXT_LEN); textarea_info[type_id].value[MAX_ENVELOPE_TEXT_LEN] = '\0'; -#else - /* !!! BUGGY !!! MAX_ENVELOPE_TEXT_LEN != MAX_GADGET_TEXTSIZE !!! */ - strcpy(textarea_info[type_id].value, gi->textarea.value); -#endif level.changed = TRUE; } @@ -9637,8 +10975,15 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) int type_id = gi->custom_type_id; int i; - if (type_id >= ED_TEXTBUTTON_ID_PROPERTIES_FIRST && - type_id <= ED_TEXTBUTTON_ID_PROPERTIES_LAST) + if (type_id >= ED_TEXTBUTTON_ID_LEVELINFO_FIRST && + type_id <= ED_TEXTBUTTON_ID_LEVELINFO_LAST) + { + edit_mode_levelinfo = gi->custom_type_id; + + DrawLevelInfoWindow(); + } + else if (type_id >= ED_TEXTBUTTON_ID_PROPERTIES_FIRST && + type_id <= ED_TEXTBUTTON_ID_PROPERTIES_LAST) { edit_mode_properties = gi->custom_type_id; @@ -9649,12 +10994,21 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) char *template_filename = getDefaultLevelFilename(-1); boolean new_template = !fileExists(template_filename); + /* backup original "level.field" (needed to track playfield changes) */ + CopyPlayfield(level.field, FieldBackup); + + /* "SaveLevelTemplate()" uses "level.field", so copy editor playfield */ + CopyPlayfield(Feld, level.field); + if (new_template || - Request("Save this template and kill the old ?", REQ_ASK)) + Request("Save this template and kill the old?", REQ_ASK)) SaveLevelTemplate(); if (new_template) - Request("Template saved !", REQ_CONFIRM); + Request("Template saved!", REQ_CONFIRM); + + /* restore original "level.field" (needed to track playfield changes) */ + CopyPlayfield(FieldBackup, level.field); } else if (type_id == ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE && custom_element.num_change_pages < MAX_CHANGE_PAGES) @@ -9767,7 +11121,7 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) if (level.use_custom_template && !fileExists(template_filename)) { - Request("No level template found !", REQ_CONFIRM); + Request("No level template found!", REQ_CONFIRM); level.use_custom_template = FALSE; ModifyGadget(gi, GDI_CHECKED, FALSE, GDI_END); @@ -9799,7 +11153,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (id < ED_NUM_CTRL1_BUTTONS && id != GADGET_ID_SINGLE_ITEMS && - id != GADGET_ID_PROPERTIES && id != GADGET_ID_PICK_ELEMENT && edit_mode != ED_MODE_DRAWING && drawing_function != GADGET_ID_PICK_ELEMENT && @@ -9925,6 +11278,27 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; + case GADGET_ID_PROPERTIES: + if (edit_mode != ED_MODE_PROPERTIES) + { + properties_element = new_element; + DrawPropertiesWindow(); + edit_mode = ED_MODE_PROPERTIES; + + last_level_drawing_function = drawing_function; + ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], + MB_LEFTBUTTON); + } + else + { + DrawDrawingWindow(); + edit_mode = ED_MODE_DRAWING; + + ClickOnGadget(level_editor_gadget[last_level_drawing_function], + MB_LEFTBUTTON); + } + break; + case GADGET_ID_WRAP_LEFT: WrapLevel(-step, 0); break; @@ -9961,25 +11335,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) RandomPlacement(new_element); break; - case GADGET_ID_PROPERTIES: - if (edit_mode != ED_MODE_PROPERTIES) - { - properties_element = new_element; - DrawPropertiesWindow(); - edit_mode = ED_MODE_PROPERTIES; - - last_level_drawing_function = drawing_function; - ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], - MB_LEFTBUTTON); - } - else - { - DrawDrawingWindow(); - edit_mode = ED_MODE_DRAWING; - - ClickOnGadget(level_editor_gadget[last_level_drawing_function], - MB_LEFTBUTTON); - } + case GADGET_ID_ZOOM: + printf("::: zoom button pressed with mouse button %d\n", button); break; case GADGET_ID_CUSTOM_COPY_FROM: @@ -10000,7 +11357,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) case GADGET_ID_UNDO: if (undo_buffer_steps == 0) { - Request("Undo buffer empty !", REQ_CONFIRM); + Request("Undo buffer empty!", REQ_CONFIRM); break; } @@ -10058,62 +11415,81 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_SAVE: - if (leveldir_current->readonly) - { - Request("This level is read only !", REQ_CONFIRM); + { + /* saving read-only levels into personal level set modifies global vars + "leveldir_current" and "level_nr"; restore them after saving level */ + LevelDirTree *leveldir_former = leveldir_current; + int level_nr_former = level_nr; + char *level_filename; + boolean new_level; + + if (leveldir_current->readonly && + !PrepareSavingIntoPersonalLevelSet()) break; - } - if (!LevelContainsPlayer()) - Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM); - else + level_filename = getDefaultLevelFilename(level_nr); + new_level = !fileExists(level_filename); + + if (new_level || + Request("Save this level and kill the old?", REQ_ASK)) { - char *level_filename = getDefaultLevelFilename(level_nr); - boolean new_level = !fileExists(level_filename); + if (leveldir_former->readonly) + ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name); - if (new_level || - Request("Save this level and kill the old ?", REQ_ASK)) - { - CopyPlayfield(Feld, level.field); + CopyPlayfield(Feld, level.field); + SaveLevel(level_nr); - SaveLevel(level_nr); - } + level.changed = FALSE; if (new_level) - Request("Level saved !", REQ_CONFIRM); + { + char level_saved_msg[64]; - level.changed = FALSE; + if (leveldir_former->readonly) + sprintf(level_saved_msg, + "Level saved as level %d into personal level set!", + level_nr); + else + strcpy(level_saved_msg, "Level saved!"); + + Request(level_saved_msg, REQ_CONFIRM); + } } + + /* "cd" back to copied-from levelset (in case of saved read-only level) */ + leveldir_current = leveldir_former; + level_nr = level_nr_former; + break; + } case GADGET_ID_TEST: - if (!LevelContainsPlayer()) - Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM); - else - { - if (LevelChanged()) - level.game_version = GAME_VERSION_ACTUAL; + if (LevelChanged()) + level.game_version = GAME_VERSION_ACTUAL; - CopyPlayfield(level.field, FieldBackup); - CopyPlayfield(Feld, level.field); + CopyPlayfield(level.field, FieldBackup); + CopyPlayfield(Feld, level.field); - CopyNativeLevel_RND_to_Native(&level); + CopyNativeLevel_RND_to_Native(&level); - UnmapLevelEditorGadgets(); - UndrawSpecialEditorDoor(); + UnmapLevelEditorGadgets(); + UndrawSpecialEditorDoor(); - CloseDoor(DOOR_CLOSE_ALL); + CloseDoor(DOOR_CLOSE_ALL); - DrawCompleteVideoDisplay(); + /* needed before playing if editor playfield area has different size */ + ClearRectangle(drawto, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); - level_editor_test_game = TRUE; + // redraw_mask = REDRAW_ALL; + + level_editor_test_game = TRUE; + + StartGameActions(FALSE, setup.autorecord, level.random_seed); - StartGameActions(FALSE, setup.autorecord, NEW_RANDOMIZE); - } break; case GADGET_ID_EXIT: - RequestExitLevelEditor(TRUE); /* if level has changed, ask user */ + RequestExitLevelEditor(TRUE, FALSE); /* if level has changed, ask user */ break; default: @@ -10292,7 +11668,7 @@ void HandleLevelEditorKeyInput(Key key) case KSYM_Escape: if (edit_mode == ED_MODE_DRAWING) { - RequestExitLevelEditor(setup.ask_on_escape_editor); + RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE); } else if (edit_mode == ED_MODE_INFO) { @@ -10316,13 +11692,19 @@ void HandleLevelEditorKeyInput(Key key) if (id != GADGET_ID_NONE) ClickOnGadget(level_editor_gadget[id], button); + else if (letter >= '1' && letter <= '3') + ClickOnGadget(level_editor_gadget[GADGET_ID_PROPERTIES], letter - '0'); + else if (letter == '?') + ClickOnGadget(level_editor_gadget[GADGET_ID_PROPERTIES], button); else if (letter == '.') ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button); - else if (key == KSYM_Return || key == setup.shortcut.toggle_pause) + else if (key == KSYM_Return || + key == KSYM_space || + key == setup.shortcut.toggle_pause) ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button); else for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) - if (letter && letter == control_info[i].shortcut) + if (letter && letter == controlbutton_info[i].shortcut) if (!anyTextGadgetActive()) ClickOnGadget(level_editor_gadget[i], button); } @@ -10330,9 +11712,10 @@ void HandleLevelEditorKeyInput(Key key) void HandleLevelEditorIdle() { - static unsigned long action_delay = 0; - unsigned long action_delay_value = GameFrameDelay; + static unsigned int action_delay = 0; + unsigned int action_delay_value = GameFrameDelay; int xpos = 1, ypos = 2; + int i; if (edit_mode != ED_MODE_PROPERTIES) return; @@ -10340,6 +11723,14 @@ void HandleLevelEditorIdle() if (!DelayReached(&action_delay, action_delay_value)) return; + for (i = 0; i < ED_NUM_SELECTBOX; i++) + { + struct GadgetInfo *gi = level_editor_gadget[selectbox_info[i].gadget_id]; + + if (gi->mapped && gi->active && gi->selectbox.open) + return; + } + DrawEditorElementAnimation(SX + xpos * TILEX, SY + ypos * TILEY + MINI_TILEY / 2); @@ -10368,7 +11759,7 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) if (gi->custom_id < ED_NUM_CTRL_BUTTONS) { - int key = control_info[gi->custom_id].shortcut; + int key = controlbutton_info[gi->custom_id].shortcut; if (key) { @@ -10563,21 +11954,29 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) DrawTextS(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, infotext); } -void RequestExitLevelEditor(boolean ask_if_level_has_changed) +void RequestExitLevelEditor(boolean ask_if_level_has_changed, + boolean quick_quit) { if (!ask_if_level_has_changed || !LevelChanged() || - Request("Level has changed ! Exit without saving ?", + Request("Level has changed! Exit without saving?", REQ_ASK | REQ_STAY_OPEN)) { - CloseDoor(DOOR_CLOSE_1); SetDoorState(DOOR_CLOSE_2); + + if (quick_quit) + FadeSkipNextFadeIn(); + game_status = GAME_MODE_MAIN; - DrawMainMenu(); + + DrawAndFadeInMainMenu(playfield_area_changed ? REDRAW_ALL : REDRAW_FIELD); } else { - CloseDoor(DOOR_CLOSE_1); - OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK); + if (!global.use_envelope_request) + { + CloseDoor(DOOR_CLOSE_1); + OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK); + } } }