X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=0c6aff395f3215fbb10fc95e3d9dd1dab6e8a6c9;hb=0f40b41943c6442963b3677ce3d18d1f04c61605;hp=7e47789d5b7cff2fa0fcff139c0d285d05890221;hpb=9073d88279c0b9c5be103a6bb4d5c608ab0d90cc;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 7e47789d..0c6aff39 100644 --- a/src/editor.c +++ b/src/editor.c @@ -67,38 +67,58 @@ #define ED_NUM_ELEMENTLIST_BUTTONS (ED_ELEMENTLIST_BUTTONS_HORIZ * \ ED_ELEMENTLIST_BUTTONS_VERT) +/* standard distances */ +#define ED_BORDER_SIZE 3 +#define ED_BORDER2_SIZE 5 +#define ED_GADGET_DISTANCE 2 + /* values for the setting windows */ -#define ED_SETTINGS_XPOS (MINI_TILEX + 8) +#define ED_SETTINGS_XSTART (3 * MINI_TILEX / 2) +#define ED_SETTINGS_YSTART (MINI_TILEY * 10) + +#define ED_SETTINGS_XOFFSET (ED_CHECKBUTTON_XSIZE + \ + 2 * ED_GADGET_DISTANCE) +#define ED_SETTINGS_YOFFSET (3 * MINI_TILEY / 2) + +#define ED_SETTINGS_XPOS(n) (ED_SETTINGS_XSTART + \ + n * ED_SETTINGS_XOFFSET) +#define ED_SETTINGS_YPOS(n) (ED_SETTINGS_YSTART + \ + n * ED_SETTINGS_YOFFSET) + +#define ED_SETTINGS1_YPOS MINI_TILEY #define ED_SETTINGS2_XPOS MINI_TILEX -#define ED_SETTINGS_YPOS MINI_TILEY -#define ED_SETTINGS2_YPOS (ED_SETTINGS_YPOS + 12 * TILEY - 2) +#define ED_SETTINGS2_YPOS (ED_SETTINGS1_YPOS + 12 * TILEY - 2) /* values for counter gadgets */ -#define ED_COUNT_ELEM_SCORE_XPOS ED_SETTINGS_XPOS -#define ED_COUNT_ELEM_SCORE_YPOS (14 * MINI_TILEY) -#define ED_COUNT_ELEM_CONTENT_XPOS ED_SETTINGS_XPOS -#define ED_COUNT_ELEM_CONTENT_YPOS (19 * MINI_TILEY) +#define ED_COUNT_ELEMENT_SCORE_XPOS ED_SETTINGS_XPOS(0) +#define ED_COUNT_ELEMENT_SCORE_YPOS ED_SETTINGS_YPOS(0) +#define ED_COUNT_ELEMENT_CONTENT_XPOS ED_SETTINGS_XPOS(0) +#define ED_COUNT_ELEMENT_CONTENT_YPOS ED_SETTINGS_YPOS(6) -#define ED_COUNTER_YSTART (ED_SETTINGS_YPOS + 2 * TILEY) +#define ED_COUNT_CHANGE_DELAY_XPOS (ED_SETTINGS_XPOS(1) + 9 * MINI_TILEX) + +#define ED_COUNTER_YSTART (ED_SETTINGS1_YPOS + 2 * TILEY) #define ED_COUNTER_YDISTANCE (3 * MINI_TILEY) #define ED_COUNTER_YPOS(n) (ED_COUNTER_YSTART + \ n * ED_COUNTER_YDISTANCE) -#define ED_COUNTER_YPOS2(n) (ED_COUNTER_YSTART + \ - n * ED_COUNTER_YDISTANCE / 2) #define ED_COUNTER2_YPOS(n) (ED_COUNTER_YSTART + \ n * ED_COUNTER_YDISTANCE - 2) -/* standard distances */ -#define ED_BORDER_SIZE 3 -#define ED_BORDER2_SIZE 5 -#define ED_GADGET_DISTANCE 2 - /* values for element content drawing areas */ #define ED_AREA_ELEM_CONTENT_XPOS ( 2 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY) -#define ED_AREA_ELEM_CONTENT2_XPOS ( 2 * MINI_TILEX) -#define ED_AREA_ELEM_CONTENT2_YPOS (28 * MINI_TILEY) +#define ED_AREA_ELEM_CONTENT2_XPOS (20 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT2_YPOS (ED_SETTINGS_YPOS(1) + \ + ED_GADGET_DISTANCE) + +#define ED_AREA_ELEM_CONTENT3_XPOS (24 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT3_YPOS (ED_SETTINGS_YPOS(2) + \ + ED_GADGET_DISTANCE) + +#define ED_AREA_ELEM_CONTENT4_XPOS (17 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(8) + \ + ED_GADGET_DISTANCE - MINI_TILEY) /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) @@ -200,9 +220,15 @@ #define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS #define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \ + 4 * (2 + ED_WIN_COUNT_YSIZE)) +#define ED_TEXTBUTTON_INACTIVE_YPOS ED_TEXTBUTTON_YPOS + +#define ED_TEXTBUTTON_TAB_XPOS ED_WIN_COUNT_XPOS +#define ED_TEXTBUTTON_TAB_YPOS (ED_WIN_COUNT_YPOS + \ 2 * (2 + ED_WIN_COUNT_YSIZE)) -#define ED_TEXTBUTTON_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \ +#define ED_TEXTBUTTON_TAB_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \ 3 * (2 + ED_WIN_COUNT_YSIZE)) + #define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE #define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE @@ -249,52 +275,60 @@ /* counter button identifiers */ #define GADGET_ID_COUNTER_FIRST (GADGET_ID_TOOLBOX_FIRST + 22) -#define GADGET_ID_ELEM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 0) -#define GADGET_ID_ELEM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 1) -#define GADGET_ID_ELEM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 2) -#define GADGET_ID_ELEM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 3) -#define GADGET_ID_ELEM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 4) -#define GADGET_ID_ELEM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 5) -#define GADGET_ID_LEVEL_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 6) -#define GADGET_ID_LEVEL_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 7) -#define GADGET_ID_LEVEL_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 8) -#define GADGET_ID_LEVEL_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 9) -#define GADGET_ID_LEVEL_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 10) -#define GADGET_ID_LEVEL_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 11) -#define GADGET_ID_LEVEL_RANDOM_DOWN (GADGET_ID_COUNTER_FIRST + 12) -#define GADGET_ID_LEVEL_RANDOM_TEXT (GADGET_ID_COUNTER_FIRST + 13) -#define GADGET_ID_LEVEL_RANDOM_UP (GADGET_ID_COUNTER_FIRST + 14) -#define GADGET_ID_LEVEL_COLLECT_DOWN (GADGET_ID_COUNTER_FIRST + 15) -#define GADGET_ID_LEVEL_COLLECT_TEXT (GADGET_ID_COUNTER_FIRST + 16) -#define GADGET_ID_LEVEL_COLLECT_UP (GADGET_ID_COUNTER_FIRST + 17) -#define GADGET_ID_LEVEL_TIMELIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 18) -#define GADGET_ID_LEVEL_TIMELIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 19) -#define GADGET_ID_LEVEL_TIMELIMIT_UP (GADGET_ID_COUNTER_FIRST + 20) -#define GADGET_ID_LEVEL_TIMESCORE_DOWN (GADGET_ID_COUNTER_FIRST + 21) -#define GADGET_ID_LEVEL_TIMESCORE_TEXT (GADGET_ID_COUNTER_FIRST + 22) -#define GADGET_ID_LEVEL_TIMESCORE_UP (GADGET_ID_COUNTER_FIRST + 23) -#define GADGET_ID_SELECT_LEVEL_DOWN (GADGET_ID_COUNTER_FIRST + 24) -#define GADGET_ID_SELECT_LEVEL_TEXT (GADGET_ID_COUNTER_FIRST + 25) -#define GADGET_ID_SELECT_LEVEL_UP (GADGET_ID_COUNTER_FIRST + 26) +#define GADGET_ID_SELECT_LEVEL_DOWN (GADGET_ID_COUNTER_FIRST + 0) +#define GADGET_ID_SELECT_LEVEL_TEXT (GADGET_ID_COUNTER_FIRST + 1) +#define GADGET_ID_SELECT_LEVEL_UP (GADGET_ID_COUNTER_FIRST + 2) +#define GADGET_ID_LEVEL_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 3) +#define GADGET_ID_LEVEL_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 4) +#define GADGET_ID_LEVEL_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 5) +#define GADGET_ID_LEVEL_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 6) +#define GADGET_ID_LEVEL_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 7) +#define GADGET_ID_LEVEL_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 8) +#define GADGET_ID_LEVEL_RANDOM_DOWN (GADGET_ID_COUNTER_FIRST + 9) +#define GADGET_ID_LEVEL_RANDOM_TEXT (GADGET_ID_COUNTER_FIRST + 10) +#define GADGET_ID_LEVEL_RANDOM_UP (GADGET_ID_COUNTER_FIRST + 11) +#define GADGET_ID_LEVEL_COLLECT_DOWN (GADGET_ID_COUNTER_FIRST + 12) +#define GADGET_ID_LEVEL_COLLECT_TEXT (GADGET_ID_COUNTER_FIRST + 13) +#define GADGET_ID_LEVEL_COLLECT_UP (GADGET_ID_COUNTER_FIRST + 14) +#define GADGET_ID_LEVEL_TIMELIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 15) +#define GADGET_ID_LEVEL_TIMELIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 16) +#define GADGET_ID_LEVEL_TIMELIMIT_UP (GADGET_ID_COUNTER_FIRST + 17) +#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_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 21) +#define GADGET_ID_ELEMENT_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 22) +#define GADGET_ID_ELEMENT_SCORE_UP (GADGET_ID_COUNTER_FIRST + 23) +#define GADGET_ID_ELEMENT_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 24) +#define GADGET_ID_ELEMENT_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 25) +#define GADGET_ID_ELEMENT_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 26) +#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 28) +#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 29) +#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 30) +#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 31) +#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 32) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 33) #define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0) -#define GADGET_ID_ELEM_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) -#define GADGET_ID_ELEM_CONTENT_1 (GADGET_ID_DRAWING_AREA_FIRST + 2) -#define GADGET_ID_ELEM_CONTENT_2 (GADGET_ID_DRAWING_AREA_FIRST + 3) -#define GADGET_ID_ELEM_CONTENT_3 (GADGET_ID_DRAWING_AREA_FIRST + 4) -#define GADGET_ID_ELEM_CONTENT_4 (GADGET_ID_DRAWING_AREA_FIRST + 5) -#define GADGET_ID_ELEM_CONTENT_5 (GADGET_ID_DRAWING_AREA_FIRST + 6) -#define GADGET_ID_ELEM_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 7) -#define GADGET_ID_ELEM_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 8) +#define GADGET_ID_ELEMENT_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) +#define GADGET_ID_ELEMENT_CONTENT_1 (GADGET_ID_DRAWING_AREA_FIRST + 2) +#define GADGET_ID_ELEMENT_CONTENT_2 (GADGET_ID_DRAWING_AREA_FIRST + 3) +#define GADGET_ID_ELEMENT_CONTENT_3 (GADGET_ID_DRAWING_AREA_FIRST + 4) +#define GADGET_ID_ELEMENT_CONTENT_4 (GADGET_ID_DRAWING_AREA_FIRST + 5) +#define GADGET_ID_ELEMENT_CONTENT_5 (GADGET_ID_DRAWING_AREA_FIRST + 6) +#define GADGET_ID_ELEMENT_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 7) +#define GADGET_ID_ELEMENT_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 8) #define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 9) -#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 10) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 11) +#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 10) +#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 11) +#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 12) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 13) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 12) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 14) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -302,17 +336,22 @@ /* selectbox identifiers */ #define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 2) -#define GADGET_ID_CUSTOM_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 0) +#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 0) +#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 1) +#define GADGET_ID_CUSTOM_WALKABLE_LAYER (GADGET_ID_SELECTBOX_FIRST + 2) +#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 3) +#define GADGET_ID_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 4) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 1) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 5) #define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0) #define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1) #define GADGET_ID_PROPERTIES_ADVANCED (GADGET_ID_TEXTBUTTON_FIRST + 2) +#define GADGET_ID_SAVE_AS_TEMPLATE (GADGET_ID_TEXTBUTTON_FIRST + 3) /* gadgets for scrolling of drawing area */ -#define GADGET_ID_SCROLLING_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 3) +#define GADGET_ID_SCROLLING_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 4) #define GADGET_ID_SCROLL_UP (GADGET_ID_SCROLLING_FIRST + 0) #define GADGET_ID_SCROLL_DOWN (GADGET_ID_SCROLLING_FIRST + 1) @@ -339,13 +378,21 @@ #define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 5) #define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 6) #define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 7) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 8) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_CUSTOM_PUSHABLE (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 8) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 9) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_CUSTOM_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_CUSTOM_CHANGEABLE (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_CHANGE_DELAY_FIXED (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CHANGE_DELAY_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 19) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 20) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -357,21 +404,26 @@ #define RADIO_NR_RANDOM_ELEMENTS 2 /* values for counter gadgets */ -#define ED_COUNTER_ID_ELEM_SCORE 0 -#define ED_COUNTER_ID_ELEM_CONTENT 1 -#define ED_COUNTER_ID_LEVEL_XSIZE 2 -#define ED_COUNTER_ID_LEVEL_YSIZE 3 -#define ED_COUNTER_ID_LEVEL_COLLECT 4 -#define ED_COUNTER_ID_LEVEL_TIMELIMIT 5 -#define ED_COUNTER_ID_LEVEL_TIMESCORE 6 -#define ED_COUNTER_ID_LEVEL_RANDOM 7 -#define ED_COUNTER_ID_SELECT_LEVEL 8 - -#define ED_NUM_COUNTERBUTTONS 9 +#define ED_COUNTER_ID_SELECT_LEVEL 0 +#define ED_COUNTER_ID_LEVEL_XSIZE 1 +#define ED_COUNTER_ID_LEVEL_YSIZE 2 +#define ED_COUNTER_ID_LEVEL_COLLECT 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_SCORE 7 +#define ED_COUNTER_ID_ELEMENT_CONTENT 8 +#define ED_COUNTER_ID_CHANGE_DELAY_FIX 9 +#define ED_COUNTER_ID_CHANGE_DELAY_RND 10 + +#define ED_NUM_COUNTERBUTTONS 11 #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_CHANGE_FIRST ED_COUNTER_ID_CHANGE_DELAY_FIX +#define ED_COUNTER_ID_CHANGE_LAST ED_COUNTER_ID_CHANGE_DELAY_RND + /* values for scrollbutton gadgets */ #define ED_SCROLLBUTTON_ID_AREA_UP 0 #define ED_SCROLLBUTTON_ID_AREA_DOWN 1 @@ -405,16 +457,27 @@ #define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR /* values for selectbox gadgets */ -#define ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE 0 +#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 0 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 1 +#define ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER 2 +#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 3 +#define ED_SELECTBOX_ID_CHANGE_CAUSE 4 + +#define ED_NUM_SELECTBOX 5 -#define ED_NUM_SELECTBOX 1 +#define ED_SELECTBOX_ID_CUSTOM_FIRST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION +#define ED_SELECTBOX_ID_CUSTOM_LAST ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER + +#define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS +#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_CAUSE /* values for textbutton gadgets */ #define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0 #define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 1 #define ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED 2 +#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 3 -#define ED_NUM_TEXTBUTTON 3 +#define ED_NUM_TEXTBUTTON 4 /* values for checkbutton gadgets */ #define ED_CHECKBUTTON_ID_DOUBLE_SPEED 0 @@ -423,18 +486,29 @@ #define ED_CHECKBUTTON_ID_STICK_ELEMENT 3 #define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 4 #define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 5 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 6 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 7 -#define ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE 8 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 9 - -#define ED_NUM_CHECKBUTTONS 10 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 6 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 7 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 8 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 9 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 10 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 11 +#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE 12 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 13 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 14 +#define ED_CHECKBUTTON_ID_CUSTOM_CHANGEABLE 15 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY_FIXED 16 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY_RANDOM 17 + +#define ED_NUM_CHECKBUTTONS 18 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED #define ED_CHECKBUTTON_ID_CUSTOM_FIRST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE -#define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY +#define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE + +#define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_CHANGEABLE +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_DELAY_RANDOM /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -531,6 +605,8 @@ static int random_placement_background_element = EL_SAND; static boolean random_placement_background_restricted = FALSE; static boolean stick_element_properties_window = FALSE; static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES]; +static boolean custom_element_change_events[NUM_CHANGE_EVENTS]; +static struct CustomElementInfo custom_element; static struct { @@ -543,23 +619,15 @@ static struct } counterbutton_info[ED_NUM_COUNTERBUTTONS] = { { - ED_COUNT_ELEM_SCORE_XPOS, ED_COUNT_ELEM_SCORE_YPOS, - MIN_SCORE, MAX_SCORE, - GADGET_ID_ELEM_SCORE_DOWN, GADGET_ID_ELEM_SCORE_UP, - GADGET_ID_ELEM_SCORE_TEXT, - NULL, /* will be set when used */ - "element score", NULL - }, - { - ED_COUNT_ELEM_CONTENT_XPOS, ED_COUNT_ELEM_CONTENT_YPOS, - MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, - GADGET_ID_ELEM_CONTENT_DOWN, GADGET_ID_ELEM_CONTENT_UP, - GADGET_ID_ELEM_CONTENT_TEXT, - &level.num_yam_contents, - "element content", NULL + DX + 5 - SX, DY + 3 - SY, + 1, 100, + GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, + GADGET_ID_SELECT_LEVEL_TEXT, + &level_nr, + NULL, NULL }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(2), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(2), MIN_LEV_FIELDX, MAX_LEV_FIELDX, GADGET_ID_LEVEL_XSIZE_DOWN, GADGET_ID_LEVEL_XSIZE_UP, GADGET_ID_LEVEL_XSIZE_TEXT, @@ -567,7 +635,7 @@ static struct "playfield size", "width", }, { - ED_SETTINGS_XPOS + 2 * DXSIZE, ED_COUNTER_YPOS(2), + ED_SETTINGS_XPOS(0) + 2 * DXSIZE, ED_COUNTER_YPOS(2), MIN_LEV_FIELDY, MAX_LEV_FIELDY, GADGET_ID_LEVEL_YSIZE_DOWN, GADGET_ID_LEVEL_YSIZE_UP, GADGET_ID_LEVEL_YSIZE_TEXT, @@ -575,7 +643,7 @@ static struct NULL, "height", }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(3), 0, 999, GADGET_ID_LEVEL_COLLECT_DOWN, GADGET_ID_LEVEL_COLLECT_UP, GADGET_ID_LEVEL_COLLECT_TEXT, @@ -583,7 +651,7 @@ static struct "number of emeralds to collect", NULL }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(4), 0, 999, GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP, GADGET_ID_LEVEL_TIMELIMIT_TEXT, @@ -591,7 +659,7 @@ static struct "time available to solve level", "(0 => no time limit)" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(5), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(5), 0, 255, GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, GADGET_ID_LEVEL_TIMESCORE_TEXT, @@ -599,7 +667,7 @@ static struct "score for each 10 seconds left", NULL }, { - ED_SETTINGS_XPOS, ED_COUNTER2_YPOS(8), + ED_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(8), 1, 100, GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP, GADGET_ID_LEVEL_RANDOM_TEXT, @@ -607,12 +675,36 @@ static struct "random element placement", "in" }, { - DX + 5 - SX, DY + 3 - SY, - 1, 100, - GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, - GADGET_ID_SELECT_LEVEL_TEXT, - &level_nr, - NULL, NULL + ED_COUNT_ELEMENT_SCORE_XPOS, ED_COUNT_ELEMENT_SCORE_YPOS, + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_SCORE_DOWN, GADGET_ID_ELEMENT_SCORE_UP, + GADGET_ID_ELEMENT_SCORE_TEXT, + NULL, /* will be set when used */ + "element score", NULL + }, + { + ED_COUNT_ELEMENT_CONTENT_XPOS, ED_COUNT_ELEMENT_CONTENT_YPOS, + MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, + GADGET_ID_ELEMENT_CONTENT_DOWN, GADGET_ID_ELEMENT_CONTENT_UP, + GADGET_ID_ELEMENT_CONTENT_TEXT, + &level.num_yamyam_contents, + "element content", NULL + }, + { + ED_COUNT_CHANGE_DELAY_XPOS, ED_SETTINGS_YPOS(2), + 0, 999, + GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP, + GADGET_ID_CHANGE_DELAY_FIX_TEXT, + &custom_element.change.delay_fixed, + NULL, "units (fixed)" + }, + { + ED_COUNT_CHANGE_DELAY_XPOS, ED_SETTINGS_YPOS(3), + 0, 999, + GADGET_ID_CHANGE_DELAY_RND_DOWN, GADGET_ID_CHANGE_DELAY_RND_UP, + GADGET_ID_CHANGE_DELAY_RND_TEXT, + &custom_element.change.delay_random, + NULL, "units (random)" } }; @@ -626,14 +718,14 @@ static struct } textinput_info[ED_NUM_TEXTINPUT] = { { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(0), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(0), GADGET_ID_LEVEL_NAME, MAX_LEVEL_NAME_LEN, level.name, "Title" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(1), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1), GADGET_ID_LEVEL_AUTHOR, MAX_LEVEL_AUTHOR_LEN, level.author, @@ -641,32 +733,108 @@ static struct } }; +static struct ValueTextInfo options_walk_to_action[] = +{ + { EP_DIGGABLE, "diggable" }, + { EP_COLLECTIBLE, "collectible" }, + { EP_PUSHABLE, "pushable" }, + { -1, NULL } +}; +static int index_walk_to_action = 0; + +static struct ValueTextInfo options_move_direction[] = +{ + { MV_BIT_LEFT, "left" }, + { MV_BIT_RIGHT, "right" }, + { MV_BIT_UP, "up" }, + { MV_BIT_DOWN, "down" }, + { MV_BIT_HORIZONTAL, "horizontal" }, + { MV_BIT_VERTICAL, "vertical" }, + { MV_BIT_ALL_DIRECTIONS, "all directions" }, + { MV_BIT_TOWARDS_PLAYER, "towards player" }, + { MV_BIT_AWAY_FROM_PLAYER, "away from player" }, + { MV_BIT_ALONG_LEFT_SIDE, "along left side" }, + { MV_BIT_ALONG_RIGHT_SIDE, "along right side" }, + { -1, NULL } +}; +static int index_move_direction = 0; + +static struct ValueTextInfo options_walkable_layer[] = +{ + { EP_WALKABLE_OVER, "over" }, + { EP_WALKABLE_INSIDE, "inside" }, + { EP_WALKABLE_UNDER, "under" }, + { -1, NULL } +}; +static int index_walkable_layer = 0; + +static struct ValueTextInfo options_time_units[] = +{ + { 50, "seconds" }, + { 1, "frames" }, + { -1, NULL } +}; +static int index_time_units = 0; + static struct ValueTextInfo options_change_cause[] = { - { 1, "specified delay" }, - { 2, "impact (active)" }, - { 3, "impact (passive)" }, - { 4, "touched by player" }, - { 5, "pressed by player" }, - { -1, NULL } + { 1, "specified delay" }, + { 2, "impact (active)" }, + { 3, "impact (passive)" }, + { 4, "touched by player" }, + { 5, "pressed by player" }, + { -1, NULL } }; -static int index_change_cause = 0; +static int index_change_cause = 0, value_change_cause = 0; static struct { int x, y; int gadget_id; - int size; + int size; /* char size of selectbox or '-1' (dynamically determined) */ struct ValueTextInfo *options; - int *index; + int *index, *value; char *text, *infotext; } selectbox_info[ED_NUM_SELECTBOX] = { { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3), - GADGET_ID_CUSTOM_CHANGE_CAUSE, - 17, + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_WALK_TO_ACTION, + -1, + options_walk_to_action, &index_walk_to_action, + &custom_element.walk_to_action, + NULL, "diggable/collectible/pushable" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_MOVE_DIRECTION, + -1, + options_move_direction, &index_move_direction, + &custom_element.move_direction, + "can move", "element move direction" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(10), + GADGET_ID_CUSTOM_WALKABLE_LAYER, + -1, + options_walkable_layer, &index_walkable_layer, + &custom_element.walkable_layer, + "player can walk", "layer where player can walk" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(4), + GADGET_ID_CHANGE_TIME_UNITS, + -1, + options_time_units, &index_time_units, + &custom_element.change.delay_frames, + "delay time given in", "delay time units for change" + }, + { + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(8), + GADGET_ID_CHANGE_CAUSE, + -1, options_change_cause, &index_change_cause, + &value_change_cause, "test:", "test-selectbox entry" }, }; @@ -676,33 +844,34 @@ static struct int x, y; int gadget_id; int size; - char *value; - char *infotext; + char *text, *infotext; } textbutton_info[ED_NUM_TEXTBUTTON] = { { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(1), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1), GADGET_ID_PROPERTIES_INFO, - 11, "Information", - "Show information about element" + 11, "Information", "Show information about element" }, { - ED_SETTINGS_XPOS + 166, ED_COUNTER_YPOS(1), + ED_SETTINGS_XPOS(0) + 166, ED_COUNTER_YPOS(1), GADGET_ID_PROPERTIES_CONFIG, - 11, "Configure", - "Configure element properties" + 11, "Configure", "Configure element properties" }, { - ED_SETTINGS_XPOS + 332, ED_COUNTER_YPOS(1), + ED_SETTINGS_XPOS(0) + 332, ED_COUNTER_YPOS(1), GADGET_ID_PROPERTIES_ADVANCED, - 11, "Advanced", - "Advanced element configuration" + 11, "Advanced", "Advanced element configuration" + }, + { + ED_SETTINGS_XPOS(0) + 262, ED_SETTINGS_YPOS(11), + GADGET_ID_SAVE_AS_TEMPLATE, + -1, "Save as template", "Save current settings as new template" }, }; static struct { - int xpos, ypos; + int gd_x, gd_y; int x, y; int gadget_id; char *infotext; @@ -748,7 +917,7 @@ static struct static struct { - int xpos, ypos; + int gd_x, gd_y; int x, y; int width, height; int type; @@ -793,14 +962,14 @@ static struct } radiobutton_info[ED_NUM_RADIOBUTTONS] = { { - ED_SETTINGS_XPOS + 160, ED_COUNTER2_YPOS(8), + ED_SETTINGS_XPOS(0) + 160, ED_COUNTER2_YPOS(8), GADGET_ID_RANDOM_PERCENTAGE, RADIO_NR_RANDOM_ELEMENTS, &random_placement_method, RANDOM_USE_PERCENTAGE, "percentage", "use percentage for random elements" }, { - ED_SETTINGS_XPOS + 340, ED_COUNTER2_YPOS(8), + ED_SETTINGS_XPOS(0) + 340, ED_COUNTER2_YPOS(8), GADGET_ID_RANDOM_QUANTITY, RADIO_NR_RANDOM_ELEMENTS, &random_placement_method, RANDOM_USE_QUANTITY, @@ -817,64 +986,112 @@ static struct } checkbutton_info[ED_NUM_CHECKBUTTONS] = { { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(6) - MINI_TILEY, + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(6) - MINI_TILEY, GADGET_ID_DOUBLE_SPEED, &level.double_speed, "double speed movement", "set movement speed of player" }, { - ED_SETTINGS_XPOS + 340, ED_COUNTER_YPOS(6) - MINI_TILEY, + ED_SETTINGS_XPOS(0) + 340, ED_COUNTER_YPOS(6) - MINI_TILEY, GADGET_ID_GRAVITY, &level.gravity, "gravity", "set level gravity" }, { - ED_SETTINGS_XPOS, ED_COUNTER2_YPOS(9) - MINI_TILEY, + ED_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(9) - MINI_TILEY, GADGET_ID_RANDOM_RESTRICTED, &random_placement_background_restricted, "restrict random placement to", "set random placement restriction" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4), + ED_SETTINGS_XPOS(0), 0, /* set at runtime */ GADGET_ID_STICK_ELEMENT, &stick_element_properties_window, - "stick window to edit content", "stick window to edit content" + "stick this screen to edit content","stick this screen to edit content" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(4), GADGET_ID_EM_SLIPPERY_GEMS, &level.em_slippery_gems, "slip down from certain flat walls","use EM style slipping behaviour" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(10), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3), GADGET_ID_CUSTOM_INDESTRUCTIBLE, &custom_element_properties[EP_INDESTRUCTIBLE], "indestructible", "element cannot be destroyed" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(11), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_WALK_TO_OBJECT, + &custom_element_properties[EP_WALK_TO_OBJECT], + NULL, "player can dig/collect/push element" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_CAN_MOVE, + &custom_element_properties[EP_CAN_MOVE], + NULL, "element can move in some direction" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(6), GADGET_ID_CUSTOM_CAN_FALL, &custom_element_properties[EP_CAN_FALL], "can fall", "element can fall down" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(12), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(7), GADGET_ID_CUSTOM_CAN_SMASH, &custom_element_properties[EP_CAN_SMASH], "can smash", "element can smash other elements" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(13), - GADGET_ID_CUSTOM_PUSHABLE, - &custom_element_properties[EP_PUSHABLE], - "pushable", "element can be pushed" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(8), + GADGET_ID_CUSTOM_CAN_EXPLODE, + &custom_element_properties[EP_CAN_EXPLODE], + "can explode to:", "element can explode to other elements" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(14), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_SLIPPERY, &custom_element_properties[EP_SLIPPERY], "slippery", "other elements can fall down from it" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), + GADGET_ID_CUSTOM_WALKABLE, + &custom_element_properties[EP_WALKABLE], + NULL, "player can walk on the same field" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_USE_GRAPHIC, + &custom_element.use_gfx_element, + "use graphic of element:", "use graphic for custom element" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(11), + GADGET_ID_CUSTOM_USE_TEMPLATE, + &custom_element.use_template, + "use template", "use template for custom properties" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_CHANGEABLE, + &custom_element_properties[EP_CHANGEABLE], + "element changes to after:", "element can change to other element" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2), + GADGET_ID_CHANGE_DELAY_FIXED, + &custom_element_change_events[CE_DELAY_FIXED], + "delay of", "element changes after fixed delay" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), + GADGET_ID_CHANGE_DELAY_RANDOM, + &custom_element_change_events[CE_DELAY_RANDOM], + "delay of", "element changes after random delay" } }; @@ -906,9 +1123,12 @@ static int new_element3 = EL_SAND; /* forward declaration for internal use */ static void ModifyEditorCounter(int, int); static void ModifyEditorCounterLimits(int, int, int); +static void ModifyEditorSelectbox(int, int); +static void ModifyEditorElementList(); static void DrawDrawingWindow(); static void DrawLevelInfoWindow(); static void DrawPropertiesWindow(); +static boolean checkPropertiesConfig(); static void CopyLevelToUndoBuffer(int); static void HandleDrawingAreas(struct GadgetInfo *); static void HandleCounterButtons(struct GadgetInfo *); @@ -927,7 +1147,6 @@ static int last_drawing_function = GADGET_ID_SINGLE_ITEMS; static boolean draw_with_brush = FALSE; static int properties_element = 0; -static short ElementContent[MAX_ELEMENT_CONTENTS][3][3]; static short FieldBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static int undo_buffer_position = 0; @@ -1956,8 +2175,8 @@ static void CreateControlButtons() y += DY; width = ED_SCROLLBUTTON2_XSIZE; height = ED_SCROLLBUTTON2_YSIZE; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].xpos; - gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].ypos; + 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; } @@ -1967,8 +2186,8 @@ static void CreateControlButtons() y += SY; width = ED_SCROLLBUTTON_XSIZE; height = ED_SCROLLBUTTON_YSIZE; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].xpos; - gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].ypos; + 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; } @@ -2085,9 +2304,9 @@ static void CreateCounterButtons() xpos += 2 * ED_GADGET_DISTANCE; ypos += ED_GADGET_DISTANCE; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[sid].xpos; + 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].ypos; + gd_y = DOOR_GFX_PAGEY1 + scrollbutton_info[sid].gd_y; x_size = ED_SCROLLBUTTON_XSIZE; y_size = ED_SCROLLBUTTON_YSIZE; } @@ -2219,7 +2438,7 @@ static void CreateDrawingAreas() int gx = SX + ED_AREA_ELEM_CONTENT_XPOS + 5 * (i % 4) * MINI_TILEX; int gy = SX + ED_AREA_ELEM_CONTENT_YPOS + 6 * (i / 4) * MINI_TILEY; - id = GADGET_ID_ELEM_CONTENT_0 + i; + id = GADGET_ID_ELEMENT_CONTENT_0 + i; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_X, gx, @@ -2258,6 +2477,45 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; + /* ... one for each custom element optional graphic element ... */ + id = GADGET_ID_CUSTOM_GRAPHIC; + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_X, SX + ED_AREA_ELEM_CONTENT3_XPOS, + GDI_Y, SY + ED_AREA_ELEM_CONTENT3_YPOS, + GDI_WIDTH, MINI_TILEX, + GDI_HEIGHT, MINI_TILEY, + GDI_TYPE, GD_TYPE_DRAWING_AREA, + GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleDrawingAreaInfo, + GDI_CALLBACK_ACTION, HandleDrawingAreas, + GDI_END); + + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + level_editor_gadget[id] = gi; + + /* ... one areas for custom element explosion content ... */ + id = GADGET_ID_CUSTOM_CONTENT; + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_CUSTOM_TYPE_ID, i, + GDI_X, SX + ED_AREA_ELEM_CONTENT4_XPOS, + GDI_Y, SX + ED_AREA_ELEM_CONTENT4_YPOS, + GDI_WIDTH, 3 * MINI_TILEX, + GDI_HEIGHT, 3 * MINI_TILEY, + GDI_TYPE, GD_TYPE_DRAWING_AREA, + GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleDrawingAreaInfo, + GDI_CALLBACK_ACTION, HandleDrawingAreas, + GDI_END); + + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + level_editor_gadget[id] = gi; + /* ... one for each custom element change target element ... */ id = GADGET_ID_CUSTOM_CHANGED; gi = CreateGadget(GDI_CUSTOM_ID, id, @@ -2349,30 +2607,50 @@ static void CreateTextInputGadgets() static void CreateSelectboxGadgets() { int max_infotext_len = getMaxInfoTextLength(); - int i; + int i, j; for (i=0; i' operation will + implicitely cast -1 to an unsigned integer value!) */ + selectbox_info[i].size = 0; + + for (j=0; selectbox_info[i].options[j].text != NULL; j++) + if (strlen(selectbox_info[i].options[j].text) > selectbox_info[i].size) + selectbox_info[i].size = strlen(selectbox_info[i].options[j].text); + + selectbox_info[i].size++; /* add one character empty space */ + } + event_mask = GD_EVENT_RELEASED | GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; gd_x = DOOR_GFX_PAGEX4 + ED_SELECTBOX_XPOS; gd_y = DOOR_GFX_PAGEY1 + ED_SELECTBOX_YPOS; + /* determine horizontal offset for leading selectbox text */ + if (selectbox_info[i].text != NULL) + xoffset = (getFontWidth(FONT_TEXT_1) * strlen(selectbox_info[i].text) + + 2 * ED_GADGET_DISTANCE); + sprintf(infotext, "Select %s", selectbox_info[i].infotext); infotext[max_infotext_len] = '\0'; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, infotext, - GDI_X, SX + selectbox_info[i].x, + GDI_X, SX + selectbox_info[i].x + xoffset, GDI_Y, SY + selectbox_info[i].y, GDI_TYPE, GD_TYPE_SELECTBOX, GDI_SELECTBOX_OPTIONS, selectbox_info[i].options, @@ -2411,12 +2689,25 @@ static void CreateTextbuttonGadgets() char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textbutton_info[i].gadget_id; + if (textbutton_info[i].size == -1) /* dynamically determine size */ + textbutton_info[i].size = strlen(textbutton_info[i].text); + event_mask = GD_EVENT_RELEASED; - gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_XPOS; - gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_XPOS; - gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_YPOS; - gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_INACTIVE_YPOS; + if (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_ADVANCED) + { + gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_TAB_XPOS; + gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_TAB_XPOS; + gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_YPOS; + gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_INACTIVE_YPOS; + } + else + { + gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_XPOS; + gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_XPOS; + gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_YPOS; + gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_INACTIVE_YPOS; + } sprintf(infotext, "%s", textbutton_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -2427,7 +2718,7 @@ static void CreateTextbuttonGadgets() GDI_X, SX + textbutton_info[i].x, GDI_Y, SY + textbutton_info[i].y, GDI_TYPE, GD_TYPE_TEXT_BUTTON, - GDI_TEXT_VALUE, textbutton_info[i].value, + GDI_TEXT_VALUE, textbutton_info[i].text, GDI_TEXT_SIZE, textbutton_info[i].size, GDI_TEXT_FONT, FONT_INPUT_2_ACTIVE, GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2, @@ -2486,11 +2777,11 @@ static void CreateScrollbarGadgets() event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; - gd_x1 = DOOR_GFX_PAGEX8 + scrollbar_info[i].xpos; + 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].ypos; - gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].ypos; + gd_y1 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y; + gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, @@ -2804,16 +3095,60 @@ static void CopyCustomElementPropertiesToEditor(int element) { int i; + i = properties_element - EL_CUSTOM_START; + custom_element = level.custom_element[i]; + for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) custom_element_properties[i] = HAS_PROPERTY(element, i); + + for (i=0; i < NUM_CHANGE_EVENTS; i++) + custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i); + + /* set walk-to-object action selectbox help value */ + custom_element.walk_to_action = + (IS_DIGGABLE(element) ? EP_DIGGABLE : + IS_COLLECTIBLE(element) ? EP_COLLECTIBLE : + IS_PUSHABLE(element) ? EP_PUSHABLE : + EP_DIGGABLE); + + /* set walkable layer selectbox help value */ + custom_element.walkable_layer = + (IS_WALKABLE_OVER(element) ? EP_WALKABLE_OVER : + IS_WALKABLE_INSIDE(element) ? EP_WALKABLE_INSIDE : + IS_WALKABLE_UNDER(element) ? EP_WALKABLE_UNDER : + EP_WALKABLE_OVER); } static void CopyCustomElementPropertiesToGame(int element) { int i; + i = properties_element - EL_CUSTOM_START; + level.custom_element[i] = custom_element; + + /* set walk-to-object property from checkbox and selectbox */ + custom_element_properties[EP_DIGGABLE] = FALSE; + custom_element_properties[EP_COLLECTIBLE] = FALSE; + custom_element_properties[EP_PUSHABLE] = FALSE; + custom_element_properties[custom_element.walk_to_action] = + custom_element_properties[EP_WALK_TO_OBJECT]; + + /* set walkable property from checkbox and selectbox */ + custom_element_properties[EP_WALKABLE_OVER] = FALSE; + custom_element_properties[EP_WALKABLE_INSIDE] = FALSE; + custom_element_properties[EP_WALKABLE_UNDER] = FALSE; + custom_element_properties[custom_element.walkable_layer] = + custom_element_properties[EP_WALKABLE]; + for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) SET_PROPERTY(element, i, custom_element_properties[i]); + + for (i=0; i < NUM_CHANGE_EVENTS; i++) + SET_CHANGE_EVENT(element, i, custom_element_change_events[i]); + + /* copy change events also to special level editor variable */ + i = properties_element - EL_CUSTOM_START; + custom_element = level.custom_element[i]; } void DrawLevelEd() @@ -3009,6 +3344,41 @@ static void ModifyEditorCounterLimits(int counter_id, int min, int max) ModifyGadget(gi, GDI_NUMBER_MIN, min, GDI_NUMBER_MAX, max, GDI_END); } +static void ModifyEditorSelectbox(int selectbox_id, int new_value) +{ + int gadget_id = selectbox_info[selectbox_id].gadget_id; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + int new_index_value = 0; + int i; + + for(i=0; selectbox_info[selectbox_id].options[i].text != NULL; i++) + if (selectbox_info[selectbox_id].options[i].value == new_value) + new_index_value = i; + + *selectbox_info[selectbox_id].value = + selectbox_info[selectbox_id].options[new_index_value].value; + + ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END); +} + +static void ModifyEditorElementList() +{ + int i; + + for (i=0; ideco.design; + int element = editor_elements[element_shift + i]; + + UnmapGadget(gi); + getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y); + ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END); + MapGadget(gi); + } +} + static void PickDrawingElement(int button, int element) { if (button < 1 || button > 3) @@ -3039,8 +3409,17 @@ static void PickDrawingElement(int button, int element) redraw_mask |= REDRAW_DOOR_1; } +static void RedrawDrawingElements() +{ + PickDrawingElement(1, new_element1); + PickDrawingElement(2, new_element2); + PickDrawingElement(3, new_element3); +} + static void DrawDrawingWindow() { + stick_element_properties_window = FALSE; + SetMainBackgroundImage(IMG_UNDEFINED); ClearWindow(); UnmapLevelEditorWindowGadgets(); @@ -3054,9 +3433,11 @@ static void DrawDrawingWindow() MapMainDrawingArea(); } -static void DrawElementBorder(int dest_x, int dest_y, int width, int height) +static void DrawElementBorder(int dest_x, int dest_y, int width, int height, + boolean input) { - int border_graphic = IMG_EDITOR_ELEMENT_BORDER; + int border_graphic = + (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; @@ -3081,10 +3462,8 @@ static void DrawRandomPlacementBackgroundArea() int area_sx = SX + ED_AREA_RANDOM_BACKGROUND_XPOS; int area_sy = SY + ED_AREA_RANDOM_BACKGROUND_YPOS; - ElementContent[0][0][0] = random_placement_background_element; - - DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); - DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniElement(area_x, area_y, random_placement_background_element); MapDrawingArea(GADGET_ID_RANDOM_BACKGROUND); } @@ -3097,15 +3476,17 @@ static void DrawLevelInfoWindow() int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE); int xoffset_right = getCounterGadgetWidth(); int yoffset_right = ED_BORDER_SIZE; - int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE; + int xoffset_right2 = ED_SETTINGS_XOFFSET; int yoffset_right2 = ED_BORDER_SIZE; int i, x, y; + stick_element_properties_window = FALSE; + SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearWindow(); UnmapLevelEditorWindowGadgets(); - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS, + 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); @@ -3189,23 +3570,53 @@ static void DrawAmoebaContentArea() int area_sx = SX + ED_AREA_ELEM_CONTENT_XPOS; int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS; - ElementContent[0][0][0] = level.amoeba_content; - - DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); - DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniElement(area_x, area_y, level.amoeba_content); DrawText(area_sx + TILEX, area_sy + 1, "Content of amoeba", FONT_TEXT_1); MapDrawingArea(GADGET_ID_AMOEBA_CONTENT); } -static void DrawCustomChangedArea() +static void DrawCustomGraphicElementArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_GRAPHIC]; +#if 0 + int xoffset_right2 = ED_SETTINGS_XOFFSET; + int yoffset_right2 = ED_BORDER_SIZE; + int i = ED_CHECKBUTTON_ID_CUSTOM_GRAPHIC; + int text_len = strlen(checkbutton_info[i].text); + int text_width = text_len * getFontWidth(FONT_TEXT_1); + int xpos = checkbutton_info[i].x + 2 * xoffset_right2 + text_width; + int ypos = checkbutton_info[i].y + yoffset_right2; +#else + int xpos = ED_AREA_ELEM_CONTENT3_XPOS; + int ypos = ED_AREA_ELEM_CONTENT3_YPOS; +#endif + int area_sx = SX + xpos; + int area_sy = SY + ypos; + + if (!IS_CUSTOM_ELEMENT(properties_element)) + { + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); + + return; + } + + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniGraphicExt(drawto, gi->x, gi->y, + el2edimg(custom_element.gfx_element)); + + MapDrawingArea(GADGET_ID_CUSTOM_GRAPHIC); +} + +static void DrawCustomContentArea() { - int area_x = ED_AREA_ELEM_CONTENT2_XPOS / MINI_TILEX; - int area_y = ED_AREA_ELEM_CONTENT2_YPOS / MINI_TILEY; - int area_sx = SX + ED_AREA_ELEM_CONTENT2_XPOS; - int area_sy = SY + ED_AREA_ELEM_CONTENT2_YPOS; - int i = properties_element - EL_CUSTOM_START; + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CONTENT]; + int area_sx = SX + ED_AREA_ELEM_CONTENT4_XPOS; + int area_sy = SY + ED_AREA_ELEM_CONTENT4_YPOS; + int x, y; if (!IS_CUSTOM_ELEMENT(properties_element)) { @@ -3215,19 +3626,52 @@ static void DrawCustomChangedArea() return; } - ElementContent[0][0][0] = level.custom_element_successor[i]; + DrawElementBorder(area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE); + + for (y=0; y<3; y++) + for (x=0; x<3; x++) + DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX,gi->y + y * MINI_TILEY, + el2edimg(custom_element.content[x][y])); + + MapDrawingArea(GADGET_ID_CUSTOM_CONTENT); +} + +static void DrawCustomChangedArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGED]; +#if 0 + int xoffset_right2 = ED_SETTINGS_XOFFSET; + int yoffset_right2 = ED_BORDER_SIZE; + int i = ED_CHECKBUTTON_ID_CUSTOM_CHANGEABLE; + int text_len = strlen(checkbutton_info[i].text); + int text_width = text_len * getFontWidth(FONT_TEXT_1); + int xpos = checkbutton_info[i].x + 2 * xoffset_right2 + text_width; + int ypos = checkbutton_info[i].y + yoffset_right2; +#else + int xpos = ED_AREA_ELEM_CONTENT2_XPOS; + int ypos = ED_AREA_ELEM_CONTENT2_YPOS; +#endif + int area_sx = SX + xpos; + int area_sy = SY + ypos; - DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); - DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); + if (!IS_CUSTOM_ELEMENT(properties_element)) + { + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); - DrawText(area_sx + TILEX, area_sy + 1, "Element after change", FONT_TEXT_1); + return; + } + + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniGraphicExt(drawto, gi->x, gi->y, + el2edimg(custom_element.change.successor)); MapDrawingArea(GADGET_ID_CUSTOM_CHANGED); } static void DrawElementContentAreas() { - int counter_id = ED_COUNTER_ID_ELEM_CONTENT; + int counter_id = ED_COUNTER_ID_ELEMENT_CONTENT; int area_x = ED_AREA_ELEM_CONTENT_XPOS / MINI_TILEX; int area_y = ED_AREA_ELEM_CONTENT_YPOS / MINI_TILEY; int area_sx = SX + ED_AREA_ELEM_CONTENT_XPOS; @@ -3237,12 +3681,7 @@ static void DrawElementContentAreas() int i, x, y; for (i=0; i 0) + counterbutton_info[counter_id].value = elements_with_counter[i].value; + element_score_text = elements_with_counter[i].text; + element_has_score = TRUE; +#else + int x = counterbutton_info[counter_id].x + xoffset_right; + int y = counterbutton_info[counter_id].y + yoffset_right; + + counterbutton_info[counter_id].value = elements_with_counter[i].value; + DrawTextF(x, y, FONT_TEXT_1, elements_with_counter[i].text); + + ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value); + MapCounterButtons(counter_id); +#endif + break; + } + } + + if (IS_CUSTOM_ELEMENT(properties_element)) { - DrawTextF(pad_x, pad_y + screen_line * font2_height, font1_nr, - properties_text); - screen_line++; + counterbutton_info[counter_id].value = &temporary_dummy_score; + element_score_text = "Score for certain actions"; + element_has_score = TRUE; + } - for (i=0; properties[i].value != -1; i++) - { - if (!HAS_PROPERTY(properties_element, properties[i].value)) - continue; + if (element_has_score) + { + int x = counterbutton_info[counter_id].x + xoffset_right; + int y = counterbutton_info[counter_id].y + yoffset_right; + + DrawTextF(x, y, FONT_TEXT_1, element_score_text); + + ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value); + MapCounterButtons(counter_id); + } + + if (HAS_CONTENT(properties_element) || + IS_CUSTOM_ELEMENT(properties_element)) + { + /* draw stickybutton gadget */ + i = ED_CHECKBUTTON_ID_STICK_ELEMENT; + if (HAS_CONTENT(properties_element)) + checkbutton_info[i].y = ED_COUNTER_YPOS(4); + else + checkbutton_info[i].y = ED_SETTINGS_YPOS(1); + x = checkbutton_info[i].x + xoffset_right2; + y = checkbutton_info[i].y + yoffset_right2; - DrawTextF(pad_x, pad_y + screen_line * font2_height, font2_nr, - properties[i].text); - screen_line++; + DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text); + ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id], + GDI_CHECKED, *checkbutton_info[i].value, + GDI_Y, SY + checkbutton_info[i].y, GDI_END); + MapCheckbuttonGadget(i); + + if (IS_CUSTOM_ELEMENT(properties_element)) + { + DrawCustomGraphicElementArea(); + DrawCustomContentArea(); } + else if (IS_AMOEBOID(properties_element)) + DrawAmoebaContentArea(); + else + DrawElementContentAreas(); + } - screen_line++; + if (IS_GEM(properties_element)) + { + /* draw checkbutton gadget */ + i = ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS; + x = checkbutton_info[i].x + xoffset_right2; + y = checkbutton_info[i].y + yoffset_right2; + + DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text); + ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id], + GDI_CHECKED, *checkbutton_info[i].value, GDI_END); + MapCheckbuttonGadget(i); } -#endif - PrintInfoText("Description:", FONT_TEXT_1, screen_line); - if (PrintElementDescriptionFromFile(filename, screen_line + 1) == 0) - PrintInfoText("No description available.", FONT_TEXT_1, screen_line); + if (IS_CUSTOM_ELEMENT(properties_element)) + { + /* draw checkbutton gadgets */ + for (i = ED_CHECKBUTTON_ID_CUSTOM_FIRST; + i <= ED_CHECKBUTTON_ID_CUSTOM_LAST; i++) + { + x = checkbutton_info[i].x + xoffset_right2; + y = checkbutton_info[i].y + yoffset_right2; + + DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text); + ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id], + GDI_CHECKED, *checkbutton_info[i].value, GDI_END); + MapCheckbuttonGadget(i); + } + + /* draw selectbox gadgets */ + for (i=ED_SELECTBOX_ID_CUSTOM_FIRST; i <= ED_SELECTBOX_ID_CUSTOM_LAST; i++) + { + int yoffset = ED_BORDER_SIZE; + + x = selectbox_info[i].x; + y = selectbox_info[i].y + yoffset; + + DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text); + ModifyEditorSelectbox(i, *selectbox_info[i].value); + MapSelectboxGadget(i); + } + + /* draw textbutton gadgets */ + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE); + } } static void DrawPropertiesAdvanced() { - DrawText(SX + ED_SETTINGS_XPOS, SY + 5 * TILEY, - "Under construction! :-)", FONT_TEXT_1); + char infotext[MAX_OUTPUT_LINESIZE + 1]; + int max_infotext_len = getMaxInfoTextLength(); + int xoffset_right = getCounterGadgetWidth(); + int yoffset_right = ED_BORDER_SIZE; + int xoffset_right2 = ED_SETTINGS_XOFFSET; + int yoffset_right2 = ED_BORDER_SIZE; + int i, x, y; + + /* draw stickybutton gadget */ + i = ED_CHECKBUTTON_ID_STICK_ELEMENT; + checkbutton_info[i].y = ED_SETTINGS_YPOS(0); + x = checkbutton_info[i].x + xoffset_right2; + y = checkbutton_info[i].y + yoffset_right2; + + DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text); + ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id], + GDI_CHECKED, *checkbutton_info[i].value, + GDI_Y, SY + checkbutton_info[i].y, GDI_END); + MapCheckbuttonGadget(i); + + /* draw counter gadgets */ + for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++) + { + if (counterbutton_info[i].infotext_right) + { + x = counterbutton_info[i].x + xoffset_right; + y = counterbutton_info[i].y + yoffset_right; + + sprintf(infotext, "%s", counterbutton_info[i].infotext_right); + infotext[max_infotext_len] = '\0'; + DrawTextF(x, y, FONT_TEXT_1, infotext); + } + + ModifyEditorCounter(i, *counterbutton_info[i].value); + MapCounterButtons(i); + } + + /* draw checkbutton gadgets */ + for (i = ED_CHECKBUTTON_ID_CHANGE_FIRST; + i <= ED_CHECKBUTTON_ID_CHANGE_LAST; i++) + { + x = checkbutton_info[i].x + xoffset_right2; + y = checkbutton_info[i].y + yoffset_right2; + + DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text); + ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id], + GDI_CHECKED, *checkbutton_info[i].value, GDI_END); + MapCheckbuttonGadget(i); + } + + /* draw selectbox gadgets */ + for (i=ED_SELECTBOX_ID_CHANGE_FIRST; i<=ED_SELECTBOX_ID_CHANGE_LAST; i++) + { + int yoffset = ED_BORDER_SIZE; + + x = selectbox_info[i].x; + y = selectbox_info[i].y + yoffset; + + DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text); + ModifyEditorSelectbox(i, *selectbox_info[i].value); + MapSelectboxGadget(i); + } + + DrawCustomChangedArea(); } static void DrawPropertiesWindow() @@ -3788,6 +4327,8 @@ static void DrawPropertiesWindow() int xstart = 2; int ystart = 4; + stick_element_properties_window = FALSE; + /* make sure that previous properties edit mode exists for this element */ if (edit_mode_properties == ED_MODE_PROPERTIES_ADVANCED && !IS_CUSTOM_ELEMENT(properties_element)) @@ -3797,17 +4338,20 @@ static void DrawPropertiesWindow() !checkPropertiesConfig()) edit_mode_properties = ED_MODE_PROPERTIES_INFO; + if (IS_CUSTOM_ELEMENT(properties_element)) + CopyCustomElementPropertiesToEditor(properties_element); + UnmapLevelEditorWindowGadgets(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearWindow(); - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS, + DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, "Element Settings", FONT_TITLE_1); DrawElementBorder(SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, - TILEX, TILEY); + TILEX, TILEY, FALSE); DrawGraphicAnimationExt(drawto, SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, @@ -4450,6 +4994,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) int sx = gi->event.x, sy = gi->event.y; int min_sx = 0, min_sy = 0; int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1; + int item_xsize = gi->drawing.item_xsize, item_ysize = gi->drawing.item_ysize; int lx = 0, ly = 0; int min_lx = 0, min_ly = 0; int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; @@ -4494,7 +5039,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) /* automatically switch to 'single item' drawing mode, if needed */ actual_drawing_function = - (draw_level ? drawing_function : GADGET_ID_SINGLE_ITEMS); + (draw_level || drawing_function == GADGET_ID_PICK_ELEMENT ? + drawing_function : GADGET_ID_SINGLE_ITEMS); switch (actual_drawing_function) { @@ -4545,29 +5091,51 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) } else { - DrawMiniGraphicExt(drawto, - gi->x + sx * MINI_TILEX, - gi->y + sy * MINI_TILEY, - el2edimg(new_element)); - DrawMiniGraphicExt(window, - gi->x + sx * MINI_TILEX, - gi->y + sy * MINI_TILEY, - el2edimg(new_element)); + if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY) + DrawMiniGraphicExt(drawto, + gi->x + sx * MINI_TILEX, + gi->y + sy * MINI_TILEY, + el2edimg(new_element)); + else + DrawGraphicExt(drawto, + gi->x + sx * TILEX, + gi->y + sy * TILEY, + el2img(new_element), 0); if (id == GADGET_ID_AMOEBA_CONTENT) level.amoeba_content = new_element; - else if (id == GADGET_ID_CUSTOM_CHANGED && - IS_CUSTOM_ELEMENT(properties_element)) + else if (id == GADGET_ID_CUSTOM_GRAPHIC) + { + int i = properties_element - EL_CUSTOM_START; + + new_element = GFX_ELEMENT(new_element); + custom_element.gfx_element = new_element; + level.custom_element[i] = custom_element; + + ModifyEditorElementList(); + RedrawDrawingElements(); + + FrameCounter = 0; /* restart animation frame counter */ + } + else if (id == GADGET_ID_CUSTOM_CONTENT) + { + int i = properties_element - EL_CUSTOM_START; + + custom_element.content[sx][sy] = new_element; + level.custom_element[i] = custom_element; + } + else if (id == GADGET_ID_CUSTOM_CHANGED) { int i = properties_element - EL_CUSTOM_START; - level.custom_element_successor[i] = new_element; + custom_element.change.successor = new_element; + level.custom_element[i] = custom_element; } else if (id == GADGET_ID_RANDOM_BACKGROUND) random_placement_background_element = new_element; - else if (id >= GADGET_ID_ELEM_CONTENT_0 && - id <= GADGET_ID_ELEM_CONTENT_7) - level.yam_content[id - GADGET_ID_ELEM_CONTENT_0][sx][sy] = + else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && + id <= GADGET_ID_ELEMENT_CONTENT_7) + level.yamyam_content[id - GADGET_ID_ELEMENT_CONTENT_0][sx][sy] = new_element; } break; @@ -4665,8 +5233,25 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (button_release_event) ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFTBUTTON); - else + else if (draw_level) PickDrawingElement(button, Feld[lx][ly]); + else if (id == GADGET_ID_AMOEBA_CONTENT) + PickDrawingElement(button, level.amoeba_content); + else if (id == GADGET_ID_CUSTOM_GRAPHIC) + PickDrawingElement(button, custom_element.gfx_element); + else if (id == GADGET_ID_CUSTOM_CONTENT) + PickDrawingElement(button, custom_element.content[sx][sy]); + else if (id == GADGET_ID_CUSTOM_CHANGED) + PickDrawingElement(button, custom_element.change.successor); + else if (id == GADGET_ID_RANDOM_BACKGROUND) + PickDrawingElement(button, random_placement_background_element); + else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && + id <= GADGET_ID_ELEMENT_CONTENT_7) + { + int i = id - GADGET_ID_ELEMENT_CONTENT_0; + + PickDrawingElement(button, level.yamyam_content[i][sx][sy]); + } break; @@ -4709,7 +5294,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi) switch (counter_id) { - case ED_COUNTER_ID_ELEM_CONTENT: + case ED_COUNTER_ID_ELEMENT_CONTENT: DrawElementContentAreas(); break; @@ -4729,6 +5314,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) default: break; } + + if (counter_id >= ED_COUNTER_ID_CHANGE_FIRST && + counter_id <= ED_COUNTER_ID_CHANGE_LAST) + CopyCustomElementPropertiesToGame(properties_element); } static void HandleTextInputGadgets(struct GadgetInfo *gi) @@ -4741,6 +5330,14 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) int type_id = gi->custom_type_id; *selectbox_info[type_id].index = gi->selectbox.index; + *selectbox_info[type_id].value = + selectbox_info[type_id].options[gi->selectbox.index].value; + + if ((type_id >= ED_SELECTBOX_ID_CUSTOM_FIRST && + type_id <= ED_SELECTBOX_ID_CUSTOM_LAST) || + (type_id >= ED_SELECTBOX_ID_CHANGE_FIRST && + type_id <= ED_SELECTBOX_ID_CHANGE_LAST)) + CopyCustomElementPropertiesToGame(properties_element); #if 0 printf("Selected text value: '%s' [%d]\n", @@ -4772,9 +5369,17 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) *checkbutton_info[type_id].value ^= TRUE; - if (type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST && - type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) + if ((type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST && + type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) || + (type_id >= ED_CHECKBUTTON_ID_CHANGE_FIRST && + type_id <= ED_CHECKBUTTON_ID_CHANGE_LAST)) CopyCustomElementPropertiesToGame(properties_element); + + if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC) + { + ModifyEditorElementList(); + RedrawDrawingElements(); + } } static void HandleControlButtons(struct GadgetInfo *gi) @@ -4783,13 +5388,14 @@ static void HandleControlButtons(struct GadgetInfo *gi) int button = gi->event.button; int step = BUTTON_STEPSIZE(button); int new_element = BUTTON_ELEMENT(button); - int i, x, y; + int x, y; if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT) DrawLevelText(0, 0, 0, TEXT_END); if (id < ED_NUM_CTRL1_BUTTONS && id != GADGET_ID_PROPERTIES && - edit_mode != ED_MODE_DRAWING) + id != GADGET_ID_PICK_ELEMENT && edit_mode != ED_MODE_DRAWING && + drawing_function != GADGET_ID_PICK_ELEMENT) { DrawDrawingWindow(); edit_mode = ED_MODE_DRAWING; @@ -4903,18 +5509,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); } - for (i=0; ideco.design; - int element = editor_elements[element_shift + i]; - - UnmapGadget(gi); - getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y); - ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END); - MapGadget(gi); - } + ModifyEditorElementList(); + break; case GADGET_ID_WRAP_LEFT: @@ -4943,7 +5539,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) case GADGET_ID_FLOOD_FILL: case GADGET_ID_GRAB_BRUSH: case GADGET_ID_PICK_ELEMENT: - last_drawing_function = drawing_function; + if (drawing_function != GADGET_ID_PICK_ELEMENT) + last_drawing_function = drawing_function; drawing_function = id; draw_with_brush = FALSE; break; @@ -5066,12 +5663,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) PickDrawingElement(button, new_element); -#if 1 - if (!stick_element_properties_window) -#else - if (!HAS_CONTENT(properties_element) || - !stick_element_properties_window) -#endif + if (!stick_element_properties_window && + drawing_function != GADGET_ID_PICK_ELEMENT) { properties_element = new_element; if (edit_mode == ED_MODE_PROPERTIES) @@ -5360,19 +5953,55 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) DeleteBrushFromCursor(); } } - else if (id == GADGET_ID_AMOEBA_CONTENT) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Amoeba content"); - else if (id == GADGET_ID_CUSTOM_CHANGED) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Next element after change"); - else if (id == GADGET_ID_RANDOM_BACKGROUND) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Random placement background"); + else if (drawing_function == GADGET_ID_PICK_ELEMENT) + { + if (id == GADGET_ID_AMOEBA_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(level.amoeba_content)); + else if (id == GADGET_ID_CUSTOM_GRAPHIC) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(custom_element.use_gfx_element)); + else if (id == GADGET_ID_CUSTOM_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(custom_element.content[sx][sy])); + else if (id == GADGET_ID_CUSTOM_CHANGED) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(custom_element.change.successor)); + else if (id == GADGET_ID_RANDOM_BACKGROUND) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(random_placement_background_element)); + else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && + id <= GADGET_ID_ELEMENT_CONTENT_7) + { + int i = id - GADGET_ID_ELEMENT_CONTENT_0; + + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(level.yamyam_content[i][sx][sy])); + } + } else - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Content area %d position: %d, %d", - id - GADGET_ID_ELEM_CONTENT_0 + 1, sx, sy); + { + if (id == GADGET_ID_AMOEBA_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Amoeba content"); + else if (id == GADGET_ID_CUSTOM_GRAPHIC) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Custom graphic element"); + else if (id == GADGET_ID_CUSTOM_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Custom element content position: %d, %d", sx, sy); + else if (id == GADGET_ID_CUSTOM_CHANGED) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "New element after change"); + else if (id == GADGET_ID_RANDOM_BACKGROUND) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Random placement background"); + else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && + id <= GADGET_ID_ELEMENT_CONTENT_7) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Content area %d position: %d, %d", + id - GADGET_ID_ELEMENT_CONTENT_0 + 1, sx, sy); + } } void RequestExitLevelEditor(boolean ask_if_level_has_changed)