Changeset 100


Ignore:
Timestamp:
Dec 26, 2014, 8:10:40 PM (10 years ago)
Author:
chronos
Message:
  • Added: Support for autogeneration of bridges between separated areas.
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Forms/UFormMain.lfm

    r97 r100  
    55  Width = 775
    66  Caption = 'xTactics'
    7   ClientHeight = 592
     7  ClientHeight = 595
    88  ClientWidth = 775
    99  Menu = MainMenu1
     
    1818  object StatusBar1: TStatusBar
    1919    Left = 0
    20     Height = 29
    21     Top = 563
     20    Height = 26
     21    Top = 569
    2222    Width = 775
    2323    Panels = <   
     
    3535  object ToolBar1: TToolBar
    3636    Left = 0
    37     Height = 563
     37    Height = 569
    3838    Top = 0
    3939    Width = 40
     
    7373    object ToolButton6: TToolButton
    7474      Left = 1
    75       Top = 172
     75      Top = 194
    7676      Action = AZoomIn
    7777    end
    7878    object ToolButton7: TToolButton
    7979      Left = 1
    80       Top = 204
     80      Top = 226
    8181      Action = AZoomOut
    8282    end
    8383    object ToolButton8: TToolButton
    8484      Left = 1
    85       Top = 236
     85      Top = 258
    8686      Action = AZoomAll
    8787    end
    8888    object ToolButton9: TToolButton
    8989      Left = 1
     90      Height = 32
    9091      Top = 162
    9192      Width = 32
     
    9495    object ToolButton10: TToolButton
    9596      Left = 1
    96       Top = 268
     97      Height = 32
     98      Top = 290
    9799      Width = 32
    98100      Style = tbsSeparator
     
    100102    object ToolButton11: TToolButton
    101103      Left = 1
    102       Top = 278
     104      Top = 322
    103105      Action = Core.AGameLoad
    104106    end
    105107    object ToolButton12: TToolButton
    106108      Left = 1
    107       Top = 310
     109      Top = 354
    108110      Action = Core.AGameSave
    109111    end
    110112    object ToolButton13: TToolButton
    111113      Left = 1
    112       Top = 342
     114      Top = 386
    113115      Action = Core.AExit
    114116    end
     
    116118  object PaintBox1: TPaintBox
    117119    Left = 40
    118     Height = 563
     120    Height = 569
    119121    Top = 0
    120122    Width = 735
    121123    Align = alClient
    122124    OnMouseDown = PaintBox1MouseDown
     125    OnMouseLeave = PaintBox1MouseLeave
    123126    OnMouseMove = PaintBox1MouseMove
    124127    OnMouseUp = PaintBox1MouseUp
    125     OnMouseLeave = PaintBox1MouseLeave
    126128    OnMouseWheelDown = PaintBox1MouseWheelDown
    127129    OnMouseWheelUp = PaintBox1MouseWheelUp
  • trunk/Forms/UFormMain.pas

    r97 r100  
    171171    PaintBox1.Repaint;
    172172    StatusBar1.Panels[1].Text := IntToStr(Trunc(DrawDuration / OneMillisecond)) + ' / ' +
    173       IntToStr(Trunc(TimerPeriod / OneMillisecond)) + ' ms';
     173      IntToStr(Trunc(TimerPeriod / OneMillisecond)) + ' ms' +
     174      ' ' + IntToStr(Core.Game.Map.CellLinks.Count);
    174175    NewCaption := 'xTactics';
    175176    if Assigned(Core.Game.CurrentPlayer) then
  • trunk/Forms/UFormNew.lfm

    r98 r100  
    4949      object ListView1: TListView
    5050        Left = 4
    51         Height = 364
     51        Height = 367
    5252        Top = 4
    5353        Width = 1207
     
    8888        Left = 224
    8989        Height = 25
    90         Top = 376
     90        Top = 379
    9191        Width = 83
    9292        Action = APlayerRemove
     
    9797        Left = 16
    9898        Height = 25
    99         Top = 376
     99        Top = 379
    100100        Width = 83
    101101        Action = APlayerAdd
     
    106106        Left = 120
    107107        Height = 25
    108         Top = 376
     108        Top = 379
    109109        Width = 83
    110110        Action = APlayerModify
     
    330330        Caption = 'Image file:'
    331331        ParentColor = False
     332      end
     333      object CheckBoxBridges: TCheckBox
     334        Left = 8
     335        Height = 24
     336        Top = 310
     337        Width = 204
     338        Caption = 'Bridges between cells'
     339        TabOrder = 14
    332340      end
    333341    end
     
    361369      object Label6: TLabel
    362370        Left = 8
    363         Height = 25
     371        Height = 22
    364372        Top = 248
    365         Width = 129
     373        Width = 116
    366374        Caption = 'Win objective:'
    367375        ParentColor = False
     
    369377      object ComboBoxWinObjective: TComboBox
    370378        Left = 232
    371         Height = 33
     379        Height = 30
    372380        Top = 240
    373381        Width = 328
  • trunk/Forms/UFormNew.lrt

    r82 r100  
    2121TFORMNEW.BUTTONIMAGEBROWSE.CAPTION=Browse
    2222TFORMNEW.LABEL9.CAPTION=Image file:
     23TFORMNEW.CHECKBOXBRIDGES.CAPTION=Bridges between cells
    2324TFORMNEW.TABSHEET3.CAPTION=Rules
    2425TFORMNEW.RADIOGROUPGROWCELLS.CAPTION=Growing cells
  • trunk/Forms/UFormNew.pas

    r91 r100  
    2424    ButtonPlayerModify: TButton;
    2525    ButtonPlayerRemove: TButton;
     26    CheckBoxBridges: TCheckBox;
    2627    CheckBoxFogOfWar: TCheckBox;
    2728    CheckBoxCity: TCheckBox;
     
    354355  EditImageFile.Text := Game.MapImageFileName;
    355356  CheckBoxFogOfWar.Checked := Game.FogOfWar;
     357  CheckBoxBridges.Checked := Game.BridgeEnabled;
    356358end;
    357359
     
    383385  Game.MapImageFileName := EditImageFile.Text;
    384386  Game.FogOfWar := CheckBoxFogOfWar.Checked;
     387  Game.BridgeEnabled := CheckBoxBridges.Checked;
    385388end;
    386389
  • trunk/Languages/xtactics.cs.po

    r99 r100  
    267267msgstr "Nová hra"
    268268
     269#: tformnew.checkboxbridges.caption
     270msgid "Bridges between cells"
     271msgstr "Mosty mezi buňkami"
     272
    269273#: tformnew.checkboxcity.caption
    270274msgid "Cities"
     
    420424#: tformsettings.checkbox2.caption
    421425msgid "Automatic DPI"
    422 msgstr ""
     426msgstr "Automatické DPI"
    423427
    424428#: tformsettings.checkboxdevelmode.caption
     
    441445#: tformsettings.label4.caption
    442446msgid "DPI:"
    443 msgstr ""
     447msgstr "DPI:"
    444448
    445449#: tformsettings.label5.caption
    446450msgid "x"
    447 msgstr ""
     451msgstr "x"
    448452
    449453#: tformsettings.tabsheetdebug.caption
    450454msgid "Debug"
    451 msgstr ""
     455msgstr "Ladění"
    452456
    453457#: tformsettings.tabsheetgeneral.caption
    454458msgid "General"
    455 msgstr ""
     459msgstr "Obecné"
    456460
    457461#: ucore.sendgame
     
    578582#: uformplayer.sagronotattacking
    579583msgid "Not attacking"
    580 msgstr ""
     584msgstr "Neútočící"
    581585
    582586#: uformplayer.scomputer
     
    627631#: ugame.szerozoomnotalowed
    628632msgid "Zero zoom not allowed"
    629 msgstr ""
    630 
     633msgstr "Nulové přiblížení není povoleno"
  • trunk/Languages/xtactics.po

    r99 r100  
    255255msgstr ""
    256256
     257#: tformnew.checkboxbridges.caption
     258msgid "Bridges between cells"
     259msgstr ""
     260
    257261#: tformnew.checkboxcity.caption
    258262msgid "Cities"
  • trunk/UCore.pas

    r99 r100  
    359359    //ApplyToAll(DesignDPI);
    360360    FormNew.Show;
     361    FormNew.Hide;
    361362    for I := 0 to Screen.FormCount - 1 do begin
    362363      StoreDimensions(Screen.Forms[I], StoredDimension);
    363364      ScaleDimensions(Screen.Forms[I], StoredDimension);
    364365    end;
    365     FormNew.Hide;
    366366    ScaleImageList(Core.ImageListSmall, DesignDPI);
    367367    ScaleImageList(Core.ImageListLarge, DesignDPI);
  • trunk/UGame.pas

    r96 r100  
    2626  TCells = class;
    2727  TMap = class;
     28  TCellLinks = class;
     29  TMapArea = class;
    2830
    2931  TFloatPoint = record
     
    3941  TCell = class
    4042  private
     43    FArea: TMapArea;
    4144    FMap: TMap;
    4245    FPower: Integer;
     46    procedure SetArea(AValue: TMapArea);
    4347    procedure SetPower(AValue: Integer);
    4448  public
     
    5458    Neighbors: TCells;
    5559    Mark: Boolean;
     60    procedure AreaExtend;
    5661    procedure FixRefId;
    5762    procedure LoadFromNode(Node: TDOMNode);
     
    6671    property Power: Integer read FPower write SetPower;
    6772    property Map: TMap read FMap write FMap;
     73    property Area: TMapArea read FArea write SetArea;
    6874  end;
    6975
     
    7884    procedure LoadFromNode(Node: TDOMNode);
    7985    procedure SaveToNode(Node: TDOMNode);
     86    procedure ClearMark;
     87  end;
     88
     89  TCellLink = class
     90    Points: array of TPoint;
     91    Cell1: TCell;
     92    Cell2: TCell;
     93  end;
     94
     95  TCellLinks = class(TObjectList)
     96
    8097  end;
    8198
     
    116133  TMapShape = (msRectangle, msImage);
    117134
     135  { TMapArea }
     136
     137  TMapArea = class
     138    Id: Integer;
     139    Map: TMap;
     140    BridgeCount: Integer;
     141    Cells: TCells;
     142    procedure GetBorderCells(List: TCells);
     143    constructor Create;
     144    destructor Destroy; override;
     145  end;
     146
     147  TMapAreas = class(TObjectList)
     148
     149  end;
     150
    118151  { TMap }
    119152
     
    136169    Shape: TMapShape;
    137170    Image: TImage;
     171    CellLinks: TCellLinks;
     172    Areas: TMapAreas;
    138173    function IsOutsideShape(Coord: TPoint): Boolean; virtual;
    139174    function IsCellsNeighbor(Cell1, Cell2: TCell): Boolean; virtual;
     
    357392    procedure UpdateRepeatMoves(Player: TPlayer);
    358393    procedure CheckCounterMove(Move: TUnitMove);
     394    function SearchDifferentCellArea(List: TCells; SourceArea, DestArea: TMapArea): TCell;
     395    procedure BuildTerrain;
     396    procedure BuildBridges;
     397    procedure BuildMapAreas;
    359398  public
    360399    Players: TPlayers;
     
    377416    FileName: string;
    378417    FogOfWar: Boolean;
     418    BridgeEnabled: Boolean;
    379419    function AttackProbability(AttackCount, DefendCount: Integer): Double;
    380420    procedure LoadConfig(Config: TXmlConfig; Path: string);
     
    499539end;
    500540
     541{ TMapArea }
     542
     543procedure TMapArea.GetBorderCells(List: TCells);
     544var
     545  I: Integer;
     546  J: Integer;
     547  NeighVoidCount: Integer;
     548begin
     549  List.Clear;
     550
     551  // Unset mark for all cells
     552  for I := 0 to Map.Cells.Count - 1 do
     553    TCell(Map.Cells[I]).Mark := False;
     554
     555  for I := 0 to Cells.Count - 1 do
     556  with TCell(Cells[I]) do begin
     557    NeighVoidCount := 0;
     558    for J := 0 to Neighbors.Count - 1 do
     559    with TCell(Neighbors[J]) do
     560      if (Terrain = ttVoid) then Inc(NeighVoidCount);
     561
     562    if (NeighVoidCount > 0) and (Area = Self) and (not Mark) then begin
     563        List.Add(TCell(Self.Cells[I]));
     564        Mark := True;
     565      end;
     566  end;
     567end;
     568
     569constructor TMapArea.Create;
     570begin
     571  Cells := TCells.Create;
     572  Cells.OwnsObjects := False;
     573end;
     574
     575destructor TMapArea.Destroy;
     576begin
     577  Cells.Free;
     578  inherited Destroy;
     579end;
     580
    501581{ TPlayerCell }
    502582
     
    641721  try
    642722    Lock;
     723    // Draw cell links
     724    Pen.Color := clBlack;
     725    Pen.Style := psSolid;
     726    Pen.Width := 3;
     727    for C := 0 to Player.Game.Map.CellLinks.Count - 1 do
     728    with TCellLink(Player.Game.Map.CellLinks[C]) do begin
     729      if Length(Points) >= 2 then begin
     730        MoveTo(View.CellToCanvasPos(Points[0]));
     731        for I := 1 to Length(Points) - 1 do
     732          LineTo(View.CellToCanvasPos(Points[I]));
     733      end;
     734    end;
     735
     736    // Draw cells
    643737    for C := 0 to Cells.Count - 1 do begin
    644738      Cell := TPlayerCell(Cells[C]);
     
    769863end;
    770864
     865procedure TCells.ClearMark;
     866var
     867  I: Integer;
     868begin
     869  for I := 0 to Count - 1 do
     870    TCell(Items[I]).Mark := False;
     871end;
     872
    771873{ TPlayers }
    772874
     
    9571059
    9581060  // Generate neighbours
    959   for Y := 0 to self.FSize.Y - 1 do
     1061  for Y := 0 to Self.FSize.Y - 1 do
    9601062  for X := 0 to FSize.X - 1 do
    9611063  with TCell(Cells[Y * FSize.X + X]) do begin
     
    12881390  I: Integer;
    12891391  NewCell: TCell;
    1290   NeighCells: TCellArray;
    12911392begin
    12921393  // Free previous
     
    13131414  Size := Point(0, 0);
    13141415  Image := TImage.Create(nil);
     1416  CellLinks := TCellLinks.Create;
     1417  Areas := TMapAreas.Create;
    13151418end;
    13161419
    13171420destructor TMap.Destroy;
    13181421begin
     1422  Areas.Free;
     1423  CellLinks.Free;
    13191424  Image.Free;
    13201425  Size := Point(0, 0);
     
    14671572    raise Exception.Create('Not allowed to substract power under zero do negative value');
    14681573  FPower := AValue;
     1574end;
     1575
     1576procedure TCell.SetArea(AValue: TMapArea);
     1577begin
     1578  if FArea = AValue then Exit;
     1579  if Assigned(FArea) then FArea.Cells.Remove(Self);
     1580  FArea := AValue;
     1581  if Assigned(FArea) then FArea.Cells.Add(Self);
     1582end;
     1583
     1584procedure TCell.AreaExtend;
     1585var
     1586  I: Integer;
     1587begin
     1588  for I := 0 to Neighbors.Count - 1 do
     1589  with TCell(Neighbors[I]) do
     1590  if (Terrain <> ttVoid) and (not Assigned(Area)) then begin
     1591    Area := Self.Area;
     1592    AreaExtend;
     1593  end;
    14691594end;
    14701595
     
    23852510end;
    23862511
     2512function TGame.SearchDifferentCellArea(List: TCells; SourceArea, DestArea: TMapArea): TCell;
     2513var
     2514  NewList: TCells;
     2515  NewListVoid: TCells;
     2516  I: Integer;
     2517  C: Integer;
     2518begin
     2519  Result := nil;
     2520  NewList := TCells.Create;
     2521  NewList.OwnsObjects := False;
     2522  NewListVoid := TCells.Create;
     2523  NewListVoid.OwnsObjects := False;
     2524
     2525  for C := 0 to List.Count - 1 do
     2526  with TCell(List[C]) do begin
     2527    for I := 0 to Neighbors.Count - 1 do
     2528    with TCell(Neighbors[I]) do
     2529    if (not Mark) and (Terrain <> ttVoid) and (Area <> SourceArea) and ((DestArea = nil) or (DestArea = Area)) then begin
     2530      NewList.Add(TCell(TCell(List[C]).Neighbors[I]));
     2531      Mark := True;
     2532    end else
     2533    if (not Mark) and (Terrain = ttVoid) then begin
     2534      NewListVoid.Add(TCell(TCell(List[C]).Neighbors[I]));
     2535      Mark := True;
     2536    end;
     2537  end;
     2538
     2539  if NewList.Count > 0 then begin
     2540    // We found cell with different area
     2541    Result := TCell(NewList[Random(NewList.Count)]);
     2542  end else
     2543  if NewListVoid.Count > 0 then begin
     2544    // Cell was not found but we have more void cells to check
     2545    Result := SearchDifferentCellArea(NewListVoid, SourceArea, DestArea);
     2546  end;
     2547
     2548  NewListVoid.Free;
     2549  NewList.Free;
     2550end;
     2551
     2552procedure TGame.BuildTerrain;
     2553var
     2554  C: Integer;
     2555begin
     2556  if (Map.Shape = msImage) and FileExists(MapImageFileName) and
     2557  (LoadedImageFileName <> MapImageFileName) then begin
     2558    LoadedImageFileName := MapImageFileName;
     2559    Map.Image.Picture.LoadFromFile(MapImageFileName);
     2560  end;
     2561
     2562  // Randomize map terrain
     2563  for C := 0 to Map.Cells.Count - 1 do
     2564  with TCell(Map.Cells[C]) do begin
     2565    if (VoidEnabled and (Random < VoidPercentage / 100)) or
     2566    (Map.IsOutsideShape(PosPx)) then Terrain := ttVoid
     2567      else begin
     2568        if CityEnabled and (Random < CityPercentage / 100) then Terrain := ttCity
     2569          else Terrain := ttNormal;
     2570      end;
     2571    Power := Random(MaxNeutralUnits + 1);
     2572    Player := nil;
     2573  end;
     2574end;
     2575
     2576procedure TGame.BuildBridges;
     2577var
     2578  List: TCells;
     2579  Cell: TCell;
     2580  FoundCell1: TCell;
     2581  FoundCell2: TCell;
     2582  I: Integer;
     2583  J: Integer;
     2584  NewLink: TCellLink;
     2585begin
     2586  // Build area bridges
     2587  if Map.Areas.Count > 1 then
     2588  for I := 0 to Map.Areas.Count - 1 do
     2589  with TMapArea(Map.Areas[I]) do begin
     2590    List := TCells.Create;
     2591    List.OwnsObjects := False;
     2592    GetBorderCells(List);
     2593    Cell := TCell(List[Random(List.Count)]);
     2594    List.Clear;
     2595    List.Add(Cell);
     2596
     2597    Map.Cells.ClearMark;
     2598
     2599    // Find nearest cell with different area
     2600    FoundCell1 := SearchDifferentCellArea(List, TMapArea(Map.Areas[I]), nil);
     2601    if Assigned(FoundCell1) then begin
     2602      // Again find back nearest cell with different area.
     2603      // This will ensure that both cells are closest ones
     2604
     2605      Map.Cells.ClearMark;
     2606      List[0] := FoundCell1;
     2607      FoundCell2 := SearchDifferentCellArea(List, FoundCell1.Area, TMapArea(Map.Areas[I]));
     2608      if Assigned(FoundCell2) then begin
     2609        FoundCell1.Neighbors.Add(FoundCell2);
     2610        FoundCell2.Neighbors.Add(FoundCell1);
     2611        NewLink := TCellLink.Create;
     2612        SetLength(NewLink.Points, 2);
     2613        NewLink.Cell1 := FoundCell2;
     2614        NewLink.Points[0] := FoundCell2.PosPx;
     2615        NewLink.Cell2 := FoundCell1;
     2616        NewLink.Points[1] := FoundCell1.PosPx;
     2617        Map.CellLinks.Add(NewLink);
     2618        Inc(BridgeCount);
     2619      end;
     2620    end;
     2621
     2622    List.Free;
     2623  end;
     2624end;
     2625
     2626procedure TGame.BuildMapAreas;
     2627var
     2628  C: Integer;
     2629  NewArea: TMapArea;
     2630begin
     2631  for C := 0 to Map.Cells.Count - 1 do
     2632  with TCell(Map.Cells[C]) do
     2633    Area := nil;
     2634  Map.Areas.Clear;
     2635  for C := 0 to Map.Cells.Count - 1 do
     2636  with TCell(Map.Cells[C]) do
     2637  if (Terrain <> ttVoid) and (not Assigned(Area)) then begin
     2638    NewArea := TMapArea(Map.Areas[Map.Areas.Add(TMapArea.Create)]);
     2639    NewArea.Id := Map.Areas.Count;
     2640    NewArea.Map := Map;
     2641    Area := NewArea;
     2642    AreaExtend;
     2643  end;
     2644end;
     2645
    23872646procedure TGame.SaveConfig(Config: TXmlConfig; Path: string);
    23882647begin
     
    23992658    SetValue(Path + '/CityEnabled', CityEnabled);
    24002659    SetValue(Path + '/CityPercentage', CityPercentage);
     2660    SetValue(Path + '/BridgeEnabled', BridgeEnabled);
    24012661    SetValue(Path + '/GrowAmount', Integer(GrowAmount));
    24022662    SetValue(Path + '/GrowCells', Integer(GrowCells));
     
    24212681    CityEnabled := GetValue(Path + '/CityEnabled', False);
    24222682    CityPercentage := GetValue(Path + '/CityPercentage', 10);
     2683    BridgeEnabled := GetValue(Path + '/BridgeEnabled', True);
    24232684    GrowAmount := TGrowAmount(GetValue(Path + '/GrowAmount', Integer(gaBySquareRoot)));
    24242685    GrowCells := TGrowCells(GetValue(Path + '/GrowCells', Integer(gcPlayerAll)));
     
    24502711      CityEnabled := ReadBoolean(RootNode, 'CityEnabled', False);
    24512712      CityPercentage := ReadInteger(RootNode, 'CityPercentage', 0);
     2713      BridgeEnabled := ReadBoolean(RootNode, 'BridgeEnabled', False);
    24522714      TurnCounter := ReadInteger(RootNode, 'TurnCounter', 0);
    24532715      WinObjective := TWinObjective(ReadInteger(RootNode, 'WinObjective', Integer(woDefeatAllOponents)));
     
    25032765      WriteBoolean(RootNode, 'CityEnabled', CityEnabled);
    25042766      WriteInteger(RootNode, 'CityPercentage', CityPercentage);
     2767      WriteBoolean(RootNode, 'BridgeEnabled', BridgeEnabled);
    25052768      WriteInteger(RootNode, 'TurnCounter', TurnCounter);
    25062769      WriteInteger(RootNode, 'WinObjective', Integer(WinObjective));
     
    26552918  Counter: Integer;
    26562919  C: Integer;
     2920  LastAreaCount: Integer;
    26572921begin
    26582922  FileName := SNewGameFile;
    26592923  TurnCounter := 1;
    26602924  Moves.Clear;
    2661   if (Map.Shape = msImage) and FileExists(MapImageFileName) and
    2662   (LoadedImageFileName <> MapImageFileName) then begin
    2663     LoadedImageFileName := MapImageFileName;
    2664     Map.Image.Picture.LoadFromFile(MapImageFileName);
    2665   end;
    2666   for C := 0 to Map.Cells.Count - 1 do
    2667   with TCell(Map.Cells[C]) do begin
    2668     if (VoidEnabled and (Random < VoidPercentage / 100)) or
    2669     (Map.IsOutsideShape(PosPx)) then Terrain := ttVoid
    2670       else begin
    2671         if CityEnabled and (Random < CityPercentage / 100) then Terrain := ttCity
    2672           else Terrain := ttNormal;
    2673       end;
    2674     Power := Random(MaxNeutralUnits + 1);
    2675     Player := nil;
     2925
     2926  BuildTerrain;
     2927  if BridgeEnabled then begin
     2928    // Connect all areas to all cells be accessible
     2929    for I := 0 to Map.CellLinks.Count - 1 do
     2930    with TCellLink(Map.CellLinks[I]) do begin
     2931      Cell1.Neighbors.Remove(Cell2);
     2932      Cell2.Neighbors.Remove(Cell1);
     2933    end;
     2934    Map.CellLinks.Clear;
     2935    BuildMapAreas;
     2936    LastAreaCount := -1;
     2937    while (Map.Areas.Count > 1) and (Map.Areas.Count <> LastAreaCount) do begin
     2938      LastAreaCount := Map.Areas.Count;
     2939      BuildBridges;
     2940      BuildMapAreas;
     2941    end;
    26762942  end;
    26772943
     
    28193085  try
    28203086    Lock;
     3087
     3088    // Draw cell links
     3089    Pen.Color := clBlack;
     3090    Pen.Style := psSolid;
     3091    Pen.Width := 3;
     3092    for C := 0 to CellLinks.Count - 1 do
     3093    with TCellLink(CellLinks[C]) do begin
     3094      if Length(Points) >= 2 then begin
     3095        MoveTo(Points[0]);
     3096        for I := 1 to Length(Points) - 1 do
     3097          LineTo(Points[I]);
     3098      end;
     3099    end;
     3100
     3101    // Draw cells
    28213102    for C := 0 to Cells.Count - 1 do begin
    28223103      Cell := TCell(Cells[C]);
Note: See TracChangeset for help on using the changeset viewer.