X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=23b2dfdcd04c294edf4b352eda39df86ed67730b;hb=db0cf963a41d958dc11ee1d3cfb2b1f88cba7f76;hp=1ec48e18f5c19486e62cd27a36a7ced35de26ab0;hpb=ba702cd338586991ab20176cf5587afbb4d77af7;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 1ec48e18..23b2dfdc 100644 --- a/src/editor.c +++ b/src/editor.c @@ -3119,7 +3119,11 @@ static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1; /* actual position of level editor drawing area in level playfield */ static int level_xpos = -1, level_ypos = -1; +#if 1 +#define IN_ED_FIELD(x,y) IN_FIELD(x, y, ed_fieldx, ed_fieldy) +#else #define IN_ED_FIELD(x,y) ((x)>=0 && (x)=0 &&(y) to_x) - swap_numbers(&from_x, &to_x); + if (new_element == EL_UNDEFINED) + { + last_x = -1; + last_y = -1; - for (x = from_x; x <= to_x; x++) - DrawLineElement(x, y, element, change_level); + return; } - else if (from_x == to_x) /* vertical line */ + + if (IS_TUBE(new_element)) { - int x = from_x; - int y; + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; - if (from_y > to_y) - swap_numbers(&from_y, &to_y); + /* if existing element is tube, keep all existing tube directions */ + if (IS_TUBE(old_element)) + direction |= getOpenDirectionFromTube(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_TUBE(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 = getOpenDirectionFromTube(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getTubeFromOpenDirection(last_direction_new); + + direction |= dir; + } + } - for (y = from_y; y <= to_y; y++) - DrawLineElement(x, y, element, change_level); + new_element = getTubeFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedTube, change_level); } - else /* diagonal line */ + else if (IS_BELT(new_element)) + { + int belt_nr = getBeltNrFromBeltElement(new_element); + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if existing element is belt, keep all existing belt directions */ + if (IS_BELT(old_element)) + direction |= getOpenDirectionFromBelt(old_element); + + for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; 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_BELT(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_belt_nr = getBeltNrFromBeltElement(last_element_old); + int last_direction_old = getOpenDirectionFromBelt(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getBeltFromNrAndOpenDirection(last_belt_nr, + last_direction_new); + direction |= dir; + } + } + + new_element = getBeltFromNrAndOpenDirectionNotEmpty(belt_nr, direction, + new_element); + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedBelt, change_level); + } + else if (IS_ACID_POOL_OR_ACID(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if existing element is pool, keep all existing pool directions */ + if (IS_ACID_POOL_OR_ACID(old_element)) + direction |= getOpenDirectionFromPool(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_ACID_POOL_OR_ACID(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 = getOpenDirectionFromPool(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getPoolFromOpenDirection(last_direction_new); + + direction |= dir; + } + } + +#if 1 + int foo = last_element_new; + + if (foo == EL_EMPTY) + foo = EL_ACID; + + if (last_element_new == EL_EMPTY) + last_element_new = old_element; + + if (last_element_new != EL_UNDEFINED) + new_element = getPoolFromOpenDirectionNotEmpty(direction, + foo); + else + new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element); + +#else + +#if 0 + if (last_element_new == EL_EMPTY) + last_element_new = new_element; +#else + if (last_element_new == EL_EMPTY) + last_element_new = EL_ACID; +#endif + +#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 + +#endif + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedPool, change_level); + } + else if (IS_EMC_PILLAR(new_element)) + { + int last_element_new = EL_UNDEFINED; + int direction = MV_NONE; + int i; + + /* if existing element is pillar, keep all existing pillar directions */ + if (IS_EMC_PILLAR(old_element)) + direction |= getOpenDirectionFromPillar(old_element); + + for (i = MV_BIT_UP; i <= MV_BIT_DOWN; 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_EMC_PILLAR(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 = getOpenDirectionFromPillar(last_element_old); + int last_direction_new = last_direction_old | dir_opposite; + + last_element_new = getPillarFromOpenDirection(last_direction_new); + + direction |= dir; + } + } + + new_element = getPillarFromOpenDirectionNotEmpty(direction, new_element); + + if (last_element_new != EL_UNDEFINED) + MergeAndCloseNeighbourElements(x, y, &new_element, + last_x, last_y, &last_element_new, + getClosedPillar, change_level); + } + else if (IS_BELT_SWITCH(old_element)) + { + int belt_nr = getBeltNrFromBeltSwitchElement(old_element); + int belt_dir = getBeltDirFromBeltSwitchElement(old_element); + + belt_dir = (belt_dir == MV_LEFT ? MV_NONE : + belt_dir == MV_NONE ? MV_RIGHT : MV_LEFT); + + new_element = getBeltSwitchElementFromBeltNrAndBeltDir(belt_nr, belt_dir); + } + else { - int len_x = ABS(to_x - from_x); - int len_y = ABS(to_y - from_y); - int x, y; + static int swappable_elements[][2] = + { + { EL_EXIT_CLOSED, EL_EXIT_OPEN }, + { EL_DYNAMITE, EL_DYNAMITE_ACTIVE }, + { EL_EM_DYNAMITE, EL_EM_DYNAMITE_ACTIVE }, + { EL_QUICKSAND_EMPTY, EL_QUICKSAND_FULL }, + { EL_EMERALD, EL_WALL_EMERALD }, + { EL_EMERALD_YELLOW, EL_WALL_EMERALD_YELLOW }, + { EL_EMERALD_RED, EL_WALL_EMERALD_RED }, + { EL_EMERALD_PURPLE, EL_WALL_EMERALD_PURPLE }, + { EL_DIAMOND, EL_WALL_DIAMOND }, + { EL_BD_DIAMOND, EL_WALL_BD_DIAMOND }, + { EL_GATE_1, EL_GATE_1_GRAY }, + { EL_GATE_2, EL_GATE_2_GRAY }, + { EL_GATE_3, EL_GATE_3_GRAY }, + { EL_GATE_4, EL_GATE_4_GRAY }, + { EL_EM_GATE_1, EL_EM_GATE_1_GRAY }, + { EL_EM_GATE_2, EL_EM_GATE_2_GRAY }, + { EL_EM_GATE_3, EL_EM_GATE_3_GRAY }, + { EL_EM_GATE_4, EL_EM_GATE_4_GRAY }, + { EL_EMC_GATE_5, EL_EMC_GATE_5_GRAY }, + { EL_EMC_GATE_6, EL_EMC_GATE_6_GRAY }, + { EL_EMC_GATE_7, EL_EMC_GATE_7_GRAY }, + { EL_EMC_GATE_8, EL_EMC_GATE_8_GRAY }, + { EL_DC_GATE_WHITE, EL_DC_GATE_WHITE_GRAY }, + { EL_TIME_ORB_EMPTY, EL_TIME_ORB_FULL }, + { EL_LAMP, EL_LAMP_ACTIVE }, + { EL_SOKOBAN_FIELD_EMPTY, EL_SOKOBAN_FIELD_FULL }, + { EL_SP_BASE, EL_SP_BUGGY_BASE }, + { EL_PEARL, EL_WALL_PEARL }, + { EL_CRYSTAL, EL_WALL_CRYSTAL }, + { EL_TIMEGATE_CLOSED, EL_TIMEGATE_OPEN }, + { EL_SWITCHGATE_CLOSED, EL_SWITCHGATE_OPEN }, + { EL_SWITCHGATE_SWITCH_UP, EL_SWITCHGATE_SWITCH_DOWN }, + { EL_DC_SWITCHGATE_SWITCH_UP, EL_DC_SWITCHGATE_SWITCH_DOWN }, + { EL_LIGHT_SWITCH, EL_LIGHT_SWITCH_ACTIVE }, + { EL_LANDMINE, EL_DC_LANDMINE }, + { EL_SHIELD_NORMAL, EL_SHIELD_DEADLY }, + { EL_STEEL_EXIT_CLOSED, EL_STEEL_EXIT_OPEN }, + { EL_EM_EXIT_CLOSED, EL_EM_EXIT_OPEN }, + { EL_EM_STEEL_EXIT_CLOSED, EL_EM_STEEL_EXIT_OPEN }, + { EL_QUICKSAND_FAST_EMPTY, EL_QUICKSAND_FAST_FULL }, + + { -1, -1 }, + }; + int i; - if (len_y < len_x) /* a < 1 */ + for (i = 0; swappable_elements[i][0] != -1; i++) { - float a = (float)len_y / (float)len_x; + int element1 = swappable_elements[i][0]; + int element2 = swappable_elements[i][1]; + + if (old_element == element1 || old_element == element2) + new_element = (old_element == element1 ? element2 : element1); + } + } + + SetElementSimple(x, y, new_element, change_level); + + last_x = x; + last_y = y; +} + +static void ResetIntelliDraw() +{ + int x, y; + + for (x = 0; x < lev_fieldx; x++) + for (y = 0; y < lev_fieldy; y++) + IntelliDrawBuffer[x][y] = Feld[x][y]; + + SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE); +} - if (from_x > to_x) - swap_number_pairs(&from_x, &from_y, &to_x, &to_y); +static void SetElementExt(int x, int y, int element, boolean change_level) +{ + if (element < 0) + SetElementSimple(x, y, Feld[x][y], change_level); + else if (GetKeyModState() & KMOD_Shift) + SetElementIntelliDraw(x, y, element, change_level); + else + SetElementSimple(x, y, element, change_level); +} + +static void SetElement(int x, int y, int element) +{ + SetElementExt(x, y, element, TRUE); +} + +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); +} + +static void DrawLine(int from_x, int from_y, int to_x, int to_y, + int element, boolean change_level) +{ + int xsize = ABS(to_x - from_x); + int ysize = ABS(to_y - from_y); + int dx = (to_x < from_x ? -1 : +1); + int dy = (to_y < from_y ? -1 : +1); + int i; - for (x = 0; x <= len_x; x++) + if (from_y == to_y) /* horizontal line */ + { + for (i = 0; i <= xsize; i++) + DrawLineElement(from_x + i * dx, from_y, element, change_level); + } + else if (from_x == to_x) /* vertical line */ + { + for (i = 0; i <= ysize; i++) + DrawLineElement(from_x, from_y + i * dy, element, change_level); + } + else /* diagonal line */ + { + if (ysize < xsize) /* a < 1 */ + { + float a = (float)ysize / (float)xsize; + + for (i = 0; i <= xsize; i++) { - y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1); + int x = dx * i; + int y = dy * (int)(a * i + 0.5); + DrawLineElement(from_x + x, from_y + y, element, change_level); } } else /* a >= 1 */ { - float a = (float)len_x / (float)len_y; - - if (from_y > to_y) - swap_number_pairs(&from_x, &from_y, &to_x, &to_y); + float a = (float)xsize / (float)ysize; - for (y = 0; y <= len_y; y++) + for (i = 0; i <= ysize; i++) { - x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1); + int x = dx * (int)(a * i + 0.5); + int y = dy * i; + DrawLineElement(from_x + x, from_y + y, element, change_level); } } @@ -8617,7 +9241,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, for (y = 0; y < brush_height; y++) { - for (x=0; x < brush_width; x++) + for (x = 0; x < brush_width; x++) { brush_buffer[x][y] = Feld[from_lx + x][from_ly + y]; @@ -9047,6 +9671,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) actual_drawing_function = GADGET_ID_PICK_ELEMENT; } + if (GetKeyModState() & KMOD_Shift) + { + if (button_press_event || button_release_event) + ResetIntelliDraw(); + } + switch (actual_drawing_function) { case GADGET_ID_SINGLE_ITEMS: @@ -9059,17 +9689,27 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !inside_drawing_area) DeleteBrushFromCursor(); + +#if 0 + ResetIntelliDraw(); +#endif } - if (!button) + if (!button || button_release_event) break; if (draw_with_brush) { +#if 0 if (!button_release_event) +#endif CopyBrushToLevel(sx, sy, button); } +#if 1 + else +#else else if (new_element != Feld[lx][ly]) +#endif { if (new_element == EL_PLAYER_1) { @@ -9080,18 +9720,30 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { if (Feld[x][y] == EL_PLAYER_1) { +#if 1 + SetElement(x, y, EL_EMPTY); +#else Feld[x][y] = EL_EMPTY; +#if 1 + if (IN_ED_FIELD(x - level_xpos, y - level_ypos)) + DrawMiniElement(x - level_xpos, y - level_ypos, EL_EMPTY); +#else if (x - level_xpos >= 0 && x - level_xpos < ed_fieldx && y - level_ypos >= 0 && y - level_ypos < ed_fieldy) - DrawMiniElement(x - level_xpos, y - level_ypos, - EL_EMPTY); + DrawMiniElement(x - level_xpos, y - level_ypos, EL_EMPTY); +#endif +#endif } } } } +#if 1 + SetElement(lx, ly, new_element); +#else Feld[lx][ly] = new_element; DrawMiniElement(sx, sy, new_element); +#endif } } else