X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Feditor.c;h=e5d956709d9408f9c96090a185d2677de2669727;hb=HEAD;hp=fc122b245a5e44ba39fb617ce8b1e79e32effd12;hpb=a0bf1f7caa9235d7f86898a216f0b8449bf08023;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index fc122b24..671ac61d 100644 --- a/src/editor.c +++ b/src/editor.c @@ -2465,6 +2465,7 @@ static struct ValueTextInfo options_group_choice_mode[] = { ANIM_LINEAR, "linear" }, { ANIM_PINGPONG, "pingpong" }, { ANIM_PINGPONG2, "pingpong 2" }, + { ANIM_LEVEL_NR, "level number" }, { -1, NULL } }; @@ -4697,8 +4698,8 @@ static int editor_el_deflektor[] = EL_DF_MIRROR_START, EL_DF_MIRROR_ROTATING_START, + EL_DF_MIRROR_FIXED_START, EL_DF_CELL, - EL_DF_MINE, EL_DF_FIBRE_OPTIC_RED_1, EL_DF_FIBRE_OPTIC_YELLOW_1, @@ -4713,7 +4714,12 @@ static int editor_el_deflektor[] = EL_DF_STEEL_WALL, EL_DF_WOODEN_WALL, EL_DF_REFRACTOR, - EL_EMPTY + EL_DF_MINE, + + EL_DF_SLOPE_1, + EL_DF_SLOPE_2, + EL_DF_SLOPE_3, + EL_DF_SLOPE_4 }; static int *editor_hl_deflektor_ptr = editor_hl_deflektor; static int *editor_el_deflektor_ptr = editor_el_deflektor; @@ -8912,8 +8918,8 @@ static void AdjustDrawingAreaGadgets(void) if (suppressBorderElement()) { - ed_xsize = max_ed_fieldx; - ed_ysize = max_ed_fieldy; + ed_xsize = lev_fieldx; + ed_ysize = lev_fieldy; } // check if we need any scrollbars @@ -11702,6 +11708,12 @@ static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element, EL_DF_RECEIVER_DOWN, EL_DF_RECEIVER_LEFT }, + { + EL_DF_SLOPE_1, + EL_DF_SLOPE_4, + EL_DF_SLOPE_3, + EL_DF_SLOPE_2 + }, { -1, @@ -11918,6 +11930,24 @@ static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element, EL_DF_MIRROR_ROTATING_3, EL_DF_MIRROR_ROTATING_2 }, + { + EL_DF_MIRROR_FIXED_1, + EL_DF_MIRROR_FIXED_16, + EL_DF_MIRROR_FIXED_15, + EL_DF_MIRROR_FIXED_14, + EL_DF_MIRROR_FIXED_13, + EL_DF_MIRROR_FIXED_12, + EL_DF_MIRROR_FIXED_11, + EL_DF_MIRROR_FIXED_10, + EL_DF_MIRROR_FIXED_9, + EL_DF_MIRROR_FIXED_8, + EL_DF_MIRROR_FIXED_7, + EL_DF_MIRROR_FIXED_6, + EL_DF_MIRROR_FIXED_5, + EL_DF_MIRROR_FIXED_4, + EL_DF_MIRROR_FIXED_3, + EL_DF_MIRROR_FIXED_2 + }, { -1, @@ -12025,19 +12055,10 @@ static boolean isHiresDrawElement(int element) static int numHiresTiles(int element) { - if (!IS_MM_WALL(element)) - return 1; - - int bits = MM_WALL_BITS(element); - int num_bits = 0; - - while (bits) - { - bits &= bits - 1; - num_bits++; - } + if (IS_MM_WALL(element)) + return get_number_of_bits(MM_WALL_BITS(element)); - return num_bits; + return 1; } static void SetDrawModeHiRes(int element) @@ -12327,6 +12348,9 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, #define CB_BRUSH_TO_CLIPBOARD 7 #define CB_BRUSH_TO_CLIPBOARD_SMALL 8 #define CB_UPDATE_BRUSH_POSITION 9 +#define CB_FLIP_BRUSH_X 10 +#define CB_FLIP_BRUSH_Y 11 +#define CB_FLIP_BRUSH_XY 12 #define MAX_CB_PART_SIZE 10 #define MAX_CB_LINE_SIZE (MAX_LEV_FIELDX + 1) // text plus newline @@ -12335,6 +12359,185 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, MAX_CB_NUM_LINES * \ MAX_CB_PART_SIZE) +static int getFlippedTileExt(int map[], int element) +{ + int i; + + for (i = 0; map[i] != -1; i++) + if (map[i] == element) + return map[i ^ 1]; // get flipped element by flipping LSB of index + + return element; +} + +static int getFlippedTileX(int element) +{ + int map[] = + { + EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT, + EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT, + EL_BUG_LEFT, EL_BUG_RIGHT, + EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT, + EL_PACMAN_LEFT, EL_PACMAN_RIGHT, + EL_ARROW_LEFT, EL_ARROW_RIGHT, + EL_MOLE_LEFT, EL_MOLE_RIGHT, + EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_RIGHT, + EL_YAMYAM_LEFT, EL_YAMYAM_RIGHT, + EL_SP_PORT_LEFT, EL_SP_PORT_RIGHT, + EL_SP_GRAVITY_PORT_LEFT, EL_SP_GRAVITY_PORT_RIGHT, + EL_SP_GRAVITY_ON_PORT_LEFT, EL_SP_GRAVITY_ON_PORT_RIGHT, + EL_SP_GRAVITY_OFF_PORT_LEFT, EL_SP_GRAVITY_OFF_PORT_RIGHT, + EL_CONVEYOR_BELT_1_LEFT, EL_CONVEYOR_BELT_1_RIGHT, + EL_CONVEYOR_BELT_2_LEFT, EL_CONVEYOR_BELT_2_RIGHT, + EL_CONVEYOR_BELT_3_LEFT, EL_CONVEYOR_BELT_3_RIGHT, + EL_CONVEYOR_BELT_4_LEFT, EL_CONVEYOR_BELT_4_RIGHT, + EL_SPRING_LEFT, EL_SPRING_RIGHT, + EL_SP_CHIP_LEFT, EL_SP_CHIP_RIGHT, + EL_TUBE_VERTICAL_LEFT, EL_TUBE_VERTICAL_RIGHT, + EL_TUBE_LEFT_UP, EL_TUBE_RIGHT_UP, + EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_DOWN, + EL_DC_STEELWALL_1_LEFT, EL_DC_STEELWALL_1_RIGHT, + EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_1_TOPRIGHT, + EL_DC_STEELWALL_1_BOTTOMLEFT, EL_DC_STEELWALL_1_BOTTOMRIGHT, + EL_DC_STEELWALL_1_TOPLEFT_2, EL_DC_STEELWALL_1_TOPRIGHT_2, + EL_DC_STEELWALL_1_BOTTOMLEFT_2, EL_DC_STEELWALL_1_BOTTOMRIGHT_2, + EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_RIGHT, + EL_ACID_POOL_TOPLEFT, EL_ACID_POOL_TOPRIGHT, + EL_ACID_POOL_BOTTOMLEFT, EL_ACID_POOL_BOTTOMRIGHT, + + -1 + }; + + return getFlippedTileExt(map, element); +} + +static int getFlippedTileY(int element) +{ + int map[] = + { + EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN, + EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN, + EL_BUG_UP, EL_BUG_DOWN, + EL_SPACESHIP_UP, EL_SPACESHIP_DOWN, + EL_PACMAN_UP, EL_PACMAN_DOWN, + EL_ARROW_UP, EL_ARROW_DOWN, + EL_MOLE_UP, EL_MOLE_DOWN, + EL_BALLOON_SWITCH_UP, EL_BALLOON_SWITCH_DOWN, + EL_YAMYAM_UP, EL_YAMYAM_DOWN, + EL_SP_PORT_UP, EL_SP_PORT_DOWN, + EL_SP_GRAVITY_PORT_UP, EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_ON_PORT_UP, EL_SP_GRAVITY_ON_PORT_DOWN, + EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, + EL_SP_CHIP_TOP, EL_SP_CHIP_BOTTOM, + EL_TUBE_HORIZONTAL_UP, EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_UP, EL_TUBE_LEFT_DOWN, + EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + EL_DC_STEELWALL_1_TOP, EL_DC_STEELWALL_1_BOTTOM, + EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_1_BOTTOMLEFT, + EL_DC_STEELWALL_1_TOPRIGHT, EL_DC_STEELWALL_1_BOTTOMRIGHT, + EL_DC_STEELWALL_1_TOPLEFT_2, EL_DC_STEELWALL_1_BOTTOMLEFT_2, + EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_BOTTOMRIGHT_2, + EL_DC_STEELWALL_2_TOP, EL_DC_STEELWALL_2_BOTTOM, + EL_EMC_WALL_1, EL_EMC_WALL_3, + + -1 + }; + + return getFlippedTileExt(map, element); +} + +static int getFlippedTileXY(int element) +{ + int map[] = + { + EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_UP, + EL_BD_BUTTERFLY_RIGHT, EL_BD_BUTTERFLY_DOWN, + EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_UP, + EL_BD_FIREFLY_RIGHT, EL_BD_FIREFLY_DOWN, + EL_BUG_LEFT, EL_BUG_UP, + EL_BUG_RIGHT, EL_BUG_DOWN, + EL_SPACESHIP_LEFT, EL_SPACESHIP_UP, + EL_SPACESHIP_RIGHT, EL_SPACESHIP_DOWN, + EL_PACMAN_LEFT, EL_PACMAN_UP, + EL_PACMAN_RIGHT, EL_PACMAN_DOWN, + EL_ARROW_LEFT, EL_ARROW_UP, + EL_ARROW_RIGHT, EL_ARROW_DOWN, + EL_MOLE_LEFT, EL_MOLE_UP, + EL_MOLE_RIGHT, EL_MOLE_DOWN, + EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_UP, + EL_BALLOON_SWITCH_RIGHT, EL_BALLOON_SWITCH_DOWN, + EL_YAMYAM_LEFT, EL_YAMYAM_UP, + EL_YAMYAM_RIGHT, EL_YAMYAM_DOWN, + EL_SP_PORT_LEFT, EL_SP_PORT_UP, + EL_SP_PORT_RIGHT, EL_SP_PORT_DOWN, + EL_SP_GRAVITY_PORT_LEFT, EL_SP_GRAVITY_PORT_UP, + EL_SP_GRAVITY_PORT_RIGHT, EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_ON_PORT_LEFT, EL_SP_GRAVITY_ON_PORT_UP, + EL_SP_GRAVITY_ON_PORT_RIGHT, EL_SP_GRAVITY_ON_PORT_DOWN, + EL_SP_GRAVITY_OFF_PORT_LEFT, EL_SP_GRAVITY_OFF_PORT_UP, + EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_DOWN, + EL_SP_CHIP_LEFT, EL_SP_CHIP_TOP, + EL_SP_CHIP_RIGHT, EL_SP_CHIP_BOTTOM, + EL_TUBE_VERTICAL, EL_TUBE_HORIZONTAL, + EL_TUBE_VERTICAL_LEFT, EL_TUBE_HORIZONTAL_UP, + EL_TUBE_VERTICAL_RIGHT, EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, + EL_DC_STEELWALL_1_LEFT, EL_DC_STEELWALL_1_TOP, + EL_DC_STEELWALL_1_RIGHT, EL_DC_STEELWALL_1_BOTTOM, + EL_DC_STEELWALL_1_HORIZONTAL, EL_DC_STEELWALL_1_VERTICAL, + EL_DC_STEELWALL_1_TOPRIGHT, EL_DC_STEELWALL_1_BOTTOMLEFT, + EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_BOTTOMLEFT_2, + EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_TOP, + EL_DC_STEELWALL_2_RIGHT, EL_DC_STEELWALL_2_BOTTOM, + EL_DC_STEELWALL_2_HORIZONTAL, EL_DC_STEELWALL_2_VERTICAL, + EL_EXPANDABLE_WALL_HORIZONTAL, EL_EXPANDABLE_WALL_VERTICAL, + EL_EXPANDABLE_STEELWALL_HORIZONTAL, EL_EXPANDABLE_STEELWALL_VERTICAL, + + -1 + }; + + return getFlippedTileExt(map, element); +} + +static int getFlippedTile(int element, int mode) +{ + if (IS_MM_ELEMENT(element)) + { + // get MM game element + element = map_element_RND_to_MM(element); + + // get flipped game element + element = (mode == CB_FLIP_BRUSH_X ? getFlippedTileX_MM(element) : + mode == CB_FLIP_BRUSH_Y ? getFlippedTileY_MM(element) : + mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY_MM(element) : + element); + + // get RND game element again + element = map_element_MM_to_RND(element); + } + else + { + // get flipped game element + element = (mode == CB_FLIP_BRUSH_X ? getFlippedTileX(element) : + mode == CB_FLIP_BRUSH_Y ? getFlippedTileY(element) : + mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY(element) : + element); + } + + return element; +} + +static void SwapFlippedTiles(short *tile1, short *tile2, int mode) +{ + // flip tiles + short tile1_flipped = getFlippedTile(*tile1, mode); + short tile2_flipped = getFlippedTile(*tile2, mode); + + // swap tiles + *tile1 = tile2_flipped; + *tile2 = tile1_flipped; +} + static void DrawBrushElement(int sx, int sy, int element, boolean change_level) { DrawLineElement(sx, sy, element, change_level); @@ -12695,6 +12898,37 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, delete_old_brush = TRUE; } + else if (mode == CB_FLIP_BRUSH_X) + { + for (y = 0; y < brush_height; y++) + for (x = 0; x < (brush_width + 1) / 2; x++) + SwapFlippedTiles(&brush_buffer[x][y], + &brush_buffer[brush_width - x - 1][y], mode); + + CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR); + } + else if (mode == CB_FLIP_BRUSH_Y) + { + for (y = 0; y < (brush_height + 1) / 2; y++) + for (x = 0; x < brush_width; x++) + SwapFlippedTiles(&brush_buffer[x][y], + &brush_buffer[x][brush_height - y - 1], mode); + + CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR); + } + else if (mode == CB_FLIP_BRUSH_XY) + { + CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR); + + for (y = 0; y < MAX(brush_width, brush_height); y++) + for (x = 0; x <= y; x++) + SwapFlippedTiles(&brush_buffer[x][y], + &brush_buffer[y][x], mode); + + swap_numbers(&brush_width, &brush_height); + + CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR); + } if (mode == CB_UPDATE_BRUSH_POSITION) { @@ -12729,6 +12963,22 @@ static void DeleteBrushFromCursor(void) CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR); } +static void FlipBrushX(void) +{ + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X); +} + +static void FlipBrushY(void) +{ + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_Y); +} + +static void RotateBrush(void) +{ + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_XY); + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X); +} + void DumpBrush(void) { CopyBrushExt(0, 0, 0, 0, 0, CB_DUMP_BRUSH); @@ -13057,7 +13307,8 @@ static void WrapLevel(int dx, int dy) CopyLevelToUndoBuffer(UNDO_ACCUMULATE); } -static void DrawAreaElementHighlight(boolean highlighted) +static void DrawAreaElementHighlight(boolean highlighted, + boolean highlighted_similar) { DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); @@ -13070,26 +13321,69 @@ static void DrawAreaElementHighlight(boolean highlighted) { for (y = 0; y < ed_fieldy; y++) { + boolean highlight = FALSE; int lx = x + level_xpos; int ly = y + level_ypos; if (!IN_LEV_FIELD(lx, ly)) continue; - if (Tile[lx][ly] != new_element1) + // check if element is the same + if (Tile[lx][ly] == new_element1) + highlight = TRUE; + + // check if element is similar + if (highlighted_similar && + strEqual(element_info[Tile[lx][ly]].class_name, + element_info[new_element1].class_name)) + highlight = TRUE; + + // check if element is matching MM style wall + if (IS_MM_WALL(Tile[lx][ly]) && + map_mm_wall_element(Tile[lx][ly]) == new_element1) + highlight = TRUE; + + if (!highlight) continue; - int sx = SX + x * ed_tilesize; - int sy = SY + y * ed_tilesize; - int from_sx = sx; - int from_sy = sy; - int to_sx = sx + ed_tilesize - 1; - int to_sy = sy + ed_tilesize - 1; - - DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); - DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); - DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy); - DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy); + if (IS_MM_WALL(Tile[lx][ly]) && !highlighted_similar) + { + int i; + + for (i = 0; i < 4; i++) + { + if (!(MM_WALL_BITS(Tile[lx][ly]) & (1 << i))) + continue; + + int xx = x * 2 + (i % 2); + int yy = y * 2 + (i / 2); + int sx = SX + xx * ed_tilesize / 2; + int sy = SY + yy * ed_tilesize / 2; + int from_sx = sx; + int from_sy = sy; + int to_sx = sx + ed_tilesize / 2 - 1; + int to_sy = sy + ed_tilesize / 2 - 1; + + DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); + DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); + DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy); + DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy); + } + } + else + { + int sx = SX + x * ed_tilesize; + int sy = SY + y * ed_tilesize; + int from_sx = sx; + int from_sy = sy; + int to_sx = sx + ed_tilesize - 1; + int to_sy = sy + ed_tilesize - 1; + + DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); + DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); + DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy); + DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy); + } } } } @@ -14669,6 +14963,16 @@ void HandleLevelEditorKeyInput(Key key) if (letter && letter == controlbutton_info[i].shortcut) if (!anyTextGadgetActive()) ClickOnGadget(level_editor_gadget[i], button); + + if (draw_with_brush) + { + if (letter == 'x') + FlipBrushX(); + else if (letter == 'y') + FlipBrushY(); + else if (letter == 'z') + RotateBrush(); + } } static void HandleLevelEditorIdle_Properties(void) @@ -14702,16 +15006,20 @@ static void HandleLevelEditorIdle_Properties(void) static void HandleLevelEditorIdle_Drawing(void) { static boolean last_highlighted = FALSE; + static boolean last_highlighted_similar = FALSE; boolean highlighted = (GetKeyModState() & KMOD_Alt); + boolean highlighted_similar = (GetKeyModState() & KMOD_Shift); - if (highlighted != last_highlighted) + if (highlighted != last_highlighted || + (highlighted && highlighted_similar != last_highlighted_similar)) { - DrawAreaElementHighlight(highlighted); - - last_highlighted = highlighted; + DrawAreaElementHighlight(highlighted, highlighted_similar); redraw_mask |= REDRAW_FIELD; } + + last_highlighted = highlighted; + last_highlighted_similar = highlighted_similar; } void HandleLevelEditorIdle(void) @@ -14975,7 +15283,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed, vp_door_2->height == VYSIZE) CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); else - SetDoorState(DOOR_CLOSE_2); + SetDoorState(DOOR_CLOSE_ALL); BackToFront();