X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=dd757b0560755526e7be89a91d8c4904b0e49673;hb=720b0a62c8af0585e9517ed7a98ea336304c02e4;hp=4707b4ff1264b4137867189dd452310e047212a1;hpb=bb14567afe79714fc177fdd2d205bc9a7bf3c9b6;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 4707b4ff..dd757b05 100644 --- a/src/editor.c +++ b/src/editor.c @@ -20,6 +20,7 @@ #include "tools.h" #include "files.h" #include "game.h" +#include "init.h" #include "tape.h" @@ -67,38 +68,68 @@ #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 +#define ED_GADGET_TEXT_DISTANCE (2 * ED_GADGET_DISTANCE) + /* 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_BORDER2_SIZE 5 -#define ED_GADGET_DISTANCE 2 - /* values for element content drawing areas */ +/* amoeba content */ #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) +/* custom change target */ +#define ED_AREA_ELEM_CONTENT2_XPOS (20 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT2_YPOS (ED_SETTINGS_YPOS(2) + \ + ED_GADGET_DISTANCE) +/* optional custom graphic */ +#define ED_AREA_ELEM_CONTENT3_XPOS (24 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT3_YPOS (ED_SETTINGS_YPOS(1) + \ + ED_GADGET_DISTANCE) +/* custom element content */ +#define ED_AREA_ELEM_CONTENT4_XPOS (29 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(12) + \ + ED_GADGET_DISTANCE - MINI_TILEY) +/* custom change trigger element */ +#define ED_AREA_ELEM_CONTENT5_XPOS (28 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT5_YPOS (ED_SETTINGS_YPOS(7) + \ + ED_GADGET_DISTANCE) +/* extended custom change target */ +#define ED_AREA_ELEM_CONTENT6_XPOS (29 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT6_YPOS (ED_SETTINGS_YPOS(10) + \ + ED_GADGET_DISTANCE - MINI_TILEY) /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) @@ -200,9 +231,15 @@ #define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS #define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \ + 4 * (2 + ED_WIN_COUNT_YSIZE)) +#define ED_TEXTBUTTON_INACTIVE_YPOS ED_TEXTBUTTON_YPOS + +#define ED_TEXTBUTTON_TAB_XPOS ED_WIN_COUNT_XPOS +#define ED_TEXTBUTTON_TAB_YPOS (ED_WIN_COUNT_YPOS + \ 2 * (2 + ED_WIN_COUNT_YSIZE)) -#define ED_TEXTBUTTON_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \ +#define ED_TEXTBUTTON_TAB_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \ 3 * (2 + ED_WIN_COUNT_YSIZE)) + #define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE #define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE @@ -249,52 +286,83 @@ /* 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_GEMSLIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 12) +#define GADGET_ID_LEVEL_GEMSLIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 13) +#define GADGET_ID_LEVEL_GEMSLIMIT_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_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 30) +#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 31) +#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 32) +#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 33) +#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 34) +#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 35) +#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 36) +#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 37) +#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 38) +#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 39) +#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 40) +#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 41) +#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 42) +#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 43) +#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 44) +#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 45) +#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 46) +#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 47) +#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 48) +#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 49) +#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 50) +#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 51) +#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 52) +#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 53) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 54) #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_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 12) +#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 13) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 14) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 15) /* 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 + 16) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -302,17 +370,31 @@ /* selectbox identifiers */ #define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 2) -#define GADGET_ID_CUSTOM_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 0) +#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 0) +#define GADGET_ID_CUSTOM_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_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 5) +#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 6) +#define GADGET_ID_CUSTOM_ACCESS_TYPE (GADGET_ID_SELECTBOX_FIRST + 7) +#define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 8) +#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 9) +#define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 10) +#define GADGET_ID_CHANGE_COLLIDE_ACTION (GADGET_ID_SELECTBOX_FIRST + 11) +#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 12) +#define GADGET_ID_CHANGE_POWER (GADGET_ID_SELECTBOX_FIRST + 13) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 1) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 14) #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) @@ -328,7 +410,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) @@ -338,14 +420,31 @@ #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_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 8) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 9) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CHANGE_BY_COLLISION (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CHANGE_BY_OTHER (GADGET_ID_CHECKBUTTON_FIRST + 28) /* 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 + 29) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -357,21 +456,36 @@ #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_GEMSLIMIT 3 +#define ED_COUNTER_ID_LEVEL_TIMELIMIT 4 +#define ED_COUNTER_ID_LEVEL_TIMESCORE 5 +#define ED_COUNTER_ID_LEVEL_RANDOM 6 +#define ED_COUNTER_ID_ELEMENT_SCORE 7 +#define ED_COUNTER_ID_ELEMENT_CONTENT 8 +#define ED_COUNTER_ID_CUSTOM_SCORE 9 +#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 10 +#define ED_COUNTER_ID_PUSH_DELAY_FIX 11 +#define ED_COUNTER_ID_PUSH_DELAY_RND 12 +#define ED_COUNTER_ID_MOVE_DELAY_FIX 13 +#define ED_COUNTER_ID_MOVE_DELAY_RND 14 +#define ED_COUNTER_ID_CHANGE_DELAY_FIX 15 +#define ED_COUNTER_ID_CHANGE_DELAY_RND 16 +#define ED_COUNTER_ID_CHANGE_CONT_RND 17 + +#define ED_NUM_COUNTERBUTTONS 18 #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_CONT_RND + /* values for scrollbutton gadgets */ #define ED_SCROLLBUTTON_ID_AREA_UP 0 #define ED_SCROLLBUTTON_ID_AREA_DOWN 1 @@ -405,16 +519,36 @@ #define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR /* values for selectbox gadgets */ -#define ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE 0 - -#define ED_NUM_SELECTBOX 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_MOVE_STEPSIZE 5 +#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 6 +#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE 7 +#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 8 +#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 9 +#define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 10 +#define ED_SELECTBOX_ID_CHANGE_COLLIDE_ACTION 11 +#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 12 +#define ED_SELECTBOX_ID_CHANGE_POWER 13 + +#define ED_NUM_SELECTBOX 14 + +#define ED_SELECTBOX_ID_CUSTOM_FIRST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION +#define ED_SELECTBOX_ID_CUSTOM_LAST ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER + +#define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS +#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_POWER /* values for textbutton gadgets */ #define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0 #define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 1 #define ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED 2 +#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 3 -#define ED_NUM_TEXTBUTTON 3 +#define ED_NUM_TEXTBUTTON 4 /* values for checkbutton gadgets */ #define ED_CHECKBUTTON_ID_DOUBLE_SPEED 0 @@ -422,19 +556,39 @@ #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_EXPLODE_FIRE 6 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 7 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 8 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 9 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 10 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 11 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 12 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 13 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 14 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 15 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 16 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 17 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 18 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 19 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 20 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 21 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 22 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 23 +#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 24 +#define ED_CHECKBUTTON_ID_CHANGE_BY_COLLISION 25 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER 26 + +#define ED_NUM_CHECKBUTTONS 27 #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_ACCESSIBLE + +#define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_BY_OTHER /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -480,6 +634,10 @@ #define MIN_SCORE 0 #define MAX_SCORE 255 +/* values for elements with gem count */ +#define MIN_GEM_COUNT 0 +#define MAX_GEM_COUNT 100 + /* values for random placement */ #define RANDOM_USE_PERCENTAGE 0 #define RANDOM_USE_QUANTITY 1 @@ -530,15 +688,9 @@ 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 { @@ -547,81 +699,164 @@ 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] = { + /* ---------- level and editor settings ---------------------------------- */ + { - 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, + GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP, + GADGET_ID_LEVEL_GEMSLIMIT_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" }, + + /* ---------- element settings: configure (various elements) ------------- */ + { - 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" + }, + + /* ---------- element settings: configure (custom elements) ------------- */ + + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), + MIN_SCORE, MAX_SCORE, + GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, + GADGET_ID_CUSTOM_SCORE_TEXT, + &custom_element.score, + NULL, "collect score", NULL + }, + { + ED_SETTINGS_XPOS(13) + 10, ED_SETTINGS_YPOS(3), + MIN_GEM_COUNT, MAX_GEM_COUNT, + GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP, + GADGET_ID_CUSTOM_GEMCOUNT_TEXT, + &custom_element.gem_count, + NULL, "gems", NULL + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4), + 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(4), + 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(7), + 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(7), + 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 + }, + + /* ---------- element settings: advanced (custom elements) --------------- */ + + { + 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 + }, + { + ED_SETTINGS_XPOS(3), ED_SETTINGS_YPOS(12), + 0, 100, + GADGET_ID_CHANGE_CONT_RND_DOWN, GADGET_ID_CHANGE_CONT_RND_UP, + GADGET_ID_CHANGE_CONT_RND_TEXT, + &custom_element.change.random, + NULL, "use random change:", NULL + }, }; static struct @@ -634,14 +869,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, @@ -649,33 +884,268 @@ static struct } }; -static struct ValueTextInfo options_change_cause[] = +static struct ValueTextInfo options_access_type[] = +{ + { EP_WALKABLE, "walk" }, + { EP_PASSABLE, "pass" }, + { -1, NULL } +}; +static int value_access_type = 0; + +static struct ValueTextInfo options_access_layer[] = +{ + { EP_ACCESSIBLE_OVER, "over" }, + { EP_ACCESSIBLE_INSIDE, "inside" }, + { EP_ACCESSIBLE_UNDER, "under" }, + { -1, NULL } +}; +static int value_access_layer = 0; + +static struct ValueTextInfo options_walk_to_action[] = +{ + { EP_DIGGABLE, "diggable" }, + { EP_COLLECTIBLE, "collectible" }, + { EP_PUSHABLE, "pushable" }, + { -1, NULL } +}; +static int value_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" }, + { MV_TURNING_LEFT, "turning left" }, + { MV_TURNING_RIGHT, "turning right" }, + { -1, NULL } +}; + +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 struct ValueTextInfo options_move_stepsize[] = +{ + { 1, "very slow" }, + { 2, "slow" }, + { 4, "normal" }, + { 8, "fast" }, + { 16, "very fast" }, + { -1, NULL } +}; + +static struct ValueTextInfo options_smash_targets[] = +{ + { EP_CAN_SMASH_PLAYER, "player" }, + { EP_CAN_SMASH_ENEMIES, "enemies" }, + { EP_CAN_SMASH_EVERYTHING, "everything" }, + { -1, NULL } +}; +static int value_smash_targets = 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 value_deadliness = 0; + +static struct ValueTextInfo options_consistency[] = +{ + { EP_CAN_EXPLODE, "can explode" }, + { EP_INDESTRUCTIBLE, "indestructible" }, + { -1, NULL } +}; +static int value_consistency = 0; + +static struct ValueTextInfo options_time_units[] = +{ + { 50, "seconds" }, + { 1, "frames" }, + { -1, NULL } +}; + +static struct ValueTextInfo options_change_player_action[] = +{ + { CE_TOUCHED_BY_PLAYER, "touched" }, + { CE_PRESSED_BY_PLAYER, "pressed" }, + { CE_PUSHED_BY_PLAYER, "pushed" }, + { -1, NULL } +}; +static int value_change_player_action = 0; + +static struct ValueTextInfo options_change_collide_action[] = { - { 1, "specified delay" }, - { 2, "impact (active)" }, - { 3, "impact (passive)" }, - { 4, "touched by player" }, - { 5, "pressed by player" }, - { -1, NULL } + { CE_COLLISION, "on collision" }, + { CE_IMPACT, "on impact" }, + { CE_SMASHED, "when smashed" }, + { -1, NULL } +}; +static int value_change_collide_action = 0; + +static struct ValueTextInfo options_change_other_action[] = +{ + { CE_OTHER_IS_TOUCHING, "touching" }, + { CE_OTHER_IS_CHANGING, "change of" }, + { CE_OTHER_IS_EXPLODING, "explosion of" }, + { CE_OTHER_GETS_TOUCHED, "player touches" }, + { CE_OTHER_GETS_PRESSED, "player presses" }, + { CE_OTHER_GETS_PUSHED, "player pushes" }, + { CE_OTHER_GETS_COLLECTED, "player collects" }, + { -1, NULL } +}; +static int value_change_other_action = 0; + +static struct ValueTextInfo options_change_power[] = +{ + { CP_NON_DESTRUCTIVE, "non-destructive" }, + { CP_HALF_DESTRUCTIVE, "half-destructive" }, + { CP_FULL_DESTRUCTIVE, "full-destructive" }, + { -1, NULL } }; -static int index_change_cause = 0; static struct { int x, y; int gadget_id; - int size; + int size; /* char size of selectbox or '-1' (dynamically determined) */ struct ValueTextInfo *options; - int *index; - char *text, *infotext; + int *value; + char *text_left, *text_right, *infotext; } selectbox_info[ED_NUM_SELECTBOX] = { + /* ---------- element settings: configure (custom elements) ------------- */ + + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_ACCESS_TYPE, + -1, + options_access_type, + &value_access_type, + "player can", NULL, "type of access to this field" + }, + { + ED_SETTINGS_XPOS(11), ED_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_ACCESS_LAYER, + -1, + options_access_layer, + &value_access_layer, + NULL, NULL, "layer of access for this field" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_WALK_TO_ACTION, + -1, + options_walk_to_action, + &value_walk_to_action, + NULL, NULL, "diggable/collectible/pushable" + }, { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3), - GADGET_ID_CUSTOM_CHANGE_CAUSE, - 17, - options_change_cause, &index_change_cause, - "test:", "test-selectbox entry" + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_MOVE_PATTERN, + -1, + options_move_pattern, + &custom_element.move_pattern, + "can move", NULL, "element move direction" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), + GADGET_ID_CUSTOM_MOVE_DIRECTION, + -1, + options_move_direction, + &custom_element.move_direction_initial, + "starts moving", NULL, "initial element move direction" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8), + GADGET_ID_CUSTOM_MOVE_STEPSIZE, + -1, + options_move_stepsize, + &custom_element.move_stepsize, + "move/fall speed", NULL, "speed of element movement" + }, + { + ED_SETTINGS_XPOS(7), ED_SETTINGS_YPOS(9), + GADGET_ID_CUSTOM_SMASH_TARGETS, + -1, + options_smash_targets, + &value_smash_targets, + "can smash", NULL, "elements that can be smashed" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(11), + GADGET_ID_CUSTOM_DEADLINESS, + -1, + options_deadliness, + &value_deadliness, + "deadly when", NULL, "deadliness of element" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(12), + GADGET_ID_CUSTOM_CONSISTENCY, + -1, + options_consistency, + &value_consistency, + NULL, "explodes to:", "consistency/destructibility" + }, + + /* ---------- element settings: advanced (custom elements) --------------- */ + + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(4), + GADGET_ID_CHANGE_TIME_UNITS, + -1, + options_time_units, + &custom_element.change.delay_frames, + "delay time given in", NULL, "delay time units for change" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(5), + GADGET_ID_CHANGE_PLAYER_ACTION, + -1, + options_change_player_action, + &value_change_player_action, + NULL, "by player", "type of player contact" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_COLLIDE_ACTION, + -1, + options_change_collide_action, + &value_change_collide_action, + NULL, NULL, "change after impact or smash" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_OTHER_ACTION, + -1, + options_change_other_action, + &value_change_other_action, + NULL, "element:", "type of other element action" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(10), + GADGET_ID_CHANGE_POWER, + -1, + options_change_power, + &custom_element.change.power, + "power:", NULL, "power of extended change" }, }; @@ -684,33 +1154,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(13), + 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; @@ -756,7 +1227,7 @@ static struct static struct { - int xpos, ypos; + int gd_x, gd_y; int x, y; int width, height; int type; @@ -797,18 +1268,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, @@ -816,74 +1287,191 @@ static struct } }; +static boolean can_explode_by_fire = FALSE; +static boolean can_explode_smashed = FALSE; +static boolean can_explode_impact = FALSE; + static struct { int x, y; int gadget_id; boolean *value; - char *text, *infotext; + char *text_right, *infotext; } checkbutton_info[ED_NUM_CHECKBUTTONS] = { + /* ---------- level and editor settings ---------------------------------- */ + { - 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" }, + + /* ---------- element settings: configure (various elements) ------------- */ + { - 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" }, + + /* ---------- element settings: configure (custom elements) ------------- */ + + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_ACCESSIBLE, + &custom_element_properties[EP_ACCESSIBLE], + NULL, "player can walk to or pass this field" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), + 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(10), - GADGET_ID_CUSTOM_INDESTRUCTIBLE, - &custom_element_properties[0].indestructible, - "indestructible", "element cannot be destroyed" + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_CAN_MOVE, + &custom_element_properties[EP_CAN_MOVE], + NULL, "element can move in some direction" }, { - ED_SETTINGS_XPOS, 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" - }, - { - ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(13), - GADGET_ID_CUSTOM_PUSHABLE, - &custom_element_properties[0].pushable, - "pushable", "element can be pushed" + &custom_element_properties[EP_CAN_SMASH], + NULL, "element can smash other elements" }, { - 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(11), + GADGET_ID_CUSTOM_DEADLY, + &custom_element_properties[EP_DEADLY], + NULL, "element can kill the player" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(12), + GADGET_ID_CUSTOM_EXPLODE_RESULT, + &custom_element_properties[EP_EXPLODE_RESULT], + NULL, "set consistency/destructibility" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_EXPLODE_FIRE, + &can_explode_by_fire, + "by fire", "element can explode by fire/explosion" + }, + { + ED_SETTINGS_XPOS(7), ED_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_EXPLODE_SMASH, + &can_explode_smashed, + "smashed", "element can explode when smashed" + }, + { + ED_SETTINGS_XPOS(13), ED_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_EXPLODE_IMPACT, + &can_explode_impact, + "impact", "element can explode on impact" + }, + + /* ---------- element settings: advanced (custom elements) --------------- */ + + { + 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(2), + GADGET_ID_CUSTOM_CAN_CHANGE, + &custom_element_properties[EP_CAN_CHANGE], + "element changes to after/when:","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" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5), + GADGET_ID_CHANGE_BY_PLAYER, + &custom_element_change_events[CE_BY_PLAYER], + NULL, "element changes by player contact" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_BY_COLLISION, + &custom_element_change_events[CE_BY_COLLISION], + NULL, "element changes by impact or smash" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_BY_OTHER, + &custom_element_change_events[CE_BY_OTHER], + NULL, "element changes by other element" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8), + GADGET_ID_CHANGE_USE_EXPLOSION, + &custom_element.change.explode, + "explode instead of change", "element explodes instead of change" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(9), + GADGET_ID_CHANGE_USE_CONTENT, + &custom_element.change.use_content, + "use extended change target:", "element changes to more elements" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(11), + GADGET_ID_CHANGE_ONLY_COMPLETE, + &custom_element.change.only_complete, + "only use complete change", "only use complete extended content" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(12), + GADGET_ID_CHANGE_USE_RANDOM, + &custom_element.change.use_random_change, + NULL, "use random value for new content" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_USE_TEMPLATE, + &level.use_custom_template, + "use template", "use template for custom properties" + }, }; @@ -914,9 +1502,12 @@ static int new_element3 = EL_SAND; /* forward declaration for internal use */ static void ModifyEditorCounter(int, int); static void ModifyEditorCounterLimits(int, int, int); +static void ModifyEditorSelectbox(int, int); +static void ModifyEditorElementList(); static void DrawDrawingWindow(); static void DrawLevelInfoWindow(); static void DrawPropertiesWindow(); +static boolean checkPropertiesConfig(); static void CopyLevelToUndoBuffer(int); static void HandleDrawingAreas(struct GadgetInfo *); static void HandleCounterButtons(struct GadgetInfo *); @@ -935,7 +1526,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; @@ -1964,8 +2554,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; } @@ -1975,8 +2565,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; } @@ -2065,6 +2655,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) + + ED_GADGET_TEXT_DISTANCE); for (j=0; j<2; j++) { @@ -2093,9 +2690,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; } @@ -2115,7 +2712,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, @@ -2164,7 +2761,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, @@ -2227,7 +2824,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, @@ -2266,11 +2863,11 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; - /* ... one for each custom element change target element ... */ - id = GADGET_ID_CUSTOM_CHANGED; + /* ... 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_CONTENT2_XPOS, - GDI_Y, SY + ED_AREA_ELEM_CONTENT2_YPOS, + 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, @@ -2285,12 +2882,31 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; - /* ... and one for random placement background restrictions */ + /* ... one area 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); - id = GADGET_ID_RANDOM_BACKGROUND; + 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_CHANGE_TARGET; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_X, SX + ED_AREA_RANDOM_BACKGROUND_XPOS, - GDI_Y, SY + ED_AREA_RANDOM_BACKGROUND_YPOS, + GDI_X, SX + ED_AREA_ELEM_CONTENT2_XPOS, + GDI_Y, SY + ED_AREA_ELEM_CONTENT2_YPOS, GDI_WIDTH, MINI_TILEX, GDI_HEIGHT, MINI_TILEY, GDI_TYPE, GD_TYPE_DRAWING_AREA, @@ -2304,28 +2920,86 @@ static void CreateDrawingAreas() Error(ERR_EXIT, "cannot create gadget"); level_editor_gadget[id] = gi; -} - -static void CreateTextInputGadgets() -{ - int max_infotext_len = getMaxInfoTextLength(); - int i; - 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) + + ED_GADGET_TEXT_DISTANCE); + sprintf(infotext, "Select %s", selectbox_info[i].infotext); infotext[max_infotext_len] = '\0'; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_INFO_TEXT, infotext, - GDI_X, SX + selectbox_info[i].x, + GDI_X, SX + selectbox_info[i].x + xoffset, GDI_Y, SY + selectbox_info[i].y, GDI_TYPE, GD_TYPE_SELECTBOX, GDI_SELECTBOX_OPTIONS, selectbox_info[i].options, - GDI_SELECTBOX_INDEX, selectbox_info[i].index, GDI_TEXT_SIZE, selectbox_info[i].size, GDI_TEXT_FONT, FONT_INPUT_1, GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE, @@ -2419,12 +3113,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'; @@ -2435,7 +3142,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, @@ -2494,11 +3201,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, @@ -2615,7 +3322,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(); @@ -2641,6 +3348,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]); @@ -2667,7 +3418,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); } @@ -2678,11 +3428,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_GADGET_TEXT_DISTANCE; + 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]); } @@ -2693,11 +3478,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]); } @@ -2808,67 +3614,209 @@ 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++) + /* needed here to initialize combined element properties */ + InitElementPropertiesEngine(level.game_version); + + 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); + + /* ---------- element settings: configure (custom elements) ------------- */ + + /* set accessible layer selectbox help value */ + value_access_type = + (IS_WALKABLE(element) ? EP_WALKABLE : + IS_PASSABLE(element) ? EP_PASSABLE : + value_access_type); + value_access_layer = + (IS_ACCESSIBLE_OVER(element) ? EP_ACCESSIBLE_OVER : + IS_ACCESSIBLE_INSIDE(element) ? EP_ACCESSIBLE_INSIDE : + IS_ACCESSIBLE_UNDER(element) ? EP_ACCESSIBLE_UNDER : + value_access_layer); + custom_element_properties[EP_ACCESSIBLE] = + (IS_ACCESSIBLE_OVER(element) || + IS_ACCESSIBLE_INSIDE(element) || + IS_ACCESSIBLE_UNDER(element)); + + /* set walk-to-object action selectbox help value */ + value_walk_to_action = + (IS_DIGGABLE(element) ? EP_DIGGABLE : + IS_COLLECTIBLE(element) ? EP_COLLECTIBLE : + IS_PUSHABLE(element) ? EP_PUSHABLE : + value_walk_to_action); + custom_element_properties[EP_WALK_TO_OBJECT] = + (IS_DIGGABLE(element) || + IS_COLLECTIBLE(element) || + IS_PUSHABLE(element)); + + /* set smash targets selectbox help value */ + value_smash_targets = + (CAN_SMASH_EVERYTHING(element) ? EP_CAN_SMASH_EVERYTHING : + CAN_SMASH_ENEMIES(element) ? EP_CAN_SMASH_ENEMIES : + CAN_SMASH_PLAYER(element) ? EP_CAN_SMASH_PLAYER : + value_smash_targets); + custom_element_properties[EP_CAN_SMASH] = + (CAN_SMASH_EVERYTHING(element) || + CAN_SMASH_ENEMIES(element) || + CAN_SMASH_PLAYER(element)); + + /* set deadliness selectbox help value */ + value_deadliness = + (DONT_TOUCH(element) ? EP_DONT_TOUCH : + DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH : + DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO : + value_deadliness); + custom_element_properties[EP_DEADLY] = + (DONT_TOUCH(element) || + DONT_COLLIDE_WITH(element) || + DONT_RUN_INTO(element)); + + /* set consistency selectbox help value */ + value_consistency = + (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE : + CAN_EXPLODE(element) ? EP_CAN_EXPLODE : + value_consistency); + custom_element_properties[EP_EXPLODE_RESULT] = + (IS_INDESTRUCTIBLE(element) || + CAN_EXPLODE(element)); + + /* special case: sub-settings dependent from main setting */ + if (CAN_EXPLODE(element)) { - 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); - } + can_explode_by_fire = CAN_EXPLODE_BY_FIRE(element); + can_explode_smashed = CAN_EXPLODE_SMASHED(element); + can_explode_impact = CAN_EXPLODE_IMPACT(element); + }; + + /* ---------- element settings: advanced (custom elements) --------------- */ + + /* set change by player selectbox help value */ + value_change_player_action = + (HAS_CHANGE_EVENT(element, CE_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER : + HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER : + HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : + value_change_player_action); + + /* set change by collision selectbox help value */ + value_change_collide_action = + (HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED : + HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT : + HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION : + value_change_collide_action); + + /* set change by other element action selectbox help value */ + value_change_other_action = + (HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED : + HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PUSHED) ? CE_OTHER_GETS_PUSHED : + HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PRESSED) ? CE_OTHER_GETS_PRESSED : + HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED : + HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING : + HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING : + HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING : + value_change_other_action); } -static void CopyCustomElementPropertiesToGame() +static void CopyCustomElementPropertiesToGame(int element) { int i; - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + element_info[properties_element] = custom_element; + + /* ---------- element settings: configure (custom elements) ------------- */ + + /* set accessible 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[EP_PASSABLE_OVER] = FALSE; + custom_element_properties[EP_PASSABLE_INSIDE] = FALSE; + custom_element_properties[EP_PASSABLE_UNDER] = FALSE; + custom_element_properties[((value_access_type == EP_WALKABLE ? + EP_WALKABLE_OVER : EP_PASSABLE_OVER) + + (value_access_layer - EP_ACCESSIBLE_OVER))] = + custom_element_properties[EP_ACCESSIBLE]; + + /* 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[value_walk_to_action] = + custom_element_properties[EP_WALK_TO_OBJECT]; + + /* set smash property from checkbox and selectbox */ + custom_element_properties[EP_CAN_SMASH_PLAYER] = FALSE; + custom_element_properties[EP_CAN_SMASH_ENEMIES] = FALSE; + custom_element_properties[EP_CAN_SMASH_EVERYTHING] = FALSE; + custom_element_properties[value_smash_targets] = + custom_element_properties[EP_CAN_SMASH]; + + /* 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[value_deadliness] = + custom_element_properties[EP_DEADLY]; + + /* set consistency property from checkbox and selectbox */ + custom_element_properties[EP_INDESTRUCTIBLE] = FALSE; + custom_element_properties[EP_CAN_EXPLODE] = FALSE; + custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE; + custom_element_properties[EP_CAN_EXPLODE_SMASHED] = FALSE; + custom_element_properties[EP_CAN_EXPLODE_IMPACT] = FALSE; + custom_element_properties[value_consistency] = + custom_element_properties[EP_EXPLODE_RESULT]; + + /* special case: sub-settings dependent from main setting */ + if (custom_element_properties[EP_CAN_EXPLODE]) { - 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; + custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = can_explode_by_fire; + custom_element_properties[EP_CAN_EXPLODE_SMASHED] = can_explode_smashed; + custom_element_properties[EP_CAN_EXPLODE_IMPACT] = can_explode_impact; } + + /* ---------- element settings: advanced (custom elements) --------------- */ + + /* set player change event from checkbox and selectbox */ + custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE; + custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE; + custom_element_change_events[CE_PUSHED_BY_PLAYER] = FALSE; + custom_element_change_events[value_change_player_action] = + custom_element_change_events[CE_BY_PLAYER]; + + /* set collision change event from checkbox and selectbox */ + custom_element_change_events[CE_COLLISION] = FALSE; + custom_element_change_events[CE_IMPACT] = FALSE; + custom_element_change_events[CE_SMASHED] = FALSE; + custom_element_change_events[value_change_collide_action] = + custom_element_change_events[CE_BY_COLLISION]; + + /* set other element action change event from checkbox and selectbox */ + custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE; + custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE; + custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE; + custom_element_change_events[CE_OTHER_GETS_TOUCHED] = FALSE; + custom_element_change_events[CE_OTHER_GETS_PRESSED] = FALSE; + custom_element_change_events[CE_OTHER_GETS_PUSHED] = FALSE; + custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE; + custom_element_change_events[value_change_other_action] = + custom_element_change_events[CE_BY_OTHER]; + + 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() @@ -2919,6 +3867,7 @@ void DrawLevelEd() redraw_mask |= REDRAW_ALL; ReinitializeElementListButtons(); /* only needed after setup changes */ + ModifyEditorElementList(); /* may be needed for custom elements */ UnmapTapeButtons(); MapControlButtons(); @@ -3036,14 +3985,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; @@ -3064,6 +4005,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) @@ -3094,8 +4070,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(); @@ -3109,9 +4094,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; @@ -3136,102 +4123,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(); @@ -3244,23 +4171,21 @@ 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() { - 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_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)) { @@ -3270,292 +4195,152 @@ static void DrawCustomChangedArea() return; } - ElementContent[0][0][0] = level.custom_element_successor[i]; - - DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); - DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); - - 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.gfx_element)); - MapDrawingArea(GADGET_ID_CUSTOM_CHANGED); + MapDrawingArea(GADGET_ID_CUSTOM_GRAPHIC); } -static void DrawElementContentAreas() +static void DrawCustomContentArea() { - 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; ix + x * MINI_TILEX,gi->y + y * MINI_TILEY, + el2edimg(custom_element.content[x][y])); - 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; + MapDrawingArea(GADGET_ID_CUSTOM_CONTENT); } -static void DrawPropertiesConfig() +static void DrawCustomChangeTargetArea() { - int counter_id = ED_COUNTER_ID_ELEM_SCORE; - 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; + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TARGET]; + int xpos = ED_AREA_ELEM_CONTENT2_XPOS; + int ypos = ED_AREA_ELEM_CONTENT2_YPOS; + int area_sx = SX + xpos; + int area_sy = SY + ypos; - /* check if there are elements where a score can be chosen for */ - for (i=0; elements_with_counter[i].element != -1; i++) + if (!IS_CUSTOM_ELEMENT(properties_element)) { - if (elements_with_counter[i].element == properties_element) - { - int x = counterbutton_info[counter_id].x + xoffset_right; - int y = counterbutton_info[counter_id].y + yoffset_right; - - counterbutton_info[counter_id].value = elements_with_counter[i].value; - DrawTextF(x, y, FONT_TEXT_1, elements_with_counter[i].text); + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); - ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value); - MapCounterButtons(counter_id); - break; - } + return; } - if (HAS_CONTENT(properties_element) || - IS_CUSTOM_ELEMENT(properties_element)) - { - /* draw stickybutton gadget */ - i = ED_CHECKBUTTON_ID_STICK_ELEMENT; - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniGraphicExt(drawto, gi->x, gi->y, + el2edimg(custom_element.change.target_element)); - 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); + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TARGET); +} - if (HAS_CONTENT(properties_element)) - { - if (IS_AMOEBOID(properties_element)) - DrawAmoebaContentArea(); - else - DrawElementContentAreas(); - } - else if (IS_CUSTOM_ELEMENT(properties_element)) - DrawCustomChangedArea(); - } +static void DrawCustomChangeContentArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_CONTENT]; + int area_sx = SX + ED_AREA_ELEM_CONTENT6_XPOS; + int area_sy = SY + ED_AREA_ELEM_CONTENT6_YPOS; + int x, y; - if (IS_GEM(properties_element)) + if (!IS_CUSTOM_ELEMENT(properties_element)) { - /* draw checkbutton gadget */ - i = ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS; - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); - 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); + return; } - if (IS_CUSTOM_ELEMENT(properties_element)) - { - int nr = properties_element - EL_CUSTOM_START; - - CopyCustomElementPropertiesToEditor(); + DrawElementBorder(area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE); - /* draw checkbutton gadget */ - i = ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE; - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; + 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.change.content[x][y])); - checkbutton_info[i].value = &custom_element_properties[nr].indestructible; - - 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 checkbutton gadget */ - i = ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL; - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; - - checkbutton_info[i].value = &custom_element_properties[nr].can_fall; + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_CONTENT); +} - 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); +static void DrawCustomChangeTriggerArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TRIGGER]; + int xpos = ED_AREA_ELEM_CONTENT5_XPOS; + int ypos = ED_AREA_ELEM_CONTENT5_YPOS; + int area_sx = SX + xpos; + int area_sy = SY + ypos; - /* draw checkbutton gadget */ - i = ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH; - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; + if (!IS_CUSTOM_ELEMENT(properties_element)) + { + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); - checkbutton_info[i].value = &custom_element_properties[nr].can_smash; + return; + } - 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); + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniGraphicExt(drawto, gi->x, gi->y, + el2edimg(custom_element.change.trigger_element)); - /* draw checkbutton gadget */ - i = ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE; - x = checkbutton_info[i].x + xoffset_right2; - y = checkbutton_info[i].y + yoffset_right2; + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TRIGGER); +} - checkbutton_info[i].value = &custom_element_properties[nr].pushable; +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; - 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); + for (i=0; ialt_design[GD_BUTTON_UNPRESSED]; int gd_x = gd->x + gd_gi->border.width / 2; int gd_y = gd->y + gd_gi->height - 1; - Pixel line_color = GetPixel(gd->bitmap, gd_x, gd_y); + 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)) @@ -3759,28 +4550,89 @@ static void DrawPropertiesTabulatorGadgets() int gadget_id = textbutton_info[i].gadget_id; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; boolean active = (i != edit_mode_properties); - Pixel color = (active ? BLACK_PIXEL : line_color); - /* draw solid or black line below tabulator button */ - FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, 1, color); + /* 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 */ - FillRectangle(drawto, gd_gi->x, gd_gi->y + gd_gi->height + 1, - 3 * gd_gi->width + 2 * ED_GADGET_DISTANCE, ED_GADGET_DISTANCE, - line_color); + 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" }, +#if 0 + { EP_CAN_SMASH, "- can smash" }, +#endif + { EP_CAN_SMASH_PLAYER, "- can smash player" }, + { EP_CAN_SMASH_ENEMIES, "- can smash good and bad guys" }, + { EP_CAN_SMASH_EVERYTHING, "- can smash everything smashable" }, + { EP_CAN_EXPLODE, "- can explode" }, + { EP_CAN_EXPLODE_BY_FIRE, " - by fire or explosions" }, + { EP_CAN_EXPLODE_SMASHED, " - when smashed" }, + { EP_CAN_EXPLODE_IMPACT, " - on impact" }, + + { 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); - int num_elements_in_level; + char *percentage_text = "In this level:"; + char *properties_text = "Standard properties:"; float percentage; - int screen_line = 2; - int x, y; + 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; y= 0; i--) + if (buffer[i] == ' ') + break; + + if (strlen(&element_name[i + 1]) <= max_chars_per_line) + { + buffer[i] = '\0'; + next_pos = i + 1; + } + } + + DrawTextF(x, y - font_height / 2, font_nr, buffer); + + strncpy(buffer, &element_name[next_pos], max_chars_per_line); + buffer[max_chars_per_line] = '\0'; + + DrawTextF(x, y + font_height / 2, font_nr, buffer); + } } static void DrawPropertiesWindow() @@ -3808,26 +4921,33 @@ 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); UnmapLevelEditorWindowGadgets(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearWindow(); - DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS, + DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, "Element Settings", FONT_TITLE_1); DrawElementBorder(SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, - TILEX, TILEY); + TILEX, TILEY, FALSE); DrawGraphicAnimationExt(drawto, SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, @@ -3835,8 +4955,8 @@ static void DrawPropertiesWindow() FrameCounter = 0; /* restart animation frame counter */ - DrawTextF((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY, - FONT_TEXT_1, getElementInfoText(properties_element)); + DrawElementName((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY, + properties_element); DrawPropertiesTabulatorGadgets(); @@ -4374,12 +5494,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) @@ -4470,6 +5584,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) int sx = gi->event.x, sy = gi->event.y; int min_sx = 0, min_sy = 0; int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1; + int item_xsize = gi->drawing.item_xsize, item_ysize = gi->drawing.item_ysize; int lx = 0, ly = 0; int min_lx = 0, min_ly = 0; int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; @@ -4514,7 +5629,12 @@ 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); + + /* clicking into drawing area with pressed Control key picks element */ + if (GetKeyModState() & KMOD_Control) + actual_drawing_function = GADGET_ID_PICK_ELEMENT; switch (actual_drawing_function) { @@ -4565,29 +5685,55 @@ 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_CHANGE_TARGET) + { + custom_element.change.target_element = new_element; + element_info[properties_element] = custom_element; + } + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + { + custom_element.change.content[sx][sy] = new_element; + element_info[properties_element] = custom_element; + } + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + { + custom_element.change.trigger_element = 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; @@ -4685,8 +5831,29 @@ 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_CHANGE_TARGET) + PickDrawingElement(button, custom_element.change.target_element); + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + PickDrawingElement(button, custom_element.change.content[sx][sy]); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + PickDrawingElement(button, custom_element.change.trigger_element); + 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; @@ -4729,7 +5896,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi) switch (counter_id) { - case ED_COUNTER_ID_ELEM_CONTENT: + case ED_COUNTER_ID_ELEMENT_CONTENT: DrawElementContentAreas(); break; @@ -4749,6 +5916,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) @@ -4760,13 +5933,14 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) { int type_id = gi->custom_type_id; - *selectbox_info[type_id].index = gi->selectbox.index; + *selectbox_info[type_id].value = + selectbox_info[type_id].options[gi->selectbox.index].value; -#if 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 + 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) @@ -4792,9 +5966,19 @@ 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(); + + DrawPropertiesAdvancedDrawingAreas(); + } } static void HandleControlButtons(struct GadgetInfo *gi) @@ -4803,13 +5987,15 @@ 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 && + !(GetKeyModState() & KMOD_Control)) { DrawDrawingWindow(); edit_mode = ED_MODE_DRAWING; @@ -4923,18 +6109,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: @@ -4963,7 +6139,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; @@ -4993,6 +6170,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--; @@ -5017,6 +6200,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; xcustom_id == GADGET_ID_SINGLE_ITEMS) /* special case 1 */ sprintf(shortcut, " ('.' or '%c')", key); - else if (gi->custom_id == GADGET_ID_TEST) /* special case 2 */ + else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) /* special case 2 */ + sprintf(shortcut, " ('%c' or 'Ctrl')", key); + else if (gi->custom_id == GADGET_ID_TEST) /* special case 3 */ sprintf(shortcut, " ('Enter' or 'Shift-%c')", key); else /* normal case */ sprintf(shortcut, " ('%s%c')", @@ -5277,6 +6465,11 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) int min_sx = 0, min_sy = 0; int max_sx = gi->drawing.area_xsize - 1; int max_sy = gi->drawing.area_ysize - 1; + int actual_drawing_function = drawing_function; + + /* pressed Control key: simulate picking element */ + if (GetKeyModState() & KMOD_Control) + actual_drawing_function = GADGET_ID_PICK_ELEMENT; ClearEditorGadgetInfoText(); @@ -5317,7 +6510,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) start_ly = ly; } - switch (drawing_function) + switch (actual_drawing_function) { case GADGET_ID_SINGLE_ITEMS: infotext = "Drawing single items"; @@ -5355,7 +6548,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) break; } - if (drawing_function == GADGET_ID_PICK_ELEMENT) + if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s: %d, %d", infotext, lx, ly); else @@ -5363,7 +6556,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) "%s: %d, %d", infotext, ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1); } - else if (drawing_function == GADGET_ID_PICK_ELEMENT) + else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(Feld[lx][ly])); else @@ -5380,19 +6573,67 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) DeleteBrushFromCursor(); } } - else if (id == GADGET_ID_AMOEBA_CONTENT) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Amoeba content"); - else if (id == GADGET_ID_CUSTOM_CHANGED) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Next element after change"); - else if (id == GADGET_ID_RANDOM_BACKGROUND) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Random placement background"); + else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) + { + if (id == GADGET_ID_AMOEBA_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(level.amoeba_content)); + else if (id == GADGET_ID_CUSTOM_GRAPHIC) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.gfx_element)); + else if (id == GADGET_ID_CUSTOM_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.content[sx][sy])); + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.change.target_element)); + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.change.content[sx][sy])); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.change.trigger_element)); + else if (id == GADGET_ID_RANDOM_BACKGROUND) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(random_placement_background_element)); + else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && + id <= GADGET_ID_ELEMENT_CONTENT_7) + { + int i = id - GADGET_ID_ELEMENT_CONTENT_0; + + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(level.yamyam_content[i][sx][sy])); + } + } else - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Content area %d position: %d, %d", - id - GADGET_ID_ELEM_CONTENT_0 + 1, sx, sy); + { + if (id == GADGET_ID_AMOEBA_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Amoeba content"); + else if (id == GADGET_ID_CUSTOM_GRAPHIC) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Custom graphic element"); + else if (id == GADGET_ID_CUSTOM_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Custom element content position: %d, %d", sx, sy); + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "New element after change"); + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "New extended elements after change"); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Other element triggering 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) @@ -5406,7 +6647,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed) /* CloseDoor(DOOR_CLOSE_ALL); */ - game_status = MAINMENU; + game_status = GAME_MODE_MAIN; DrawMainMenu(); } else