X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=778232e23fc507e9287a4df15b72247fca34ca05;hb=a85d66e030463ca9cf9700888481ebf2a04f8740;hp=1951d1f47bce14d94be2a9a2ab83d05267444ec5;hpb=514321a85f7dda02848a3ce78667329f9c891156;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 1951d1f4..778232e2 100644 --- a/src/editor.c +++ b/src/editor.c @@ -22,6 +22,13 @@ #include "game.h" #include "tape.h" + +/* + ----------------------------------------------------------------------------- + screen and artwork graphic pixel position definitions + ----------------------------------------------------------------------------- +*/ + /* positions in the level editor */ #define ED_WIN_MB_LEFT_XPOS 6 #define ED_WIN_MB_LEFT_YPOS 258 @@ -30,25 +37,6 @@ #define ED_WIN_MB_RIGHT_XPOS 78 #define ED_WIN_MB_RIGHT_YPOS ED_WIN_MB_LEFT_YPOS -/* other constants for the editor */ -#define ED_SCROLL_NO 0 -#define ED_SCROLL_LEFT 1 -#define ED_SCROLL_RIGHT 2 -#define ED_SCROLL_UP 4 -#define ED_SCROLL_DOWN 8 - -/* screens in the level editor */ -#define ED_MODE_DRAWING 0 -#define ED_MODE_INFO 1 -#define ED_MODE_PROPERTIES 2 - -/* how many steps can be cancelled */ -#define NUM_UNDO_STEPS (10 + 1) - -/* values for elements with score */ -#define MIN_SCORE 0 -#define MAX_SCORE 255 - /* values for the control window */ #define ED_CTRL_BUTTONS_GFX_YPOS 236 #define ED_CTRL_BUTTONS_ALT_GFX_YPOS 142 @@ -79,37 +67,63 @@ #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_XOFFSET_CHECKBOX (ED_CHECKBUTTON_XSIZE + \ + 2 * ED_GADGET_DISTANCE) + +#define ED_SETTINGS_XOFFSET ED_XOFFSET_CHECKBOX +#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_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_SETTINGS_YPOS + 2 * TILEY) +#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_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(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) @@ -204,12 +218,37 @@ #define ED_BUTTON_PLUS_YSIZE ED_BUTTON_COUNT_YSIZE #define ED_SELECTBOX_XPOS ED_WIN_COUNT_XPOS -#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + 2 + \ - ED_WIN_COUNT_YSIZE) +#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + \ + 2 + ED_WIN_COUNT_YSIZE) #define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE #define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE -/* editor gadget identifiers */ +#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_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 + +/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */ +#define INFOTEXT_XPOS SX +#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) +#define INFOTEXT_XSIZE SXSIZE +#define INFOTEXT_YSIZE MINI_TILEX + + +/* + ----------------------------------------------------------------------------- + editor gadget definitions + ----------------------------------------------------------------------------- +*/ /* drawing toolbox buttons */ #define GADGET_ID_NONE -1 @@ -241,52 +280,75 @@ /* 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_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 + 27) +#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_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) @@ -294,10 +356,25 @@ /* selectbox identifiers */ #define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 2) -#define GADGET_ID_SELECTBOX_TEST (GADGET_ID_SELECTBOX_FIRST + 0) +#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 + 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_SELECTBOX_FIRST + 1) +#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) @@ -313,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) @@ -323,14 +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_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_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_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 + 12) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 19) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -342,21 +426,34 @@ #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_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 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 + /* values for scrollbutton gadgets */ #define ED_SCROLLBUTTON_ID_AREA_UP 0 #define ED_SCROLLBUTTON_ID_AREA_DOWN 1 @@ -390,9 +487,30 @@ #define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR /* values for selectbox gadgets */ -#define ED_SELECTBOX_ID_TEST 0 +#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 8 -#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 4 /* values for checkbutton gadgets */ #define ED_CHECKBUTTON_ID_DOUBLE_SPEED 0 @@ -400,19 +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_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_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_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 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_SLIPPERY +#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_USE_GRAPHIC +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_DELAY /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -423,15 +551,55 @@ #define ED_RADIOBUTTON_ID_LEVEL_FIRST ED_RADIOBUTTON_ID_PERCENTAGE #define ED_RADIOBUTTON_ID_LEVEL_LAST ED_RADIOBUTTON_ID_QUANTITY + +/* + ----------------------------------------------------------------------------- + some internally used definitions + ----------------------------------------------------------------------------- +*/ + /* values for CopyLevelToUndoBuffer() */ #define UNDO_IMMEDIATE 0 #define UNDO_ACCUMULATE 1 -/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */ -#define INFOTEXT_XPOS SX -#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) -#define INFOTEXT_XSIZE SXSIZE -#define INFOTEXT_YSIZE MINI_TILEX +/* values for scrollbars */ +#define ED_SCROLL_NO 0 +#define ED_SCROLL_LEFT 1 +#define ED_SCROLL_RIGHT 2 +#define ED_SCROLL_UP 4 +#define ED_SCROLL_DOWN 8 + +/* screens in the level editor */ +#define ED_MODE_DRAWING 0 +#define ED_MODE_INFO 1 +#define ED_MODE_PROPERTIES 2 + +/* sub-screens in the element properties section */ +#define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO +#define ED_MODE_PROPERTIES_CONFIG ED_TEXTBUTTON_ID_PROPERTIES_CONFIG +#define ED_MODE_PROPERTIES_ADVANCED ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED + +/* how many steps can be cancelled */ +#define NUM_UNDO_STEPS (10 + 1) + +/* values for elements with score */ +#define MIN_SCORE 0 +#define MAX_SCORE 255 + +/* values for random placement */ +#define RANDOM_USE_PERCENTAGE 0 +#define RANDOM_USE_QUANTITY 1 + +/* maximal size of level editor drawing area */ +#define MAX_ED_FIELDX (2 * SCR_FIELDX) +#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1) + + +/* + ----------------------------------------------------------------------------- + some internally used data structure definitions + ----------------------------------------------------------------------------- +*/ static struct { @@ -463,24 +631,14 @@ static struct { 'E', "exit level editor" } }; -/* values for random placement */ -#define RANDOM_USE_PERCENTAGE 0 -#define RANDOM_USE_QUANTITY 1 - static int random_placement_value = 10; static int random_placement_method = RANDOM_USE_QUANTITY; static int random_placement_background_element = EL_SAND; static boolean random_placement_background_restricted = FALSE; static boolean stick_element_properties_window = FALSE; - -static struct -{ - boolean indestructible; - boolean can_fall; - boolean can_smash; - boolean pushable; - boolean slippery; -} custom_element_properties[NUM_CUSTOM_ELEMENTS]; +static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES]; +static boolean custom_element_change_events[NUM_CHANGE_EVENTS]; +static struct ElementInfo custom_element; static struct { @@ -489,80 +647,136 @@ 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] = { { - 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, 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_ZEITBONUS], - "score for each 10 seconds left", NULL + &level.score[SC_TIME_BONUS], + "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" }, { - 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(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 */ + NULL, NULL, NULL + }, + { + 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_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_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, "delay", NULL, + }, + { + 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, "+random", NULL } }; @@ -576,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, @@ -591,38 +805,199 @@ static struct } }; -static char *test_values[] = +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[] = +{ + { MV_NO_MOVING, "automatic" }, + { MV_LEFT, "left" }, + { MV_RIGHT, "right" }, + { MV_UP, "up" }, + { MV_DOWN, "down" }, + { -1, NULL } +}; +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 } +}; +static int index_change_cause = 0, value_change_cause = 0; + +static struct +{ + int x, y; + int gadget_id; + int size; /* char size of selectbox or '-1' (dynamically determined) */ + struct ValueTextInfo *options; + int *index, *value; + char *text_left, *text_right, *infotext; +} selectbox_info[ED_NUM_SELECTBOX] = { - "test 1", - "test 2", - "dieser test-text ist viel zu lang fuer die selectbox", - "letzter text", - NULL + { + 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, + -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(0), ED_COUNTER_YPOS(8), + GADGET_ID_CHANGE_CAUSE, + -1, + options_change_cause, &index_change_cause, + &value_change_cause, + "test:", NULL, "test-selectbox entry" + }, }; -static int test_index = 0; static struct { int x, y; int gadget_id; int size; - char **values; - int *index; char *text, *infotext; -} selectbox_info[ED_NUM_SELECTBOX] = +} textbutton_info[ED_NUM_TEXTBUTTON] = { { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3), - GADGET_ID_SELECTBOX_TEST, - MAX_PLAYER_NAME_LEN, - test_values, &test_index, - "test:", "test-selectbox entry" + ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1), + GADGET_ID_PROPERTIES_INFO, + 11, "Information", "Show information about element" + }, + { + ED_SETTINGS_XPOS(0) + 166, ED_COUNTER_YPOS(1), + GADGET_ID_PROPERTIES_CONFIG, + 11, "Configure", "Configure element properties" + }, + { + ED_SETTINGS_XPOS(0) + 332, ED_COUNTER_YPOS(1), + GADGET_ID_PROPERTIES_ADVANCED, + 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; @@ -668,7 +1043,7 @@ static struct static struct { - int xpos, ypos; + int gd_x, gd_y; int x, y; int width, height; int type; @@ -709,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, @@ -733,74 +1108,119 @@ 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, 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), - GADGET_ID_CUSTOM_INDESTRUCTIBLE, - &custom_element_properties[0].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(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(2), + GADGET_ID_CUSTOM_DEADLY, + &custom_element_properties[EP_DEADLY], + NULL, "element can kill the player" + }, + { + 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(11), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_CAN_FALL, - &custom_element_properties[0].can_fall, + &custom_element_properties[EP_CAN_FALL], "can fall", "element can fall down" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(12), + ED_SETTINGS_XPOS(6), ED_SETTINGS_YPOS(9), GADGET_ID_CUSTOM_CAN_SMASH, - &custom_element_properties[0].can_smash, - "can smash", "element can smash other elements" + &custom_element_properties[EP_CAN_SMASH], + "can smash on impact", "element can smash other elements" }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(13), - GADGET_ID_CUSTOM_PUSHABLE, - &custom_element_properties[0].pushable, - "pushable", "element can be pushed" - }, - { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(14), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), GADGET_ID_CUSTOM_SLIPPERY, - &custom_element_properties[0].slippery, + &custom_element_properties[EP_SLIPPERY], "slippery", "other elements can fall down from it" - } + }, + { + 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(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(0), ED_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_USE_TEMPLATE, + &custom_element.use_template, + "use template", "use template for custom properties" + }, + { + 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_XPOS(1), ED_SETTINGS_YPOS(3), + GADGET_ID_CHANGE_DELAY, + &custom_element_change_events[CE_DELAY], + NULL, "element changes after delay" + }, }; -/* maximal size of level editor drawing area */ -#define MAX_ED_FIELDX (2 * SCR_FIELDX) -#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1) + +/* + ----------------------------------------------------------------------------- + some internally used variables + ----------------------------------------------------------------------------- +*/ /* actual size of level editor drawing area */ static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1; @@ -823,14 +1243,18 @@ 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 *); static void HandleTextInputGadgets(struct GadgetInfo *); static void HandleSelectboxGadgets(struct GadgetInfo *); +static void HandleTextbuttonGadgets(struct GadgetInfo *); static void HandleRadiobuttons(struct GadgetInfo *); static void HandleCheckbuttons(struct GadgetInfo *); static void HandleControlButtons(struct GadgetInfo *); @@ -843,13 +1267,13 @@ 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; static int undo_buffer_steps = 0; static int edit_mode; +static int edit_mode_properties; static int element_shift = 0; @@ -1624,6 +2048,13 @@ editor_elements_info[] = NULL } }; + +/* + ----------------------------------------------------------------------------- + functions + ----------------------------------------------------------------------------- +*/ + static void ReinitializeElementList() { int pos = 0; @@ -1684,7 +2115,7 @@ static void ReinitializeElementListButtons() static int getCounterGadgetWidth() { - return (DXSIZE + getFontWidth(FONT_INPUT) - 2 * ED_GADGET_DISTANCE); + return (DXSIZE + getFontWidth(FONT_INPUT_1) - 2 * ED_GADGET_DISTANCE); } static int getMaxInfoTextLength() @@ -1864,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; } @@ -1875,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; } @@ -1965,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++) { @@ -1993,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; } @@ -2015,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, @@ -2036,7 +2474,8 @@ static void CreateCounterButtons() if (j == 0) { - int font_type = FONT_INPUT; + int font_type = FONT_INPUT_1; + int font_type_active = FONT_INPUT_1_ACTIVE; int gd_width = ED_WIN_COUNT_XSIZE; id = counterbutton_info[i].gadget_id_text; @@ -2045,6 +2484,7 @@ static void CreateCounterButtons() if (i == ED_COUNTER_ID_SELECT_LEVEL) { font_type = FONT_LEVEL_NUMBER; + font_type_active = FONT_LEVEL_NUMBER; xpos += 2 * ED_GADGET_DISTANCE; ypos -= ED_GADGET_DISTANCE; @@ -2062,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, @@ -2070,10 +2510,11 @@ static void CreateCounterButtons() GDI_NUMBER_MAX, counterbutton_info[i].max_value, GDI_TEXT_SIZE, 3, GDI_TEXT_FONT, font_type, + GDI_TEXT_FONT_ACTIVE, font_type_active, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y, - GDI_BORDER_SIZE, ED_BORDER_SIZE, - GDI_TEXTINPUT_DESIGN_WIDTH, gd_width, + GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE, + GDI_DESIGN_WIDTH, gd_width, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCounterButtons, @@ -2124,7 +2565,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, @@ -2163,6 +2604,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, @@ -2233,11 +2713,12 @@ static void CreateTextInputGadgets() GDI_TYPE, GD_TYPE_TEXTINPUT_ALPHANUMERIC, GDI_TEXT_VALUE, textinput_info[i].value, GDI_TEXT_SIZE, textinput_info[i].size, - GDI_TEXT_FONT, FONT_INPUT, + GDI_TEXT_FONT, FONT_INPUT_1, + GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y, - GDI_BORDER_SIZE, ED_BORDER_SIZE, - GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE, + GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE, + GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleTextInputGadgets, @@ -2253,41 +2734,63 @@ 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_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'; 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_VALUES, selectbox_info[i].values, + GDI_SELECTBOX_OPTIONS, selectbox_info[i].options, GDI_SELECTBOX_INDEX, selectbox_info[i].index, GDI_TEXT_SIZE, selectbox_info[i].size, - GDI_TEXT_FONT, FONT_INPUT, + GDI_TEXT_FONT, FONT_INPUT_1, + GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y, - GDI_BORDER_SIZE, ED_BORDER_SIZE, - GDI_BORDER_SIZE_SELECTBUTTON, getFontHeight(FONT_INPUT), - GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE, + GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE, + GDI_BORDER_SIZE_SELECTBUTTON, getFontWidth(FONT_INPUT_1), + GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleSelectboxGadgets, @@ -2300,6 +2803,71 @@ static void CreateSelectboxGadgets() } } +static void CreateTextbuttonGadgets() +{ + int max_infotext_len = getMaxInfoTextLength(); + int i; + + for (i=0; i= 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'; + + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_CUSTOM_TYPE_ID, i, + GDI_INFO_TEXT, infotext, + 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].text, + GDI_TEXT_SIZE, textbutton_info[i].size, + GDI_TEXT_FONT, FONT_INPUT_2_ACTIVE, + GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2, + GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, + GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1, + GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2, + GDI_BORDER_SIZE, ED_BORDER2_SIZE, ED_BORDER_SIZE, + GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE, + GDI_DECORATION_SHIFTING, 1, 1, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, + GDI_CALLBACK_ACTION, HandleTextbuttonGadgets, + GDI_END); + + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + level_editor_gadget[id] = gi; + } +} + static void CreateScrollbarGadgets() { int i; @@ -2337,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, @@ -2357,7 +2925,7 @@ static void CreateScrollbarGadgets() GDI_STATE, GD_BUTTON_UNPRESSED, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, - GDI_BORDER_SIZE, ED_BORDER_SIZE, + GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, @@ -2458,7 +3026,7 @@ void CreateLevelEditorGadgets() int old_game_status = game_status; /* setting 'game_status' is needed to get the right fonts for the editor */ - game_status = LEVELED; + game_status = GAME_MODE_EDITOR; ReinitializeElementList(); @@ -2467,6 +3035,7 @@ void CreateLevelEditorGadgets() CreateDrawingAreas(); CreateTextInputGadgets(); CreateSelectboxGadgets(); + CreateTextbuttonGadgets(); CreateScrollbarGadgets(); CreateCheckbuttonGadgets(); @@ -2483,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]); @@ -2509,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); } @@ -2520,21 +3132,82 @@ 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]); } +static void MapTextbuttonGadget(int id) +{ + MapGadget(level_editor_gadget[textbutton_info[id].gadget_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]); } @@ -2645,67 +3318,102 @@ static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY], dst[x][y] = src[x][y]; } -static void CopyCustomElementPropertiesToEditor() +static void CopyCustomElementPropertiesToEditor(int element) { int i; - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - int properties = Properties1[element]; - - custom_element_properties[i].indestructible = - ((properties & EP_BIT_INDESTRUCTIBLE) != 0 ? TRUE : FALSE); - - custom_element_properties[i].can_fall = - ((properties & EP_BIT_CAN_FALL) != 0 ? TRUE : FALSE); - - custom_element_properties[i].can_smash = - ((properties & EP_BIT_CAN_SMASH) != 0 ? TRUE : FALSE); - - custom_element_properties[i].pushable = - ((properties & EP_BIT_PUSHABLE) != 0 ? TRUE : FALSE); - - custom_element_properties[i].slippery = - ((properties & EP_BIT_SLIPPERY) != 0 ? TRUE : FALSE); - } + 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() +static void CopyCustomElementPropertiesToGame(int element) { int i; - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - - Properties1[element] = EP_BITMASK_DEFAULT; - - if (custom_element_properties[i].indestructible) - Properties1[element] |= EP_BIT_INDESTRUCTIBLE; - else - Properties1[element] &= ~EP_BIT_INDESTRUCTIBLE; - - if (custom_element_properties[i].can_fall) - Properties1[element] |= EP_BIT_CAN_FALL; - else - Properties1[element] &= ~EP_BIT_CAN_FALL; - - if (custom_element_properties[i].can_smash) - Properties1[element] |= EP_BIT_CAN_SMASH; - else - Properties1[element] &= ~EP_BIT_CAN_SMASH; - - if (custom_element_properties[i].pushable) - Properties1[element] |= EP_BIT_PUSHABLE; - else - Properties1[element] &= ~EP_BIT_PUSHABLE; - - if (custom_element_properties[i].slippery) - Properties1[element] |= EP_BIT_SLIPPERY; - else - Properties1[element] &= ~EP_BIT_SLIPPERY; - } + 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]); + + 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 */ + custom_element = element_info[properties_element]; } void DrawLevelEd() @@ -2723,8 +3431,10 @@ void DrawLevelEd() else { edit_mode = ED_MODE_DRAWING; + edit_mode_properties = ED_MODE_PROPERTIES_INFO; ResetUndoBuffer(); + level_xpos = -1; level_ypos = -1; } @@ -2871,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; @@ -2899,6 +3601,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) @@ -2929,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(); @@ -2944,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; @@ -2971,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(); @@ -3079,23 +3767,43 @@ 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]; + int xpos = ED_AREA_ELEM_CONTENT3_XPOS; + int ypos = ED_AREA_ELEM_CONTENT3_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.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)) { @@ -3105,50 +3813,60 @@ 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]; + int xpos = ED_AREA_ELEM_CONTENT2_XPOS; + int ypos = ED_AREA_ELEM_CONTENT2_YPOS; + 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); + + return; + } - DrawText(area_sx + TILEX, area_sy + 1, "Element after change", FONT_TEXT_1); + 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 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; for (i=0; i= max_lines_per_screen) + return FALSE; + + DrawText(sx, sy + screen_line * font_height, text, font_nr); + + return TRUE; +} + +static int PrintElementDescriptionFromFile(char *filename, int screen_line) +{ + int font_nr = FONT_TEXT_2; + int font_width = getFontWidth(font_nr); + int pad_x = ED_SETTINGS_XPOS(0); + int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width; + char line[MAX_LINE_LEN]; + char buffer[max_chars_per_line + 1]; + int buffer_len; + int lines_printed = 0; + FILE *file; + + if (filename == NULL) + return 0; + + if (!(file = fopen(filename, MODE_READ))) + return 0; + + buffer[0] = '\0'; + buffer_len = 0; + + while(!feof(file)) { - int element; - int *value; - char *text; - } elements_with_counter[] = - { - { EL_EMERALD, &level.score[SC_EDELSTEIN], TEXT_COLLECTING }, - { EL_BD_DIAMOND, &level.score[SC_EDELSTEIN], TEXT_COLLECTING }, - { EL_EMERALD_YELLOW,&level.score[SC_EDELSTEIN], TEXT_COLLECTING }, - { EL_EMERALD_RED, &level.score[SC_EDELSTEIN], TEXT_COLLECTING }, - { EL_EMERALD_PURPLE,&level.score[SC_EDELSTEIN], TEXT_COLLECTING }, - { EL_DIAMOND, &level.score[SC_DIAMANT], TEXT_COLLECTING }, - { EL_BUG_RIGHT, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BUG_UP, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BUG_LEFT, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BUG_DOWN, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_UP, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_LEFT, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_DOWN, &level.score[SC_KAEFER], TEXT_SMASHING }, - { EL_SPACESHIP_RIGHT,&level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_SPACESHIP_UP, &level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_SPACESHIP_LEFT, &level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_SPACESHIP_DOWN, &level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_BD_FIREFLY_RIGHT,&level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_BD_FIREFLY_UP, &level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_BD_FIREFLY_LEFT, &level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_BD_FIREFLY_DOWN, &level.score[SC_FLIEGER], TEXT_SMASHING }, - { EL_YAMYAM, &level.score[SC_MAMPFER], TEXT_SMASHING }, - { EL_DARK_YAMYAM, &level.score[SC_MAMPFER], 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_KOKOSNUSS], TEXT_CRACKING }, - { EL_DYNAMITE, &level.score[SC_DYNAMIT], TEXT_COLLECTING }, - { EL_KEY_1, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_KEY_2, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_KEY_3, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_KEY_4, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_EM_KEY_1_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_EM_KEY_2_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_EM_KEY_3_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING }, - { EL_EM_KEY_4_FILE, &level.score[SC_SCHLUESSEL], 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 } - }; + char *line_ptr, *word_ptr; + boolean last_line_was_empty = TRUE; - SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); - ClearWindow(); - UnmapLevelEditorWindowGadgets(); + /* read next line of input file */ + if (!fgets(line, MAX_LINE_LEN, file)) + break; - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS, - "Element Settings", FONT_TITLE_1); + /* skip comments (lines directly beginning with '#') */ + if (line[0] == '#') + continue; - DrawElementBorder(SX + xstart * MINI_TILEX, - SY + ystart * MINI_TILEY + MINI_TILEY / 2, - TILEX, TILEY); - DrawGraphicAnimationExt(drawto, - SX + xstart * MINI_TILEX, - SY + ystart * MINI_TILEY + MINI_TILEY / 2, - el2edimg(properties_element), -1, NO_MASKING); + /* cut trailing newline from input line */ + for (line_ptr = line; *line_ptr; line_ptr++) + { + if (*line_ptr == '\n' || *line_ptr == '\r') + { + *line_ptr = '\0'; + break; + } + } - FrameCounter = 0; /* restart animation frame counter */ + if (strlen(line) == 0) /* special case: force empty line */ + strcpy(line, "\n"); - DrawTextF((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY, - FONT_TEXT_1, getElementInfoText(properties_element)); + word_ptr = line; + + while (*word_ptr) + { + boolean print_buffer = FALSE; + int word_len; + + /* skip leading whitespaces */ + while (*word_ptr == ' ' || *word_ptr == '\t') + word_ptr++; + + line_ptr = word_ptr; + word_len = 0; + + /* look for end of next word */ + while (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0') + { + line_ptr++; + word_len++; + } + + if (word_len == 0) + { + continue; + } + else if (*word_ptr == '\n') /* special case: force empty line */ + { + if (buffer_len == 0) + word_ptr++; + + /* prevent printing of multiple empty lines */ + if (buffer_len > 0 || !last_line_was_empty) + print_buffer = TRUE; + } + else if (word_len < max_chars_per_line - buffer_len) + { + /* word fits into text buffer -- add word */ + + if (buffer_len > 0) + buffer[buffer_len++] = ' '; + + strncpy(&buffer[buffer_len], word_ptr, word_len); + buffer_len += word_len; + buffer[buffer_len] = '\0'; + word_ptr += word_len; + } + else if (buffer_len > 0) + { + /* not enough space left for word in text buffer -- print buffer */ + + print_buffer = TRUE; + } + else + { + /* word does not fit at all into empty text buffer -- cut word */ + + strncpy(buffer, word_ptr, max_chars_per_line); + buffer[max_chars_per_line] = '\0'; + word_ptr += max_chars_per_line; + print_buffer = TRUE; + } + + if (print_buffer) + { + if (!PrintInfoText(buffer, font_nr, screen_line + lines_printed)) + return lines_printed; + + last_line_was_empty = (buffer_len == 0); + lines_printed++; + + buffer[0] = '\0'; + buffer_len = 0; + print_buffer = FALSE; + } + } + } + + fclose(file); + + if (buffer_len > 0) + if (PrintInfoText(buffer, font_nr, screen_line + lines_printed)) + lines_printed++; + + return lines_printed; +} + +static void DrawPropertiesTabulatorGadgets() +{ + struct GadgetInfo *gd_gi = level_editor_gadget[GADGET_ID_PROPERTIES_INFO]; + struct GadgetDesign *gd = &gd_gi->alt_design[GD_BUTTON_UNPRESSED]; + int gd_x = gd->x + gd_gi->border.width / 2; + int gd_y = gd->y + 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)) + id_last = ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED; + + for (i=id_first; i <= id_last; i++) + { + int gadget_id = textbutton_info[i].gadget_id; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + boolean active = (i != edit_mode_properties); + + /* draw background line below tabulator button */ + ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width,1); + + /* draw solid line below inactive tabulator buttons */ + if (!active && tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width,1, tab_color); + + ModifyGadget(gi, GDI_ACTIVE, active, GDI_END); + MapTextbuttonGadget(i); + } + + /* draw little border line below tabulator buttons */ + if (tab_color != BLACK_PIXEL) /* black => transparent */ + FillRectangle(drawto, gd_gi->x, gd_gi->y + gd_gi->height + 1, + 3 * gd_gi->width + 2 * ED_GADGET_DISTANCE, + ED_GADGET_DISTANCE, tab_color); +} + +static void DrawPropertiesInfo() +{ + static struct + { + int value; + char *text; + } + properties[] = + { + /* 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_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" }, + { EP_PASSABLE_OVER, "- player can pass over it" }, + { EP_PASSABLE_INSIDE, "- player can pass through it" }, + { EP_PASSABLE_UNDER, "- player can pass under it" }, + + /* pre-defined properties */ + { EP_CAN_PASS_MAGIC_WALL, "- can pass magic walls" }, + { EP_HAS_CONTENT, "- can contain other elements" }, + + { -1, NULL } + }; + char *filename = getElementDescriptionFilename(properties_element); + char *percentage_text = "In this level:"; + char *properties_text = "Standard properties:"; + float percentage; + int num_elements_in_level; + int num_standard_properties = 0; + int font1_nr = FONT_TEXT_1; + int font2_nr = FONT_TEXT_2; + int font1_width = getFontWidth(font1_nr); + int font2_height = getFontHeight(font2_nr); + 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; yevent.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; @@ -4078,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) { @@ -4129,29 +5167,45 @@ 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; + element_info[properties_element] = custom_element; + + ModifyEditorElementList(); + RedrawDrawingElements(); - level.custom_element_successor[i] = new_element; + FrameCounter = 0; /* restart animation frame counter */ + } + else if (id == GADGET_ID_CUSTOM_CONTENT) + { + 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_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; @@ -4249,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; @@ -4293,7 +5364,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi) switch (counter_id) { - case ED_COUNTER_ID_ELEM_CONTENT: + case ED_COUNTER_ID_ELEMENT_CONTENT: DrawElementContentAreas(); break; @@ -4313,6 +5384,12 @@ static void HandleCounterButtons(struct GadgetInfo *gi) default: break; } + + 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); } static void HandleTextInputGadgets(struct GadgetInfo *gi) @@ -4322,12 +5399,28 @@ static void HandleTextInputGadgets(struct GadgetInfo *gi) static void HandleSelectboxGadgets(struct GadgetInfo *gi) { - *selectbox_info[gi->custom_type_id].index = gi->selectbox.index; + int type_id = gi->custom_type_id; -#if 1 - printf("Selected text value: '%s'\n", - selectbox_info[gi->custom_type_id].values[gi->selectbox.index]); -#endif + *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); +} + +static void HandleTextbuttonGadgets(struct GadgetInfo *gi) +{ + if (gi->custom_type_id >= ED_TEXTBUTTON_ID_PROPERTIES_INFO && + gi->custom_type_id <= ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED) + { + edit_mode_properties = gi->custom_type_id; + + DrawPropertiesWindow(); + } } static void HandleRadiobuttons(struct GadgetInfo *gi) @@ -4342,9 +5435,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) - CopyCustomElementPropertiesToGame(); + 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) @@ -4353,13 +5454,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; @@ -4473,18 +5575,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: @@ -4513,7 +5605,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; @@ -4543,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--; @@ -4567,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_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) @@ -4956,7 +6093,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed) /* CloseDoor(DOOR_CLOSE_ALL); */ - game_status = MAINMENU; + game_status = GAME_MODE_MAIN; DrawMainMenu(); } else