X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=1f75066ab6f627b435b96cea1b5261470c4473cf;hb=61e7a86bf1dad5f041802e539950185eb921bd68;hp=4852f3e3de182ddb7d88c1a139b95d04b09bf0b0;hpb=68f0ce90185b6ea19cad62bc6328326bda538951;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 4852f3e3..1f75066a 100644 --- a/src/editor.c +++ b/src/editor.c @@ -277,7 +277,7 @@ #define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE #define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE -/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */ +/* values for ClearEditorGadgetInfoText() and HandleEditorGadgetInfoText() */ #define INFOTEXT_XPOS SX #define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) #define INFOTEXT_XSIZE SXSIZE @@ -443,18 +443,20 @@ #define GADGET_ID_MAGIC_BALL_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 16) #define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 17) #define GADGET_ID_START_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 18) -#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 19) -#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 20) -#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 21) -#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 22) -#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 23) -#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 24) -#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 25) -#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 26) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 27) +#define GADGET_ID_ARTWORK_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 19) +#define GADGET_ID_EXPLOSION_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 20) +#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 21) +#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 22) +#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 23) +#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 24) +#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 25) +#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 26) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 27) +#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 28) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 29) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 28) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 30) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -554,38 +556,40 @@ #define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 14) #define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 15) #define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 41) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 42) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 43) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 43) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 44) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 47) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 48) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -775,37 +779,39 @@ #define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 12 #define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 13 #define ED_CHECKBUTTON_ID_USE_START_ELEMENT 14 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 15 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 16 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 17 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 18 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 19 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 20 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 21 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 22 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 23 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 24 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 25 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 26 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 27 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 28 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 29 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 30 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 31 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 32 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 33 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 34 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 35 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 36 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 37 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 38 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 39 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 40 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 41 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 42 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 43 - -#define ED_NUM_CHECKBUTTONS 44 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 15 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 16 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 17 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 18 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 19 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 20 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 21 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 22 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 23 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 24 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 25 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 26 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 27 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 28 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 29 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 30 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 31 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 32 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 33 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 34 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 35 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 36 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 37 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 38 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 39 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 40 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 41 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 42 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 43 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 44 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 45 + +#define ED_NUM_CHECKBUTTONS 46 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_INITIAL_GRAVITY #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -849,17 +855,19 @@ #define ED_DRAWING_ID_MAGIC_BALL_CONTENT_7 16 #define ED_DRAWING_ID_AMOEBA_CONTENT 17 #define ED_DRAWING_ID_START_ELEMENT 18 -#define ED_DRAWING_ID_CUSTOM_GRAPHIC 19 -#define ED_DRAWING_ID_CUSTOM_CONTENT 20 -#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 21 -#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 22 -#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 23 -#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 24 -#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 25 -#define ED_DRAWING_ID_GROUP_CONTENT 26 -#define ED_DRAWING_ID_RANDOM_BACKGROUND 27 +#define ED_DRAWING_ID_ARTWORK_ELEMENT 19 +#define ED_DRAWING_ID_EXPLOSION_ELEMENT 20 +#define ED_DRAWING_ID_CUSTOM_GRAPHIC 21 +#define ED_DRAWING_ID_CUSTOM_CONTENT 22 +#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 23 +#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 24 +#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 25 +#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 26 +#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 27 +#define ED_DRAWING_ID_GROUP_CONTENT 28 +#define ED_DRAWING_ID_RANDOM_BACKGROUND 29 -#define ED_NUM_DRAWING_AREAS 28 +#define ED_NUM_DRAWING_AREAS 30 /* @@ -1531,11 +1539,13 @@ static struct ValueTextInfo options_change_other_action[] = { CE_PLAYER_DROPS_X, "player drops/throws" }, { CE_TOUCHING_X, "touching" }, { CE_HITTING_X, "hitting" }, + { CE_DIGGING_X, "digging" }, { CE_HIT_BY_X, "hit by" }, { CE_SWITCH_OF_X, "switch of" }, { CE_CHANGE_OF_X, "change by page of" }, { CE_EXPLOSION_OF_X, "explosion of" }, { CE_MOVE_OF_X, "move of" }, + { CE_CREATION_OF_X, "creation of" }, { CE_VALUE_GETS_ZERO_OF_X, "CE value gets 0 of" }, { -1, NULL } @@ -1641,6 +1651,9 @@ static struct ValueTextInfo options_action_type[] = { CA_HEADLINE_CE_ACTIONS, "[CE actions]" }, { CA_SET_CE_SCORE, "set CE score" }, { CA_SET_CE_VALUE, "set CE value" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_ENGINE_ACTIONS, "[engine actions]" }, + { CA_SET_ENGINE_SCAN_MODE, "set scan mode" }, { -1, NULL } }; @@ -1832,6 +1845,15 @@ static struct ValueTextInfo options_action_arg_direction[] = { -1, NULL } }; +static struct ValueTextInfo options_action_arg_scan_mode[] = +{ + { CA_ARG_SCAN_MODE_HEADLINE, "[mode]" }, + { CA_ARG_SCAN_MODE_NORMAL, "normal" }, + { CA_ARG_SCAN_MODE_REVERSE, "reverse" }, + + { -1, NULL } +}; + static char options_change_page_strings[MAX_CHANGE_PAGES][10]; static struct ValueTextInfo options_change_page[MAX_CHANGE_PAGES + 1] = { @@ -1882,6 +1904,7 @@ action_arg_options[] = { CA_SET_PLAYER_ARTWORK, 1, options_action_arg_artwork, }, { CA_SET_CE_SCORE, 3, options_action_arg_number, }, { CA_SET_CE_VALUE, 3, options_action_arg_number, }, + { CA_SET_ENGINE_SCAN_MODE, 1, options_action_arg_scan_mode, }, { -1, FALSE, NULL } }; @@ -2426,56 +2449,70 @@ static struct "can grow into anything diggable", "grow into more than just sand" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), GADGET_ID_DOUBLE_SPEED, GADGET_ID_NONE, &level.double_speed, NULL, "double speed movement", "set initial movement speed of player" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, &level.block_snap_field, NULL, "block snapped field when snapping", "use snapping delay to show animation" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE, &level.block_last_field, NULL, "block last field when moving", "player blocks last field when moving" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_SP_BLOCK_LAST_FIELD, GADGET_ID_NONE, &level.sp_block_last_field, NULL, "block last field when moving", "player blocks last field when moving" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), GADGET_ID_INSTANT_RELOCATION, GADGET_ID_NONE, &level.instant_relocation, NULL, "no scrolling when relocating", "player gets relocated without delay" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE, &level.use_start_element[0], NULL, "use level start element:", "start level at this element's position" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, + &level.use_artwork_element[0], + NULL, + "use artwork from element:", "use player artwork from other element" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, + &level.use_explosion_element[0], + NULL, + "use explosion from element:", "use explosion properties from element" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, &level.can_pass_to_walkable, NULL, "can pass to walkable element", "player can pass to empty or walkable" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE, &custom_element_properties[EP_CAN_MOVE_INTO_ACID], NULL, @@ -2795,12 +2832,30 @@ static struct /* ---------- level start element ---------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(6), + -1, ED_AREA_1X1_SETTINGS_YPOS(7), GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, &level.start_element[0], 1, 1, NULL, NULL, NULL, "level start element" }, + /* ---------- player artwork element ------------------------------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(8), + GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, + &level.artwork_element[0], 1, 1, + NULL, NULL, NULL, "element for player artwork" + }, + + /* ---------- player explosion element ----------------------------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(9), + GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, + &level.explosion_element[0], 1, 1, + NULL, NULL, NULL, "element for player explosion" + }, + /* ---------- element settings: configure 1 (custom elements) ----------- */ /* ---------- custom graphic --------------------------------------------- */ @@ -2919,6 +2974,7 @@ static void ModifyEditorSelectboxValue(int, int); static void ModifyEditorSelectboxOptions(int, struct ValueTextInfo *); static void ModifyEditorDrawingArea(int, int, int); static void ModifyEditorElementList(); +static void AdjustElementListScrollbar(); static void RedrawDrawingElements(); static void DrawDrawingWindow(); static void DrawLevelInfoWindow(); @@ -2937,6 +2993,7 @@ static void HandleRadiobuttons(struct GadgetInfo *); static void HandleCheckbuttons(struct GadgetInfo *); static void HandleControlButtons(struct GadgetInfo *); static void HandleDrawingAreaInfo(struct GadgetInfo *); +static void PrintEditorGadgetInfoText(struct GadgetInfo *); static struct GadgetInfo *level_editor_gadget[NUM_EDITOR_GADGETS]; static int right_gadget_border[NUM_EDITOR_GADGETS]; @@ -2958,6 +3015,12 @@ static int element_shift = 0; static int editor_hl_boulderdash[] = { + EL_INTERNAL_CASCADE_BD_ACTIVE, + EL_CHAR('B'), + EL_CHAR('D'), + EL_EMPTY, + +#if 0 EL_CHAR('B'), EL_CHAR('O'), EL_CHAR('U'), @@ -2972,6 +3035,7 @@ static int editor_hl_boulderdash[] = EL_CHAR('A'), EL_CHAR('S'), EL_CHAR('H'), +#endif }; static int editor_el_boulderdash[] = @@ -3008,6 +3072,12 @@ static int num_editor_el_boulderdash = SIZEOF_ARRAY_INT(editor_el_boulderdash); static int editor_hl_emerald_mine[] = { + EL_INTERNAL_CASCADE_EM_ACTIVE, + EL_CHAR('E'), + EL_CHAR('M'), + EL_EMPTY, + +#if 0 EL_CHAR('E'), EL_CHAR('M'), EL_CHAR('E'), @@ -3022,6 +3092,7 @@ static int editor_hl_emerald_mine[] = EL_CHAR('I'), EL_CHAR('N'), EL_CHAR('E'), +#endif }; static int editor_el_emerald_mine[] = @@ -3108,6 +3179,12 @@ static int num_editor_el_emerald_mine=SIZEOF_ARRAY_INT(editor_el_emerald_mine); static int editor_hl_emerald_mine_club[] = { + EL_INTERNAL_CASCADE_EMC_ACTIVE, + EL_CHAR('E'), + EL_CHAR('M'), + EL_CHAR('C'), + +#if 0 EL_CHAR('E'), EL_CHAR('M'), EL_CHAR('E'), @@ -3127,6 +3204,7 @@ static int editor_hl_emerald_mine_club[] = EL_CHAR('L'), EL_CHAR('U'), EL_CHAR('B'), +#endif }; static int editor_el_emerald_mine_club[] = @@ -3176,18 +3254,10 @@ static int editor_el_emerald_mine_club[] = EL_EMC_WALL_11, EL_EMC_WALL_12, -#if RELEASE_3_1_2 - EL_EMPTY, -#else EL_EMC_ANDROID, -#endif EL_BALLOON, EL_BALLOON_SWITCH_ANY, -#if RELEASE_3_1_2 - EL_EMPTY, -#else EL_BALLOON_SWITCH_NONE, -#endif EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_RIGHT, @@ -3196,38 +3266,18 @@ static int editor_el_emerald_mine_club[] = EL_EMC_GRASS, EL_EMC_PLANT, -#if RELEASE_3_1_2 - EL_EMPTY, - EL_EMPTY, -#else EL_EMC_LENSES, EL_EMC_MAGNIFIER, -#endif -#if RELEASE_3_1_2 - EL_EMPTY, - EL_EMPTY, -#else EL_EMC_MAGIC_BALL, EL_EMC_MAGIC_BALL_SWITCH, -#endif EL_SPRING, -#if RELEASE_3_1_2 - EL_EMPTY, -#else EL_EMC_SPRING_BUMPER, -#endif - -#if RELEASE_3_1_2 - EL_EMPTY, -#else #if 0 EL_EMC_DRIPPER, #else EL_EMPTY, -#endif - #endif EL_EMC_FAKE_GRASS, EL_EMPTY, @@ -3240,10 +3290,17 @@ static int num_editor_el_emerald_mine_club=SIZEOF_ARRAY_INT(editor_el_emerald_mi static int editor_hl_more[] = { + EL_INTERNAL_CASCADE_RND_ACTIVE, + EL_CHAR('R'), + EL_CHAR('N'), + EL_CHAR('D'), + +#if 0 EL_CHAR('M'), EL_CHAR('O'), EL_CHAR('R'), EL_CHAR('E'), +#endif }; static int editor_el_more[] = @@ -3335,6 +3392,12 @@ static int num_editor_el_more = SIZEOF_ARRAY_INT(editor_el_more); static int editor_hl_sokoban[] = { + EL_INTERNAL_CASCADE_SB_ACTIVE, + EL_CHAR('S'), + EL_CHAR('B'), + EL_EMPTY, + +#if 0 EL_CHAR('S'), EL_CHAR('O'), EL_CHAR('K'), @@ -3344,6 +3407,7 @@ static int editor_hl_sokoban[] = EL_CHAR('B'), EL_CHAR('A'), EL_CHAR('N'), +#endif }; static int editor_el_sokoban[] = @@ -3360,6 +3424,12 @@ static int num_editor_el_sokoban = SIZEOF_ARRAY_INT(editor_el_sokoban); static int editor_hl_supaplex[] = { + EL_INTERNAL_CASCADE_SP_ACTIVE, + EL_CHAR('S'), + EL_CHAR('P'), + EL_EMPTY, + +#if 0 EL_CHAR('S'), EL_CHAR('U'), EL_CHAR('P'), @@ -3369,6 +3439,7 @@ static int editor_hl_supaplex[] = EL_CHAR('L'), EL_CHAR('E'), EL_CHAR('X'), +#endif }; static int editor_el_supaplex[] = @@ -3434,6 +3505,12 @@ static int num_editor_el_supaplex = SIZEOF_ARRAY_INT(editor_el_supaplex); static int editor_hl_diamond_caves[] = { + EL_INTERNAL_CASCADE_DC_ACTIVE, + EL_CHAR('D'), + EL_CHAR('C'), + EL_CHAR('2'), + +#if 0 EL_CHAR('D'), EL_CHAR('I'), EL_CHAR('A'), @@ -3453,6 +3530,7 @@ static int editor_hl_diamond_caves[] = EL_CHAR(' '), EL_CHAR('I'), EL_CHAR('I'), +#endif }; static int editor_el_diamond_caves[] = @@ -3529,6 +3607,12 @@ static int num_editor_el_diamond_caves = SIZEOF_ARRAY_INT(editor_el_diamond_cave static int editor_hl_dx_boulderdash[] = { + EL_INTERNAL_CASCADE_DX_ACTIVE, + EL_CHAR('D'), + EL_CHAR('X'), + EL_EMPTY, + +#if 0 EL_CHAR('D'), EL_CHAR('X'), EL_CHAR('-'), @@ -3548,6 +3632,7 @@ static int editor_hl_dx_boulderdash[] = EL_CHAR('A'), EL_CHAR('S'), EL_CHAR('H'), +#endif }; static int editor_el_dx_boulderdash[] = @@ -3579,10 +3664,17 @@ static int num_editor_el_dx_boulderdash = SIZEOF_ARRAY_INT(editor_el_dx_boulderd static int editor_hl_chars[] = { + EL_INTERNAL_CASCADE_CHARS_ACTIVE, + EL_CHAR('T'), + EL_CHAR('X'), + EL_CHAR('T'), + +#if 0 EL_CHAR('T'), EL_CHAR('E'), EL_CHAR('X'), EL_CHAR('T'), +#endif }; static int editor_el_chars[] = @@ -3684,6 +3776,12 @@ static int num_editor_el_chars = SIZEOF_ARRAY_INT(editor_el_chars); static int editor_hl_custom[] = { + EL_INTERNAL_CASCADE_CE_ACTIVE, + EL_CHAR('C'), + EL_CHAR('E'), + EL_EMPTY, + +#if 0 EL_CHAR('C'), EL_CHAR('U'), EL_CHAR('S'), @@ -3703,6 +3801,7 @@ static int editor_hl_custom[] = EL_CHAR('N'), EL_CHAR('T'), EL_CHAR('S'), +#endif }; static int editor_el_custom[] = @@ -3865,19 +3964,8 @@ static int editor_el_custom[] = EL_CUSTOM_START + 124, EL_CUSTOM_START + 125, EL_CUSTOM_START + 126, - EL_CUSTOM_START + 127 -}; -static int *editor_hl_custom_ptr = editor_hl_custom; -static int *editor_el_custom_ptr = editor_el_custom; -static int num_editor_hl_custom = SIZEOF_ARRAY_INT(editor_hl_custom); -static int num_editor_el_custom = SIZEOF_ARRAY_INT(editor_el_custom); + EL_CUSTOM_START + 127, -static int editor_hl_custom_more[] = -{ -}; - -static int editor_el_custom_more[] = -{ EL_CUSTOM_START + 128, EL_CUSTOM_START + 129, EL_CUSTOM_START + 130, @@ -4036,31 +4124,26 @@ static int editor_el_custom_more[] = EL_CUSTOM_START + 252, EL_CUSTOM_START + 253, EL_CUSTOM_START + 254, - EL_CUSTOM_START + 255 -}; -static int *editor_hl_custom_more_ptr = editor_hl_custom_more; -static int *editor_el_custom_more_ptr = editor_el_custom_more; -static int num_editor_hl_custom_more = SIZEOF_ARRAY_INT(editor_hl_custom_more); -static int num_editor_el_custom_more = SIZEOF_ARRAY_INT(editor_el_custom_more); - -static int editor_hl_custom_special[] = -{ -}; + EL_CUSTOM_START + 255, -static int editor_el_custom_special[] = -{ EL_TRIGGER_ELEMENT, EL_TRIGGER_PLAYER, EL_EMPTY, EL_EMPTY }; -static int *editor_hl_custom_special_ptr = editor_hl_custom_special; -static int *editor_el_custom_special_ptr = editor_el_custom_special; -static int num_editor_hl_custom_special = SIZEOF_ARRAY_INT(editor_hl_custom_special); -static int num_editor_el_custom_special = SIZEOF_ARRAY_INT(editor_el_custom_special); +static int *editor_hl_custom_ptr = editor_hl_custom; +static int *editor_el_custom_ptr = editor_el_custom; +static int num_editor_hl_custom = SIZEOF_ARRAY_INT(editor_hl_custom); +static int num_editor_el_custom = SIZEOF_ARRAY_INT(editor_el_custom); static int editor_hl_group[] = { + EL_INTERNAL_CASCADE_GE_ACTIVE, + EL_CHAR('G'), + EL_CHAR('E'), + EL_EMPTY, + +#if 0 EL_CHAR('G'), EL_CHAR('R'), EL_CHAR('O'), @@ -4080,6 +4163,7 @@ static int editor_hl_group[] = EL_CHAR('N'), EL_CHAR('T'), EL_CHAR('S'), +#endif }; static int editor_el_group[] = @@ -4102,19 +4186,8 @@ static int editor_el_group[] = EL_GROUP_START + 12, EL_GROUP_START + 13, EL_GROUP_START + 14, - EL_GROUP_START + 15 -}; -static int *editor_hl_group_ptr = editor_hl_group; -static int *editor_el_group_ptr = editor_el_group; -static int num_editor_hl_group = SIZEOF_ARRAY_INT(editor_hl_group); -static int num_editor_el_group = SIZEOF_ARRAY_INT(editor_el_group); + EL_GROUP_START + 15, -static int editor_hl_group_more[] = -{ -}; - -static int editor_el_group_more[] = -{ EL_GROUP_START + 16, EL_GROUP_START + 17, EL_GROUP_START + 18, @@ -4135,13 +4208,19 @@ static int editor_el_group_more[] = EL_GROUP_START + 30, EL_GROUP_START + 31 }; -static int *editor_hl_group_more_ptr = editor_hl_group_more; -static int *editor_el_group_more_ptr = editor_el_group_more; -static int num_editor_hl_group_more = SIZEOF_ARRAY_INT(editor_hl_group_more); -static int num_editor_el_group_more = SIZEOF_ARRAY_INT(editor_el_group_more); +static int *editor_hl_group_ptr = editor_hl_group; +static int *editor_el_group_ptr = editor_el_group; +static int num_editor_hl_group = SIZEOF_ARRAY_INT(editor_hl_group); +static int num_editor_el_group = SIZEOF_ARRAY_INT(editor_el_group); static int editor_hl_user_defined[] = { + EL_INTERNAL_CASCADE_USER_ACTIVE, + EL_CHAR('M'), + EL_CHAR('Y'), + EL_EMPTY, + +#if 0 EL_CHAR('U'), EL_CHAR('S'), EL_CHAR('E'), @@ -4156,6 +4235,7 @@ static int editor_hl_user_defined[] = EL_CHAR('N'), EL_CHAR('E'), EL_CHAR('D'), +#endif }; static int *editor_hl_user_defined_ptr = editor_hl_user_defined; @@ -4163,6 +4243,19 @@ static int *editor_el_user_defined_ptr = NULL; static int num_editor_hl_user_defined=SIZEOF_ARRAY_INT(editor_hl_user_defined); static int num_editor_el_user_defined = 0; +static int editor_hl_dynamic[] = +{ + EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE, + EL_CHAR('U'), + EL_CHAR('S'), + EL_CHAR('E'), +}; + +static int *editor_hl_dynamic_ptr = editor_hl_dynamic; +static int *editor_el_dynamic_ptr = NULL; +static int num_editor_hl_dynamic = SIZEOF_ARRAY_INT(editor_hl_dynamic); +static int num_editor_el_dynamic = 0; + static int editor_hl_empty[] = { }; static int editor_el_empty[ED_NUM_ELEMENTLIST_BUTTONS]; @@ -4179,6 +4272,7 @@ static int num_editor_elements = 0; /* dynamically determined */ static struct { boolean *setup_value; + boolean *setup_cascade_value; int **headline_list; int *headline_list_size; @@ -4192,85 +4286,90 @@ editor_elements_info[] = { { &setup.editor.el_boulderdash, + &setup.editor_cascade.el_bd, &editor_hl_boulderdash_ptr, &num_editor_hl_boulderdash, &editor_el_boulderdash_ptr, &num_editor_el_boulderdash }, { &setup.editor.el_emerald_mine, + &setup.editor_cascade.el_em, &editor_hl_emerald_mine_ptr, &num_editor_hl_emerald_mine, &editor_el_emerald_mine_ptr, &num_editor_el_emerald_mine }, { &setup.editor.el_emerald_mine_club, + &setup.editor_cascade.el_emc, &editor_hl_emerald_mine_club_ptr, &num_editor_hl_emerald_mine_club, &editor_el_emerald_mine_club_ptr, &num_editor_el_emerald_mine_club }, { &setup.editor.el_more, + &setup.editor_cascade.el_rnd, &editor_hl_more_ptr, &num_editor_hl_more, &editor_el_more_ptr, &num_editor_el_more }, { &setup.editor.el_sokoban, + &setup.editor_cascade.el_sb, &editor_hl_sokoban_ptr, &num_editor_hl_sokoban, &editor_el_sokoban_ptr, &num_editor_el_sokoban }, { &setup.editor.el_supaplex, + &setup.editor_cascade.el_sp, &editor_hl_supaplex_ptr, &num_editor_hl_supaplex, &editor_el_supaplex_ptr, &num_editor_el_supaplex }, { &setup.editor.el_diamond_caves, + &setup.editor_cascade.el_dc, &editor_hl_diamond_caves_ptr, &num_editor_hl_diamond_caves, &editor_el_diamond_caves_ptr, &num_editor_el_diamond_caves }, { &setup.editor.el_dx_boulderdash, + &setup.editor_cascade.el_dx, &editor_hl_dx_boulderdash_ptr, &num_editor_hl_dx_boulderdash, &editor_el_dx_boulderdash_ptr, &num_editor_el_dx_boulderdash }, { &setup.editor.el_chars, + &setup.editor_cascade.el_chars, &editor_hl_chars_ptr, &num_editor_hl_chars, &editor_el_chars_ptr, &num_editor_el_chars }, { &setup.editor.el_custom, + &setup.editor_cascade.el_ce, &editor_hl_custom_ptr, &num_editor_hl_custom, &editor_el_custom_ptr, &num_editor_el_custom }, - { - &setup.editor.el_custom_more, - &editor_hl_custom_more_ptr, &num_editor_hl_custom_more, - &editor_el_custom_more_ptr, &num_editor_el_custom_more - }, - { - &setup.editor.el_custom, - &editor_hl_custom_special_ptr, &num_editor_hl_custom_special, - &editor_el_custom_special_ptr, &num_editor_el_custom_special - }, { &setup.editor.el_custom, + &setup.editor_cascade.el_ge, &editor_hl_group_ptr, &num_editor_hl_group, &editor_el_group_ptr, &num_editor_el_group }, - { - &setup.editor.el_custom_more, - &editor_hl_group_more_ptr, &num_editor_hl_group_more, - &editor_el_group_more_ptr, &num_editor_el_group_more - }, { &setup.editor.el_user_defined, + &setup.editor_cascade.el_user, &editor_hl_user_defined_ptr, &num_editor_hl_user_defined, &editor_el_user_defined_ptr, &num_editor_el_user_defined }, + { + &setup.editor.el_dynamic, + &setup.editor_cascade.el_dynamic, + &editor_hl_dynamic_ptr, &num_editor_hl_dynamic, + &editor_el_dynamic_ptr, &num_editor_el_dynamic, + }, { + &use_el_empty, &use_el_empty, &editor_hl_empty_ptr, &num_editor_hl_empty, &editor_el_empty_ptr, &num_editor_el_empty, }, { + NULL, NULL, NULL, NULL, NULL, NULL @@ -4314,7 +4413,11 @@ static char *getElementInfoText(int element) { char *info_text = NULL; +#if 1 + if (element < MAX_NUM_ELEMENTS) +#else if (element < NUM_FILE_ELEMENTS) +#endif { if (strlen(element_info[element].description) > 0) info_text = element_info[element].description; @@ -4330,17 +4433,88 @@ static char *getElementInfoText(int element) return info_text; } +static void InitDynamicEditorElementList(int **elements, int *num_elements) +{ + boolean element_found[NUM_FILE_ELEMENTS]; + int i, x, y; + + /* initialize list of used elements to "not used" */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + element_found[i] = FALSE; + + /* find all elements used in current level */ + for (y = 0; y < lev_fieldy; y++) + for (x = 0; x < lev_fieldx; x++) + if (Feld[x][y] < NUM_FILE_ELEMENTS) /* should always be true */ + element_found[Feld[x][y]] = TRUE; + + *num_elements = 0; + + /* count number of elements used in current level */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if (element_found[i]) + (*num_elements)++; + + /* add space for up to 3 more elements for padding that may be needed */ + *num_elements += 3; + + /* free memory for old list of elements, if needed */ + checked_free(*elements); + + /* allocate memory for new list of elements */ + *elements = checked_malloc(*num_elements * sizeof(int)); + + *num_elements = 0; + + /* add all elements used in current level (non-custom/group elements) */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + (*elements)[(*num_elements)++] = i; + + /* add all elements used in current level (custom/group elements) */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + (*elements)[(*num_elements)++] = i; + + while (*num_elements % 4) /* pad with empty elements, if needed */ + (*elements)[(*num_elements)++] = EL_EMPTY; +} + static void ReinitializeElementList() { + static boolean initialization_needed = TRUE; int pos = 0; int i, j; + if (initialization_needed) + { + LoadSetup_EditorCascade(); /* load last editor cascade state */ + + /* initialize editor cascade element from saved cascade state */ + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) + { + int *cascade_element = &(*editor_elements_info[i].headline_list)[0]; + boolean cascade_value = *editor_elements_info[i].setup_cascade_value; + + if (IS_EDITOR_CASCADE(*cascade_element)) + *cascade_element = + (cascade_value ? EL_CASCADE_ACTIVE(*cascade_element) : + EL_CASCADE_INACTIVE(*cascade_element)); + } + + initialization_needed = FALSE; + } + checked_free(editor_elements); /* reload optional user defined element list for each invocation of editor */ LoadUserDefinedEditorElementList(&editor_el_user_defined_ptr, &num_editor_el_user_defined); + /* initialize dynamic level element list for each invocation of editor */ + InitDynamicEditorElementList(&editor_el_dynamic_ptr, + &num_editor_el_dynamic); + /* initialize list of empty elements (used for padding, if needed) */ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) editor_el_empty[i] = EL_EMPTY; @@ -4366,11 +4540,26 @@ static void ReinitializeElementList() /* determine size of element list */ for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { + boolean found_inactive_cascade = FALSE; + if (*editor_elements_info[i].setup_value) { if (setup.editor.el_headlines) + { num_editor_elements += *editor_elements_info[i].headline_list_size; + for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) + { + int element = (*editor_elements_info[i].headline_list)[j]; + + if (IS_EDITOR_CASCADE_INACTIVE(element)) + found_inactive_cascade = TRUE; + } + } + + if (found_inactive_cascade) + continue; + num_editor_elements += *editor_elements_info[i].element_list_size; } } @@ -4389,22 +4578,33 @@ static void ReinitializeElementList() /* fill element list */ for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { + boolean found_inactive_cascade = FALSE; + if (*editor_elements_info[i].setup_value) { if (setup.editor.el_headlines) + { for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) - editor_elements[pos++] = (*editor_elements_info[i].headline_list)[j]; + { + int element = (*editor_elements_info[i].headline_list)[j]; + + editor_elements[pos++] = element; + + if (IS_EDITOR_CASCADE_INACTIVE(element)) + found_inactive_cascade = TRUE; + } + } + + if (found_inactive_cascade) + continue; for (j = 0; j < *editor_elements_info[i].element_list_size; j++) editor_elements[pos++] = (*editor_elements_info[i].element_list)[j]; } } - /* correct position of element list scrollbar */ - if (element_shift < 0) - element_shift = 0; - if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) - element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; + /* (this function is also called before editor gadgets are initialized!) */ + AdjustElementListScrollbar(); } void PrintEditorElementList() @@ -4414,10 +4614,25 @@ void PrintEditorElementList() for (i = 0; editor_elements_info[i].setup_value != stop; i++) { + int cascade_element = (*editor_elements_info[i].headline_list)[0]; + + if (IS_EDITOR_CASCADE(cascade_element)) + { + int cascade_element_show = EL_CASCADE_INACTIVE(cascade_element); + char *headline = element_info[cascade_element_show].editor_description; + + printf_line_with_prefix("# ", "-", 77); + printf("# %s\n", headline); + printf_line_with_prefix("# ", "-", 77); + } + for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) { int element = (*editor_elements_info[i].headline_list)[j]; + if (IS_EDITOR_CASCADE(element)) + element = EL_CHAR_MINUS; + printf("# %s\n", element_info[element].token_name); } @@ -4477,6 +4692,10 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, int src_x, src_y; int num_mini_tilex = width / MINI_TILEX + 1; int num_mini_tiley = height / MINI_TILEY + 1; + int from_x = dest_x - MINI_TILEX / 2; + int from_y = dest_y - MINI_TILEY / 2; + int to_x = from_x + num_mini_tilex * MINI_TILEX - 1; + int to_y = from_y + num_mini_tiley * MINI_TILEY - 1; int x, y; getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y); @@ -4484,10 +4703,14 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, for (y = 0; y < num_mini_tiley; y++) for (x = 0; x < num_mini_tilex; x++) BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, - dest_x - MINI_TILEX / 2 + x * MINI_TILEX, - dest_y - MINI_TILEY / 2 + y * MINI_TILEY); + from_x + x * MINI_TILEX, from_y + y * MINI_TILEY); ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2); + + DrawSimpleBlackLine(drawto, from_x, from_y, to_x, from_y); + DrawSimpleBlackLine(drawto, to_x, from_y, to_x, to_y); + DrawSimpleBlackLine(drawto, to_x, to_y, from_x, to_y); + DrawSimpleBlackLine(drawto, from_x, to_y, from_x, from_y); } static void DrawDrawingArea(int id) @@ -5530,7 +5753,11 @@ void FreeLevelEditorGadgets() int i; for (i = 0; i < NUM_EDITOR_GADGETS; i++) + { FreeGadget(level_editor_gadget[i]); + + level_editor_gadget[i] = NULL; + } } static void MapCounterButtons(int id) @@ -5961,11 +6188,12 @@ static boolean LevelContainsPlayer() return TRUE; /* !!! CURRENTLY DEACTIVATED !!! */ - for (y = 0; y < lev_fieldy; y++) - for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] == EL_PLAYER_1 || - Feld[x][y] == EL_SP_MURPHY) - player_found = TRUE; + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) + { + if (Feld[x][y] == EL_PLAYER_1 || + Feld[x][y] == EL_SP_MURPHY) + player_found = TRUE; + } return player_found; } @@ -5995,6 +6223,32 @@ static int setSelectboxValue(int selectbox_id, int new_value) return new_index_value; } +static void setSelectboxSpecialActionVariablesIfNeeded() +{ + int i; + + /* change action mode and arg variables according to action type variable */ + for (i = 0; action_arg_options[i].value != -1; i++) + { + if (action_arg_options[i].value == custom_element_change.action_type) + { + int mode = action_arg_options[i].mode; + + /* only change if corresponding selectbox has changed */ + if (selectbox_info[ED_SELECTBOX_ID_ACTION_MODE].options != + action_arg_modes[mode]) + custom_element_change.action_mode = -1; + + /* only change if corresponding selectbox has changed */ + if (selectbox_info[ED_SELECTBOX_ID_ACTION_ARG].options != + action_arg_options[i].options) + custom_element_change.action_arg = -1; + + break; + } + } +} + static void setSelectboxSpecialActionOptions() { int i; @@ -6015,6 +6269,7 @@ static void setSelectboxSpecialActionOptions() action_arg_options[i].options); ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_ARG, custom_element_change.action_arg); + break; } } } @@ -6331,11 +6586,13 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_X : HAS_CHANGE_EVENT(element, CE_TOUCHING_X) ? CE_TOUCHING_X : HAS_CHANGE_EVENT(element, CE_HITTING_X) ? CE_HITTING_X : + HAS_CHANGE_EVENT(element, CE_DIGGING_X) ? CE_DIGGING_X : HAS_CHANGE_EVENT(element, CE_HIT_BY_X) ? CE_HIT_BY_X : HAS_CHANGE_EVENT(element, CE_SWITCH_OF_X) ? CE_SWITCH_OF_X : HAS_CHANGE_EVENT(element, CE_CHANGE_OF_X) ? CE_CHANGE_OF_X : HAS_CHANGE_EVENT(element, CE_EXPLOSION_OF_X) ? CE_EXPLOSION_OF_X : HAS_CHANGE_EVENT(element, CE_MOVE_OF_X) ? CE_MOVE_OF_X : + HAS_CHANGE_EVENT(element, CE_CREATION_OF_X) ? CE_CREATION_OF_X : HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X : custom_element_change.other_action); } @@ -6470,11 +6727,13 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_PLAYER_DROPS_X] = FALSE; custom_element_change_events[CE_TOUCHING_X] = FALSE; custom_element_change_events[CE_HITTING_X] = FALSE; + custom_element_change_events[CE_DIGGING_X] = FALSE; custom_element_change_events[CE_HIT_BY_X] = FALSE; custom_element_change_events[CE_SWITCH_OF_X] = FALSE; custom_element_change_events[CE_CHANGE_OF_X] = FALSE; custom_element_change_events[CE_EXPLOSION_OF_X] = FALSE; custom_element_change_events[CE_MOVE_OF_X] = FALSE; + custom_element_change_events[CE_CREATION_OF_X] = FALSE; custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE; custom_element_change_events[custom_element_change.other_action] = custom_element_change_events[CE_BY_OTHER_ACTION]; @@ -6557,6 +6816,7 @@ void DrawLevelEd() redraw_mask |= REDRAW_ALL; + ReinitializeElementList(); /* update dynamic level element list */ ReinitializeElementListButtons(); /* custom element may look different */ UnmapTapeButtons(); @@ -6675,6 +6935,26 @@ static void AdjustEditorScrollbar(int id) GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); } +static void AdjustElementListScrollbar() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]; + int items_max, items_visible, item_position; + + /* correct position of element list scrollbar */ + if (element_shift < 0) + element_shift = 0; + if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) + element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; + + items_max = num_editor_elements / ED_ELEMENTLIST_BUTTONS_HORIZ; + items_visible = ED_ELEMENTLIST_BUTTONS_VERT; + item_position = element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ; + + ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max, + GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible, + GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); +} + static void ModifyEditorCounterValue(int counter_id, int new_value) { int *counter_value = counterbutton_info[counter_id].value; @@ -6750,8 +7030,10 @@ static void ModifyEditorElementList() 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); } } @@ -6824,10 +7106,15 @@ static void DrawLevelInfoWindow() ClearWindow(); UnmapLevelEditorWindowGadgets(); +#if 0 + DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Level Settings"); + DrawTextSCentered(ED_SETTINGS2_YPOS, FONT_TITLE_1, "Editor Settings"); +#else DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, "Level Settings", FONT_TITLE_1); DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS2_YPOS, "Editor Settings", FONT_TITLE_1); +#endif /* draw counter gadgets */ for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++) @@ -7448,13 +7735,21 @@ static void DrawPropertiesConfig() { int player_nr = GET_PLAYER_NR(properties_element); - /* this property can be set for every player individually */ + /* these properties can be set for every player individually */ drawingarea_info[ED_DRAWING_ID_START_ELEMENT].value = &level.start_element[player_nr]; + drawingarea_info[ED_DRAWING_ID_ARTWORK_ELEMENT].value = + &level.artwork_element[player_nr]; + drawingarea_info[ED_DRAWING_ID_EXPLOSION_ELEMENT].value = + &level.explosion_element[player_nr]; - /* this property can be set for every player individually */ + /* these properties can be set for every player individually */ checkbutton_info[ED_CHECKBUTTON_ID_USE_START_ELEMENT].value = &level.use_start_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT].value = + &level.use_artwork_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT].value = + &level.use_explosion_element[player_nr]; MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID); MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ? @@ -7463,10 +7758,14 @@ static void DrawPropertiesConfig() MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DOUBLE_SPEED); MapDrawingArea(ED_DRAWING_ID_START_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_EXPLOSION_ELEMENT); } if (IS_GEM(properties_element)) @@ -7660,7 +7959,18 @@ static void DrawPropertiesChange() DrawPropertiesChangeDrawingAreas(); } -static void DrawElementName(int x, int y, int element) +static void DrawEditorElementAnimation(int x, int y) +{ + int graphic = el2img(properties_element); + int frame = (ANIM_MODE(graphic) == ANIM_CE_VALUE ? + custom_element.ce_value_fixed_initial : + ANIM_MODE(graphic) == ANIM_CE_SCORE ? + custom_element.collect_score_initial : FrameCounter); + + DrawGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING); +} + +static void DrawEditorElementName(int x, int y, int element) { char *element_name = getElementInfoText(element); int font_nr = FONT_TEXT_1; @@ -7734,21 +8044,37 @@ static void DrawPropertiesWindow() SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearWindow(); +#if 0 + DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Element Settings"); +#else DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, "Element Settings", FONT_TITLE_1); +#endif + +#if 1 + FrameCounter = 0; /* restart animation frame counter */ +#endif DrawElementBorder(SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, TILEX, TILEY, FALSE); +#if 1 + DrawEditorElementAnimation(SX + xstart * MINI_TILEX, + SY + ystart * MINI_TILEY + MINI_TILEY / 2); +#else DrawGraphicAnimationExt(drawto, SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, el2img(properties_element), -1, NO_MASKING); +#endif +#if 0 FrameCounter = 0; /* restart animation frame counter */ +#endif - DrawElementName((xstart + 3) * MINI_TILEX + 1, (ystart + 1) * MINI_TILEY + 1, - properties_element); + DrawEditorElementName((xstart + 3) * MINI_TILEX + 1, + (ystart + 1) * MINI_TILEY + 1, + properties_element); DrawPropertiesTabulatorGadgets(); @@ -8819,11 +9145,15 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) { if (type_id == ED_SELECTBOX_ID_ACTION_TYPE) { - /* when changing action type, reset action mode and action arg */ + /* when changing action type, also check action mode and action arg */ if (value_old != value_new) { +#if 1 + setSelectboxSpecialActionVariablesIfNeeded(); +#else custom_element_change.action_mode = -1; custom_element_change.action_arg = -1; +#endif } DrawPropertiesChange(); @@ -9329,6 +9659,37 @@ static void HandleControlButtons(struct GadgetInfo *gi) int element_position = id - GADGET_ID_ELEMENTLIST_FIRST; int new_element = editor_elements[element_position + element_shift]; + if (IS_EDITOR_CASCADE(new_element)) + { + int i; + + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) + { + int *cascade_element= &(*editor_elements_info[i].headline_list)[0]; + boolean *cascade_value=editor_elements_info[i].setup_cascade_value; + + if (*cascade_element == new_element) + { + *cascade_element = EL_CASCADE_TOGGLE(*cascade_element); + *cascade_value = IS_EDITOR_CASCADE_ACTIVE(*cascade_element); + + /* update element selection list */ + ReinitializeElementList(); + ModifyEditorElementList(); + + /* update cascading gadget info text */ + PrintEditorGadgetInfoText(level_editor_gadget[id]); + + /* save current editor cascading state */ + SaveSetup_EditorCascade(); + + break; + } + } + + break; + } + if (last_custom_copy_mode != -1) { if (CopyCustomElement(properties_element, new_element, @@ -9466,10 +9827,15 @@ void HandleLevelEditorIdle() if (!DelayReached(&action_delay, action_delay_value)) return; +#if 1 + DrawEditorElementAnimation(SX + xpos * TILEX, + SY + ypos * TILEY + MINI_TILEY / 2); +#else DrawGraphicAnimationExt(drawto, SX + xpos * TILEX, SY + ypos * TILEY + MINI_TILEY / 2, el2img(properties_element), -1, NO_MASKING); +#endif MarkTileDirty(xpos, ypos); MarkTileDirty(xpos, ypos + 1); @@ -9482,25 +9848,66 @@ void ClearEditorGadgetInfoText() DrawBackground(INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE); } +void PrintEditorGadgetInfoText(struct GadgetInfo *gi) +{ + char infotext[MAX_OUTPUT_LINESIZE + 1]; + char shortcut[MAX_OUTPUT_LINESIZE + 1]; + int max_infotext_len = getMaxInfoTextLength(); + + if (gi == NULL || gi->info_text == NULL) + return; + + strncpy(infotext, gi->info_text, max_infotext_len); + infotext[max_infotext_len] = '\0'; + + if (gi->custom_id < ED_NUM_CTRL_BUTTONS) + { + int key = control_info[gi->custom_id].shortcut; + + if (key) + { + if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) /* special case 1 */ + sprintf(shortcut, " ('.' or '%c')", key); + 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')", + (key >= 'A' && key <= 'Z' ? "Shift-" : ""), key); + + if (strlen(infotext) + strlen(shortcut) <= max_infotext_len) + strcat(infotext, shortcut); + } + } + + DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2); +} + void HandleEditorGadgetInfoText(void *ptr) { struct GadgetInfo *gi = (struct GadgetInfo *)ptr; +#if 0 char infotext[MAX_OUTPUT_LINESIZE + 1]; char shortcut[MAX_OUTPUT_LINESIZE + 1]; int max_infotext_len = getMaxInfoTextLength(); +#endif if (game_status != GAME_MODE_EDITOR) return; ClearEditorGadgetInfoText(); - if (gi->event.type == GD_EVENT_INFO_LEAVING) + if (gi == NULL || gi->event.type == GD_EVENT_INFO_LEAVING) return; /* misuse this function to delete brush cursor, if needed */ if (edit_mode == ED_MODE_DRAWING && draw_with_brush) DeleteBrushFromCursor(); +#if 1 + PrintEditorGadgetInfoText(gi); +#else if (gi == NULL || gi->info_text == NULL) return; @@ -9529,6 +9936,7 @@ void HandleEditorGadgetInfoText(void *ptr) } DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2); +#endif } static void HandleDrawingAreaInfo(struct GadgetInfo *gi)