X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Feditor.c;h=2798beecd3a495faffa45ef3e306d7fb5eafeb79;hp=49073d30d004043d6c35dd455426f15f936c70e0;hb=ffd72ec82d108006fce6246f2d0023057c39af35;hpb=ad5c7e778ae33255b403c0de955cfecc78a66b2c diff --git a/src/editor.c b/src/editor.c index 49073d30..2798beec 100644 --- a/src/editor.c +++ b/src/editor.c @@ -97,27 +97,31 @@ #define ED_TABBUTTON_XSIZE (graphic_info[IMG_EDITOR_TABBUTTON].width) #define ED_TABBUTTON_YSIZE (graphic_info[IMG_EDITOR_TABBUTTON].height) -#define ED_LEVEL_SETTINGS_TABS_X (editor.settings.tabs.x) -#define ED_LEVEL_SETTINGS_TABS_Y (editor.settings.tabs.y) -#define ED_ELEMENT_SETTINGS_TABS_X (editor.settings.tabs.x) -#define ED_ELEMENT_SETTINGS_TABS_Y (editor.settings.tabs.y + \ +#define ED_SETTINGS_LEVEL_TABS_X (editor.settings.tabs.x) +#define ED_SETTINGS_LEVEL_TABS_Y (editor.settings.tabs.y) +#define ED_SETTINGS_ELEMENT_TABS_X (editor.settings.tabs.x) +#define ED_SETTINGS_ELEMENT_TABS_Y (editor.settings.tabs.y + \ editor.settings.tabs.yoffset2) #define ED_SETTINGS_TABS_XOFFSET (editor.settings.tabs.draw_xoffset) #define ED_SETTINGS_TABS_YOFFSET (editor.settings.tabs.draw_yoffset) -#define ED_LEVEL_SETTINGS_XSTART (ED_LEVEL_SETTINGS_TABS_X + \ +#define ED_LEVEL_TABS_XSTART (ED_SETTINGS_LEVEL_TABS_X) +#define ED_LEVEL_TABS_YSTART (ED_SETTINGS_LEVEL_TABS_Y) +#define ED_LEVEL_SETTINGS_XSTART (ED_SETTINGS_LEVEL_TABS_X + \ ED_SETTINGS_TABS_XOFFSET) -#define ED_LEVEL_SETTINGS_YSTART (ED_LEVEL_SETTINGS_TABS_Y + \ +#define ED_LEVEL_SETTINGS_YSTART (ED_SETTINGS_LEVEL_TABS_Y + \ ED_TABBUTTON_YSIZE + \ ED_GADGET_TINY_DISTANCE + \ ED_TAB_BAR_HEIGHT + \ ED_SETTINGS_TABS_YOFFSET + \ getFontHeight(FONT_TEXT_1) + \ ED_GADGET_TEXT_DISTANCE) -#define ED_ELEMENT_SETTINGS_XSTART (ED_ELEMENT_SETTINGS_TABS_X + \ +#define ED_ELEMENT_TABS_XSTART (ED_SETTINGS_ELEMENT_TABS_X) +#define ED_ELEMENT_TABS_YSTART (ED_SETTINGS_ELEMENT_TABS_Y) +#define ED_ELEMENT_SETTINGS_XSTART (ED_SETTINGS_ELEMENT_TABS_X + \ ED_SETTINGS_TABS_XOFFSET) -#define ED_ELEMENT_SETTINGS_YSTART (ED_ELEMENT_SETTINGS_TABS_Y + \ +#define ED_ELEMENT_SETTINGS_YSTART (ED_SETTINGS_ELEMENT_TABS_Y + \ ED_TABBUTTON_YSIZE + \ ED_GADGET_TINY_DISTANCE + \ ED_TAB_BAR_HEIGHT + \ @@ -128,62 +132,99 @@ #define ED_SETTINGS_YOFFSET (ED_CHECKBUTTON_YSIZE + \ ED_GADGET_LINE_DISTANCE) -#define ED_POS_LEVEL_SETTINGS_RANGE (10000) -#define ED_POS_LEVEL_SETTINGS_FIRST (1 * ED_POS_LEVEL_SETTINGS_RANGE) -#define ED_POS_LEVEL_SETTINGS_LAST (2 * ED_POS_LEVEL_SETTINGS_RANGE - 1) -#define ED_POS_ELEMENT_SETTINGS_FIRST (2 * ED_POS_LEVEL_SETTINGS_RANGE) -#define ED_POS_ELEMENT_SETTINGS_LAST (3 * ED_POS_LEVEL_SETTINGS_RANGE - 1) +#define ED_POS_RANGE (10000) +#define ED_POS_LEVEL_TABS_FIRST (1 * ED_POS_RANGE) +#define ED_POS_LEVEL_TABS_LAST (2 * ED_POS_RANGE - 1) +#define ED_POS_LEVEL_SETTINGS_FIRST (2 * ED_POS_RANGE) +#define ED_POS_LEVEL_SETTINGS_LAST (3 * ED_POS_RANGE - 1) +#define ED_POS_ELEMENT_TABS_FIRST (3 * ED_POS_RANGE) +#define ED_POS_ELEMENT_TABS_LAST (4 * ED_POS_RANGE - 1) +#define ED_POS_ELEMENT_SETTINGS_FIRST (4 * ED_POS_RANGE) +#define ED_POS_ELEMENT_SETTINGS_LAST (5 * ED_POS_RANGE - 1) + +#define ED_LEVEL_TABS_XPOS(n) (ED_POS_LEVEL_TABS_FIRST + (n)) +#define ED_LEVEL_TABS_YPOS(n) (ED_POS_LEVEL_TABS_FIRST + (n)) #define ED_LEVEL_SETTINGS_XPOS(n) (ED_POS_LEVEL_SETTINGS_FIRST + (n)) #define ED_LEVEL_SETTINGS_YPOS(n) (ED_POS_LEVEL_SETTINGS_FIRST + (n)) +#define ED_ELEMENT_TABS_XPOS(n) (ED_POS_ELEMENT_TABS_FIRST + (n)) +#define ED_ELEMENT_TABS_YPOS(n) (ED_POS_ELEMENT_TABS_FIRST + (n)) + #define ED_ELEMENT_SETTINGS_XPOS(n) (ED_POS_ELEMENT_SETTINGS_FIRST + (n)) #define ED_ELEMENT_SETTINGS_YPOS(n) (ED_POS_ELEMENT_SETTINGS_FIRST + (n)) +#define IS_POS_LEVEL_TABS(n) ((n) >= ED_POS_LEVEL_TABS_FIRST && \ + (n) <= ED_POS_LEVEL_TABS_LAST) #define IS_POS_LEVEL_SETTINGS(n) ((n) >= ED_POS_LEVEL_SETTINGS_FIRST && \ (n) <= ED_POS_LEVEL_SETTINGS_LAST) +#define IS_POS_ELEMENT_TABS(n) ((n) >= ED_POS_ELEMENT_TABS_FIRST && \ + (n) <= ED_POS_ELEMENT_TABS_LAST) #define IS_POS_ELEMENT_SETTINGS(n) ((n) >= ED_POS_ELEMENT_SETTINGS_FIRST && \ (n) <= ED_POS_ELEMENT_SETTINGS_LAST) +#define ED_LEVEL_TABS_LINE(n) ((n) - ED_POS_LEVEL_TABS_FIRST) #define ED_LEVEL_SETTINGS_LINE(n) ((n) - ED_POS_LEVEL_SETTINGS_FIRST) +#define ED_ELEMENT_TABS_LINE(n) ((n) - ED_POS_ELEMENT_TABS_FIRST) #define ED_ELEMENT_SETTINGS_LINE(n) ((n) - ED_POS_ELEMENT_SETTINGS_FIRST) +#define ED_LEVEL_TABS_X(n) (ED_LEVEL_TABS_XSTART + \ + (n) * ED_SETTINGS_TABS_XOFFSET) +#define ED_LEVEL_TABS_Y(n) (ED_LEVEL_TABS_YSTART + \ + (n) * ED_SETTINGS_TABS_YOFFSET) + #define ED_LEVEL_SETTINGS_X(n) (ED_LEVEL_SETTINGS_XSTART + \ (n) * ED_SETTINGS_XOFFSET) #define ED_LEVEL_SETTINGS_Y(n) (ED_LEVEL_SETTINGS_YSTART + \ (n) * ED_SETTINGS_YOFFSET) +#define ED_ELEMENT_TABS_X(n) (ED_ELEMENT_TABS_XSTART + \ + (n) * ED_SETTINGS_TABS_XOFFSET) +#define ED_ELEMENT_TABS_Y(n) (ED_ELEMENT_TABS_YSTART + \ + (n) * ED_SETTINGS_TABS_YOFFSET) + #define ED_ELEMENT_SETTINGS_X(n) (ED_ELEMENT_SETTINGS_XSTART + \ (n) * ED_SETTINGS_XOFFSET) #define ED_ELEMENT_SETTINGS_Y(n) (ED_ELEMENT_SETTINGS_YSTART + \ (n) * ED_SETTINGS_YOFFSET) +#define ED_POS_TO_LEVEL_TABS_X(n) \ + (ED_LEVEL_TABS_X(ED_LEVEL_TABS_LINE(n))) +#define ED_POS_TO_LEVEL_TABS_Y(n) \ + (ED_LEVEL_TABS_Y(ED_LEVEL_TABS_LINE(n))) + #define ED_POS_TO_LEVEL_SETTINGS_X(n) \ (ED_LEVEL_SETTINGS_X(ED_LEVEL_SETTINGS_LINE(n))) #define ED_POS_TO_LEVEL_SETTINGS_Y(n) \ (ED_LEVEL_SETTINGS_Y(ED_LEVEL_SETTINGS_LINE(n))) +#define ED_POS_TO_ELEMENT_TABS_X(n) \ + (ED_ELEMENT_TABS_X(ED_ELEMENT_TABS_LINE(n))) +#define ED_POS_TO_ELEMENT_TABS_Y(n) \ + (ED_ELEMENT_TABS_Y(ED_ELEMENT_TABS_LINE(n))) + #define ED_POS_TO_ELEMENT_SETTINGS_X(n) \ (ED_ELEMENT_SETTINGS_X(ED_ELEMENT_SETTINGS_LINE(n))) #define ED_POS_TO_ELEMENT_SETTINGS_Y(n) \ (ED_ELEMENT_SETTINGS_Y(ED_ELEMENT_SETTINGS_LINE(n))) -#define ED_SETTINGS_X(n) (IS_POS_LEVEL_SETTINGS(n) ? \ +#define ED_SETTINGS_X(n) (IS_POS_LEVEL_TABS(n) ? \ + ED_POS_TO_LEVEL_TABS_X(n) : \ + IS_POS_LEVEL_SETTINGS(n) ? \ ED_POS_TO_LEVEL_SETTINGS_X(n) : \ + IS_POS_ELEMENT_TABS(n) ? \ + ED_POS_TO_ELEMENT_TABS_X(n) : \ IS_POS_ELEMENT_SETTINGS(n) ? \ ED_POS_TO_ELEMENT_SETTINGS_X(n) : (n)) -#define ED_SETTINGS_Y(n) (IS_POS_LEVEL_SETTINGS(n) ? \ +#define ED_SETTINGS_Y(n) (IS_POS_LEVEL_TABS(n) ? \ + ED_POS_TO_LEVEL_TABS_Y(n) : \ + IS_POS_LEVEL_SETTINGS(n) ? \ ED_POS_TO_LEVEL_SETTINGS_Y(n) : \ + IS_POS_ELEMENT_TABS(n) ? \ + ED_POS_TO_ELEMENT_TABS_Y(n) : \ IS_POS_ELEMENT_SETTINGS(n) ? \ ED_POS_TO_ELEMENT_SETTINGS_Y(n) : (n)) -#define ED_TAB_SETTINGS_X(n) (IS_POS_LEVEL_SETTINGS(n) ? \ - ED_LEVEL_SETTINGS_TABS_X : \ - ED_ELEMENT_SETTINGS_TABS_X) -#define ED_TAB_SETTINGS_Y(n) (IS_POS_LEVEL_SETTINGS(n) ? \ - ED_LEVEL_SETTINGS_TABS_Y : \ - ED_ELEMENT_SETTINGS_TABS_Y) - #define ED_SETTINGS_XOFF(n) (5 * ((n) % 4) * \ ED_DRAWINGAREA_TILE_SIZE) #define ED_SETTINGS_YOFF(n) (5 * ((n) / 4) * \ @@ -553,12 +594,13 @@ #define GADGET_ID_PROPERTIES_CONFIG_1 (GADGET_ID_TEXTBUTTON_FIRST + 4) #define GADGET_ID_PROPERTIES_CONFIG_2 (GADGET_ID_TEXTBUTTON_FIRST + 5) #define GADGET_ID_PROPERTIES_CHANGE (GADGET_ID_TEXTBUTTON_FIRST + 6) -#define GADGET_ID_SAVE_AS_TEMPLATE (GADGET_ID_TEXTBUTTON_FIRST + 7) -#define GADGET_ID_ADD_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 8) -#define GADGET_ID_DEL_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 9) +#define GADGET_ID_SAVE_AS_TEMPLATE_1 (GADGET_ID_TEXTBUTTON_FIRST + 7) +#define GADGET_ID_SAVE_AS_TEMPLATE_2 (GADGET_ID_TEXTBUTTON_FIRST + 8) +#define GADGET_ID_ADD_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 9) +#define GADGET_ID_DEL_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 10) /* graphicbutton identifiers */ -#define GADGET_ID_GRAPHICBUTTON_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 10) +#define GADGET_ID_GRAPHICBUTTON_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 11) #define GADGET_ID_PREV_CHANGE_PAGE (GADGET_ID_GRAPHICBUTTON_FIRST + 0) #define GADGET_ID_NEXT_CHANGE_PAGE (GADGET_ID_GRAPHICBUTTON_FIRST + 1) @@ -630,19 +672,20 @@ #define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 42) #define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 43) #define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 45) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 46) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 47) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 48) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 49) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 50) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 51) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 52) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 53) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 54) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_1 (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_2 (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 47) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 48) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 51) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 52) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 53) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 54) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 55) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 55) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 56) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -801,11 +844,12 @@ #define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1 4 #define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2 5 #define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE 6 -#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 7 -#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE 8 -#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE 9 +#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1 7 +#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2 8 +#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE 9 +#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE 10 -#define ED_NUM_TEXTBUTTONS 10 +#define ED_NUM_TEXTBUTTONS 11 #define ED_TEXTBUTTON_ID_LEVELINFO_FIRST ED_TEXTBUTTON_ID_LEVELINFO_LEVEL #define ED_TEXTBUTTON_ID_LEVELINFO_LAST ED_TEXTBUTTON_ID_LEVELINFO_EDITOR @@ -829,63 +873,64 @@ /* values for checkbutton gadgets */ #define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 0 -#define ED_CHECKBUTTON_ID_STICK_ELEMENT 1 -#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 2 -#define ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE 3 -#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 4 -#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 5 -#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 6 -#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 7 -#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 8 -#define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 9 -#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 10 -#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 11 -#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 12 -#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 13 -#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 14 -#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 15 -#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 16 -#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 17 -#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 18 -#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 19 -#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 20 -#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 21 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 22 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 23 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 24 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 25 -#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 26 -#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 27 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 28 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 29 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 30 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 31 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 32 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 33 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 34 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 35 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 36 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 37 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 38 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 39 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 40 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 41 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 42 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 43 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 44 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 45 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 46 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 47 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 48 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 49 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 50 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 51 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 52 - -#define ED_NUM_CHECKBUTTONS 53 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 1 +#define ED_CHECKBUTTON_ID_STICK_ELEMENT 2 +#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 3 +#define ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE 4 +#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 5 +#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 6 +#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 7 +#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 8 +#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 9 +#define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 10 +#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 11 +#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 12 +#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 13 +#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 14 +#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 15 +#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 16 +#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 17 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 18 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 19 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 20 +#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 21 +#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 22 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 23 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 24 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 25 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 26 +#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 27 +#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 28 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 29 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 30 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 31 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 32 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 33 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 34 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 35 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 36 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 37 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 38 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 39 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 40 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 41 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 42 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 43 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 44 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 45 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 46 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 47 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 48 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 49 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 50 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 51 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 52 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 53 + +#define ED_NUM_CHECKBUTTONS 54 #define ED_CHECKBUTTON_ID_EDITOR_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED -#define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED +#define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 #define ED_CHECKBUTTON_ID_CUSTOM1_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC #define ED_CHECKBUTTON_ID_CUSTOM1_LAST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE @@ -943,6 +988,9 @@ #define ED_NUM_DRAWING_AREAS 33 +#define ED_DRAWING_ID_EDITOR_FIRST ED_DRAWING_ID_RANDOM_BACKGROUND +#define ED_DRAWING_ID_EDITOR_LAST ED_DRAWING_ID_RANDOM_BACKGROUND + /* ----------------------------------------------------------------------------- @@ -2529,68 +2577,83 @@ static struct int gadget_id_align; int size; char *text; - char *text_left, *text_right, *infotext; + char *text_above, *text_left, *text_right, *infotext; } textbutton_info[ED_NUM_TEXTBUTTONS] = { + /* ---------- level and editor settings (tabs) --------------------------- */ + { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), + ED_LEVEL_TABS_XPOS(0), ED_LEVEL_TABS_YPOS(0), GADGET_ID_LEVELINFO_LEVEL, GADGET_ID_NONE, 8, "Level", - NULL, NULL, "Configure level properties" + NULL, NULL, NULL, "Configure level properties" }, { -1, -1, GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_LEVELINFO_LEVEL, 8, "Editor", - NULL, NULL, "Configure editor properties" + NULL, NULL, NULL, "Configure editor properties" }, + + /* ---------- element settings (tabs) ------------------------------------ */ + { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + ED_ELEMENT_TABS_XPOS(0), ED_ELEMENT_TABS_YPOS(0), GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE, 8, "Info", - NULL, NULL, "Show information about element" + NULL, NULL, NULL, "Show information about element" }, { -1, -1, GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_PROPERTIES_INFO, 8, "Config", - NULL, NULL, "Configure element properties" + NULL, NULL, NULL, "Configure element properties" }, { -1, -1, GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_PROPERTIES_INFO, 8, "Config 1", - NULL, NULL, "Configure element properties, part 1" + NULL, NULL, NULL, "Configure element properties, part 1" }, { -1, -1, GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_PROPERTIES_CONFIG_1, 8, "Config 2", - NULL, NULL, "Configure element properties, part 2" + NULL, NULL, NULL, "Configure element properties, part 2" }, { -1, -1, GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_PROPERTIES_CONFIG_2, 8, "Change", - NULL, NULL, "Configure custom element change pages" + NULL, NULL, NULL, "Configure custom element change pages" }, + + /* ---------- element settings (buttons) --------------------------------- */ + { -1, -1, - GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE, + GADGET_ID_SAVE_AS_TEMPLATE_1, GADGET_ID_CUSTOM_USE_TEMPLATE_1, + -1, "Save", + NULL, " ", "As Template", "Save current settings as new template" + }, + { + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(3), + GADGET_ID_SAVE_AS_TEMPLATE_2, GADGET_ID_NONE, -1, "Save", - " ", "As Template", "Save current settings as new template" + "Template to use for new levels:", NULL, "this level as level template", + "Save current settings as new template" }, { -1, -1, GADGET_ID_ADD_CHANGE_PAGE, GADGET_ID_PASTE_CHANGE_PAGE, -1, "New", - NULL, NULL, "Add new change page" + NULL, NULL, NULL, "Add new change page" }, { -1, -1, GADGET_ID_DEL_CHANGE_PAGE, GADGET_ID_ADD_CHANGE_PAGE, -1, "Delete", - NULL, NULL, "Delete current change page" + NULL, NULL, NULL, "Delete current change page" }, }; @@ -2755,6 +2818,13 @@ static struct NULL, "restrict random placement to:", "set random placement restriction" }, + { + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_USE_TEMPLATE_2, GADGET_ID_NONE, + &level.use_custom_template, + NULL, + "use template for custom elements", "use template for custom properties" + }, /* ---------- element settings: configure (various elements) ------------- */ @@ -2959,7 +3029,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_CUSTOM_USE_TEMPLATE, GADGET_ID_NONE, + GADGET_ID_CUSTOM_USE_TEMPLATE_1, GADGET_ID_NONE, &level.use_custom_template, NULL, "use template", "use template for custom properties" @@ -4826,7 +4896,6 @@ static boolean use_el_empty = FALSE; static int *editor_elements = NULL; /* dynamically allocated */ static int num_editor_elements = 0; /* dynamically determined */ -static boolean setup_editor_show_always = TRUE; static boolean setup_editor_cascade_never = FALSE; static int editor_hl_unused[] = { EL_EMPTY }; @@ -4849,67 +4918,67 @@ static struct editor_elements_info[] = { { - &setup_editor_show_always, + &setup.editor.el_classic, &setup_editor_cascade_never, &editor_hl_unused_ptr, &num_editor_hl_unused, &editor_el_players_ptr, &num_editor_el_players }, { - &setup.editor.el_boulderdash, + &setup.editor.el_classic, &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.el_classic, &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.el_classic, &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.el_classic, &setup.editor_cascade.el_rnd, &editor_hl_rnd_ptr, &num_editor_hl_rnd, &editor_el_rnd_ptr, &num_editor_el_rnd }, { - &setup.editor.el_sokoban, + &setup.editor.el_classic, &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.el_classic, &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.el_classic, &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.el_classic, &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.el_classic, &setup.editor_cascade.el_chars, &editor_hl_chars_ptr, &num_editor_hl_chars, &editor_el_chars_ptr, &num_editor_el_chars }, { - &setup.editor.el_steel_chars, + &setup.editor.el_classic, &setup.editor_cascade.el_steel_chars, &editor_hl_steel_chars_ptr, &num_editor_hl_steel_chars, &editor_el_steel_chars_ptr, &num_editor_el_steel_chars @@ -6135,8 +6204,8 @@ static void CreateTextbuttonGadgets() struct GadgetInfo *gi; unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; - int x = SX + ED_TAB_SETTINGS_X(textbutton_info[i].x); - int y = SY + ED_TAB_SETTINGS_Y(textbutton_info[i].y); + int x = SX + ED_SETTINGS_X(textbutton_info[i].x); + int y = SY + ED_SETTINGS_Y(textbutton_info[i].y); if (textbutton_info[i].size == -1) /* dynamically determine size */ textbutton_info[i].size = strlen(textbutton_info[i].text); @@ -6730,9 +6799,12 @@ static void MapTextbuttonGadget(int id) struct GadgetInfo *gi = level_editor_gadget[textbutton_info[id].gadget_id]; int xoffset_left = getTextWidthForGadget(textbutton_info[id].text_left); int xoffset_right = ED_GADGET_TEXT_DISTANCE; + int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE; int yoffset = (gi->height - font_height) / 2; int x_left = gi->x - xoffset_left; int x_right = gi->x + gi->width + xoffset_right; + int y_above = gi->y - yoffset_above; + int x = gi->x; int y = gi->y + yoffset; /* only show button to delete change pages when more than minimum pages */ @@ -6740,6 +6812,9 @@ static void MapTextbuttonGadget(int id) custom_element.num_change_pages == MIN_CHANGE_PAGES) return; + if (textbutton_info[id].text_above) + DrawText(x, y_above, textbutton_info[id].text_above, font_nr); + if (textbutton_info[id].text_left) DrawText(x_left, y, textbutton_info[id].text_left, font_nr); @@ -7528,11 +7603,13 @@ static void CopyElementPropertiesToEditor(int element) static boolean AskToCopyAndModifyLevelTemplate() { - if (Request("Copy and modify level template?", REQ_ASK)) + if (Request("Copy and modify settings from level template?", REQ_ASK)) { level.use_custom_template = FALSE; - ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE], + ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE_1], + GDI_CHECKED, FALSE, GDI_END); + ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE_2], GDI_CHECKED, FALSE, GDI_END); return TRUE; @@ -8256,6 +8333,9 @@ static void DrawLevelInfoEditor() /* draw drawing area */ MapDrawingArea(ED_DRAWING_ID_RANDOM_BACKGROUND); + + /* draw textbutton gadgets */ + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2); } static void DrawLevelInfoWindow() @@ -9053,7 +9133,7 @@ static void DrawPropertiesConfig() MapSelectboxGadget(i); /* draw textbutton gadgets */ - MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE); + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); /* draw text input gadgets */ MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME); @@ -9093,7 +9173,7 @@ static void DrawPropertiesConfig() /* draw checkbutton gadgets */ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1); /* draw counter gadgets */ MapCounterButtons(ED_COUNTER_ID_GROUP_CONTENT); @@ -9102,7 +9182,7 @@ static void DrawPropertiesConfig() MapSelectboxGadget(ED_SELECTBOX_ID_GROUP_CHOICE_MODE); /* draw textbutton gadgets */ - MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE); + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); /* draw drawing area gadgets */ DrawGroupElementArea(properties_element); @@ -10964,6 +11044,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; int id = gi->custom_id; + int type_id = gi->custom_type_id; boolean button_press_event; boolean button_release_event; boolean inside_drawing_area = !gi->event.off_borders; @@ -11073,9 +11154,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) SetElementButton(lx, ly, new_element, button); } } - else + else if (!button_release_event) { - int type_id = gi->custom_type_id; int pos = sx * drawingarea_info[type_id].area_ysize + sy; if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY) @@ -11202,17 +11282,22 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) PickDrawingElement(button, Feld[lx][ly]); else { - int type_id = gi->custom_type_id; int pos = sx * drawingarea_info[type_id].area_ysize + sy; PickDrawingElement(button, drawingarea_info[type_id].value[pos]); } - break; - default: break; } + + /* do not mark level as modified for certain non-level-changing gadgets */ + if ((type_id >= ED_DRAWING_ID_EDITOR_FIRST && + type_id <= ED_DRAWING_ID_EDITOR_LAST) || + actual_drawing_function == GADGET_ID_PICK_ELEMENT) + return; + + level.changed = TRUE; } static void HandleCounterButtons(struct GadgetInfo *gi) @@ -11309,6 +11394,11 @@ static void HandleCounterButtons(struct GadgetInfo *gi) counter_id <= ED_COUNTER_ID_CHANGE_LAST)) CopyElementPropertiesToGame(properties_element); + /* do not mark level as modified for certain non-level-changing gadgets */ + if (counter_id >= ED_COUNTER_ID_EDITOR_FIRST && + counter_id <= ED_COUNTER_ID_EDITOR_LAST) + return; + level.changed = TRUE; } @@ -11393,7 +11483,8 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) DrawPropertiesWindow(); } - else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE) + else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1 || + type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2) { boolean new_template = !fileExists(getLocalLevelTemplateFilename()); @@ -11418,6 +11509,10 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) { struct ElementInfo *ei = &element_info[properties_element]; + /* when modifying custom element, ask for copying level template */ + if (level.use_custom_template && !AskToCopyAndModifyLevelTemplate()) + return; + setElementChangePages(ei, ei->num_change_pages + 1); /* set new change page to be new current change page */ @@ -11435,6 +11530,10 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) { struct ElementInfo *ei = &element_info[properties_element]; + /* when modifying custom element, ask for copying level template */ + if (level.use_custom_template && !AskToCopyAndModifyLevelTemplate()) + return; + /* copy all change pages after change page to be deleted */ for (i = ei->current_change_page; i < ei->num_change_pages - 1; i++) ei->change_page[i] = ei->change_page[i + 1]; @@ -11474,10 +11573,16 @@ static void HandleGraphicbuttonGadgets(struct GadgetInfo *gi) int current_change_page = ei->current_change_page; if (type_id == ED_GRAPHICBUTTON_ID_COPY_CHANGE_PAGE) + { element_info[EL_INTERNAL_CLIPBOARD_CHANGE].change_page[0] = ei->change_page[current_change_page]; + } else if (type_id == ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE) { + /* when modifying custom element, ask for copying level template */ + if (level.use_custom_template && !AskToCopyAndModifyLevelTemplate()) + return; + ei->change_page[current_change_page] = element_info[EL_INTERNAL_CLIPBOARD_CHANGE].change_page[0]; @@ -11490,8 +11595,15 @@ static void HandleGraphicbuttonGadgets(struct GadgetInfo *gi) static void HandleRadiobuttons(struct GadgetInfo *gi) { - *radiobutton_info[gi->custom_type_id].value = - radiobutton_info[gi->custom_type_id].checked_value; + int type_id = gi->custom_type_id; + + *radiobutton_info[type_id].value = + radiobutton_info[type_id].checked_value; + + /* do not mark level as modified for certain non-level-changing gadgets */ + if (type_id >= ED_RADIOBUTTON_ID_EDITOR_FIRST && + type_id <= ED_RADIOBUTTON_ID_EDITOR_LAST) + return; level.changed = TRUE; } @@ -11509,7 +11621,7 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) || (type_id >= ED_CHECKBUTTON_ID_CHANGE_FIRST && type_id <= ED_CHECKBUTTON_ID_CHANGE_LAST)) && - type_id != ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE)) + type_id != ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1)) { CopyElementPropertiesToGame(properties_element); } @@ -11518,8 +11630,18 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) { UpdateCustomElementGraphicGadgets(); } - else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE) + else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 || + type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2) { + boolean template_related_changes_found = FALSE; + int i; + + /* check if any custom or group elements have been changed */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if ((IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)) && + element_info[i].modified_settings) + template_related_changes_found = TRUE; + if (level.use_custom_template && !fileExists(getGlobalLevelTemplateFilename())) { @@ -11533,6 +11655,7 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) } if (level.use_custom_template && + template_related_changes_found && !Request("Discard changes and use level template?", REQ_ASK)) { level.use_custom_template = FALSE; @@ -11542,11 +11665,23 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) return; } + if (!level.use_custom_template && + Request("Copy settings from level template?", REQ_ASK)) + { + return; + } + LoadLevelTemplate(level.use_custom_template ? -1 : level_nr); DrawEditModeWindow(); } + /* do not mark level as modified for certain non-level-changing gadgets */ + if ((type_id >= ED_CHECKBUTTON_ID_EDITOR_FIRST && + type_id <= ED_CHECKBUTTON_ID_EDITOR_LAST) || + type_id == ED_CHECKBUTTON_ID_STICK_ELEMENT) + return; + level.changed = TRUE; }