X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=e56fa695c08339ca4117751f2ffbbba329754c0d;hb=c145af8280c5ad22978e42621bbe5c0f3a8ada3c;hp=10a59ce5d1a6e27731fc89806a4e401eea0abd50;hpb=6c54b168b94ebbd1fb1b44ce7bbfc671d3326cb4;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 10a59ce5..e56fa695 100644 --- a/src/editor.c +++ b/src/editor.c @@ -71,6 +71,7 @@ #define ED_BORDER_SIZE 3 #define ED_BORDER2_SIZE 5 #define ED_GADGET_DISTANCE 2 +#define ED_GADGET_TEXT_DISTANCE (2 * ED_GADGET_DISTANCE) /* values for the setting windows */ #define ED_SETTINGS_XSTART (3 * MINI_TILEX / 2) @@ -104,26 +105,26 @@ n * ED_COUNTER_YDISTANCE - 2) /* values for element content drawing areas */ +/* amoeba content */ #define ED_AREA_ELEM_CONTENT_XPOS ( 2 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY) +/* custom change target */ #define ED_AREA_ELEM_CONTENT2_XPOS (20 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT2_YPOS (ED_SETTINGS_YPOS(2) + \ ED_GADGET_DISTANCE) - +/* optional custom graphic */ #define ED_AREA_ELEM_CONTENT3_XPOS (24 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT3_YPOS (ED_SETTINGS_YPOS(1) + \ ED_GADGET_DISTANCE) - -#if 1 +/* custom element content */ #define ED_AREA_ELEM_CONTENT4_XPOS (29 * MINI_TILEX) -#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(3) + \ +#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(2) + \ ED_GADGET_DISTANCE - MINI_TILEY) -#else -#define ED_AREA_ELEM_CONTENT4_XPOS (17 * MINI_TILEX) -#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(11) + \ - ED_GADGET_DISTANCE - MINI_TILEY) -#endif +/* custom change trigger element */ +#define ED_AREA_ELEM_CONTENT5_XPOS (30 * MINI_TILEX + MINI_TILEX / 2) +#define ED_AREA_ELEM_CONTENT5_YPOS (ED_SETTINGS_YPOS(7) + \ + ED_GADGET_DISTANCE) /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) @@ -344,11 +345,12 @@ #define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 9) #define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 10) #define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 11) -#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 12) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 13) +#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 12) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 13) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 14) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 14) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 15) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -361,13 +363,16 @@ #define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 2) #define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 3) #define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 4) -#define GADGET_ID_CUSTOM_WALKABLE_LAYER (GADGET_ID_SELECTBOX_FIRST + 5) -#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 6) -#define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 7) -#define GADGET_ID_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 8) +#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 5) +#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 6) +#define GADGET_ID_CUSTOM_WALKABLE_LAYER (GADGET_ID_SELECTBOX_FIRST + 7) +#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 8) +#define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 9) +#define GADGET_ID_CHANGE_IMPACT_ACTION (GADGET_ID_SELECTBOX_FIRST + 10) +#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 11) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 9) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 12) #define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0) #define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1) @@ -402,21 +407,26 @@ #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_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 7) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 8) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 11) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_CUSTOM_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_CUSTOM_CHANGEABLE (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 8) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 9) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_CUSTOM_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CHANGE_IMPACT_SMASHED (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CHANGE_BY_OTHER (GADGET_ID_CHECKBUTTON_FIRST + 24) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 25) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -494,18 +504,21 @@ #define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 2 #define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 3 #define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 4 -#define ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER 5 -#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 6 -#define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 7 -#define ED_SELECTBOX_ID_CHANGE_CAUSE 8 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE 5 +#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 6 +#define ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER 7 +#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 8 +#define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 9 +#define ED_SELECTBOX_ID_CHANGE_IMPACT_ACTION 10 +#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 11 -#define ED_NUM_SELECTBOX 9 +#define ED_NUM_SELECTBOX 12 #define ED_SELECTBOX_ID_CUSTOM_FIRST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION #define ED_SELECTBOX_ID_CUSTOM_LAST ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER #define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS -#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_CAUSE +#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_OTHER_ACTION /* values for textbutton gadgets */ #define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0 @@ -522,20 +535,25 @@ #define ED_CHECKBUTTON_ID_STICK_ELEMENT 3 #define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 4 #define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 5 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 6 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 7 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 8 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 9 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 10 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 11 -#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE 12 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 13 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 14 -#define ED_CHECKBUTTON_ID_CUSTOM_CHANGEABLE 15 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 16 -#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 17 - -#define ED_NUM_CHECKBUTTONS 18 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 6 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 7 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 8 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 9 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 10 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 11 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 12 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 13 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 14 +#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE 15 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 16 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 17 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 18 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 19 +#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 20 +#define ED_CHECKBUTTON_ID_CHANGE_IMPACT_SMASHED 21 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER 22 + +#define ED_NUM_CHECKBUTTONS 23 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -544,7 +562,7 @@ #define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM_WALKABLE #define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC -#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_BY_OTHER /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -816,7 +834,7 @@ static struct ValueTextInfo options_walk_to_action[] = { EP_PUSHABLE, "pushable" }, { -1, NULL } }; -static int index_walk_to_action = 0; +static int value_walk_to_action = 0; static struct ValueTextInfo options_move_pattern[] = { @@ -833,7 +851,6 @@ static struct ValueTextInfo options_move_pattern[] = { MV_ALONG_RIGHT_SIDE, "along right side" }, { -1, NULL } }; -static int index_move_pattern = 0; static struct ValueTextInfo options_move_direction[] = { @@ -844,17 +861,24 @@ static struct ValueTextInfo options_move_direction[] = { MV_DOWN, "down" }, { -1, NULL } }; -static int index_move_direction = 0; + +static struct ValueTextInfo options_move_stepsize[] = +{ + { 1, "very slow" }, + { 2, "slow" }, + { 4, "normal" }, + { 8, "fast" }, + { 16, "very fast" }, + { -1, NULL } +}; static struct ValueTextInfo options_consistency[] = { + { EP_CAN_EXPLODE, "can explode" }, { EP_INDESTRUCTIBLE, "indestructible" }, - { EP_CAN_EXPLODE_BY_FIRE, "can explode by fire" }, - { EP_CAN_EXPLODE_SMASHED, "can explode when smashed" }, - { EP_CAN_EXPLODE_IMPACT, "can explode on impact" }, { -1, NULL } }; -static int index_consistency = 0; +static int value_consistency = 0; static struct ValueTextInfo options_deadliness[] = { @@ -863,7 +887,16 @@ static struct ValueTextInfo options_deadliness[] = { EP_DONT_TOUCH, "touching" }, { -1, NULL } }; -static int index_deadliness = 0; +static int value_deadliness = 0; + +static struct ValueTextInfo options_smash_targets[] = +{ + { EP_CAN_SMASH_PLAYER, "player" }, + { EP_CAN_SMASH_ENEMIES, "enemies" }, + { EP_CAN_SMASH_EVERYTHING, "everything" }, + { -1, NULL } +}; +static int value_smash_targets = 0; static struct ValueTextInfo options_walkable_layer[] = { @@ -872,7 +905,7 @@ static struct ValueTextInfo options_walkable_layer[] = { EP_WALKABLE_UNDER, "under" }, { -1, NULL } }; -static int index_walkable_layer = 0; +static int value_walkable_layer = 0; static struct ValueTextInfo options_time_units[] = { @@ -880,26 +913,33 @@ static struct ValueTextInfo options_time_units[] = { 1, "frames" }, { -1, NULL } }; -static int index_time_units = 0; static struct ValueTextInfo options_change_player_action[] = { - { CE_PRESSED_BY_PLAYER, "pressed" }, { CE_TOUCHED_BY_PLAYER, "touched" }, + { CE_PRESSED_BY_PLAYER, "pressed" }, + { CE_PUSHED_BY_PLAYER, "pushed" }, + { -1, NULL } +}; +static int value_change_player_action = 0; + +static struct ValueTextInfo options_change_impact_action[] = +{ + { CE_IMPACT, "on impact" }, + { CE_SMASHED, "when smashed" }, { -1, NULL } }; -static int index_change_player_action = 0, value_change_player_action = 0; +static int value_change_impact_action = 0; -static struct ValueTextInfo options_change_cause[] = +static struct ValueTextInfo options_change_other_action[] = { - { 1, "specified delay" }, - { 2, "impact (active)" }, - { 3, "impact (passive)" }, - { 4, "touched by player" }, - { 5, "pressed by player" }, + { CE_OTHER_COLLECTING, "collecting" }, + { CE_OTHER_PUSHING, "pushing" }, + { CE_OTHER_CHANGING, "change of" }, + { CE_OTHER_EXPLODING, "explosion of" }, { -1, NULL } }; -static int index_change_cause = 0, value_change_cause = 0; +static int value_change_other_action = 0; static struct { @@ -907,7 +947,7 @@ static struct int gadget_id; int size; /* char size of selectbox or '-1' (dynamically determined) */ struct ValueTextInfo *options; - int *index, *value; + int *value; char *text_left, *text_right, *infotext; } selectbox_info[ED_NUM_SELECTBOX] = { @@ -915,31 +955,31 @@ static struct ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4), GADGET_ID_CUSTOM_WALK_TO_ACTION, -1, - options_walk_to_action, &index_walk_to_action, - &custom_element.walk_to_action, + options_walk_to_action, + &value_walk_to_action, NULL, NULL, "diggable/collectible/pushable" }, { - ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_CONSISTENCY, -1, - options_consistency, &index_consistency, - &custom_element.consistency, - NULL, "to", "consistency/destructibility" + options_consistency, + &value_consistency, + NULL, "explodes to:", "consistency/destructibility" }, { - ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2), + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(1), GADGET_ID_CUSTOM_DEADLINESS, -1, - options_deadliness, &index_deadliness, - &custom_element.deadliness, + options_deadliness, + &value_deadliness, "deadly when", NULL, "deadliness of element" }, { ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), GADGET_ID_CUSTOM_MOVE_PATTERN, -1, - options_move_pattern, &index_move_pattern, + options_move_pattern, &custom_element.move_pattern, "can move", NULL, "element move direction" }, @@ -947,23 +987,39 @@ static struct ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7), GADGET_ID_CUSTOM_MOVE_DIRECTION, -1, - options_move_direction, &index_move_direction, + options_move_direction, &custom_element.move_direction_initial, "starts moving", NULL, "initial element move direction" }, { - ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(13), + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(9), + GADGET_ID_CUSTOM_MOVE_STEPSIZE, + -1, + options_move_stepsize, + &custom_element.move_stepsize, + "move speed", NULL, "speed of element movement" + }, + { + ED_SETTINGS_XPOS(7), ED_SETTINGS_YPOS(10), + GADGET_ID_CUSTOM_SMASH_TARGETS, + -1, + options_smash_targets, + &value_smash_targets, + "can smash", NULL, "elements that can be smashed" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(12), GADGET_ID_CUSTOM_WALKABLE_LAYER, -1, - options_walkable_layer, &index_walkable_layer, - &custom_element.walkable_layer, + options_walkable_layer, + &value_walkable_layer, "player can walk", NULL, "layer where player can walk" }, { ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(4), GADGET_ID_CHANGE_TIME_UNITS, -1, - options_time_units, &index_time_units, + options_time_units, &custom_element.change.delay_frames, "delay time given in", NULL, "delay time units for change" }, @@ -971,17 +1027,25 @@ static struct ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(5), GADGET_ID_CHANGE_PLAYER_ACTION, -1, - options_change_player_action, &index_change_player_action, + options_change_player_action, &value_change_player_action, NULL, "by player", "type of player contact" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), - GADGET_ID_CHANGE_CAUSE, + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_IMPACT_ACTION, -1, - options_change_cause, &index_change_cause, - &value_change_cause, - "test:", NULL, "test-selectbox entry" + options_change_impact_action, + &value_change_impact_action, + NULL, NULL, "change after impact or smash" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_OTHER_ACTION, + -1, + options_change_other_action, + &value_change_other_action, + NULL, "other element:", "type of other element action" }, }; @@ -1162,11 +1226,29 @@ static struct "slip down from certain flat walls","use EM style slipping behaviour" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), GADGET_ID_CUSTOM_EXPLODE_RESULT, &custom_element_properties[EP_EXPLODE_RESULT], NULL, "set consistency/destructibility" }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_EXPLODE_FIRE, + &custom_element_properties[EP_CAN_EXPLODE_BY_FIRE], + "by fire", "element can explode by fire/explosion" + }, + { + ED_SETTINGS_XPOS(7), ED_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_EXPLODE_SMASH, + &custom_element_properties[EP_CAN_EXPLODE_SMASHED], + "smashed", "element can explode when smashed" + }, + { + ED_SETTINGS_XPOS(13), ED_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_EXPLODE_IMPACT, + &custom_element_properties[EP_CAN_EXPLODE_IMPACT], + "impact", "element can explode on impact" + }, { ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(4), GADGET_ID_CUSTOM_WALK_TO_OBJECT, @@ -1174,7 +1256,7 @@ static struct NULL, "player can dig/collect/push element" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1), GADGET_ID_CUSTOM_DEADLY, &custom_element_properties[EP_DEADLY], NULL, "element can kill the player" @@ -1186,25 +1268,25 @@ static struct NULL, "element can move in some direction" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), GADGET_ID_CUSTOM_CAN_FALL, &custom_element_properties[EP_CAN_FALL], "can fall", "element can fall down" }, { - ED_SETTINGS_XPOS(6), ED_SETTINGS_YPOS(9), + ED_SETTINGS_XPOS(6), ED_SETTINGS_YPOS(10), GADGET_ID_CUSTOM_CAN_SMASH, &custom_element_properties[EP_CAN_SMASH], - "can smash on impact", "element can smash other elements" + NULL, "element can smash other elements" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(11), GADGET_ID_CUSTOM_SLIPPERY, &custom_element_properties[EP_SLIPPERY], "slippery", "other elements can fall down from it" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(13), + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(12), GADGET_ID_CUSTOM_WALKABLE, &custom_element_properties[EP_WALKABLE], NULL, "player can walk on the same field" @@ -1223,8 +1305,8 @@ static struct }, { ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2), - GADGET_ID_CUSTOM_CHANGEABLE, - &custom_element_properties[EP_CHANGEABLE], + GADGET_ID_CUSTOM_CAN_CHANGE, + &custom_element_properties[EP_CAN_CHANGE], "element changes to after/when:","element can change to other element" }, { @@ -1239,6 +1321,18 @@ static struct &custom_element_change_events[CE_BY_PLAYER], NULL, "element changes by player contact" }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_IMPACT_SMASHED, + &custom_element_change_events[CE_IMPACT_SMASHED], + NULL, "element changes by impact or smash" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_BY_OTHER, + &custom_element_change_events[CE_BY_OTHER], + NULL, "element changes by other element" + }, }; @@ -2428,7 +2522,7 @@ static void CreateCounterButtons() if (counterbutton_info[i].text_left != NULL) xoffset = (getFontWidth(FONT_TEXT_1) * strlen(counterbutton_info[i].text_left) + - 2 * ED_GADGET_DISTANCE); + ED_GADGET_TEXT_DISTANCE); for (j=0; j<2; j++) { @@ -2670,7 +2764,7 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; /* ... one for each custom element change target element ... */ - id = GADGET_ID_CUSTOM_CHANGED; + id = GADGET_ID_CUSTOM_CHANGE_TARGET; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_X, SX + ED_AREA_ELEM_CONTENT2_XPOS, GDI_Y, SY + ED_AREA_ELEM_CONTENT2_YPOS, @@ -2688,8 +2782,26 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; - /* ... and one for random placement background restrictions */ + /* ... one for each custom element change trigger element ... */ + id = GADGET_ID_CUSTOM_CHANGE_TRIGGER; + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_X, SX + ED_AREA_ELEM_CONTENT5_XPOS, + GDI_Y, SY + ED_AREA_ELEM_CONTENT5_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; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_X, SX + ED_AREA_RANDOM_BACKGROUND_XPOS, @@ -2796,7 +2908,7 @@ static void CreateSelectboxGadgets() if (selectbox_info[i].text_left != NULL) xoffset = (getFontWidth(FONT_TEXT_1) * strlen(selectbox_info[i].text_left) + - 2 * ED_GADGET_DISTANCE); + ED_GADGET_TEXT_DISTANCE); sprintf(infotext, "Select %s", selectbox_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -2808,7 +2920,6 @@ static void CreateSelectboxGadgets() GDI_Y, SY + selectbox_info[i].y, GDI_TYPE, GD_TYPE_SELECTBOX, GDI_SELECTBOX_OPTIONS, selectbox_info[i].options, - GDI_SELECTBOX_INDEX, selectbox_info[i].index, GDI_TEXT_SIZE, selectbox_info[i].size, GDI_TEXT_FONT, FONT_INPUT_1, GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE, @@ -3179,7 +3290,7 @@ static void MapSelectboxGadget(int id) { int xoffset_left = 0; int yoffset_left = ED_BORDER_SIZE; - int xoffset_right = ED_BORDER_SIZE; + int xoffset_right = ED_GADGET_TEXT_DISTANCE; int yoffset_right = ED_BORDER_SIZE; int x = selectbox_info[id].x + xoffset_left; int y = selectbox_info[id].y + yoffset_left; @@ -3357,7 +3468,7 @@ static void CopyCustomElementPropertiesToEditor(int element) custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i); /* set walk-to-object action selectbox help value */ - custom_element.walk_to_action = + value_walk_to_action = (IS_DIGGABLE(element) ? EP_DIGGABLE : IS_COLLECTIBLE(element) ? EP_COLLECTIBLE : IS_PUSHABLE(element) ? EP_PUSHABLE : @@ -3368,16 +3479,16 @@ static void CopyCustomElementPropertiesToEditor(int element) IS_PUSHABLE(element)); /* set consistency selectbox help value */ - custom_element.consistency = - (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE : - CAN_EXPLODE_BY_FIRE(element) ? EP_CAN_EXPLODE_BY_FIRE : - EP_INDESTRUCTIBLE); + value_consistency = + (CAN_EXPLODE(element) ? EP_CAN_EXPLODE : + IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE : + EP_CAN_EXPLODE); custom_element_properties[EP_EXPLODE_RESULT] = - (IS_INDESTRUCTIBLE(element) || - CAN_EXPLODE_BY_FIRE(element)); + (CAN_EXPLODE(element) || + IS_INDESTRUCTIBLE(element)); /* set deadliness selectbox help value */ - custom_element.deadliness = + value_deadliness = (DONT_TOUCH(element) ? EP_DONT_TOUCH : DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH : DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO : @@ -3387,8 +3498,19 @@ static void CopyCustomElementPropertiesToEditor(int element) DONT_COLLIDE_WITH(element) || DONT_RUN_INTO(element)); + /* set smash targets selectbox help value */ + value_smash_targets = + (CAN_SMASH_EVERYTHING(element) ? EP_CAN_SMASH_EVERYTHING : + CAN_SMASH_ENEMIES(element) ? EP_CAN_SMASH_ENEMIES : + CAN_SMASH_PLAYER(element) ? EP_CAN_SMASH_PLAYER : + EP_CAN_SMASH_PLAYER); + custom_element_properties[EP_CAN_SMASH] = + (CAN_SMASH_EVERYTHING(element) || + CAN_SMASH_ENEMIES(element) || + CAN_SMASH_PLAYER(element)); + /* set walkable layer selectbox help value */ - custom_element.walkable_layer = + value_walkable_layer = (IS_WALKABLE_OVER(element) ? EP_WALKABLE_OVER : IS_WALKABLE_INSIDE(element) ? EP_WALKABLE_INSIDE : IS_WALKABLE_UNDER(element) ? EP_WALKABLE_UNDER : @@ -3400,9 +3522,24 @@ static void CopyCustomElementPropertiesToEditor(int element) /* set change by player selectbox help value */ value_change_player_action = - (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : + (HAS_CHANGE_EVENT(element, CE_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER : + HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : CE_PRESSED_BY_PLAYER); + + /* set change by impact/smash selectbox help value */ + value_change_impact_action = + (HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED : + HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT : + CE_IMPACT); + + /* set change by other element action selectbox help value */ + value_change_other_action = + (HAS_CHANGE_EVENT(element, CE_OTHER_EXPLODING) ? CE_OTHER_EXPLODING : + HAS_CHANGE_EVENT(element, CE_OTHER_CHANGING) ? CE_OTHER_CHANGING : + HAS_CHANGE_EVENT(element, CE_OTHER_PUSHING) ? CE_OTHER_PUSHING : + HAS_CHANGE_EVENT(element, CE_OTHER_COLLECTING) ? CE_OTHER_COLLECTING : + CE_OTHER_COLLECTING); } static void CopyCustomElementPropertiesToGame(int element) @@ -3415,33 +3552,56 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_properties[EP_DIGGABLE] = FALSE; custom_element_properties[EP_COLLECTIBLE] = FALSE; custom_element_properties[EP_PUSHABLE] = FALSE; - custom_element_properties[custom_element.walk_to_action] = + custom_element_properties[value_walk_to_action] = custom_element_properties[EP_WALK_TO_OBJECT]; /* set consistency property from checkbox and selectbox */ + custom_element_properties[EP_CAN_EXPLODE] = FALSE; custom_element_properties[EP_INDESTRUCTIBLE] = FALSE; - custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE; - custom_element_properties[custom_element.consistency] = + custom_element_properties[value_consistency] = custom_element_properties[EP_EXPLODE_RESULT]; /* set deadliness property from checkbox and selectbox */ custom_element_properties[EP_DONT_RUN_INTO] = FALSE; custom_element_properties[EP_DONT_COLLIDE_WITH] = FALSE; custom_element_properties[EP_DONT_TOUCH] = FALSE; - custom_element_properties[custom_element.deadliness] = + custom_element_properties[value_deadliness] = custom_element_properties[EP_DEADLY]; + /* set smash property from checkbox and selectbox */ + custom_element_properties[EP_CAN_SMASH_PLAYER] = FALSE; + custom_element_properties[EP_CAN_SMASH_ENEMIES] = FALSE; + custom_element_properties[EP_CAN_SMASH_EVERYTHING] = FALSE; + custom_element_properties[value_smash_targets] = + custom_element_properties[EP_CAN_SMASH]; + /* set walkable property from checkbox and selectbox */ custom_element_properties[EP_WALKABLE_OVER] = FALSE; custom_element_properties[EP_WALKABLE_INSIDE] = FALSE; custom_element_properties[EP_WALKABLE_UNDER] = FALSE; - custom_element_properties[custom_element.walkable_layer] = + custom_element_properties[value_walkable_layer] = custom_element_properties[EP_WALKABLE]; /* set player change event from checkbox and selectbox */ - custom_element.change.events &= ~CE_PRESSED_BY_PLAYER; - custom_element.change.events &= ~CE_TOUCHED_BY_PLAYER; - custom_element.change.events |= value_change_player_action; + custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE; + custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE; + custom_element_change_events[CE_PUSHED_BY_PLAYER] = FALSE; + custom_element_change_events[value_change_player_action] = + custom_element_change_events[CE_BY_PLAYER]; + + /* set player change event from checkbox and selectbox */ + custom_element_change_events[CE_IMPACT] = FALSE; + custom_element_change_events[CE_SMASHED] = FALSE; + custom_element_change_events[value_change_impact_action] = + custom_element_change_events[CE_IMPACT_SMASHED]; + + /* set other element action change event from checkbox and selectbox */ + custom_element_change_events[CE_OTHER_COLLECTING] = FALSE; + custom_element_change_events[CE_OTHER_PUSHING] = FALSE; + custom_element_change_events[CE_OTHER_CHANGING] = FALSE; + custom_element_change_events[CE_OTHER_EXPLODING] = FALSE; + custom_element_change_events[value_change_other_action] = + custom_element_change_events[CE_BY_OTHER]; for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) SET_PROPERTY(element, i, custom_element_properties[i]); @@ -3860,9 +4020,9 @@ static void DrawCustomContentArea() MapDrawingArea(GADGET_ID_CUSTOM_CONTENT); } -static void DrawCustomChangedArea() +static void DrawCustomChangeTargetArea() { - struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGED]; + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TARGET]; int xpos = ED_AREA_ELEM_CONTENT2_XPOS; int ypos = ED_AREA_ELEM_CONTENT2_YPOS; int area_sx = SX + xpos; @@ -3880,7 +4040,30 @@ static void DrawCustomChangedArea() DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(custom_element.change.successor)); - MapDrawingArea(GADGET_ID_CUSTOM_CHANGED); + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TARGET); +} + +static void DrawCustomChangeTriggerArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TRIGGER]; + int xpos = ED_AREA_ELEM_CONTENT5_XPOS; + int ypos = ED_AREA_ELEM_CONTENT5_YPOS; + int area_sx = SX + xpos; + int area_sy = SY + ypos; + + if (!IS_CUSTOM_ELEMENT(properties_element)) + { + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); + + return; + } + + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniGraphicExt(drawto, gi->x, gi->y, + el2edimg(custom_element.change.trigger)); + + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TRIGGER); } static void DrawElementContentAreas() @@ -4174,8 +4357,16 @@ static void DrawPropertiesInfo() { EP_CAN_MOVE, "- can move" }, { EP_CAN_FALL, "- can fall" }, - { EP_CAN_SMASH, "- can smash other objects" }, - { EP_CAN_EXPLODE_BY_FIRE, "- can explode (by fire/explosion)" }, +#if 0 + { EP_CAN_SMASH, "- can smash" }, +#endif + { EP_CAN_SMASH_PLAYER, "- can smash player" }, + { EP_CAN_SMASH_ENEMIES, "- can smash good and bad guys" }, + { EP_CAN_SMASH_EVERYTHING, "- can smash everything smashable" }, + { EP_CAN_EXPLODE, "- can explode" }, + { EP_CAN_EXPLODE_BY_FIRE, " - by fire or explosions" }, + { EP_CAN_EXPLODE_SMASHED, " - when smashed" }, + { EP_CAN_EXPLODE_IMPACT, " - on impact" }, { EP_DONT_RUN_INTO, "- deadly when running into" }, { EP_DONT_COLLIDE_WITH, "- deadly when colliding with" }, @@ -4436,7 +4627,8 @@ static void DrawPropertiesAdvanced() /* draw drawing area gadgets */ DrawCustomGraphicElementArea(); - DrawCustomChangedArea(); + DrawCustomChangeTargetArea(); + DrawCustomChangeTriggerArea(); } static void DrawElementName(int x, int y, int element) @@ -5278,11 +5470,16 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) custom_element.content[sx][sy] = new_element; element_info[properties_element] = custom_element; } - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) { custom_element.change.successor = new_element; element_info[properties_element] = custom_element; } + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + { + custom_element.change.trigger = new_element; + element_info[properties_element] = custom_element; + } else if (id == GADGET_ID_RANDOM_BACKGROUND) random_placement_background_element = new_element; else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && @@ -5393,8 +5590,10 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) PickDrawingElement(button, custom_element.gfx_element); else if (id == GADGET_ID_CUSTOM_CONTENT) PickDrawingElement(button, custom_element.content[sx][sy]); - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) PickDrawingElement(button, custom_element.change.successor); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + PickDrawingElement(button, custom_element.change.trigger); else if (id == GADGET_ID_RANDOM_BACKGROUND) PickDrawingElement(button, random_placement_background_element); else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && @@ -5483,7 +5682,6 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) { int type_id = gi->custom_type_id; - *selectbox_info[type_id].index = gi->selectbox.index; *selectbox_info[type_id].value = selectbox_info[type_id].options[gi->selectbox.index].value; @@ -6124,9 +6322,12 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) else if (id == GADGET_ID_CUSTOM_CONTENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(custom_element.content[sx][sy])); - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(custom_element.change.successor)); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(custom_element.change.trigger)); else if (id == GADGET_ID_RANDOM_BACKGROUND) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(random_placement_background_element)); @@ -6150,9 +6351,12 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) else if (id == GADGET_ID_CUSTOM_CONTENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "Custom element content position: %d, %d", sx, sy); - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "New element after change"); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Other element triggering change"); else if (id == GADGET_ID_RANDOM_BACKGROUND) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "Random placement background");