X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=778232e23fc507e9287a4df15b72247fca34ca05;hb=a85d66e030463ca9cf9700888481ebf2a04f8740;hp=8e326ea29e5fe32324bbf40c97b7f8aabaacc448;hpb=5371d88561e5304599c11e33ed98dc3e5868f69f;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 8e326ea2..778232e2 100644 --- a/src/editor.c +++ b/src/editor.c @@ -67,45 +67,64 @@ #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_XPOS2 (3 * MINI_TILEX + 8) -#define ED_SETTINGS_YPOS MINI_TILEY -#define ED_SETTINGS2_XPOS MINI_TILEX -#define ED_SETTINGS2_YPOS (ED_SETTINGS_YPOS + 12 * TILEY - 2) +#define ED_SETTINGS_XSTART (3 * MINI_TILEX / 2) +#define ED_SETTINGS_YSTART (MINI_TILEY * 10) -/* values for counter gadgets */ -#define ED_COUNT_ELEMENT_SCORE_XPOS ED_SETTINGS_XPOS -#define ED_COUNT_ELEMENT_SCORE_YPOS (11 * MINI_TILEY) -#define ED_COUNT_ELEMENT_CONTENT_XPOS ED_SETTINGS_XPOS -#define ED_COUNT_ELEMENT_CONTENT_YPOS (19 * MINI_TILEY) +#define ED_XOFFSET_CHECKBOX (ED_CHECKBUTTON_XSIZE + \ + 2 * ED_GADGET_DISTANCE) -#define ED_COUNT_CHANGE_DELAY_XPOS (ED_SETTINGS_XPOS2 + 9 * MINI_TILEX) +#define ED_SETTINGS_XOFFSET ED_XOFFSET_CHECKBOX +#define ED_SETTINGS_YOFFSET (3 * MINI_TILEY / 2) -#define ED_COUNT_CHANGE_DELAY_XPOS (ED_SETTINGS_XPOS2 + 9 * MINI_TILEX) +#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_COUNTER_YSTART (ED_SETTINGS_YPOS + 2 * TILEY) +#define ED_SETTINGS1_YPOS MINI_TILEY +#define ED_SETTINGS2_XPOS MINI_TILEX +#define ED_SETTINGS2_YPOS (ED_SETTINGS1_YPOS + 12 * TILEY - 2) + +/* values for counter gadgets */ +#define ED_COUNT_PUSH_DELAY_RND_XPOS (ED_SETTINGS_XPOS(1) + 16 * MINI_TILEX) +#define ED_COUNT_MOVE_DELAY_RND_XPOS ED_COUNT_PUSH_DELAY_RND_XPOS +#define ED_COUNT_CHANGE_DELAY_RND_XPOS (ED_SETTINGS_XPOS(1) + 13 * 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 (20 * MINI_TILEX) -#define ED_AREA_ELEM_CONTENT2_YPOS (ED_COUNTER_YPOS2(5) + \ +#define ED_AREA_ELEM_CONTENT2_YPOS (ED_SETTINGS_YPOS(2) + \ + ED_GADGET_DISTANCE) + +#define ED_AREA_ELEM_CONTENT3_XPOS (24 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT3_YPOS (ED_SETTINGS_YPOS(1) + \ ED_GADGET_DISTANCE) +#if 1 +#define ED_AREA_ELEM_CONTENT4_XPOS (29 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(3) + \ + ED_GADGET_DISTANCE - MINI_TILEY) +#else +#define ED_AREA_ELEM_CONTENT4_XPOS (17 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(11) + \ + ED_GADGET_DISTANCE - MINI_TILEY) +#endif + /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) #define ED_AREA_RANDOM_BACKGROUND_YPOS (31 * MINI_TILEY) @@ -204,15 +223,17 @@ #define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE #define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE -#define ED_SELECTBOX_CHANGE_UNITS_XPOS (ED_SETTINGS_XPOS2 + \ - ED_CHECKBUTTON_XSIZE + \ - 2 * ED_GADGET_DISTANCE) - #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 @@ -286,15 +307,30 @@ #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) +#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 28) +#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 29) +#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 30) +#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 31) +#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 32) +#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 33) +#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 34) +#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 35) +#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 36) +#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 37) +#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 38) +#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 39) +#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 40) +#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 41) +#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 42) +#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 43) +#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 44) +#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 45) +#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 46) +#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 47) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 33) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 48) #define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0) #define GADGET_ID_ELEMENT_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) @@ -307,11 +343,12 @@ #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_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 10) -#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 11) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 12) +#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 + 13) +#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) @@ -319,18 +356,25 @@ /* selectbox identifiers */ #define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 2) -#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 0) -#define GADGET_ID_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 1) +#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 0) +#define GADGET_ID_CUSTOM_CONSISTENCY (GADGET_ID_SELECTBOX_FIRST + 1) +#define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 2) +#define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 3) +#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 4) +#define GADGET_ID_CUSTOM_WALKABLE_LAYER (GADGET_ID_SELECTBOX_FIRST + 5) +#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 6) +#define GADGET_ID_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 7) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 2) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 8) #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) @@ -346,7 +390,7 @@ #define GADGET_ID_SCROLL_LIST_DOWN (GADGET_ID_SCROLLING_LIST_FIRST + 1) #define GADGET_ID_SCROLL_LIST_VERTICAL (GADGET_ID_SCROLLING_LIST_FIRST + 2) -/* buttons for level/element properties */ +/* checkbuttons for level/element properties */ #define GADGET_ID_CHECKBUTTON_FIRST (GADGET_ID_SCROLLING_LIST_FIRST + 3) #define GADGET_ID_RANDOM_PERCENTAGE (GADGET_ID_CHECKBUTTON_FIRST + 0) @@ -356,23 +400,21 @@ #define GADGET_ID_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 4) #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_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 8) -#define GADGET_ID_CUSTOM_COLLECTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_CUSTOM_PUSHABLE (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_CUSTOM_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 7) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 8) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 9) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 10) #define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 11) #define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_CUSTOM_WALKABLE_OVER (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_CUSTOM_WALKABLE_INSIDE (GADGET_ID_CHECKBUTTON_FIRST+ 16) -#define GADGET_ID_CUSTOM_WALKABLE_UNDER (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_CUSTOM_CHANGEABLE (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CHANGE_DELAY_FIXED (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_CHANGE_DELAY_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 20) +#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 (GADGET_ID_CHECKBUTTON_FIRST + 18) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 19) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -393,14 +435,22 @@ #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_COUNTER_ID_CUSTOM_SCORE 9 +#define ED_COUNTER_ID_PUSH_DELAY_FIX 10 +#define ED_COUNTER_ID_PUSH_DELAY_RND 11 +#define ED_COUNTER_ID_MOVE_DELAY_FIX 12 +#define ED_COUNTER_ID_MOVE_DELAY_RND 13 +#define ED_COUNTER_ID_CHANGE_DELAY_FIX 14 +#define ED_COUNTER_ID_CHANGE_DELAY_RND 15 -#define ED_NUM_COUNTERBUTTONS 11 +#define ED_NUM_COUNTERBUTTONS 16 #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_CUSTOM_FIRST ED_COUNTER_ID_CUSTOM_SCORE +#define ED_COUNTER_ID_CUSTOM_LAST ED_COUNTER_ID_MOVE_DELAY_RND + #define ED_COUNTER_ID_CHANGE_FIRST ED_COUNTER_ID_CHANGE_DELAY_FIX #define ED_COUNTER_ID_CHANGE_LAST ED_COUNTER_ID_CHANGE_DELAY_RND @@ -437,10 +487,19 @@ #define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR /* values for selectbox gadgets */ -#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 0 -#define ED_SELECTBOX_ID_CHANGE_CAUSE 1 +#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 0 +#define ED_SELECTBOX_ID_CUSTOM_CONSISTENCY 1 +#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 2 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 3 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 4 +#define ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER 5 +#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 6 +#define ED_SELECTBOX_ID_CHANGE_CAUSE 7 -#define ED_NUM_SELECTBOX 2 +#define ED_NUM_SELECTBOX 8 + +#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 @@ -449,8 +508,9 @@ #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 @@ -458,31 +518,29 @@ #define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 2 #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_DIGGABLE 6 -#define ED_CHECKBUTTON_ID_CUSTOM_COLLECTIBLE 7 -#define ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE 8 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 5 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 6 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 7 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 8 #define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 9 #define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 10 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 11 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 12 -#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_OVER 13 -#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_INSIDE 14 -#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_UNDER 15 -#define ED_CHECKBUTTON_ID_CUSTOM_CHANGEABLE 16 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY_FIXED 17 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY_RANDOM 18 +#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 16 -#define ED_NUM_CHECKBUTTONS 19 +#define ED_NUM_CHECKBUTTONS 17 #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_WALKABLE_UNDER +#define ED_CHECKBUTTON_ID_CUSTOM_FIRST ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT +#define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM_WALKABLE -#define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_CHANGEABLE -#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_DELAY_RANDOM +#define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_DELAY /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -580,7 +638,7 @@ 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 CustomElementChangeInfo custom_element_change; +static struct ElementInfo custom_element; static struct { @@ -589,7 +647,7 @@ static struct int gadget_id_down, gadget_id_up; int gadget_id_text; int *value; - char *infotext_above, *infotext_right; + char *text_above, *text_left, *text_right; } counterbutton_info[ED_NUM_COUNTERBUTTONS] = { { @@ -598,87 +656,127 @@ static struct GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, GADGET_ID_SELECT_LEVEL_TEXT, &level_nr, - NULL, NULL + NULL, 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, &level.fieldx, - "playfield size", "width", + "playfield size", NULL, "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, &level.fieldy, - NULL, "height", + NULL, 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, &level.gems_needed, - "number of emeralds to collect", NULL + "number of emeralds to collect", NULL, 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, &level.time, - "time available to solve level", "(0 => no time limit)" + "time available to solve level", NULL, "(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, &level.score[SC_TIME_BONUS], - "score for each 10 seconds left", NULL + "score for each 10 seconds left", NULL, 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, &random_placement_value, - "random element placement", "in" + "random element placement", NULL, "in" }, { - ED_COUNT_ELEMENT_SCORE_XPOS, ED_COUNT_ELEMENT_SCORE_YPOS, + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0), 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 + NULL, NULL, NULL }, { - ED_COUNT_ELEMENT_CONTENT_XPOS, ED_COUNT_ELEMENT_CONTENT_YPOS, + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(6), MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, GADGET_ID_ELEMENT_CONTENT_DOWN, GADGET_ID_ELEMENT_CONTENT_UP, GADGET_ID_ELEMENT_CONTENT_TEXT, - &level.num_yam_contents, - "element content", NULL + &level.num_yamyam_contents, + NULL, NULL, "number of content areas" + }, + { + ED_SETTINGS_XPOS(9), ED_SETTINGS_YPOS(4), + MIN_SCORE, MAX_SCORE, + GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, + GADGET_ID_CUSTOM_SCORE_TEXT, + &custom_element.score, + NULL, "score", NULL }, { - ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(6), + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5), + 0, 999, + GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP, + GADGET_ID_PUSH_DELAY_FIX_TEXT, + &custom_element.push_delay_fixed, + NULL, "push delay", NULL + }, + { + ED_COUNT_PUSH_DELAY_RND_XPOS, ED_SETTINGS_YPOS(5), + 0, 999, + GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP, + GADGET_ID_PUSH_DELAY_RND_TEXT, + &custom_element.push_delay_random, + NULL, "+random", NULL + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8), + 0, 999, + GADGET_ID_MOVE_DELAY_FIX_DOWN, GADGET_ID_MOVE_DELAY_FIX_UP, + GADGET_ID_MOVE_DELAY_FIX_TEXT, + &custom_element.move_delay_fixed, + NULL, "move delay", NULL + }, + { + ED_COUNT_MOVE_DELAY_RND_XPOS, ED_SETTINGS_YPOS(8), + 0, 999, + GADGET_ID_MOVE_DELAY_RND_DOWN, GADGET_ID_MOVE_DELAY_RND_UP, + GADGET_ID_MOVE_DELAY_RND_TEXT, + &custom_element.move_delay_random, + NULL, "+random", NULL + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(3), 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)" + &custom_element.change.delay_fixed, + NULL, "delay", NULL, }, { - ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(7), + ED_COUNT_CHANGE_DELAY_RND_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)" + &custom_element.change.delay_random, + NULL, "+random", NULL } }; @@ -692,14 +790,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, @@ -707,22 +805,87 @@ static struct } }; -static struct ValueTextInfo options_change_time_units[] = +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_pattern[] = +{ + { MV_LEFT, "left" }, + { MV_RIGHT, "right" }, + { MV_UP, "up" }, + { MV_DOWN, "down" }, + { MV_HORIZONTAL, "horizontal" }, + { MV_VERTICAL, "vertical" }, + { MV_ALL_DIRECTIONS, "all directions" }, + { MV_TOWARDS_PLAYER, "towards player" }, + { MV_AWAY_FROM_PLAYER, "away from player" }, + { MV_ALONG_LEFT_SIDE, "along left side" }, + { MV_ALONG_RIGHT_SIDE, "along right side" }, + { -1, NULL } +}; +static int index_move_pattern = 0; + +static struct ValueTextInfo options_move_direction[] = { - { 50, "seconds" }, - { 1, "frames" }, - { -1, NULL } + { MV_NO_MOVING, "automatic" }, + { MV_LEFT, "left" }, + { MV_RIGHT, "right" }, + { MV_UP, "up" }, + { MV_DOWN, "down" }, + { -1, NULL } }; -static int index_change_time_units = 0; +static int index_move_direction = 0; + +static struct ValueTextInfo options_consistency[] = +{ + { EP_INDESTRUCTIBLE, "indestructible" }, + { EP_CAN_EXPLODE_BY_FIRE, "can explode by fire" }, + { EP_CAN_EXPLODE_SMASHED, "can explode when smashed" }, + { EP_CAN_EXPLODE_IMPACT, "can explode on impact" }, + { -1, NULL } +}; +static int index_consistency = 0; + +static struct ValueTextInfo options_deadliness[] = +{ + { EP_DONT_RUN_INTO, "running into" }, + { EP_DONT_COLLIDE_WITH, "colliding with" }, + { EP_DONT_TOUCH, "touching" }, + { -1, NULL } +}; +static int index_deadliness = 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, value_change_cause = 0; @@ -730,27 +893,75 @@ static struct { int x, y; int gadget_id; - int size; /* size of selectbox (chars) or '0' (dynamically determined) */ + int size; /* char size of selectbox or '-1' (dynamically determined) */ struct ValueTextInfo *options; int *index, *value; - char *text, *infotext; + char *text_left, *text_right, *infotext; } selectbox_info[ED_NUM_SELECTBOX] = { { - ED_SELECTBOX_CHANGE_UNITS_XPOS, ED_COUNTER_YPOS2(8), + 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, NULL, "diggable/collectible/pushable" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_CONSISTENCY, + -1, + options_consistency, &index_consistency, + &custom_element.consistency, + NULL, "to", "consistency/destructibility" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_DEADLINESS, + -1, + options_deadliness, &index_deadliness, + &custom_element.deadliness, + "deadly when", NULL, "deadliness of element" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), + GADGET_ID_CUSTOM_MOVE_PATTERN, + -1, + options_move_pattern, &index_move_pattern, + &custom_element.move_pattern, + "can move", NULL, "element move direction" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7), + GADGET_ID_CUSTOM_MOVE_DIRECTION, + -1, + options_move_direction, &index_move_direction, + &custom_element.move_direction_initial, + "starts moving", NULL, "initial element move direction" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_WALKABLE_LAYER, + -1, + options_walkable_layer, &index_walkable_layer, + &custom_element.walkable_layer, + "player can walk", NULL, "layer where player can walk" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(4), GADGET_ID_CHANGE_TIME_UNITS, - 0, - options_change_time_units, &index_change_time_units, - &custom_element_change.delay_frames, - "delay units given in", "time units for change" + -1, + options_time_units, &index_time_units, + &custom_element.change.delay_frames, + "delay time given in", NULL, "delay time units for change" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(8), + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(8), GADGET_ID_CHANGE_CAUSE, - 0, + -1, options_change_cause, &index_change_cause, &value_change_cause, - "test:", "test-selectbox entry" + "test:", NULL, "test-selectbox entry" }, }; @@ -759,33 +970,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(5), + 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; @@ -831,7 +1043,7 @@ static struct static struct { - int xpos, ypos; + int gd_x, gd_y; int x, y; int width, height; int type; @@ -872,18 +1084,18 @@ static struct int radio_button_nr; int *value; int checked_value; - char *text, *infotext; + char *text_right, *infotext; } 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, @@ -896,123 +1108,111 @@ static struct int x, y; int gadget_id; boolean *value; - char *text, *infotext; + char *text_right, *infotext; } 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, 0, /* set at runtime */ + ED_SETTINGS_XPOS(0), 0, /* set at runtime */ GADGET_ID_STICK_ELEMENT, &stick_element_properties_window, "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(6), - GADGET_ID_CUSTOM_INDESTRUCTIBLE, - &custom_element_properties[EP_INDESTRUCTIBLE], - "indestructible", "element cannot be destroyed" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_EXPLODE_RESULT, + &custom_element_properties[EP_EXPLODE_RESULT], + NULL, "set consistency/destructibility" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(7), - GADGET_ID_CUSTOM_DIGGABLE, - &custom_element_properties[EP_DIGGABLE], - "diggable", "element can be digged away" + 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, ED_COUNTER_YPOS2(8), - GADGET_ID_CUSTOM_COLLECTIBLE, - &custom_element_properties[EP_COLLECTIBLE], - "collectible", "element can be collected" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_DEADLY, + &custom_element_properties[EP_DEADLY], + NULL, "element can kill the player" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(9), - GADGET_ID_CUSTOM_PUSHABLE, - &custom_element_properties[EP_PUSHABLE], - "pushable", "element can be pushed" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(6), + GADGET_ID_CUSTOM_CAN_MOVE, + &custom_element_properties[EP_CAN_MOVE], + NULL, "element can move in some direction" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(10), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_CAN_FALL, &custom_element_properties[EP_CAN_FALL], "can fall", "element can fall down" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(11), + ED_SETTINGS_XPOS(6), ED_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_CAN_SMASH, &custom_element_properties[EP_CAN_SMASH], - "can smash", "element can smash other elements" - }, - { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(12), - GADGET_ID_CUSTOM_CAN_MOVE, - &custom_element_properties[EP_CAN_MOVE], - "can move", "element can move in some direction" + "can smash on impact", "element can smash other elements" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(13), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), GADGET_ID_CUSTOM_SLIPPERY, &custom_element_properties[EP_SLIPPERY], "slippery", "other elements can fall down from it" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(14), - GADGET_ID_CUSTOM_WALKABLE_OVER, - &custom_element_properties[EP_WALKABLE_OVER], - "player can walk over", "player can walk over this element" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_WALKABLE, + &custom_element_properties[EP_WALKABLE], + NULL, "player can walk on the same field" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(15), - GADGET_ID_CUSTOM_WALKABLE_INSIDE, - &custom_element_properties[EP_WALKABLE_INSIDE], - "player can walk inside", "player can walk inside this element" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_USE_GRAPHIC, + &custom_element.use_gfx_element, + "use graphic of element:", "use graphic for custom element" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(16), - GADGET_ID_CUSTOM_WALKABLE_UNDER, - &custom_element_properties[EP_WALKABLE_UNDER], - "player can walk under", "player can walk under this element" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_USE_TEMPLATE, + &custom_element.use_template, + "use template", "use template for custom properties" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(5), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_CHANGEABLE, &custom_element_properties[EP_CHANGEABLE], "element changes to after:", "element can change to other element" }, { - ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(6), - 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, + &custom_element_change_events[CE_DELAY], + NULL, "element changes after delay" }, - { - ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(7), - GADGET_ID_CHANGE_DELAY_RANDOM, - &custom_element_change_events[CE_DELAY_RANDOM], - "delay of", "element changes after random delay" - } }; @@ -1048,6 +1248,7 @@ 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 *); @@ -1066,7 +1267,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; @@ -2095,8 +2295,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; } @@ -2106,8 +2306,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; } @@ -2196,6 +2396,13 @@ static void CreateCounterButtons() int j; int xpos = SX + counterbutton_info[i].x; /* xpos of down count button */ int ypos = SY + counterbutton_info[i].y; + int xoffset = 0; + + /* determine horizontal offset for leading counter text */ + if (counterbutton_info[i].text_left != NULL) + xoffset = (getFontWidth(FONT_TEXT_1) * + strlen(counterbutton_info[i].text_left) + + 2 * ED_GADGET_DISTANCE); for (j=0; j<2; j++) { @@ -2224,9 +2431,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; } @@ -2246,7 +2453,7 @@ static void CreateCounterButtons() gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, infotext, - GDI_X, xpos, + GDI_X, xpos + xoffset, GDI_Y, ypos, GDI_WIDTH, x_size, GDI_HEIGHT, y_size, @@ -2295,7 +2502,7 @@ static void CreateCounterButtons() gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, "enter counter value", - GDI_X, xpos, + GDI_X, xpos + xoffset, GDI_Y, ypos, GDI_TYPE, GD_TYPE_TEXTINPUT_NUMERIC, GDI_NUMBER_VALUE, 0, @@ -2400,12 +2607,32 @@ static void CreateDrawingAreas() /* ... one for each custom element optional graphic element ... */ id = GADGET_ID_CUSTOM_GRAPHIC; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_X, SX + 2 * MINI_TILEX, - GDI_Y, SY + 4 * MINI_TILEY + MINI_TILEY / 2, - GDI_WIDTH, TILEX, - GDI_HEIGHT, TILEY, + 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, TILEX, TILEY, + GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleDrawingAreaInfo, GDI_CALLBACK_ACTION, HandleDrawingAreas, @@ -2513,29 +2740,37 @@ static void CreateSelectboxGadgets() { Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; int gd_x, gd_y; - int xoffset; + int xoffset = 0; struct GadgetInfo *gi; unsigned long event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = selectbox_info[i].gadget_id; - /* (we cannot use -1 for uninitialized values if we directly compare - with results from strlen(), because the '<' and '>' operation will - implicitely cast -1 to an unsigned integer value!) */ + if (selectbox_info[i].size == -1) /* dynamically determine size */ + { + /* (we cannot use -1 for uninitialized values if we directly compare + with results from strlen(), because the '<' and '>' operation will + implicitely cast -1 to an unsigned integer value!) */ + selectbox_info[i].size = 0; - if (selectbox_info[i].size == 0) /* dynamically determined */ 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; - xoffset = (getFontWidth(FONT_TEXT_1) * strlen(selectbox_info[i].text) + - 2 * ED_GADGET_DISTANCE); + /* determine horizontal offset for leading selectbox text */ + if (selectbox_info[i].text_left != NULL) + xoffset = (getFontWidth(FONT_TEXT_1) * + strlen(selectbox_info[i].text_left) + + 2 * ED_GADGET_DISTANCE); sprintf(infotext, "Select %s", selectbox_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -2582,12 +2817,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'; @@ -2598,7 +2846,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, @@ -2657,11 +2905,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,6 +3052,50 @@ void FreeLevelEditorGadgets() static void MapCounterButtons(int id) { + char infotext[MAX_OUTPUT_LINESIZE + 1]; + int max_infotext_len = getMaxInfoTextLength(); + int xoffset_above = 0; + int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE); + int xoffset_left = 0; + int yoffset_left = ED_BORDER_SIZE; + int xoffset_right = getCounterGadgetWidth(); + int yoffset_right = ED_BORDER_SIZE; + int x, y; + + if (counterbutton_info[id].text_above) + { + x = SX + counterbutton_info[id].x + xoffset_above; + y = SY + counterbutton_info[id].y + yoffset_above; + + sprintf(infotext, "%s:", counterbutton_info[id].text_above); + infotext[max_infotext_len] = '\0'; + DrawText(x, y, infotext, FONT_TEXT_1); + } + + if (counterbutton_info[id].text_left) + { + x = SX + counterbutton_info[id].x + xoffset_left; + y = SY + counterbutton_info[id].y + yoffset_left; + + sprintf(infotext, "%s", counterbutton_info[id].text_left); + infotext[max_infotext_len] = '\0'; + DrawText(x, y, infotext, FONT_TEXT_1); + } + + if (counterbutton_info[id].text_right) + { + int gadget_id = counterbutton_info[id].gadget_id_down; + + x = level_editor_gadget[gadget_id]->x + xoffset_right; + y = SY + counterbutton_info[id].y + yoffset_right; + + sprintf(infotext, "%s", counterbutton_info[id].text_right); + infotext[max_infotext_len] = '\0'; + DrawText(x, y, infotext, FONT_TEXT_1); + } + + ModifyEditorCounter(id, *counterbutton_info[id].value); + MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_down]); MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_text]); MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_up]); @@ -2830,7 +3122,6 @@ static void MapControlButtons() ModifyEditorCounterLimits(counter_id, leveldir_current->first_level, leveldir_current->last_level); - ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value); MapCounterButtons(counter_id); } @@ -2841,11 +3132,46 @@ static void MapDrawingArea(int id) static void MapTextInputGadget(int id) { + char infotext[MAX_OUTPUT_LINESIZE + 1]; + int max_infotext_len = getMaxInfoTextLength(); + int xoffset_above = 0; + int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE); + int x = textinput_info[id].x + xoffset_above; + int y = textinput_info[id].y + yoffset_above; + + sprintf(infotext, "%s:", textinput_info[id].infotext); + infotext[max_infotext_len] = '\0'; + DrawTextF(x, y, FONT_TEXT_1, infotext); + + ModifyGadget(level_editor_gadget[textinput_info[id].gadget_id], + GDI_TEXT_VALUE, textinput_info[id].value, GDI_END); + MapGadget(level_editor_gadget[textinput_info[id].gadget_id]); } static void MapSelectboxGadget(int id) { + int xoffset_left = 0; + int yoffset_left = ED_BORDER_SIZE; + int xoffset_right = ED_BORDER_SIZE; + int yoffset_right = ED_BORDER_SIZE; + int x = selectbox_info[id].x + xoffset_left; + int y = selectbox_info[id].y + yoffset_left; + + DrawTextF(x, y, FONT_TEXT_1, selectbox_info[id].text_left); + + if (selectbox_info[id].text_right) + { + struct GadgetInfo *gi = level_editor_gadget[selectbox_info[id].gadget_id]; + + x = gi->x + gi->width + xoffset_right; + y = SY + selectbox_info[id].y + yoffset_right; + + DrawText(x, y, selectbox_info[id].text_right, FONT_TEXT_1); + } + + ModifyEditorSelectbox(id, *selectbox_info[id].value); + MapGadget(level_editor_gadget[selectbox_info[id].gadget_id]); } @@ -2856,11 +3182,32 @@ static void MapTextbuttonGadget(int id) static void MapRadiobuttonGadget(int id) { + int xoffset_right = ED_XOFFSET_CHECKBOX; + int yoffset_right = ED_BORDER_SIZE; + int x = radiobutton_info[id].x + xoffset_right; + int y = radiobutton_info[id].y + yoffset_right; + boolean checked = + (*radiobutton_info[id].value == radiobutton_info[id].checked_value); + + DrawTextF(x, y, FONT_TEXT_1, radiobutton_info[id].text_right); + ModifyGadget(level_editor_gadget[radiobutton_info[id].gadget_id], + GDI_CHECKED, checked, GDI_END); + MapGadget(level_editor_gadget[radiobutton_info[id].gadget_id]); } static void MapCheckbuttonGadget(int id) { + int xoffset_right = ED_XOFFSET_CHECKBOX; + int yoffset_right = ED_BORDER_SIZE; + int x = checkbutton_info[id].x + xoffset_right; + int y = checkbutton_info[id].y + yoffset_right; + + DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[id].text_right); + ModifyGadget(level_editor_gadget[checkbutton_info[id].gadget_id], + GDI_CHECKED, *checkbutton_info[id].value, + GDI_Y, SY + checkbutton_info[id].y, GDI_END); + MapGadget(level_editor_gadget[checkbutton_info[id].gadget_id]); } @@ -2975,22 +3322,89 @@ static void CopyCustomElementPropertiesToEditor(int element) { int i; - i = properties_element - EL_CUSTOM_START; - custom_element_change = level.custom_element[i].change; + custom_element = element_info[properties_element]; 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); + custom_element_properties[EP_WALK_TO_OBJECT] = + (IS_DIGGABLE(element) || + IS_COLLECTIBLE(element) || + IS_PUSHABLE(element)); + + /* set consistency selectbox help value */ + custom_element.consistency = + (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE : + CAN_EXPLODE_BY_FIRE(element) ? EP_CAN_EXPLODE_BY_FIRE : + EP_INDESTRUCTIBLE); + custom_element_properties[EP_EXPLODE_RESULT] = + (IS_INDESTRUCTIBLE(element) || + CAN_EXPLODE_BY_FIRE(element)); + + /* set deadliness selectbox help value */ + custom_element.deadliness = + (DONT_TOUCH(element) ? EP_DONT_TOUCH : + DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH : + DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO : + EP_DONT_RUN_INTO); + custom_element_properties[EP_DEADLY] = + (DONT_TOUCH(element) || + DONT_COLLIDE_WITH(element) || + DONT_RUN_INTO(element)); + + /* 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); + custom_element_properties[EP_WALKABLE] = + (IS_WALKABLE_OVER(element) || + IS_WALKABLE_INSIDE(element) || + IS_WALKABLE_UNDER(element)); } static void CopyCustomElementPropertiesToGame(int element) { int i; - i = properties_element - EL_CUSTOM_START; - level.custom_element[i].change = custom_element_change; + element_info[properties_element] = 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 consistency property from checkbox and selectbox */ + custom_element_properties[EP_INDESTRUCTIBLE] = FALSE; + custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE; + custom_element_properties[custom_element.consistency] = + custom_element_properties[EP_EXPLODE_RESULT]; + + /* 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_TOUCH] = FALSE; + custom_element_properties[custom_element.deadliness] = + custom_element_properties[EP_DEADLY]; + + /* 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]); @@ -2999,8 +3413,7 @@ static void CopyCustomElementPropertiesToGame(int element) 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_change = level.custom_element[i].change; + custom_element = element_info[properties_element]; } void DrawLevelEd() @@ -3168,14 +3581,6 @@ static void AdjustEditorScrollbar(int id) GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); } -static void ModifyEditorTextInput(int textinput_id, char *new_text) -{ - int gadget_id = textinput_info[textinput_id].gadget_id; - struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - - ModifyGadget(gi, GDI_TEXT_VALUE, new_text, GDI_END); -} - static void ModifyEditorCounter(int counter_id, int new_value) { int *counter_value = counterbutton_info[counter_id].value; @@ -3261,8 +3666,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(); @@ -3276,9 +3690,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; @@ -3303,102 +3719,42 @@ 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); } static void DrawLevelInfoWindow() { - char infotext[MAX_OUTPUT_LINESIZE + 1]; - int max_infotext_len = getMaxInfoTextLength(); - int xoffset_above = 0; - 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 yoffset_right2 = ED_BORDER_SIZE; - int i, x, y; + int i; + + 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); /* draw counter gadgets */ for (i=ED_COUNTER_ID_LEVEL_FIRST; i<=ED_COUNTER_ID_LEVEL_LAST; i++) - { - if (counterbutton_info[i].infotext_above) - { - x = counterbutton_info[i].x + xoffset_above; - y = counterbutton_info[i].y + yoffset_above; - - sprintf(infotext, "%s:", counterbutton_info[i].infotext_above); - infotext[max_infotext_len] = '\0'; - DrawTextF(x, y, FONT_TEXT_1, infotext); - } - - 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 text input gadgets */ - for (i=ED_TEXTINPUT_ID_LEVEL_FIRST; i<=ED_TEXTINPUT_ID_LEVEL_LAST; i++) - { - x = textinput_info[i].x + xoffset_above; - y = textinput_info[i].y + yoffset_above; - - sprintf(infotext, "%s:", textinput_info[i].infotext); - infotext[max_infotext_len] = '\0'; - - DrawTextF(x, y, FONT_TEXT_1, infotext); - ModifyEditorTextInput(i, textinput_info[i].value); - MapTextInputGadget(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++) - { - boolean checked = - (*radiobutton_info[i].value == radiobutton_info[i].checked_value); - - x = radiobutton_info[i].x + xoffset_right2; - y = radiobutton_info[i].y + yoffset_right2; - - DrawTextF(x, y, FONT_TEXT_1, radiobutton_info[i].text); - ModifyGadget(level_editor_gadget[radiobutton_info[i].gadget_id], - GDI_CHECKED, checked, GDI_END); MapRadiobuttonGadget(i); - } - /* draw checkbutton gadgets */ - for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i<=ED_CHECKBUTTON_ID_LEVEL_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 text input gadgets */ + for (i=ED_TEXTINPUT_ID_LEVEL_FIRST; i<=ED_TEXTINPUT_ID_LEVEL_LAST; i++) + MapTextInputGadget(i); /* draw drawing area */ DrawRandomPlacementBackgroundArea(); @@ -3411,33 +3767,19 @@ 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_CHANGED]; -#if 0 - int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE; - 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_x = xpos / MINI_TILEX; - int area_y = ypos / MINI_TILEY; + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_GRAPHIC]; + int xpos = ED_AREA_ELEM_CONTENT3_XPOS; + int ypos = ED_AREA_ELEM_CONTENT3_YPOS; int area_sx = SX + xpos; int area_sy = SY + ypos; @@ -3449,59 +3791,82 @@ static void DrawCustomChangedArea() return; } - ElementContent[0][0][0] = custom_element_change.successor; - - DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); -#if 1 - DrawMiniGraphicExt(drawto, - gi->x, - gi->y, - el2edimg(ElementContent[0][0][0])); -#else - DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); -#endif - -#if 0 - DrawText(area_sx + TILEX, area_sy + 1, "Element after change", FONT_TEXT_1); -#endif + 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_CHANGED); + MapDrawingArea(GADGET_ID_CUSTOM_GRAPHIC); } -static void DrawElementContentAreas() +static void DrawCustomContentArea() { - 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; - int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS; - int xoffset_right = getCounterGadgetWidth(); - int yoffset_right = ED_BORDER_SIZE; - int i, x, y; + 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; - for (i=0; ix + 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]; + int xpos = ED_AREA_ELEM_CONTENT2_XPOS; + int ypos = ED_AREA_ELEM_CONTENT2_YPOS; + 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.change.successor)); + + MapDrawingArea(GADGET_ID_CUSTOM_CHANGED); +} + +static void DrawElementContentAreas() +{ + 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; + int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS; + int i, x, y; + + for (i=0; iy + gd_gi->height - 1; Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y); int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO; +#if 1 + int id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG; +#else int id_last = ED_TEXTBUTTON_ID_PROPERTIES_INFO; +#endif int i; +#if 0 /* draw additional "configure" tabulator for configurable elements */ if (checkPropertiesConfig()) id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG; +#endif /* draw additional "advanced" tabulator for custom elements */ if (IS_CUSTOM_ELEMENT(properties_element)) @@ -3940,14 +4128,22 @@ static void DrawPropertiesInfo() { /* configurable properties */ { EP_INDESTRUCTIBLE, "- undestructible" }, + { EP_SLIPPERY, "- slippery for falling objects" }, + { EP_EM_SLIPPERY_WALL, "- slippery for some gems (EM style)" }, + { EP_DIGGABLE, "- diggable" }, { EP_COLLECTIBLE, "- collectible" }, { EP_PUSHABLE, "- pushable" }, + + { EP_CAN_MOVE, "- can move" }, { EP_CAN_FALL, "- can fall" }, { EP_CAN_SMASH, "- can smash other objects" }, - { EP_CAN_MOVE, "- can move" }, - { EP_SLIPPERY, "- slippery for falling objects" }, - { EP_EM_SLIPPERY_WALL, "- slippery for some gems (EM style)" }, + { EP_CAN_EXPLODE_BY_FIRE, "- can explode (by fire/explosion)" }, + + { EP_DONT_RUN_INTO, "- deadly when running into" }, + { EP_DONT_COLLIDE_WITH, "- deadly when colliding with" }, + { EP_DONT_TOUCH, "- deadly when touching" }, + { EP_WALKABLE_OVER, "- player can walk over it" }, { EP_WALKABLE_INSIDE, "- player can walk inside it" }, { EP_WALKABLE_UNDER, "- player can walk under it" }, @@ -3957,10 +4153,6 @@ static void DrawPropertiesInfo() /* pre-defined properties */ { EP_CAN_PASS_MAGIC_WALL, "- can pass magic walls" }, - { EP_DONT_TOUCH, "- deadly when touched" }, - { EP_ENEMY, "- can kill the player" }, - { EP_DONT_GO_TO, "- deadly when walked to" }, - { EP_CAN_EXPLODE, "- can explode" }, { EP_HAS_CONTENT, "- can contain other elements" }, { -1, NULL } @@ -3975,11 +4167,13 @@ static void DrawPropertiesInfo() int font2_nr = FONT_TEXT_2; int font1_width = getFontWidth(font1_nr); int font2_height = getFontHeight(font2_nr); - int pad_x = ED_SETTINGS_XPOS; - int pad_y = 5 * TILEY; - int screen_line = 2; + int pad_x = ED_SETTINGS_XPOS(0); + int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE; + int screen_line = 0; int i, x, y; + /* ----- print number of elements / percentage of this element in level */ + num_elements_in_level = 0; for (y=0; y 0) - { - DrawTextF(pad_x, pad_y + screen_line * font2_height, font1_nr, - properties_text); - screen_line++; + /* ----- print standard properties of this element */ - for (i=0; properties[i].value != -1; i++) - { - if (!HAS_PROPERTY(properties_element, properties[i].value)) - continue; + DrawTextF(pad_x, pad_y + screen_line++ * font2_height, font1_nr, + properties_text); - DrawTextF(pad_x, pad_y + screen_line * font2_height, font2_nr, - properties[i].text); - screen_line++; - } + for (i=0; properties[i].value != -1; i++) + { + if (!HAS_PROPERTY(properties_element, properties[i].value)) + continue; - screen_line++; + DrawTextF(pad_x, pad_y + screen_line++ * font2_height, font2_nr, + properties[i].text); + num_standard_properties++; } -#endif + + if (num_standard_properties == 0) + DrawTextF(pad_x + strlen(properties_text) * font1_width, + pad_y + (screen_line - 1) * font2_height, font2_nr, "none"); + + screen_line++; + + /* ----- print special description of this element */ PrintInfoText("Description:", FONT_TEXT_1, screen_line); if (PrintElementDescriptionFromFile(filename, screen_line + 1) == 0) PrintInfoText("No description available.", FONT_TEXT_1, screen_line); } -static void DrawPropertiesAdvanced() +#define TEXT_COLLECTING "Score for collecting" +#define TEXT_SMASHING "Score for smashing" +#define TEXT_CRACKING "Score for cracking" +#define TEXT_SPEED "Speed of amoeba growth" +#define TEXT_DURATION "Duration when activated" + +static struct { - 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_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE; - int yoffset_right2 = ED_BORDER_SIZE; - int i, x, y; + int element; + int *value; + char *text; +} elements_with_counter[] = +{ + { EL_EMERALD, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_BD_DIAMOND, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_EMERALD_YELLOW, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_EMERALD_RED, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_EMERALD_PURPLE, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_SP_INFOTRON, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_DIAMOND, &level.score[SC_DIAMOND], TEXT_COLLECTING }, + { EL_CRYSTAL, &level.score[SC_CRYSTAL], TEXT_COLLECTING }, + { EL_PEARL, &level.score[SC_PEARL], TEXT_COLLECTING }, + { EL_BUG_RIGHT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_UP, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_LEFT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_DOWN, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_UP, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_LEFT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_DOWN, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_SP_ELECTRON, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_SPACESHIP_RIGHT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_RIGHT,&level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SP_SNIKSNAK, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_DARK_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING }, + { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_NUT, &level.score[SC_NUT], TEXT_CRACKING }, + { EL_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, + { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE],TEXT_COLLECTING }, + { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE],TEXT_COLLECTING }, + { EL_DYNABOMB_INCREASE_POWER, &level.score[SC_DYNAMITE],TEXT_COLLECTING }, + { EL_SHIELD_NORMAL, &level.score[SC_SHIELD], TEXT_COLLECTING }, + { EL_SHIELD_DEADLY, &level.score[SC_SHIELD], TEXT_COLLECTING }, + { EL_EXTRA_TIME, &level.score[SC_TIME_BONUS], TEXT_COLLECTING }, + { EL_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_1_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_2_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_3_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_4_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_SPEED }, + { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_SPEED }, + { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_SPEED }, + { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_SPEED }, + { EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, + { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION }, + { -1, NULL, NULL } +}; - /* draw stickybutton gadget */ - i = ED_CHECKBUTTON_ID_STICK_ELEMENT; - checkbutton_info[i].y = ED_COUNTER_YPOS2(4); - 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); +static boolean checkPropertiesConfig() +{ + int i; - /* draw counter gadgets */ - for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++) + if (IS_GEM(properties_element) || + IS_CUSTOM_ELEMENT(properties_element) || + HAS_CONTENT(properties_element)) + return TRUE; + else + for (i=0; elements_with_counter[i].element != -1; i++) + if (elements_with_counter[i].element == properties_element) + return TRUE; + + return FALSE; +} + +static void DrawPropertiesConfig() +{ + int i; + + if (!checkPropertiesConfig()) + { + PrintInfoText("No configuration options available.", FONT_TEXT_1, 0); + + return; + } + + /* check if there are elements where a score can be chosen for */ + for (i=0; elements_with_counter[i].element != -1; i++) { - if (counterbutton_info[i].infotext_right) + if (elements_with_counter[i].element == properties_element) { - x = counterbutton_info[i].x + xoffset_right; - y = counterbutton_info[i].y + yoffset_right; + int counter_id = ED_COUNTER_ID_ELEMENT_SCORE; - sprintf(infotext, "%s", counterbutton_info[i].infotext_right); - infotext[max_infotext_len] = '\0'; - DrawTextF(x, y, FONT_TEXT_1, infotext); - } + counterbutton_info[counter_id].value = elements_with_counter[i].value; + counterbutton_info[counter_id].text_right= elements_with_counter[i].text; + MapCounterButtons(counter_id); - ModifyEditorCounter(i, *counterbutton_info[i].value); - MapCounterButtons(i); + break; + } } - /* draw checkbutton gadgets */ - for (i = ED_CHECKBUTTON_ID_CHANGE_FIRST; - i <= ED_CHECKBUTTON_ID_CHANGE_LAST; i++) + if (HAS_CONTENT(properties_element)) { - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; + /* draw stickybutton gadget */ + i = ED_CHECKBUTTON_ID_STICK_ELEMENT; + checkbutton_info[i].y = ED_COUNTER_YPOS(4); + MapCheckbuttonGadget(i); - 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); + if (IS_AMOEBOID(properties_element)) + DrawAmoebaContentArea(); + else + DrawElementContentAreas(); + } + + if (IS_GEM(properties_element)) + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS); + + if (IS_CUSTOM_ELEMENT(properties_element)) + { + /* draw stickybutton gadget */ + i = ED_CHECKBUTTON_ID_STICK_ELEMENT; + checkbutton_info[i].y = ED_SETTINGS_YPOS(0); MapCheckbuttonGadget(i); + + /* draw checkbutton gadgets */ + for (i = ED_CHECKBUTTON_ID_CUSTOM_FIRST; + i <= ED_CHECKBUTTON_ID_CUSTOM_LAST; i++) + MapCheckbuttonGadget(i); + + /* draw counter gadgets */ + for (i=ED_COUNTER_ID_CUSTOM_FIRST; i<=ED_COUNTER_ID_CUSTOM_LAST; i++) + MapCounterButtons(i); + + /* draw selectbox gadgets */ + for (i=ED_SELECTBOX_ID_CUSTOM_FIRST; i <= ED_SELECTBOX_ID_CUSTOM_LAST; i++) + MapSelectboxGadget(i); + + /* draw drawing area gadgets */ + DrawCustomContentArea(); } +} - /* map gadget for optional graphic element */ - MapDrawingArea(GADGET_ID_CUSTOM_GRAPHIC); +static void DrawPropertiesAdvanced() +{ + int i; - DrawCustomChangedArea(); + /* draw stickybutton gadget */ + i = ED_CHECKBUTTON_ID_STICK_ELEMENT; + checkbutton_info[i].y = ED_SETTINGS_YPOS(0); + MapCheckbuttonGadget(i); + + /* draw checkbutton gadgets */ + for (i = ED_CHECKBUTTON_ID_CHANGE_FIRST; + i <= ED_CHECKBUTTON_ID_CHANGE_LAST; i++) + MapCheckbuttonGadget(i); + + /* draw counter gadgets */ + for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++) + MapCounterButtons(i); /* draw selectbox gadgets */ for (i=ED_SELECTBOX_ID_CHANGE_FIRST; i<=ED_SELECTBOX_ID_CHANGE_LAST; i++) - { - int yoffset = ED_BORDER_SIZE; + MapSelectboxGadget(i); - x = selectbox_info[i].x; - y = selectbox_info[i].y + yoffset; + /* draw textbutton gadgets */ + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE); - DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text); -#if 1 - ModifyEditorSelectbox(i, *selectbox_info[i].value); -#else - ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id], - GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END); -#endif - MapSelectboxGadget(i); - } + /* draw drawing area gadgets */ + DrawCustomGraphicElementArea(); + DrawCustomChangedArea(); } static void DrawPropertiesWindow() @@ -4102,14 +4407,18 @@ 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)) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG; +#if 0 if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG && !checkPropertiesConfig()) edit_mode_properties = ED_MODE_PROPERTIES_INFO; +#endif if (IS_CUSTOM_ELEMENT(properties_element)) CopyCustomElementPropertiesToEditor(properties_element); @@ -4119,12 +4428,12 @@ static void DrawPropertiesWindow() 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, @@ -4671,12 +4980,6 @@ static void CopyLevelToUndoBuffer(int mode) SetBorderElement(); if (BorderElement != last_border_element) DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); - -#if 0 -#ifdef DEBUG - printf("level saved to undo buffer\n"); -#endif -#endif } static void RandomPlacement(int new_element) @@ -4812,7 +5115,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) { @@ -4876,34 +5180,32 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (id == GADGET_ID_AMOEBA_CONTENT) level.amoeba_content = new_element; - else if (id == GADGET_ID_CUSTOM_GRAPHIC && - IS_CUSTOM_ELEMENT(properties_element)) + else if (id == GADGET_ID_CUSTOM_GRAPHIC) { - int i = properties_element - EL_CUSTOM_START; - - if (IS_CUSTOM_ELEMENT(new_element)) - new_element = CUSTOM_ELEMENT_INFO(new_element).change.gfx_element; - - custom_element_change.gfx_element = new_element; - level.custom_element[i].change = custom_element_change; + new_element = GFX_ELEMENT(new_element); + custom_element.gfx_element = new_element; + element_info[properties_element] = custom_element; ModifyEditorElementList(); + RedrawDrawingElements(); FrameCounter = 0; /* restart animation frame counter */ } - else if (id == GADGET_ID_CUSTOM_CHANGED && - IS_CUSTOM_ELEMENT(properties_element)) + else if (id == GADGET_ID_CUSTOM_CONTENT) { - int i = properties_element - EL_CUSTOM_START; - - custom_element_change.successor = new_element; - level.custom_element[i].change = custom_element_change; + custom_element.content[sx][sy] = new_element; + element_info[properties_element] = custom_element; + } + else if (id == GADGET_ID_CUSTOM_CHANGED) + { + custom_element.change.successor = new_element; + element_info[properties_element] = custom_element; } else if (id == GADGET_ID_RANDOM_BACKGROUND) random_placement_background_element = new_element; else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && id <= GADGET_ID_ELEMENT_CONTENT_7) - level.yam_content[id - GADGET_ID_ELEMENT_CONTENT_0][sx][sy] = + level.yamyam_content[id - GADGET_ID_ELEMENT_CONTENT_0][sx][sy] = new_element; } break; @@ -5001,8 +5303,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; @@ -5066,8 +5385,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) break; } - if (counter_id >= ED_COUNTER_ID_CHANGE_FIRST && - counter_id <= ED_COUNTER_ID_CHANGE_LAST) + if ((counter_id >= ED_COUNTER_ID_CUSTOM_FIRST && + counter_id <= ED_COUNTER_ID_CUSTOM_LAST) || + (counter_id >= ED_COUNTER_ID_CHANGE_FIRST && + counter_id <= ED_COUNTER_ID_CHANGE_LAST)) CopyCustomElementPropertiesToGame(properties_element); } @@ -5084,15 +5405,11 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) *selectbox_info[type_id].value = selectbox_info[type_id].options[gi->selectbox.index].value; - if (type_id >= ED_SELECTBOX_ID_CHANGE_FIRST && - type_id <= ED_SELECTBOX_ID_CHANGE_LAST) + 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", - selectbox_info[type_id].options[gi->selectbox.index].text, - selectbox_info[type_id].options[gi->selectbox.index].value); -#endif } static void HandleTextbuttonGadgets(struct GadgetInfo *gi) @@ -5123,6 +5440,12 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) (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) @@ -5137,7 +5460,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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; @@ -5312,6 +5636,12 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; } + if (edit_mode != ED_MODE_DRAWING) + { + DrawDrawingWindow(); + edit_mode = ED_MODE_DRAWING; + } + undo_buffer_position = (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS; undo_buffer_steps--; @@ -5336,6 +5666,12 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_CLEAR: + if (edit_mode != ED_MODE_DRAWING) + { + DrawDrawingWindow(); + edit_mode = ED_MODE_DRAWING; + } + for(x=0; x= 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_ELEMENT_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)