X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=ac7b42de8b395f178fd8a7a33879ed9a6423918f;hb=ed5a795f1fd2d48a1372d46c06d86d2faab7e3c4;hp=d85d56655fa9f09967f10022b9dbad8fd6264f40;hpb=097cb899f2c98e2f300e081dd09d7db8b0f636a5;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index d85d5665..ac7b42de 100644 --- a/src/editor.c +++ b/src/editor.c @@ -559,44 +559,45 @@ #define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 12) #define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 13) #define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 41) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 42) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 43) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 45) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 46) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 47) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 48) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_SHIFTED_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 43) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 44) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 47) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 48) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 50) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 51) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -786,43 +787,44 @@ #define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 10 #define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 11 #define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 12 -#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 13 -#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 14 -#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 15 -#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 16 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 17 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 18 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 19 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 20 -#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 21 -#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 22 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 23 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 24 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 25 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 26 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 27 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 28 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 29 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 30 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 31 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 32 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 33 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 34 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 35 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 36 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 37 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 38 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 39 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 40 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 41 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 42 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 43 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 44 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 45 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 46 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 47 - -#define ED_NUM_CHECKBUTTONS 48 +#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 13 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 14 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 15 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 16 +#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 17 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 18 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 19 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 20 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 21 +#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 22 +#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 23 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 24 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 25 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 26 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 27 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 28 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 29 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 30 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 31 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 32 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 33 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 34 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 35 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 36 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 37 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 38 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 39 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 40 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 41 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 42 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 43 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 44 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 45 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 46 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 47 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 48 + +#define ED_NUM_CHECKBUTTONS 49 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -916,11 +918,11 @@ /* values for elements with score for certain actions */ #define MIN_SCORE 0 -#define MAX_SCORE 255 +#define MAX_SCORE 999 /* values for elements with count for collecting */ #define MIN_COLLECT_COUNT 0 -#define MAX_COLLECT_COUNT 255 +#define MAX_COLLECT_COUNT 999 /* values for random placement */ #define RANDOM_USE_PERCENTAGE 0 @@ -1047,7 +1049,7 @@ static struct }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(9), - 0, 255, + 0, 999, GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE, &level.score[SC_TIME_BONUS], @@ -1173,7 +1175,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), - 0, 255, + 0, 999, GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP, GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.push_delay_fixed, @@ -1181,7 +1183,7 @@ static struct }, { -1, ED_ELEMENT_SETTINGS_YPOS(7), - 0, 255, + 0, 999, GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP, GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP, &custom_element.push_delay_random, @@ -1189,7 +1191,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), - 0, 255, + 0, 999, GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP, GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.drop_delay_fixed, @@ -1197,7 +1199,7 @@ static struct }, { -1, ED_ELEMENT_SETTINGS_YPOS(8), - 0, 255, + 0, 999, GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP, GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP, &custom_element.drop_delay_random, @@ -1224,7 +1226,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12), - 0, 255, + 0, 999, GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP, GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE, &custom_element.explosion_delay, @@ -1232,7 +1234,7 @@ static struct }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), - 0, 255, + 0, 999, GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP, GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE, &custom_element.ignition_delay, @@ -2034,7 +2036,7 @@ static struct /* ---------- element settings: configure (several elements) ------------- */ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, -1, options_player_speed, @@ -2558,14 +2560,14 @@ static struct "can grow into anything diggable", "grow into more than just sand" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, &level.continuous_snapping, NULL, "continuos snapping", "use snapping without releasing key" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, &level.block_snap_field, NULL, @@ -2593,35 +2595,42 @@ static struct "no scrolling when relocating", "player gets relocated without delay" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_SHIFTED_RELOCATION, GADGET_ID_NONE, + &level.shifted_relocation, + NULL, + "no centering when relocating", "level not centered after relocation" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE, &level.use_start_element[0], NULL, "use level start element:", "start level at this element's position" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, &level.use_artwork_element[0], NULL, "use artwork from element:", "use player artwork from other element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, &level.use_explosion_element[0], NULL, "use explosion from element:", "use explosion properties from element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE, &level.initial_player_gravity[0], NULL, "use initial gravity", "set initial player gravity" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, &level.can_pass_to_walkable, NULL, @@ -2997,7 +3006,7 @@ static struct /* ---------- level start element ---------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(8), + -1, ED_AREA_1X1_SETTINGS_YPOS(9), GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, &level.start_element[0], 1, 1, NULL, NULL, NULL, "level start element" @@ -3006,7 +3015,7 @@ static struct /* ---------- player artwork element ------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(9), + -1, ED_AREA_1X1_SETTINGS_YPOS(10), GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, &level.artwork_element[0], 1, 1, NULL, NULL, NULL, "element for player artwork" @@ -3015,7 +3024,7 @@ static struct /* ---------- player explosion element ----------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(10), + -1, ED_AREA_1X1_SETTINGS_YPOS(11), GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, &level.explosion_element[0], 1, 1, NULL, NULL, NULL, "element for player explosion" @@ -3302,6 +3311,11 @@ static int editor_el_emerald_mine[] = EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + + EL_EM_EXIT_CLOSED, + EL_EM_EXIT_OPEN, + EL_EM_STEEL_EXIT_CLOSED, + EL_EM_STEEL_EXIT_OPEN, }; static int *editor_hl_emerald_mine_ptr = editor_hl_emerald_mine; static int *editor_el_emerald_mine_ptr = editor_el_emerald_mine; @@ -3633,25 +3647,25 @@ static int editor_el_diamond_caves[] = EL_SWITCHGATE_SWITCH_UP, EL_SWITCHGATE_SWITCH_DOWN, - EL_EMPTY, - EL_EMPTY, - EL_DC_SWITCHGATE_SWITCH_UP, - EL_DC_SWITCHGATE_SWITCH_DOWN, - - EL_SIGN_EXCLAMATION, - EL_SIGN_STOP, EL_LIGHT_SWITCH, EL_LIGHT_SWITCH_ACTIVE, + EL_DC_SWITCHGATE_SWITCH_UP, + EL_DC_SWITCHGATE_SWITCH_DOWN, + EL_STEEL_EXIT_CLOSED, + EL_STEEL_EXIT_OPEN, EL_STEELWALL_SLIPPERY, EL_INVISIBLE_SAND, + + EL_QUICKSAND_FAST_EMPTY, + EL_QUICKSAND_FAST_FULL, EL_LANDMINE, EL_DC_LANDMINE, EL_SHIELD_NORMAL, EL_SHIELD_DEADLY, EL_EXTRA_TIME, - EL_EMPTY, + EL_DC_MAGIC_WALL, EL_ENVELOPE_1, EL_ENVELOPE_2, @@ -3668,6 +3682,7 @@ static int editor_el_diamond_caves[] = EL_SIGN_EMERGENCY_EXIT, EL_SIGN_YIN_YANG, +#if 0 EL_SIGN_SPERMS, EL_SIGN_BULLET, EL_SIGN_HEART, @@ -3687,11 +3702,12 @@ static int editor_el_diamond_caves[] = EL_EMPTY, EL_EMPTY, EL_EMPTY, +#endif EL_DC_STEELWALL_2_SINGLE, EL_DC_STEELWALL_2_TOP, - EL_STEEL_EXIT_CLOSED, - EL_STEEL_EXIT_OPEN, + EL_SIGN_EXCLAMATION, + EL_SIGN_STOP, EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_MIDDLE, @@ -3701,52 +3717,32 @@ static int editor_el_diamond_caves[] = EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_2_VERTICAL, EL_DC_STEELWALL_1_TOPRIGHT, - EL_EMPTY, + EL_DC_GATE_WHITE, EL_DC_STEELWALL_1_VERTICAL, EL_DC_STEELWALL_2_BOTTOM, - EL_EMPTY, - EL_EMPTY, + EL_DC_KEY_WHITE, + EL_DC_GATE_WHITE_GRAY, EL_DC_STEELWALL_1_BOTTOMLEFT, EL_DC_STEELWALL_1_HORIZONTAL, EL_DC_STEELWALL_1_BOTTOMRIGHT, - EL_EMPTY, + EL_DC_GATE_FAKE_GRAY, EL_DC_STEELWALL_1_BOTTOMRIGHT_2, EL_DC_STEELWALL_1_BOTTOM, EL_DC_STEELWALL_1_BOTTOMLEFT_2, - EL_EMPTY, + EL_EXPANDABLE_STEELWALL_HORIZONTAL, EL_DC_STEELWALL_1_RIGHT, EL_EMPTY, EL_DC_STEELWALL_1_LEFT, - EL_EMPTY, + EL_EXPANDABLE_STEELWALL_VERTICAL, EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_TOP, EL_DC_STEELWALL_1_TOPLEFT_2, - EL_EMPTY, - - EL_EXPANDABLE_STEELWALL_HORIZONTAL, - EL_EXPANDABLE_STEELWALL_VERTICAL, EL_EXPANDABLE_STEELWALL_ANY, - EL_EMPTY, - - EL_EM_EXIT_CLOSED, - EL_EM_EXIT_OPEN, - EL_EM_STEEL_EXIT_CLOSED, - EL_EM_STEEL_EXIT_OPEN, - - EL_DC_KEY_WHITE, - EL_DC_GATE_WHITE, - EL_DC_GATE_WHITE_GRAY, - EL_DC_GATE_FAKE_GRAY, - - EL_DC_MAGIC_WALL, - EL_QUICKSAND_FAST_EMPTY, - EL_QUICKSAND_FAST_FULL, - EL_EMPTY, }; static int *editor_hl_diamond_caves_ptr = editor_hl_diamond_caves; static int *editor_el_diamond_caves_ptr = editor_el_diamond_caves; @@ -7004,6 +7000,11 @@ void CheckElementDescriptions() void DrawLevelEd() { CloseDoor(DOOR_CLOSE_ALL); + +#if 1 + FadeOut(REDRAW_FIELD); +#endif + OpenDoor(DOOR_OPEN_2 | DOOR_NO_DELAY); #if DEBUG @@ -7051,8 +7052,16 @@ void DrawLevelEd() #endif MapControlButtons(); +#if 0 + FadeOut(REDRAW_FIELD); +#endif + DrawEditModeWindow(); +#if 1 + FadeIn(REDRAW_FIELD); +#endif + /* copy actual editor door content to door double buffer for OpenDoor() */ BlitBitmap(drawto, bitmap_db_door, DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1); @@ -7309,7 +7318,7 @@ static void DrawDrawingWindow() stick_element_properties_window = FALSE; SetMainBackgroundImage(IMG_UNDEFINED); - ClearWindow(); + ClearField(); UnmapLevelEditorWindowGadgets(); UnmapLevelEditorToolboxCustomGadgets(); @@ -7332,7 +7341,7 @@ static void DrawLevelInfoWindow() stick_element_properties_window = FALSE; SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); - ClearWindow(); + ClearField(); UnmapLevelEditorWindowGadgets(); #if 0 @@ -8010,6 +8019,7 @@ static void DrawPropertiesConfig() MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_SHIFTED_RELOCATION); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT); @@ -8301,7 +8311,7 @@ static void DrawPropertiesWindow() MapLevelEditorToolboxCustomGadgets(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); - ClearWindow(); + ClearField(); #if 0 DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Element Settings"); @@ -8522,6 +8532,82 @@ static int getPillarFromOpenDirectionNotEmpty(int direction, int element_old) return (element_new != EL_EMPTY ? element_new : element_old); } +static int getOpenDirectionFromSteel2(int element) +{ + switch (element) + { + case EL_DC_STEELWALL_2_LEFT: return (MV_RIGHT); + case EL_DC_STEELWALL_2_RIGHT: return (MV_LEFT); + case EL_DC_STEELWALL_2_TOP: return (MV_DOWN); + case EL_DC_STEELWALL_2_BOTTOM: return (MV_UP); + case EL_DC_STEELWALL_2_HORIZONTAL: return (MV_HORIZONTAL); + case EL_DC_STEELWALL_2_VERTICAL: return (MV_VERTICAL); + case EL_DC_STEELWALL_2_MIDDLE: return (MV_ANY_DIRECTION); + case EL_DC_STEELWALL_2_SINGLE: return (MV_NONE); + } + + return MV_NONE; +} + +static int getSteel2FromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_RIGHT): return EL_DC_STEELWALL_2_LEFT; + case (MV_LEFT): return EL_DC_STEELWALL_2_RIGHT; + case (MV_DOWN): return EL_DC_STEELWALL_2_TOP; + case (MV_UP): return EL_DC_STEELWALL_2_BOTTOM; + case (MV_HORIZONTAL): return EL_DC_STEELWALL_2_HORIZONTAL; + case (MV_VERTICAL): return EL_DC_STEELWALL_2_VERTICAL; + case (MV_ANY_DIRECTION): return EL_DC_STEELWALL_2_MIDDLE; + case (MV_NONE): return EL_DC_STEELWALL_2_SINGLE; + } + + return EL_EMPTY; +} + +static int getSteel2FromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getSteel2FromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + +static int getOpenDirectionFromChip(int element) +{ + switch (element) + { + case EL_SP_CHIP_SINGLE: return (MV_NONE); + case EL_SP_CHIP_LEFT: return (MV_RIGHT); + case EL_SP_CHIP_RIGHT: return (MV_LEFT); + case EL_SP_CHIP_TOP: return (MV_DOWN); + case EL_SP_CHIP_BOTTOM: return (MV_UP); + } + + return MV_NONE; +} + +static int getChipFromOpenDirection(int direction) +{ + switch (direction) + { + case (MV_NONE): return EL_SP_CHIP_SINGLE; + case (MV_LEFT): return EL_SP_CHIP_RIGHT; + case (MV_RIGHT): return EL_SP_CHIP_LEFT; + case (MV_UP): return EL_SP_CHIP_BOTTOM; + case (MV_DOWN): return EL_SP_CHIP_TOP; + } + + return EL_EMPTY; +} + +static int getChipFromOpenDirectionNotEmpty(int direction, int element_old) +{ + int element_new = getChipFromOpenDirection(direction); + + return (element_new != EL_EMPTY ? element_new : element_old); +} + static int getClosedTube(int x, int y) { static int xy[4][2] = @@ -8532,8 +8618,8 @@ static int getClosedTube(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int tube_direction_old = getOpenDirectionFromTube(element_old); - int tube_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromTube(element_old); + int direction_new = MV_NONE; int i; for (i = 0; i < NUM_DIRECTIONS; i++) @@ -8544,12 +8630,12 @@ static int getClosedTube(int x, int y) int dir_opposite = MV_DIR_OPPOSITE(dir); if (IN_LEV_FIELD(xx, yy) && IS_TUBE(IntelliDrawBuffer[xx][yy]) && - (tube_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromTube(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - tube_direction_new |= dir; + direction_new |= dir; } - return getTubeFromOpenDirectionNotEmpty(tube_direction_new, element_old); + return getTubeFromOpenDirectionNotEmpty(direction_new, element_old); } static int getClosedBelt(int x, int y) @@ -8562,9 +8648,9 @@ static int getClosedBelt(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int belt_nr = getBeltNrFromBeltElement(element_old); - int belt_direction_old = getOpenDirectionFromBelt(element_old); - int belt_direction_new = MV_NONE; + int nr = getBeltNrFromBeltElement(element_old); + int direction_old = getOpenDirectionFromBelt(element_old); + int direction_new = MV_NONE; int i; for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) @@ -8575,12 +8661,12 @@ static int getClosedBelt(int x, int y) int dir_opposite = MV_DIR_OPPOSITE(dir); if (IN_LEV_FIELD(xx, yy) && IS_BELT(IntelliDrawBuffer[xx][yy]) && - (belt_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromBelt(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - belt_direction_new |= dir; + direction_new |= dir; } - return getBeltFromNrAndOpenDirection(belt_nr, belt_direction_new); + return getBeltFromNrAndOpenDirection(nr, direction_new); } static int getClosedPool(int x, int y) @@ -8593,8 +8679,8 @@ static int getClosedPool(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int pool_direction_old = getOpenDirectionFromPool(element_old); - int pool_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromPool(element_old); + int direction_new = MV_NONE; int i; for (i = 0; i < NUM_DIRECTIONS; i++) @@ -8606,12 +8692,12 @@ static int getClosedPool(int x, int y) if (IN_LEV_FIELD(xx, yy) && IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[xx][yy]) && - (pool_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromPool(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - pool_direction_new |= dir; + direction_new |= dir; } - return getPoolFromOpenDirectionNotEmpty(pool_direction_new, element_old); + return getPoolFromOpenDirectionNotEmpty(direction_new, element_old); } static int getClosedPillar(int x, int y) @@ -8624,8 +8710,8 @@ static int getClosedPillar(int x, int y) { 0, +1 } }; int element_old = IntelliDrawBuffer[x][y]; - int pillar_direction_old = getOpenDirectionFromPillar(element_old); - int pillar_direction_new = MV_NONE; + int direction_old = getOpenDirectionFromPillar(element_old); + int direction_new = MV_NONE; int i; for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) @@ -8636,12 +8722,72 @@ static int getClosedPillar(int x, int y) int dir_opposite = MV_DIR_OPPOSITE(dir); if (IN_LEV_FIELD(xx, yy) && IS_EMC_PILLAR(IntelliDrawBuffer[xx][yy]) && - (pillar_direction_old & dir) && + (direction_old & dir) && (getOpenDirectionFromPillar(IntelliDrawBuffer[xx][yy]) & dir_opposite)) - pillar_direction_new |= dir; + direction_new |= dir; + } + + return getPillarFromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedSteel2(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromSteel2(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_DC_STEELWALL_2(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromSteel2(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; } - return getPillarFromOpenDirectionNotEmpty(pillar_direction_new, element_old); + return getSteel2FromOpenDirectionNotEmpty(direction_new, element_old); +} + +static int getClosedChip(int x, int y) +{ + static int xy[4][2] = + { + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } + }; + int element_old = IntelliDrawBuffer[x][y]; + int direction_old = getOpenDirectionFromChip(element_old); + int direction_new = MV_NONE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + + if (IN_LEV_FIELD(xx, yy) && IS_SP_CHIP(IntelliDrawBuffer[xx][yy]) && + (direction_old & dir) && + (getOpenDirectionFromChip(IntelliDrawBuffer[xx][yy]) & dir_opposite)) + direction_new |= dir; + } + + return getChipFromOpenDirectionNotEmpty(direction_new, element_old); } static void SetElementSimple(int x, int y, int element, boolean change_level) @@ -8677,7 +8823,7 @@ static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, } static void SetElementIntelliDraw(int x, int y, int new_element, - boolean change_level) + boolean change_level, int button) { static int xy[4][2] = { @@ -8704,7 +8850,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is tube, keep all existing tube directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_TUBE(old_element)) direction |= getOpenDirectionFromTube(old_element); @@ -8730,28 +8876,10 @@ static void SetElementIntelliDraw(int x, int y, int new_element, new_element = getTubeFromOpenDirectionNotEmpty(direction, new_element); -#if 1 if (last_element_new != EL_UNDEFINED) MergeAndCloseNeighbourElements(x, y, &new_element, last_x, last_y, &last_element_new, getClosedTube, change_level); -#else - /* reduce connections of neighbour tube elements to minimal connections */ - if (last_element_new != EL_UNDEFINED) - { - /* set neighbour tube elements to newly determined tube connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); - - /* remove all open tube connections of neighbour tube elements */ - new_element = getClosedTube(x, y); - last_element_new = getClosedTube(last_x, last_y); - - /* set neighbour tube elements to new, minimized tube connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); - } -#endif } else if (IS_BELT(new_element)) { @@ -8760,7 +8888,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is belt, keep all existing belt directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_BELT(old_element)) direction |= getOpenDirectionFromBelt(old_element); @@ -8781,36 +8909,16 @@ static void SetElementIntelliDraw(int x, int y, int new_element, last_element_new = getBeltFromNrAndOpenDirection(last_belt_nr, last_direction_new); - direction |= dir; } } new_element = getBeltFromNrAndOpenDirectionNotEmpty(belt_nr, direction, new_element); - -#if 1 if (last_element_new != EL_UNDEFINED) MergeAndCloseNeighbourElements(x, y, &new_element, last_x, last_y, &last_element_new, getClosedBelt, change_level); -#else - /* reduce connections of neighbour belt elements to minimal connections */ - if (last_element_new != EL_UNDEFINED) - { - /* set neighbour belt elements to newly determined belt connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); - - /* remove all open belt connections of neighbour belt elements */ - new_element = getClosedBelt(x, y); - last_element_new = getClosedBelt(last_x, last_y); - - /* set neighbour belt elements to new, minimized belt connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); - } -#endif } else if (IS_ACID_POOL_OR_ACID(new_element)) { @@ -8818,7 +8926,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is pool, keep all existing pool directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_ACID_POOL_OR_ACID(old_element)) direction |= getOpenDirectionFromPool(old_element); @@ -8842,43 +8950,18 @@ static void SetElementIntelliDraw(int x, int y, int new_element, } } -#if 1 + /* special corrections needed for intuitively correct acid pool drawing */ if (last_element_new == EL_EMPTY) - last_element_new = EL_ACID; -#endif + last_element_new = new_element; + else if (last_element_new != EL_UNDEFINED) + new_element = last_element_new; -#if 1 - if (last_element_new != EL_UNDEFINED) - new_element = getPoolFromOpenDirectionNotEmpty(direction, - last_element_new); - else - new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); -#else new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); -#endif -#if 1 if (last_element_new != EL_UNDEFINED) MergeAndCloseNeighbourElements(x, y, &new_element, last_x, last_y, &last_element_new, getClosedPool, change_level); -#else - /* reduce connections of neighbour pool elements to minimal connections */ - if (last_element_new != EL_UNDEFINED) - { - /* set neighbour pool elements to newly determined pool connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); - - /* remove all open pool connections of neighbour pool elements */ - new_element = getClosedPool(x, y); - last_element_new = getClosedPool(last_x, last_y); - - /* set neighbour pool elements to new, minimized pool connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); - } -#endif } else if (IS_EMC_PILLAR(new_element)) { @@ -8886,7 +8969,7 @@ static void SetElementIntelliDraw(int x, int y, int new_element, int direction = MV_NONE; int i; - /* if existing element is pillar, keep all existing pillar directions */ + /* if old element is of same kind, keep all existing directions */ if (IS_EMC_PILLAR(old_element)) direction |= getOpenDirectionFromPillar(old_element); @@ -8912,28 +8995,131 @@ static void SetElementIntelliDraw(int x, int y, int new_element, new_element = getPillarFromOpenDirectionNotEmpty(direction, new_element); -#if 1 if (last_element_new != EL_UNDEFINED) MergeAndCloseNeighbourElements(x, y, &new_element, last_x, last_y, &last_element_new, getClosedPillar, change_level); -#else - /* reduce connections of neighbour pillar elements to minimal connections */ + } + else if (IS_DC_STEELWALL_2(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if old element is of same kind, keep all existing directions */ + if (IS_DC_STEELWALL_2(old_element)) + direction |= getOpenDirectionFromSteel2(old_element); + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromSteel2(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getSteel2FromOpenDirection(last_direction_new); + + direction |= dir; + } + } + + new_element = getSteel2FromOpenDirectionNotEmpty(direction, new_element); + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedSteel2, change_level); + } + else if (IS_SP_CHIP(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* (do not keep existing directions, regardless of kind of old element) */ + + for (i = 0; i < NUM_DIRECTIONS; i++) { - /* set neighbour pillar elements to newly determined pillar connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y])) + { + int dir = MV_DIR_FROM_BIT(i); + int dir_opposite = MV_DIR_OPPOSITE(dir); + int last_element_old = IntelliDrawBuffer[last_x][last_y]; + int last_direction_old = getOpenDirectionFromChip(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; - /* remove all open pillar connections of neighbour pillar elements */ - new_element = getClosedPillar(x, y); - last_element_new = getClosedPillar(last_x, last_y); + if (last_direction_old == MV_NONE) + { + last_element_new = getChipFromOpenDirection(last_direction_new); + direction |= dir; + } + else if (last_direction_old & (dir | dir_opposite)) + { + direction |= MV_DIR_OPPOSITE(last_direction_old); + } + else + { + direction |= MV_DIR_OPPOSITE(dir); + } + } + } + + new_element = getChipFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedChip, change_level); + } + else if (IS_SP_HARDWARE_BASE(new_element)) + { + int nr = GetSimpleRandom(6); + + new_element = (nr == 0 ? EL_SP_HARDWARE_BASE_1 : + nr == 1 ? EL_SP_HARDWARE_BASE_2 : + nr == 2 ? EL_SP_HARDWARE_BASE_3 : + nr == 3 ? EL_SP_HARDWARE_BASE_4 : + nr == 4 ? EL_SP_HARDWARE_BASE_5 : EL_SP_HARDWARE_BASE_6); + } + else if (new_element == EL_SP_HARDWARE_GREEN || + new_element == EL_SP_HARDWARE_BLUE || + new_element == EL_SP_HARDWARE_RED) + { + int nr = GetSimpleRandom(3); + + new_element = (nr == 0 ? EL_SP_HARDWARE_GREEN : + nr == 1 ? EL_SP_HARDWARE_BLUE : EL_SP_HARDWARE_RED); + } + else if (IS_GROUP_ELEMENT(new_element)) + { + boolean connected_drawing = FALSE; + int i; + + for (i = 0; i < NUM_DIRECTIONS; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; - /* set neighbour pillar elements to new, minimized pillar connections */ - SetElementSimple(x, y, new_element, change_level); - SetElementSimple(last_x, last_y, last_element_new, change_level); + if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && + IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element)) + connected_drawing = TRUE; } -#endif + + if (!connected_drawing) + ResolveGroupElement(new_element); + + new_element = GetElementFromGroupElement(new_element); } else if (IS_BELT_SWITCH(old_element)) { @@ -8992,7 +9178,107 @@ static void SetElementIntelliDraw(int x, int y, int new_element, { -1, -1 }, }; - int i; + static int rotatable_elements[][4] = + { + { + EL_BUG_UP, + EL_BUG_RIGHT, + EL_BUG_DOWN, + EL_BUG_LEFT + }, + + { + EL_SPACESHIP_UP, + EL_SPACESHIP_RIGHT, + EL_SPACESHIP_DOWN, + EL_SPACESHIP_LEFT + }, + + { + EL_BD_BUTTERFLY_UP, + EL_BD_BUTTERFLY_RIGHT, + EL_BD_BUTTERFLY_DOWN, + EL_BD_BUTTERFLY_LEFT + }, + + { + EL_BD_FIREFLY_UP, + EL_BD_FIREFLY_RIGHT, + EL_BD_FIREFLY_DOWN, + EL_BD_FIREFLY_LEFT + }, + + { + EL_PACMAN_UP, + EL_PACMAN_RIGHT, + EL_PACMAN_DOWN, + EL_PACMAN_LEFT + }, + + { + EL_YAMYAM_UP, + EL_YAMYAM_RIGHT, + EL_YAMYAM_DOWN, + EL_YAMYAM_LEFT + }, + + { + EL_ARROW_UP, + EL_ARROW_RIGHT, + EL_ARROW_DOWN, + EL_ARROW_LEFT + }, + + { + EL_SP_PORT_UP, + EL_SP_PORT_RIGHT, + EL_SP_PORT_DOWN, + EL_SP_PORT_LEFT + }, + + { + EL_SP_GRAVITY_PORT_UP, + EL_SP_GRAVITY_PORT_RIGHT, + EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_PORT_LEFT + }, + + { + EL_MOLE_UP, + EL_MOLE_RIGHT, + EL_MOLE_DOWN, + EL_MOLE_LEFT + }, + + { + EL_BALLOON_SWITCH_UP, + EL_BALLOON_SWITCH_RIGHT, + EL_BALLOON_SWITCH_DOWN, + EL_BALLOON_SWITCH_LEFT + }, + + { + EL_SP_GRAVITY_ON_PORT_UP, + EL_SP_GRAVITY_ON_PORT_RIGHT, + EL_SP_GRAVITY_ON_PORT_DOWN, + EL_SP_GRAVITY_ON_PORT_LEFT + }, + + { + EL_SP_GRAVITY_OFF_PORT_UP, + EL_SP_GRAVITY_OFF_PORT_RIGHT, + EL_SP_GRAVITY_OFF_PORT_DOWN, + EL_SP_GRAVITY_OFF_PORT_LEFT + }, + + { + -1, + -1, + -1, + -1, + }, + }; + int i, j; for (i = 0; swappable_elements[i][0] != -1; i++) { @@ -9002,6 +9288,20 @@ static void SetElementIntelliDraw(int x, int y, int new_element, if (old_element == element1 || old_element == element2) new_element = (old_element == element1 ? element2 : element1); } + + for (i = 0; rotatable_elements[i][0] != -1; i++) + { + for (j = 0; j < 4; j++) + { + int element = rotatable_elements[i][j]; + + if (old_element == element) + new_element = (button == 1 ? rotatable_elements[i][(j + 3) % 4] : + button == 2 ? rotatable_elements[i][0] : + button == 3 ? rotatable_elements[i][(j + 1) % 4] : + old_element); + } + } } SetElementSimple(x, y, new_element, change_level); @@ -9018,22 +9318,28 @@ static void ResetIntelliDraw() for (y = 0; y < lev_fieldy; y++) IntelliDrawBuffer[x][y] = Feld[x][y]; - SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE); + SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1); } -static void SetElementExt(int x, int y, int element, boolean change_level) +static void SetElementExt(int x, int y, int element, boolean change_level, + int button) { if (element < 0) SetElementSimple(x, y, Feld[x][y], change_level); else if (GetKeyModState() & KMOD_Shift) - SetElementIntelliDraw(x, y, element, change_level); + SetElementIntelliDraw(x, y, element, change_level, button); else SetElementSimple(x, y, element, change_level); } static void SetElement(int x, int y, int element) { - SetElementExt(x, y, element, TRUE); + SetElementExt(x, y, element, TRUE, -1); +} + +static void SetElementButton(int x, int y, int element, int button) +{ + SetElementExt(x, y, element, TRUE, button); } static void DrawLineElement(int sx, int sy, int element, boolean change_level) @@ -9041,7 +9347,7 @@ static void DrawLineElement(int sx, int sy, int element, boolean change_level) int lx = sx + level_xpos; int ly = sy + level_ypos; - SetElementExt(lx, ly, element, change_level); + SetElementExt(lx, ly, element, change_level, -1); } static void DrawLine(int from_x, int from_y, int to_x, int to_y, @@ -9586,6 +9892,10 @@ static void RandomPlacement(int new_element) int num_percentage, num_elements; int x, y; +#if 1 + ResetIntelliDraw(); +#endif + /* determine number of free positions for randomly placing the new element */ for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) { @@ -9609,20 +9919,28 @@ static void RandomPlacement(int new_element) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) if (free_position[x][y]) +#if 1 + SetElement(x, y, new_element); +#else Feld[x][y] = new_element; +#endif } else { while (num_elements > 0) { - x = RND(lev_fieldx); - y = RND(lev_fieldy); + x = GetSimpleRandom(lev_fieldx); + y = GetSimpleRandom(lev_fieldy); /* don't place element at the same position twice */ if (free_position[x][y]) { free_position[x][y] = FALSE; +#if 1 + SetElement(x, y, new_element); +#else Feld[x][y] = new_element; +#endif num_elements--; } } @@ -9791,7 +10109,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) } #if 1 - SetElement(lx, ly, new_element); + SetElementButton(lx, ly, new_element, button); #else Feld[lx][ly] = new_element; DrawMiniElement(sx, sy, new_element); @@ -10574,7 +10892,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_EXIT: - RequestExitLevelEditor(TRUE); /* if level has changed, ask user */ + RequestExitLevelEditor(TRUE, FALSE); /* if level has changed, ask user */ break; default: @@ -10753,7 +11071,7 @@ void HandleLevelEditorKeyInput(Key key) case KSYM_Escape: if (edit_mode == ED_MODE_DRAWING) { - RequestExitLevelEditor(setup.ask_on_escape_editor); + RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE); } else if (edit_mode == ED_MODE_INFO) { @@ -11024,7 +11342,8 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) DrawTextS(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, infotext); } -void RequestExitLevelEditor(boolean ask_if_level_has_changed) +void RequestExitLevelEditor(boolean ask_if_level_has_changed, + boolean quick_quit) { if (!ask_if_level_has_changed || !LevelChanged() || @@ -11033,8 +11352,21 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed) { CloseDoor(DOOR_CLOSE_1); SetDoorState(DOOR_CLOSE_2); + +#if 1 + if (quick_quit) + FadeSkipNextFadeIn(); +#else + if (quick_quit) + fading = fading_none; +#endif + game_status = GAME_MODE_MAIN; +#if 1 + DrawAndFadeInMainMenu(REDRAW_FIELD); +#else DrawMainMenu(); +#endif } else {