#include "game.h"
#include "tape.h"
+
+/*
+ -----------------------------------------------------------------------------
+ screen and artwork graphic pixel position definitions
+ -----------------------------------------------------------------------------
+*/
+
/* positions in the level editor */
#define ED_WIN_MB_LEFT_XPOS 6
#define ED_WIN_MB_LEFT_YPOS 258
#define ED_WIN_MB_RIGHT_XPOS 78
#define ED_WIN_MB_RIGHT_YPOS ED_WIN_MB_LEFT_YPOS
-/* other constants for the editor */
-#define ED_SCROLL_NO 0
-#define ED_SCROLL_LEFT 1
-#define ED_SCROLL_RIGHT 2
-#define ED_SCROLL_UP 4
-#define ED_SCROLL_DOWN 8
-
-/* screens in the level editor */
-#define ED_MODE_DRAWING 0
-#define ED_MODE_INFO 1
-#define ED_MODE_PROPERTIES 2
-
-/* how many steps can be cancelled */
-#define NUM_UNDO_STEPS (10 + 1)
-
-/* values for elements with score */
-#define MIN_SCORE 0
-#define MAX_SCORE 255
-
/* values for the control window */
#define ED_CTRL_BUTTONS_GFX_YPOS 236
#define ED_CTRL_BUTTONS_ALT_GFX_YPOS 142
#define ED_COUNTER_YDISTANCE (3 * MINI_TILEY)
#define ED_COUNTER_YPOS(n) (ED_COUNTER_YSTART + \
n * ED_COUNTER_YDISTANCE)
+#define ED_COUNTER_YPOS2(n) (ED_COUNTER_YSTART + \
+ n * ED_COUNTER_YDISTANCE / 2)
#define ED_COUNTER2_YPOS(n) (ED_COUNTER_YSTART + \
n * ED_COUNTER_YDISTANCE - 2)
+
/* standard distances */
#define ED_BORDER_SIZE 3
+#define ED_BORDER2_SIZE 5
#define ED_GADGET_DISTANCE 2
/* values for element content drawing areas */
#define ED_AREA_ELEM_CONTENT_XPOS ( 2 * MINI_TILEX)
#define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY)
+#define ED_AREA_ELEM_CONTENT2_XPOS ( 2 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT2_YPOS (28 * MINI_TILEY)
+
/* values for random placement background drawing area */
#define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX)
#define ED_AREA_RANDOM_BACKGROUND_YPOS (31 * MINI_TILEY)
#define ED_BUTTON_PLUS_YSIZE ED_BUTTON_COUNT_YSIZE
#define ED_SELECTBOX_XPOS ED_WIN_COUNT_XPOS
-#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + 2 + \
- ED_WIN_COUNT_YSIZE)
+#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + \
+ 2 + ED_WIN_COUNT_YSIZE)
#define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE
#define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE
-/* editor gadget identifiers */
+#define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS
+#define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \
+ 2 * (2 + ED_WIN_COUNT_YSIZE))
+#define ED_TEXTBUTTON_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \
+ 3 * (2 + ED_WIN_COUNT_YSIZE))
+#define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE
+#define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE
+
+/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */
+#define INFOTEXT_XPOS SX
+#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2)
+#define INFOTEXT_XSIZE SXSIZE
+#define INFOTEXT_YSIZE MINI_TILEX
+
+
+/*
+ -----------------------------------------------------------------------------
+ editor gadget definitions
+ -----------------------------------------------------------------------------
+*/
/* drawing toolbox buttons */
#define GADGET_ID_NONE -1
-#define GADGET_ID_SINGLE_ITEMS 0
-#define GADGET_ID_CONNECTED_ITEMS 1
-#define GADGET_ID_LINE 2
-#define GADGET_ID_ARC 3
-#define GADGET_ID_RECTANGLE 4
-#define GADGET_ID_FILLED_BOX 5
-#define GADGET_ID_WRAP_UP 6
-#define GADGET_ID_TEXT 7
-#define GADGET_ID_FLOOD_FILL 8
-#define GADGET_ID_WRAP_LEFT 9
-#define GADGET_ID_PROPERTIES 10
-#define GADGET_ID_WRAP_RIGHT 11
-#define GADGET_ID_RANDOM_PLACEMENT 12
-#define GADGET_ID_GRAB_BRUSH 13
-#define GADGET_ID_WRAP_DOWN 14
-#define GADGET_ID_PICK_ELEMENT 15
-#define GADGET_ID_UNDO 16
-#define GADGET_ID_INFO 17
-#define GADGET_ID_SAVE 18
-#define GADGET_ID_CLEAR 19
-#define GADGET_ID_TEST 20
-#define GADGET_ID_EXIT 21
+#define GADGET_ID_TOOLBOX_FIRST 0
+
+#define GADGET_ID_SINGLE_ITEMS (GADGET_ID_TOOLBOX_FIRST + 0)
+#define GADGET_ID_CONNECTED_ITEMS (GADGET_ID_TOOLBOX_FIRST + 1)
+#define GADGET_ID_LINE (GADGET_ID_TOOLBOX_FIRST + 2)
+#define GADGET_ID_ARC (GADGET_ID_TOOLBOX_FIRST + 3)
+#define GADGET_ID_RECTANGLE (GADGET_ID_TOOLBOX_FIRST + 4)
+#define GADGET_ID_FILLED_BOX (GADGET_ID_TOOLBOX_FIRST + 5)
+#define GADGET_ID_WRAP_UP (GADGET_ID_TOOLBOX_FIRST + 6)
+#define GADGET_ID_TEXT (GADGET_ID_TOOLBOX_FIRST + 7)
+#define GADGET_ID_FLOOD_FILL (GADGET_ID_TOOLBOX_FIRST + 8)
+#define GADGET_ID_WRAP_LEFT (GADGET_ID_TOOLBOX_FIRST + 9)
+#define GADGET_ID_PROPERTIES (GADGET_ID_TOOLBOX_FIRST + 10)
+#define GADGET_ID_WRAP_RIGHT (GADGET_ID_TOOLBOX_FIRST + 11)
+#define GADGET_ID_RANDOM_PLACEMENT (GADGET_ID_TOOLBOX_FIRST + 12)
+#define GADGET_ID_GRAB_BRUSH (GADGET_ID_TOOLBOX_FIRST + 13)
+#define GADGET_ID_WRAP_DOWN (GADGET_ID_TOOLBOX_FIRST + 14)
+#define GADGET_ID_PICK_ELEMENT (GADGET_ID_TOOLBOX_FIRST + 15)
+#define GADGET_ID_UNDO (GADGET_ID_TOOLBOX_FIRST + 16)
+#define GADGET_ID_INFO (GADGET_ID_TOOLBOX_FIRST + 17)
+#define GADGET_ID_SAVE (GADGET_ID_TOOLBOX_FIRST + 18)
+#define GADGET_ID_CLEAR (GADGET_ID_TOOLBOX_FIRST + 19)
+#define GADGET_ID_TEST (GADGET_ID_TOOLBOX_FIRST + 20)
+#define GADGET_ID_EXIT (GADGET_ID_TOOLBOX_FIRST + 21)
/* counter button identifiers */
-#define GADGET_ID_ELEM_SCORE_DOWN 22
-#define GADGET_ID_ELEM_SCORE_TEXT 23
-#define GADGET_ID_ELEM_SCORE_UP 24
-#define GADGET_ID_ELEM_CONTENT_DOWN 25
-#define GADGET_ID_ELEM_CONTENT_TEXT 26
-#define GADGET_ID_ELEM_CONTENT_UP 27
-#define GADGET_ID_LEVEL_XSIZE_DOWN 28
-#define GADGET_ID_LEVEL_XSIZE_TEXT 29
-#define GADGET_ID_LEVEL_XSIZE_UP 30
-#define GADGET_ID_LEVEL_YSIZE_DOWN 31
-#define GADGET_ID_LEVEL_YSIZE_TEXT 32
-#define GADGET_ID_LEVEL_YSIZE_UP 33
-#define GADGET_ID_LEVEL_RANDOM_DOWN 34
-#define GADGET_ID_LEVEL_RANDOM_TEXT 35
-#define GADGET_ID_LEVEL_RANDOM_UP 36
-#define GADGET_ID_LEVEL_COLLECT_DOWN 37
-#define GADGET_ID_LEVEL_COLLECT_TEXT 38
-#define GADGET_ID_LEVEL_COLLECT_UP 39
-#define GADGET_ID_LEVEL_TIMELIMIT_DOWN 40
-#define GADGET_ID_LEVEL_TIMELIMIT_TEXT 41
-#define GADGET_ID_LEVEL_TIMELIMIT_UP 42
-#define GADGET_ID_LEVEL_TIMESCORE_DOWN 43
-#define GADGET_ID_LEVEL_TIMESCORE_TEXT 44
-#define GADGET_ID_LEVEL_TIMESCORE_UP 45
-#define GADGET_ID_SELECT_LEVEL_DOWN 46
-#define GADGET_ID_SELECT_LEVEL_TEXT 47
-#define GADGET_ID_SELECT_LEVEL_UP 48
+#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)
/* drawing area identifiers */
-#define GADGET_ID_DRAWING_LEVEL 49
-#define GADGET_ID_ELEM_CONTENT_0 50
-#define GADGET_ID_ELEM_CONTENT_1 51
-#define GADGET_ID_ELEM_CONTENT_2 52
-#define GADGET_ID_ELEM_CONTENT_3 53
-#define GADGET_ID_ELEM_CONTENT_4 54
-#define GADGET_ID_ELEM_CONTENT_5 55
-#define GADGET_ID_ELEM_CONTENT_6 56
-#define GADGET_ID_ELEM_CONTENT_7 57
-#define GADGET_ID_AMOEBA_CONTENT 58
-#define GADGET_ID_RANDOM_BACKGROUND 59
+#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 27)
+
+#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_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)
/* text input identifiers */
-#define GADGET_ID_LEVEL_NAME 60
-#define GADGET_ID_LEVEL_AUTHOR 61
+#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 12)
+
+#define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0)
+#define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1)
/* selectbox identifiers */
-#define GADGET_ID_SELECTBOX_TEST 62
+#define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 2)
+
+#define GADGET_ID_CUSTOM_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 0)
+
+/* textbutton identifiers */
+#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 1)
+
+#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)
/* gadgets for scrolling of drawing area */
-#define GADGET_ID_SCROLL_UP 63
-#define GADGET_ID_SCROLL_DOWN 64
-#define GADGET_ID_SCROLL_LEFT 65
-#define GADGET_ID_SCROLL_RIGHT 66
-#define GADGET_ID_SCROLL_HORIZONTAL 67
-#define GADGET_ID_SCROLL_VERTICAL 68
+#define GADGET_ID_SCROLLING_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 3)
+
+#define GADGET_ID_SCROLL_UP (GADGET_ID_SCROLLING_FIRST + 0)
+#define GADGET_ID_SCROLL_DOWN (GADGET_ID_SCROLLING_FIRST + 1)
+#define GADGET_ID_SCROLL_LEFT (GADGET_ID_SCROLLING_FIRST + 2)
+#define GADGET_ID_SCROLL_RIGHT (GADGET_ID_SCROLLING_FIRST + 3)
+#define GADGET_ID_SCROLL_HORIZONTAL (GADGET_ID_SCROLLING_FIRST + 4)
+#define GADGET_ID_SCROLL_VERTICAL (GADGET_ID_SCROLLING_FIRST + 5)
/* gadgets for scrolling element list */
-#define GADGET_ID_SCROLL_LIST_UP 69
-#define GADGET_ID_SCROLL_LIST_DOWN 70
-#define GADGET_ID_SCROLL_LIST_VERTICAL 71
+#define GADGET_ID_SCROLLING_LIST_FIRST (GADGET_ID_SCROLLING_FIRST + 6)
+
+#define GADGET_ID_SCROLL_LIST_UP (GADGET_ID_SCROLLING_LIST_FIRST + 0)
+#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 */
-#define GADGET_ID_RANDOM_PERCENTAGE 72
-#define GADGET_ID_RANDOM_QUANTITY 73
-#define GADGET_ID_RANDOM_RESTRICTED 74
-#define GADGET_ID_DOUBLE_SPEED 75
-#define GADGET_ID_GRAVITY 76
-#define GADGET_ID_STICK_ELEMENT 77
-#define GADGET_ID_EM_SLIPPERY_GEMS 78
-#define GADGET_ID_CUSTOM_INDESTRUCTIBLE 79
-#define GADGET_ID_CUSTOM_CAN_FALL 80
-#define GADGET_ID_CUSTOM_CAN_SMASH 81
-#define GADGET_ID_CUSTOM_PUSHABLE 82
-#define GADGET_ID_CUSTOM_SLIPPERY 83
+#define GADGET_ID_CHECKBUTTON_FIRST (GADGET_ID_SCROLLING_LIST_FIRST + 3)
+
+#define GADGET_ID_RANDOM_PERCENTAGE (GADGET_ID_CHECKBUTTON_FIRST + 0)
+#define GADGET_ID_RANDOM_QUANTITY (GADGET_ID_CHECKBUTTON_FIRST + 1)
+#define GADGET_ID_RANDOM_RESTRICTED (GADGET_ID_CHECKBUTTON_FIRST + 2)
+#define GADGET_ID_DOUBLE_SPEED (GADGET_ID_CHECKBUTTON_FIRST + 3)
+#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)
/* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST 84
+#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 12)
#define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \
ED_NUM_ELEMENTLIST_BUTTONS - 1)
#define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR
/* values for selectbox gadgets */
-#define ED_SELECTBOX_ID_TEST 0
+#define ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE 0
-#define ED_NUM_SELECTBOX 1
+#define ED_NUM_SELECTBOX 1
+
+/* 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_NUM_TEXTBUTTON 3
/* values for checkbutton gadgets */
#define ED_CHECKBUTTON_ID_DOUBLE_SPEED 0
#define ED_RADIOBUTTON_ID_LEVEL_FIRST ED_RADIOBUTTON_ID_PERCENTAGE
#define ED_RADIOBUTTON_ID_LEVEL_LAST ED_RADIOBUTTON_ID_QUANTITY
+
+/*
+ -----------------------------------------------------------------------------
+ some internally used definitions
+ -----------------------------------------------------------------------------
+*/
+
/* values for CopyLevelToUndoBuffer() */
#define UNDO_IMMEDIATE 0
#define UNDO_ACCUMULATE 1
-/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */
-#define INFOTEXT_XPOS SX
-#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2)
-#define INFOTEXT_XSIZE SXSIZE
-#define INFOTEXT_YSIZE MINI_TILEX
+/* values for scrollbars */
+#define ED_SCROLL_NO 0
+#define ED_SCROLL_LEFT 1
+#define ED_SCROLL_RIGHT 2
+#define ED_SCROLL_UP 4
+#define ED_SCROLL_DOWN 8
+
+/* screens in the level editor */
+#define ED_MODE_DRAWING 0
+#define ED_MODE_INFO 1
+#define ED_MODE_PROPERTIES 2
+
+/* sub-screens in the element properties section */
+#define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO
+#define ED_MODE_PROPERTIES_CONFIG ED_TEXTBUTTON_ID_PROPERTIES_CONFIG
+#define ED_MODE_PROPERTIES_ADVANCED ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED
+
+/* how many steps can be cancelled */
+#define NUM_UNDO_STEPS (10 + 1)
+
+/* values for elements with score */
+#define MIN_SCORE 0
+#define MAX_SCORE 255
+
+/* values for random placement */
+#define RANDOM_USE_PERCENTAGE 0
+#define RANDOM_USE_QUANTITY 1
+
+/* maximal size of level editor drawing area */
+#define MAX_ED_FIELDX (2 * SCR_FIELDX)
+#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1)
+
+
+/*
+ -----------------------------------------------------------------------------
+ some internally used data structure definitions
+ -----------------------------------------------------------------------------
+*/
static struct
{
{ 'E', "exit level editor" }
};
-/* values for random placement */
-#define RANDOM_USE_PERCENTAGE 0
-#define RANDOM_USE_QUANTITY 1
-
static int random_placement_value = 10;
static int random_placement_method = RANDOM_USE_QUANTITY;
static int random_placement_background_element = EL_SAND;
static boolean random_placement_background_restricted = FALSE;
static boolean stick_element_properties_window = FALSE;
-
-static struct
-{
- boolean indestructible;
- boolean can_fall;
- boolean can_smash;
- boolean pushable;
- boolean slippery;
-} custom_element_properties[NUM_CUSTOM_ELEMENTS];
+static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES];
static struct
{
0, 255,
GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP,
GADGET_ID_LEVEL_TIMESCORE_TEXT,
- &level.score[SC_ZEITBONUS],
+ &level.score[SC_TIME_BONUS],
"score for each 10 seconds left", NULL
},
{
}
};
-static char *test_values[] =
+static struct ValueTextInfo options_change_cause[] =
{
- "test 1",
- "test 2",
- "dieser test-text ist viel zu lang fuer die selectbox",
- "letzter text"
+ { 1, "specified delay" },
+ { 2, "impact (active)" },
+ { 3, "impact (passive)" },
+ { 4, "touched by player" },
+ { 5, "pressed by player" },
+ { -1, NULL }
};
-static int test_index = 0;
+static int index_change_cause = 0;
static struct
{
int x, y;
int gadget_id;
int size;
- char **values;
+ struct ValueTextInfo *options;
int *index;
char *text, *infotext;
} selectbox_info[ED_NUM_SELECTBOX] =
{
{
ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3),
- GADGET_ID_SELECTBOX_TEST,
- MAX_PLAYER_NAME_LEN,
- test_values, &test_index,
+ GADGET_ID_CUSTOM_CHANGE_CAUSE,
+ 17,
+ options_change_cause, &index_change_cause,
"test:", "test-selectbox entry"
},
};
+static struct
+{
+ int x, y;
+ int gadget_id;
+ int size;
+ char *value;
+ char *infotext;
+} textbutton_info[ED_NUM_TEXTBUTTON] =
+{
+ {
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS(1),
+ GADGET_ID_PROPERTIES_INFO,
+ 11, "Information",
+ "Show information about element"
+ },
+ {
+ ED_SETTINGS_XPOS + 166, ED_COUNTER_YPOS(1),
+ GADGET_ID_PROPERTIES_CONFIG,
+ 11, "Configure",
+ "Configure element properties"
+ },
+ {
+ ED_SETTINGS_XPOS + 332, ED_COUNTER_YPOS(1),
+ GADGET_ID_PROPERTIES_ADVANCED,
+ 11, "Advanced",
+ "Advanced element configuration"
+ },
+};
+
static struct
{
int xpos, ypos;
"slip down from certain flat walls","use EM style slipping behaviour"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4),
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(10),
GADGET_ID_CUSTOM_INDESTRUCTIBLE,
- &custom_element_properties[0].indestructible,
+ &custom_element_properties[EP_INDESTRUCTIBLE],
"indestructible", "element cannot be destroyed"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(5),
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(11),
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_YPOS(6),
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(12),
GADGET_ID_CUSTOM_CAN_SMASH,
- &custom_element_properties[0].can_smash,
+ &custom_element_properties[EP_CAN_SMASH],
"can smash", "element can smash other elements"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(7),
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(13),
GADGET_ID_CUSTOM_PUSHABLE,
- &custom_element_properties[0].pushable,
+ &custom_element_properties[EP_PUSHABLE],
"pushable", "element can be pushed"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(8),
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(14),
GADGET_ID_CUSTOM_SLIPPERY,
- &custom_element_properties[0].slippery,
+ &custom_element_properties[EP_SLIPPERY],
"slippery", "other elements can fall down from it"
}
};
-/* maximal size of level editor drawing area */
-#define MAX_ED_FIELDX (2 * SCR_FIELDX)
-#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1)
+
+/*
+ -----------------------------------------------------------------------------
+ some internally used variables
+ -----------------------------------------------------------------------------
+*/
/* actual size of level editor drawing area */
static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1;
static void HandleCounterButtons(struct GadgetInfo *);
static void HandleTextInputGadgets(struct GadgetInfo *);
static void HandleSelectboxGadgets(struct GadgetInfo *);
+static void HandleTextbuttonGadgets(struct GadgetInfo *);
static void HandleRadiobuttons(struct GadgetInfo *);
static void HandleCheckbuttons(struct GadgetInfo *);
static void HandleControlButtons(struct GadgetInfo *);
static int undo_buffer_steps = 0;
static int edit_mode;
+static int edit_mode_properties;
static int element_shift = 0;
EL_CHAR('X'),
EL_CHAR('Y'),
EL_CHAR('Z'),
- EL_CHAR('Ä'),
+ EL_CHAR('['),
- EL_CHAR('Ö'),
- EL_CHAR('Ü'),
+ EL_CHAR('\\'),
+ EL_CHAR(']'),
EL_CHAR('^'),
EL_CHAR('_'),
- EL_CHAR(' '),
+ EL_CHAR('©'),
+ EL_CHAR('Ä'),
+ EL_CHAR('Ö'),
+ EL_CHAR('Ü'),
+
EL_CHAR('°'),
- EL_CHAR('´'),
- EL_CHAR('|')
+ EL_CHAR('®'),
+ EL_CHAR(FONT_ASCII_CURSOR),
+ EL_CHAR(' ')
};
static int num_editor_el_chars = SIZEOF_ARRAY_INT(editor_el_chars);
NULL }
};
+
+/*
+ -----------------------------------------------------------------------------
+ functions
+ -----------------------------------------------------------------------------
+*/
+
static void ReinitializeElementList()
{
int pos = 0;
static int getCounterGadgetWidth()
{
- return (DXSIZE + getFontWidth(FONT_INPUT) - 2 * ED_GADGET_DISTANCE);
+ return (DXSIZE + getFontWidth(FONT_INPUT_1) - 2 * ED_GADGET_DISTANCE);
}
static int getMaxInfoTextLength()
if (j == 0)
{
- int font_type = FONT_INPUT;
+ int font_type = FONT_INPUT_1;
+ int font_type_active = FONT_INPUT_1_ACTIVE;
int gd_width = ED_WIN_COUNT_XSIZE;
id = counterbutton_info[i].gadget_id_text;
if (i == ED_COUNTER_ID_SELECT_LEVEL)
{
font_type = FONT_LEVEL_NUMBER;
+ font_type_active = FONT_LEVEL_NUMBER;
xpos += 2 * ED_GADGET_DISTANCE;
ypos -= ED_GADGET_DISTANCE;
GDI_NUMBER_MAX, counterbutton_info[i].max_value,
GDI_TEXT_SIZE, 3,
GDI_TEXT_FONT, font_type,
+ GDI_TEXT_FONT_ACTIVE, font_type_active,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_TEXTINPUT_DESIGN_WIDTH, gd_width,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, gd_width,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleCounterButtons,
level_editor_gadget[id] = gi;
}
- /* ... one for the amoeba content */
+ /* ... one for the amoeba content ... */
id = GADGET_ID_AMOEBA_CONTENT;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_X, SX + ED_AREA_ELEM_CONTENT_XPOS,
level_editor_gadget[id] = gi;
+ /* ... one for each custom element change target element ... */
+ id = GADGET_ID_CUSTOM_CHANGED;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ 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,
+ GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
+ GDI_CALLBACK_ACTION, HandleDrawingAreas,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+
/* ... and one for random placement background restrictions */
id = GADGET_ID_RANDOM_BACKGROUND;
GDI_TYPE, GD_TYPE_TEXTINPUT_ALPHANUMERIC,
GDI_TEXT_VALUE, textinput_info[i].value,
GDI_TEXT_SIZE, textinput_info[i].size,
- GDI_TEXT_FONT, FONT_INPUT,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleTextInputGadgets,
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = selectbox_info[i].gadget_id;
- event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+ 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;
GDI_X, SX + selectbox_info[i].x,
GDI_Y, SY + selectbox_info[i].y,
GDI_TYPE, GD_TYPE_SELECTBOX,
- GDI_SELECTBOX_VALUES, selectbox_info[i].values,
+ GDI_SELECTBOX_OPTIONS, selectbox_info[i].options,
GDI_SELECTBOX_INDEX, selectbox_info[i].index,
GDI_TEXT_SIZE, selectbox_info[i].size,
- GDI_TEXT_FONT, FONT_INPUT,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_BORDER_SIZE_SELECTBUTTON, getFontHeight(FONT_INPUT),
- GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_BORDER_SIZE_SELECTBUTTON, getFontWidth(FONT_INPUT_1),
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleSelectboxGadgets,
}
}
+static void CreateTextbuttonGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i=0; i<ED_NUM_TEXTBUTTON; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = textbutton_info[i].gadget_id;
+
+ 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;
+
+ sprintf(infotext, "%s", textbutton_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, SX + textbutton_info[i].x,
+ GDI_Y, SY + textbutton_info[i].y,
+ GDI_TYPE, GD_TYPE_TEXT_BUTTON,
+ GDI_TEXT_VALUE, textbutton_info[i].value,
+ GDI_TEXT_SIZE, textbutton_info[i].size,
+ GDI_TEXT_FONT, FONT_INPUT_2_ACTIVE,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
+ GDI_BORDER_SIZE, ED_BORDER2_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_DECORATION_SHIFTING, 1, 1,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleTextbuttonGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+}
+
static void CreateScrollbarGadgets()
{
int i;
GDI_STATE, GD_BUTTON_UNPRESSED,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleControlButtons,
void CreateLevelEditorGadgets()
{
+ int old_game_status = game_status;
+
+ /* setting 'game_status' is needed to get the right fonts for the editor */
+ game_status = LEVELED;
+
ReinitializeElementList();
CreateControlButtons();
CreateDrawingAreas();
CreateTextInputGadgets();
CreateSelectboxGadgets();
+ CreateTextbuttonGadgets();
CreateScrollbarGadgets();
CreateCheckbuttonGadgets();
+
+ game_status = old_game_status;
}
void FreeLevelEditorGadgets()
MapGadget(level_editor_gadget[selectbox_info[id].gadget_id]);
}
+static void MapTextbuttonGadget(int id)
+{
+ MapGadget(level_editor_gadget[textbutton_info[id].gadget_id]);
+}
+
static void MapRadiobuttonGadget(int id)
{
MapGadget(level_editor_gadget[radiobutton_info[id].gadget_id]);
dst[x][y] = src[x][y];
}
-static void CopyCustomElementPropertiesToEditor()
+static void CopyCustomElementPropertiesToEditor(int element)
{
int i;
- for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
- int properties = Properties1[element];
-
- custom_element_properties[i].indestructible =
- ((properties & EP_BIT_INDESTRUCTIBLE) != 0 ? TRUE : FALSE);
-
- custom_element_properties[i].can_fall =
- ((properties & EP_BIT_CAN_FALL) != 0 ? TRUE : FALSE);
-
- custom_element_properties[i].can_smash =
- ((properties & EP_BIT_CAN_SMASH) != 0 ? TRUE : FALSE);
-
- custom_element_properties[i].pushable =
- ((properties & EP_BIT_PUSHABLE) != 0 ? TRUE : FALSE);
-
- custom_element_properties[i].slippery =
- ((properties & EP_BIT_SLIPPERY) != 0 ? TRUE : FALSE);
- }
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ custom_element_properties[i] = HAS_PROPERTY(element, i);
}
-static void CopyCustomElementPropertiesToGame()
+static void CopyCustomElementPropertiesToGame(int element)
{
int i;
- for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
-
- Properties1[element] = EP_BITMASK_DEFAULT;
-
- if (custom_element_properties[i].indestructible)
- Properties1[element] |= EP_BIT_INDESTRUCTIBLE;
- else
- Properties1[element] &= ~EP_BIT_INDESTRUCTIBLE;
-
- if (custom_element_properties[i].can_fall)
- Properties1[element] |= EP_BIT_CAN_FALL;
- else
- Properties1[element] &= ~EP_BIT_CAN_FALL;
-
- if (custom_element_properties[i].can_smash)
- Properties1[element] |= EP_BIT_CAN_SMASH;
- else
- Properties1[element] &= ~EP_BIT_CAN_SMASH;
-
- if (custom_element_properties[i].pushable)
- Properties1[element] |= EP_BIT_PUSHABLE;
- else
- Properties1[element] &= ~EP_BIT_PUSHABLE;
-
- if (custom_element_properties[i].slippery)
- Properties1[element] |= EP_BIT_SLIPPERY;
- else
- Properties1[element] &= ~EP_BIT_SLIPPERY;
- }
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ SET_PROPERTY(element, i, custom_element_properties[i]);
}
void DrawLevelEd()
else
{
edit_mode = ED_MODE_DRAWING;
+ edit_mode_properties = ED_MODE_PROPERTIES_INFO;
ResetUndoBuffer();
+
level_xpos = -1;
level_ypos = -1;
}
MapDrawingArea(GADGET_ID_AMOEBA_CONTENT);
}
+static void DrawCustomChangedArea()
+{
+ 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;
+
+ if (!IS_CUSTOM_ELEMENT(properties_element))
+ {
+ /* this should never happen */
+ Error(ERR_WARN, "element %d is no custom element", properties_element);
+
+ 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);
+
+ MapDrawingArea(GADGET_ID_CUSTOM_CHANGED);
+}
+
static void DrawElementContentAreas()
{
int counter_id = ED_COUNTER_ID_ELEM_CONTENT;
#define TEXT_SPEED "Speed of amoeba growth"
#define TEXT_DURATION "Duration when activated"
-static void DrawPropertiesWindow()
+static struct
+{
+ int element;
+ int *value;
+ char *text;
+} elements_with_counter[] =
+{
+ { EL_EMERALD, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_BD_DIAMOND, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_EMERALD_YELLOW, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_EMERALD_RED, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_EMERALD_PURPLE, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_DIAMOND, &level.score[SC_DIAMOND], TEXT_COLLECTING },
+ { EL_BUG_RIGHT, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BUG_UP, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BUG_LEFT, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BUG_DOWN, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_UP, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_LEFT, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_DOWN, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_SPACESHIP_RIGHT, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SPACESHIP_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SPACESHIP_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SPACESHIP_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_RIGHT,&level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING },
+ { EL_DARK_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING },
+ { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING },
+ { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_NUT, &level.score[SC_NUT], TEXT_CRACKING },
+ { EL_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
+ { EL_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_1_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_2_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_3_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_4_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_SPEED },
+ { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_SPEED },
+ { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_SPEED },
+ { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_SPEED },
+ { EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION },
+ { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION },
+ { -1, NULL, NULL }
+};
+
+static boolean checkPropertiesConfig()
+{
+ int i;
+
+ if (IS_GEM(properties_element) ||
+ IS_CUSTOM_ELEMENT(properties_element) ||
+ HAS_CONTENT(properties_element))
+ return TRUE;
+ else
+ for (i=0; elements_with_counter[i].element != -1; i++)
+ if (elements_with_counter[i].element == properties_element)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void DrawPropertiesConfig()
{
int counter_id = ED_COUNTER_ID_ELEM_SCORE;
- int num_elements_in_level;
- float percentage;
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 xstart = 2;
- int ystart = 4;
int i, x, y;
- static struct
- {
- int element;
- int *value;
- char *text;
- } elements_with_counter[] =
- {
- { EL_EMERALD, &level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_BD_DIAMOND, &level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EMERALD_YELLOW,&level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EMERALD_RED, &level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EMERALD_PURPLE,&level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_DIAMOND, &level.score[SC_DIAMANT], TEXT_COLLECTING },
- { EL_BUG_RIGHT, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUG_UP, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUG_LEFT, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUG_DOWN, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BD_BUTTERFLY_UP, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BD_BUTTERFLY_LEFT, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BD_BUTTERFLY_DOWN, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_SPACESHIP_RIGHT,&level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_SPACESHIP_UP, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_SPACESHIP_LEFT, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_SPACESHIP_DOWN, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_BD_FIREFLY_RIGHT,&level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_BD_FIREFLY_UP, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_BD_FIREFLY_LEFT, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_BD_FIREFLY_DOWN, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_YAMYAM, &level.score[SC_MAMPFER], TEXT_SMASHING },
- { EL_DARK_YAMYAM, &level.score[SC_MAMPFER], TEXT_SMASHING },
- { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING },
- { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_NUT, &level.score[SC_KOKOSNUSS], TEXT_CRACKING },
- { EL_DYNAMITE, &level.score[SC_DYNAMIT], TEXT_COLLECTING },
- { EL_KEY_1, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_KEY_2, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_KEY_3, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_KEY_4, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_1_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_2_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_3_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_4_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_SPEED },
- { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_SPEED },
- { EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION },
- { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION },
- { -1, NULL, NULL }
- };
-
- SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
- ClearWindow();
- UnmapLevelEditorWindowGadgets();
-
- DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS,
- "Element Settings", FONT_TITLE_1);
-
- DrawElementBorder(SX + xstart * MINI_TILEX,
- SY + ystart * MINI_TILEY + MINI_TILEY / 2,
- TILEX, TILEY);
- DrawGraphicAnimationExt(drawto,
- SX + xstart * MINI_TILEX,
- SY + ystart * MINI_TILEY + MINI_TILEY / 2,
- el2edimg(properties_element), -1, NO_MASKING);
-
- FrameCounter = 0; /* restart animation frame counter */
-
- DrawTextF((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY,
- FONT_TEXT_1, getElementInfoText(properties_element));
-
- num_elements_in_level = 0;
- for (y=0; y<lev_fieldy; y++)
- for (x=0; x<lev_fieldx; x++)
- if (Feld[x][y] == properties_element)
- num_elements_in_level++;
- percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
-
- DrawTextF(ED_SETTINGS_XPOS, 5 * TILEY, FONT_TEXT_1, "In this level:");
- DrawTextF(ED_SETTINGS_XPOS + 15 * getFontWidth(FONT_TEXT_1), 5 * TILEY,
- FONT_TEXT_2, "%d (%.2f%%)", num_elements_in_level,
- percentage);
/* check if there are elements where a score can be chosen for */
for (i=0; elements_with_counter[i].element != -1; i++)
}
}
- if (HAS_CONTENT(properties_element))
+ if (HAS_CONTENT(properties_element) ||
+ IS_CUSTOM_ELEMENT(properties_element))
{
/* draw stickybutton gadget */
i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
MapCheckbuttonGadget(i);
- if (IS_AMOEBOID(properties_element))
- DrawAmoebaContentArea();
- else
- DrawElementContentAreas();
+ if (HAS_CONTENT(properties_element))
+ {
+ if (IS_AMOEBOID(properties_element))
+ DrawAmoebaContentArea();
+ else
+ DrawElementContentAreas();
+ }
+ else if (IS_CUSTOM_ELEMENT(properties_element))
+ DrawCustomChangedArea();
}
if (IS_GEM(properties_element))
if (IS_CUSTOM_ELEMENT(properties_element))
{
- int nr = properties_element - EL_CUSTOM_START;
+ CopyCustomElementPropertiesToEditor(properties_element);
- CopyCustomElementPropertiesToEditor();
+ for (i = ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE;
+ i <= ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY; i++)
+ {
+ /* draw checkbutton gadget */
+ 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 checkbutton gadget */
- i = ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE;
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
+ /* draw selectbox gadget */
+ i = ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE;
+ x = selectbox_info[i].x + xoffset_right2;
+ y = selectbox_info[i].y + yoffset_right2;
- checkbutton_info[i].value = &custom_element_properties[nr].indestructible;
+ selectbox_info[i].index = &index_change_cause;
- 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);
+ DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
+ ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
+ GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
+ MapSelectboxGadget(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;
+char *getElementDescriptionFilename(int element)
+{
+ char *docs_dir = options.docs_directory;
+ char *elements_subdir = "elements";
+ static char *filename = NULL;
+ char basename[MAX_FILENAME_LEN];
- checkbutton_info[i].value = &custom_element_properties[nr].can_fall;
+ if (filename != NULL)
+ free(filename);
- 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);
+ /* 1st try: look for element description file for exactly this element */
+ sprintf(basename, "%s.txt", element_info[element].token_name);
+ filename = getPath3(docs_dir, elements_subdir, basename);
+ if (fileExists(filename))
+ return filename;
- /* draw checkbutton gadget */
- i = ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH;
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
+ free(filename);
- checkbutton_info[i].value = &custom_element_properties[nr].can_smash;
+ /* 2nd try: look for element description file for this element's class */
+ sprintf(basename, "%s.txt", element_info[element].class_name);
+ filename = getPath3(docs_dir, elements_subdir, basename);
+ if (fileExists(filename))
+ return filename;
- 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 NULL;
+}
- /* draw checkbutton gadget */
- i = ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE;
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
+static boolean PrintInfoText(char *text, int font_nr, int screen_line)
+{
+ int font_height = getFontHeight(font_nr);
+ int pad_x = ED_SETTINGS_XPOS;
+ int pad_y = 5 * TILEY;
+ int sx = SX + pad_x;
+ int sy = SY + pad_y;
+ int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
- checkbutton_info[i].value = &custom_element_properties[nr].pushable;
+ if (screen_line >= max_lines_per_screen)
+ return FALSE;
- 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);
+ DrawText(sx, sy + screen_line * font_height, text, font_nr);
- /* draw checkbutton gadget */
- i = ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY;
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
+ return TRUE;
+}
- checkbutton_info[i].value = &custom_element_properties[nr].slippery;
+static int PrintElementDescriptionFromFile(char *filename, int screen_line)
+{
+ int font_nr = FONT_TEXT_2;
+ int font_width = getFontWidth(font_nr);
+ int pad_x = ED_SETTINGS_XPOS;
+ int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
+ char line[MAX_LINE_LEN];
+ char buffer[max_chars_per_line + 1];
+ int buffer_len;
+ int lines_printed = 0;
+ FILE *file;
+
+ if (filename == NULL)
+ return 0;
+
+ if (!(file = fopen(filename, MODE_READ)))
+ return 0;
+
+ buffer[0] = '\0';
+ buffer_len = 0;
+
+ while(!feof(file))
+ {
+ char *line_ptr, *word_ptr;
+ boolean last_line_was_empty = TRUE;
- 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);
+ /* read next line of input file */
+ if (!fgets(line, MAX_LINE_LEN, file))
+ break;
- /* draw selectbox gadget */
- i = ED_SELECTBOX_ID_TEST;
- x = selectbox_info[i].x + xoffset_right2;
- y = selectbox_info[i].y + yoffset_right2;
+ /* skip comments (lines directly beginning with '#') */
+ if (line[0] == '#')
+ continue;
+
+ /* cut trailing newline from input line */
+ for (line_ptr = line; *line_ptr; line_ptr++)
+ {
+ if (*line_ptr == '\n' || *line_ptr == '\r')
+ {
+ *line_ptr = '\0';
+ break;
+ }
+ }
- selectbox_info[i].index = &test_index;
+ if (strlen(line) == 0) /* special case: force empty line */
+ strcpy(line, "\n");
- DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
- ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
- GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
- MapSelectboxGadget(i);
+ word_ptr = line;
+
+ while (*word_ptr)
+ {
+ boolean print_buffer = FALSE;
+ int word_len;
+
+ /* skip leading whitespaces */
+ while (*word_ptr == ' ' || *word_ptr == '\t')
+ word_ptr++;
+
+ line_ptr = word_ptr;
+ word_len = 0;
+
+ /* look for end of next word */
+ while (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0')
+ {
+ line_ptr++;
+ word_len++;
+ }
+
+ if (word_len == 0)
+ {
+ continue;
+ }
+ else if (*word_ptr == '\n') /* special case: force empty line */
+ {
+ if (buffer_len == 0)
+ word_ptr++;
+
+ /* prevent printing of multiple empty lines */
+ if (buffer_len > 0 || !last_line_was_empty)
+ print_buffer = TRUE;
+ }
+ else if (word_len < max_chars_per_line - buffer_len)
+ {
+ /* word fits into text buffer -- add word */
+
+ if (buffer_len > 0)
+ buffer[buffer_len++] = ' ';
+
+ strncpy(&buffer[buffer_len], word_ptr, word_len);
+ buffer_len += word_len;
+ buffer[buffer_len] = '\0';
+ word_ptr += word_len;
+ }
+ else if (buffer_len > 0)
+ {
+ /* not enough space left for word in text buffer -- print buffer */
+
+ print_buffer = TRUE;
+ }
+ else
+ {
+ /* word does not fit at all into empty text buffer -- cut word */
+
+ strncpy(buffer, word_ptr, max_chars_per_line);
+ buffer[max_chars_per_line] = '\0';
+ word_ptr += max_chars_per_line;
+ print_buffer = TRUE;
+ }
+
+ if (print_buffer)
+ {
+ if (!PrintInfoText(buffer, font_nr, screen_line + lines_printed))
+ return lines_printed;
+
+ last_line_was_empty = (buffer_len == 0);
+ lines_printed++;
+
+ buffer[0] = '\0';
+ buffer_len = 0;
+ print_buffer = FALSE;
+ }
+ }
}
+
+ fclose(file);
+
+ if (buffer_len > 0)
+ if (PrintInfoText(buffer, font_nr, screen_line + lines_printed))
+ lines_printed++;
+
+ return lines_printed;
+}
+
+static void DrawPropertiesTabulatorGadgets()
+{
+ struct GadgetInfo *gd_gi = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
+ struct GadgetDesign *gd = &gd_gi->alt_design[GD_BUTTON_UNPRESSED];
+ int gd_x = gd->x + gd_gi->border.width / 2;
+ int gd_y = gd->y + gd_gi->height - 1;
+ Pixel line_color = GetPixel(gd->bitmap, gd_x, gd_y);
+ int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
+ int id_last = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
+ int i;
+
+ /* draw additional "configure" tabulator for configurable elements */
+ if (checkPropertiesConfig())
+ id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG;
+
+ /* draw additional "advanced" tabulator for custom elements */
+ if (IS_CUSTOM_ELEMENT(properties_element))
+ id_last = ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED;
+
+ for (i=id_first; i <= id_last; i++)
+ {
+ int gadget_id = textbutton_info[i].gadget_id;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ boolean active = (i != edit_mode_properties);
+ 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);
+
+ 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);
+}
+
+static void DrawPropertiesInfo()
+{
+ static struct
+ {
+ int value;
+ char *text;
+ }
+ properties[] =
+ {
+ { EP_AMOEBALIVE, "- living amoeba" },
+ { EP_AMOEBOID, "- amoeboid" },
+ { EP_PFORTE, "- pforte" },
+ { EP_SOLID, "- solid" },
+ { EP_INDESTRUCTIBLE, "- undestructible" },
+ { EP_SLIPPERY, "- slippery" },
+ { EP_ENEMY, "- enemy" },
+ { EP_MAUER, "- mauer" },
+ { EP_CAN_FALL, "- can fall" },
+ { EP_CAN_SMASH, "- can smash" },
+ { EP_CAN_CHANGE, "- can change" },
+ { EP_CAN_MOVE, "- can move" },
+ { EP_COULD_MOVE, "- could move" },
+ { EP_DONT_TOUCH, "- don't touch" },
+ { EP_DONT_GO_TO, "- don't go to" },
+ { EP_FOOD_DARK_YAMYAM, "- food for dark yamyam" },
+ { EP_BD_ELEMENT, "- BD style" },
+ { EP_SB_ELEMENT, "- SB style" },
+ { EP_GEM, "- gem" },
+ { EP_INACTIVE, "- inactive" },
+ { EP_EXPLOSIVE, "- explosive" },
+ { EP_FOOD_PENGUIN, "- food for penguin" },
+ { EP_PUSHABLE, "- pushable" },
+ { EP_PLAYER, "- player" },
+ { EP_HAS_CONTENT, "- has content" },
+ { EP_DIGGABLE, "- diggable" },
+ { EP_SP_ELEMENT, "- SB style" },
+ { EP_WALKABLE_INSIDE, "- walkable inside" },
+ { EP_ACTIVE_BOMB, "- active bomb" },
+ { EP_BELT, "- belt" },
+ { EP_BELT_ACTIVE, "- active belt" },
+ { EP_BELT_SWITCH, "- belt switch" },
+ { EP_WALKABLE_UNDER, "- walkable under" },
+ { EP_EM_SLIPPERY_WALL, "- EM style slippery wall" },
+ { EP_CAN_BE_CRUMBLED, "- can be crumbled" },
+ { -1, NULL }
+ };
+ char *filename = getElementDescriptionFilename(properties_element);
+ char *percentage_text = "In this level:";
+ char *properties_text = "Standard properties:";
+ float percentage;
+ int num_elements_in_level;
+ int num_standard_properties = 0;
+ int font1_nr = FONT_TEXT_1;
+ int font2_nr = FONT_TEXT_2;
+ int font1_width = getFontWidth(font1_nr);
+ int font2_height = getFontHeight(font2_nr);
+ int pad_x = ED_SETTINGS_XPOS;
+ int pad_y = 5 * TILEY;
+ int screen_line = 2;
+ int i, x, y;
+
+ num_elements_in_level = 0;
+ for (y=0; y<lev_fieldy; y++)
+ for (x=0; x<lev_fieldx; x++)
+ if (Feld[x][y] == properties_element)
+ num_elements_in_level++;
+ percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
+
+ DrawTextF(pad_x, pad_y, font1_nr, percentage_text);
+ DrawTextF(pad_x + strlen(percentage_text) * font1_width, pad_y,
+ font2_nr, "%d (%.2f%%)", num_elements_in_level, percentage);
+
+ for (i=0; properties[i].value != -1; i++)
+ if (HAS_PROPERTY(properties_element, properties[i].value))
+ num_standard_properties++;
+
+ if (num_standard_properties > 0)
+ {
+ DrawTextF(pad_x, pad_y + screen_line * font2_height, font1_nr,
+ properties_text);
+ screen_line++;
+
+ for (i=0; properties[i].value != -1; i++)
+ {
+ if (!HAS_PROPERTY(properties_element, properties[i].value))
+ continue;
+
+ DrawTextF(pad_x, pad_y + screen_line * font2_height, font2_nr,
+ properties[i].text);
+ screen_line++;
+ }
+
+ screen_line++;
+ }
+
+ PrintInfoText("Description:", FONT_TEXT_1, screen_line);
+ if (PrintElementDescriptionFromFile(filename, screen_line + 1) == 0)
+ PrintInfoText("No description available.", FONT_TEXT_1, screen_line);
+}
+
+static void DrawPropertiesAdvanced()
+{
+ DrawText(SX + ED_SETTINGS_XPOS, SY + 5 * TILEY, "Coming soon!", FONT_TEXT_1);
+}
+
+static void DrawPropertiesWindow()
+{
+ int xstart = 2;
+ int ystart = 4;
+
+ /* 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 (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG &&
+ !checkPropertiesConfig())
+ edit_mode_properties = ED_MODE_PROPERTIES_INFO;
+
+ UnmapLevelEditorWindowGadgets();
+
+ SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
+ ClearWindow();
+
+ DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS,
+ "Element Settings", FONT_TITLE_1);
+
+ DrawElementBorder(SX + xstart * MINI_TILEX,
+ SY + ystart * MINI_TILEY + MINI_TILEY / 2,
+ TILEX, TILEY);
+ DrawGraphicAnimationExt(drawto,
+ SX + xstart * MINI_TILEX,
+ SY + ystart * MINI_TILEY + MINI_TILEY / 2,
+ el2img(properties_element), -1, NO_MASKING);
+
+ FrameCounter = 0; /* restart animation frame counter */
+
+ DrawTextF((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY,
+ FONT_TEXT_1, getElementInfoText(properties_element));
+
+ DrawPropertiesTabulatorGadgets();
+
+ if (edit_mode_properties == ED_MODE_PROPERTIES_INFO)
+ DrawPropertiesInfo();
+ else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG)
+ DrawPropertiesConfig();
+ else /* edit_mode_properties == ED_MODE_PROPERTIES_ADVANCED */
+ DrawPropertiesAdvanced();
}
static void DrawLineElement(int sx, int sy, int element, boolean change_level)
}
}
-static void DrawRectangle(int from_x, int from_y, int to_x, int to_y,
- int element, boolean change_level)
+static void DrawBox(int from_x, int from_y, int to_x, int to_y,
+ int element, boolean change_level)
{
DrawLine(from_x, from_y, from_x, to_y, element, change_level);
DrawLine(from_x, to_y, to_x, to_y, element, change_level);
int element, boolean change_level)
{
if (element == -1 || change_level)
- DrawRectangle(from_x, from_y, to_x, to_y, -1, FALSE);
+ DrawBox(from_x, from_y, to_x, to_y, -1, FALSE);
else
DrawAreaBorder(from_x, from_y, to_x, to_y);
}
if (letter >= 'a' && letter <= 'z')
letter_element = EL_CHAR_ASCII0 + letter + (int)('A' - 'a');
else if (letter == 'ä' || letter == 'Ä')
- letter_element = EL_CHAR_AE;
+ letter_element = EL_CHAR_AUMLAUT;
else if (letter == 'ö' || letter == 'Ö')
- letter_element = EL_CHAR_OE;
+ letter_element = EL_CHAR_OUMLAUT;
else if (letter == 'ü' || letter == 'Ü')
- letter_element = EL_CHAR_UE;
+ letter_element = EL_CHAR_UUMLAUT;
else if (letter == '^')
letter_element = EL_CHAR_COPYRIGHT;
else
if (id == GADGET_ID_AMOEBA_CONTENT)
level.amoeba_content = new_element;
+ else if (id == GADGET_ID_CUSTOM_CHANGED &&
+ IS_CUSTOM_ELEMENT(properties_element))
+ {
+ int i = properties_element - EL_CUSTOM_START;
+
+ level.custom_element_successor[i] = new_element;
+ }
else if (id == GADGET_ID_RANDOM_BACKGROUND)
random_placement_background_element = new_element;
else if (id >= GADGET_ID_ELEM_CONTENT_0 &&
else if (drawing_function == GADGET_ID_ARC)
draw_func = DrawArc;
else if (drawing_function == GADGET_ID_RECTANGLE)
- draw_func = DrawRectangle;
+ draw_func = DrawBox;
else if (drawing_function == GADGET_ID_FILLED_BOX)
draw_func = DrawFilledBox;
else if (drawing_function == GADGET_ID_GRAB_BRUSH)
static void HandleSelectboxGadgets(struct GadgetInfo *gi)
{
- *selectbox_info[gi->custom_type_id].index = gi->selectbox.index;
+ int type_id = gi->custom_type_id;
-#if 1
- printf("Selected text value: '%s'\n",
- selectbox_info[gi->custom_type_id].values[gi->selectbox.index]);
+ *selectbox_info[type_id].index = gi->selectbox.index;
+
+#if 0
+ printf("Selected text value: '%s' [%d]\n",
+ selectbox_info[type_id].options[gi->selectbox.index].text,
+ selectbox_info[type_id].options[gi->selectbox.index].value);
#endif
}
+static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
+{
+ if (gi->custom_type_id >= ED_TEXTBUTTON_ID_PROPERTIES_INFO &&
+ gi->custom_type_id <= ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED)
+ {
+ edit_mode_properties = gi->custom_type_id;
+
+ DrawPropertiesWindow();
+ }
+}
+
static void HandleRadiobuttons(struct GadgetInfo *gi)
{
*radiobutton_info[gi->custom_type_id].value =
if (type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST &&
type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST)
- CopyCustomElementPropertiesToGame();
+ CopyCustomElementPropertiesToGame(properties_element);
}
static void HandleControlButtons(struct GadgetInfo *gi)
PickDrawingElement(button, new_element);
+#if 1
+ if (!stick_element_properties_window)
+#else
if (!HAS_CONTENT(properties_element) ||
!stick_element_properties_window)
+#endif
{
properties_element = new_element;
if (edit_mode == ED_MODE_PROPERTIES)
DrawGraphicAnimationExt(drawto,
SX + xpos * TILEX,
SY + ypos * TILEY + MINI_TILEY / 2,
- el2edimg(properties_element), -1, NO_MASKING);
+ el2img(properties_element), -1, NO_MASKING);
MarkTileDirty(xpos, ypos);
MarkTileDirty(xpos, ypos + 1);
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");