diff --git a/Client/CentrED.lpi b/Client/CentrED.lpi
index 2207538..4efae26 100644
--- a/Client/CentrED.lpi
+++ b/Client/CentrED.lpi
@@ -56,7 +56,7 @@
-
+
@@ -268,6 +268,11 @@
+
+
+
+
+
diff --git a/Client/CentrED.lpr b/Client/CentrED.lpr
index dd85129..515bcdb 100644
--- a/Client/CentrED.lpr
+++ b/Client/CentrED.lpr
@@ -40,7 +40,7 @@ uses
UfrmLargeScaleCommand, UfrmVirtualLayer, UfrmFilter, UfrmTileInfo,
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
- Logging, UMap, UWorldItem, UStatics;
+ Logging, UMap, UWorldItem, UStatics, UTiledata;
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}
diff --git a/Client/UfrmMain.pas b/Client/UfrmMain.pas
index 768795c..8083ec2 100644
--- a/Client/UfrmMain.pas
+++ b/Client/UfrmMain.pas
@@ -541,7 +541,6 @@ var
z: ShortInt;
blockInfo: PBlockInfo;
targetRect: TRect;
- tileX, tileY: Word;
offsetX, offsetY: Integer;
tile: TWorldItem;
targetTiles: TWorldItemList;
@@ -1738,7 +1737,7 @@ var
item: TWorldItem;
drawX, drawY: Single;
west, south, east: Single;
- z: SmallInt;
+ z, rawZ: SmallInt;
staticItem: TStaticItem;
begin
//add normals to map tiles and materials where possible
@@ -1748,9 +1747,14 @@ begin
GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
if acFlat.Checked then
- z := 0
- else
+ begin
+ z := 0;
+ rawZ := 0;
+ end else
+ begin
z := item.Z;
+ rawZ := item.RawZ;
+ end;
if item is TMapCell then
begin
@@ -1768,7 +1772,7 @@ begin
end;
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial(item.TileID);
- ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44);
+ ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - rawZ * 4), 44, 44);
if ABlockInfo^.HighRes <> nil then
begin
@@ -2074,9 +2078,6 @@ end;
procedure TfrmMain.ProcessToolState;
var
- node: PVirtualNode;
- tileInfo: PTileInfo;
- i: Integer;
blockInfo: PBlockInfo;
begin
if acSelect.Checked then
@@ -2098,40 +2099,6 @@ begin
oglGameWindow.Cursor := crHandPoint;
end;
- if acDraw.Checked then
- begin
- tileInfo := nil;
- if frmDrawSettings.rbTileList.Checked then
- begin
- node := vdtTiles.GetFirstSelected;
- if node <> nil then
- tileInfo := vdtTiles.GetNodeData(node);
- end else if frmDrawSettings.rbRandom.Checked then
- begin
- node := vdtRandom.GetFirst;
- for i := 1 to Random(vdtRandom.RootNodeCount) do
- node := vdtRandom.GetNext(node);
-
- if node <> nil then
- tileInfo := vdtRandom.GetNodeData(node);
- end;
-
- if tileInfo <> nil then
- begin
- //TODO Update Ghost Tile
- {if tileInfo^.ID < $4000 then
- begin
- FGhostTile := TMapCell.Create(nil, nil, 0, 0);
- FGhostTile.TileID := tileInfo^.ID;
- end else
- begin
- FGhostTile := TStaticItem.Create(nil, nil, 0, 0);
- FGhostTile.TileID := tileInfo^.ID - $4000;
- TStaticItem(FGhostTile).Hue := frmHueSettings.lbHue.ItemIndex;
- end;}
- end;
- end;
-
FRepaintNeeded := True;
end;
@@ -2286,9 +2253,6 @@ begin
end;
procedure TfrmMain.UpdateSelection;
-var
- selectedRect: TRect;
- blockInfo: PBlockInfo;
procedure SetHighlight(ABlockInfo: PBlockInfo; AHighlighted: Boolean);
begin
@@ -2310,27 +2274,136 @@ var
end;
end;
+ procedure AddGhostTile(AX, AY: Word);
+ var
+ blockInfo: PBlockInfo;
+ tileInfo: PTileInfo;
+ node: PVirtualNode;
+ cell: TMapCell;
+ i: Integer;
+ begin
+ tileInfo := nil;
+ if frmDrawSettings.rbTileList.Checked then
+ begin
+ node := vdtTiles.GetFirstSelected;
+ if node <> nil then
+ tileInfo := vdtTiles.GetNodeData(node);
+ end else if frmDrawSettings.rbRandom.Checked then
+ begin
+ node := vdtRandom.GetFirst;
+ for i := 1 to Random(vdtRandom.RootNodeCount) do
+ node := vdtRandom.GetNext(node);
+
+ if node <> nil then
+ tileInfo := vdtRandom.GetNodeData(node);
+ end;
+
+ if tileInfo <> nil then
+ begin
+ //TODO Update Ghost Tile
+ if tileInfo^.ID < $4000 then
+ begin
+ cell := FLandscape.MapCell[AX, AY];
+ if cell <> nil then
+ begin
+ cell.IsGhost := True;
+ cell.GhostID := tileInfo^.ID;
+ {if (FGhostTile is TStaticItem) and (not frmDrawSettings.cbForceAltitude.Checked) then
+ begin
+ FGhostTile.Z := CurrentTile.Z;
+ if CurrentTile is TStaticItem then
+ Inc(FGhostTile.Z, ResMan.Tiledata.StaticTiles[CurrentTile.TileID].Height);
+ end else}
+ if frmDrawSettings.cbForceAltitude.Checked then
+ cell.GhostZ := frmDrawSettings.seForceAltitude.Value
+ else
+ cell.GhostZ := cell.RawZ;
+
+ OnMapChanged(cell);
+ end;
+ end else
+ begin
+ {FGhostTile := TStaticItem.Create(nil, nil, 0, 0);
+ FGhostTile.TileID := tileInfo^.ID - $4000;
+ TStaticItem(FGhostTile).Hue := frmHueSettings.lbHue.ItemIndex;}
+ end;
+
+ end;
+ end;
+
+var
+ selectedRect: TRect;
+ blockInfo: PBlockInfo;
+ item: TWorldItem;
+ cell: TMapCell;
+ i, tileX, tileY: Integer;
begin
Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection');
- selectedRect := Rect(-1, -1, -1, -1);
+ if CurrentTile = nil then
+ selectedRect := Rect(-1, -1, -1, -1)
+ else
+ selectedRect := GetSelectedRect;
+
+ //clean up old ghost tiles
+ Logger.Send([lcClient, lcDebug], 'Cleaning ghost tiles');
+ for i := FVirtualTiles.Count - 1 downto 0 do
+ begin
+ item := FVirtualTiles[i];
+ if (item is TGhostTile) and not IsInRect(item.X, item.Y, selectedRect) then
+ begin
+ FScreenBuffer.Delete(item);
+ FVirtualTiles.Delete(i);
+ end;
+ end;
+ Logger.Send([lcClient, lcDebug], 'FSelection', FSelection);
+ if FSelection.Left > -1 then
+ for tileX := FSelection.Left to FSelection.Right do
+ for tileY := FSelection.Top to FSelection.Bottom do
+ if not IsInRect(tileX, tileY, selectedRect) then
+ begin
+ cell := FLandscape.MapCell[tileX, tileY];
+ if (cell <> nil) and cell.IsGhost then
+ begin
+ cell.IsGhost := False;
+ OnMapChanged(cell);
+ end;
+ end;
+
if (CurrentTile <> nil) and (not acSelect.Checked) then
begin
+ if acDraw.Checked then
+ begin
+ if FSelection.Left = -1 then
+ begin
+ FSelection := Rect(CurrentTile.X - 1, CurrentTile.Y - 1,
+ CurrentTile.X - 1, CurrentTile.Y - 1);
+ AddGhostTile(CurrentTile.X, CurrentTile.Y);
+ end else
+ begin
+ //set new ghost tiles
+ for tileX := selectedRect.Left to selectedRect.Right do
+ for tileY := selectedRect.Top to selectedRect.Bottom do
+ if not IsInRect(tileX, tileY, FSelection) then
+ AddGhostTile(tileX, tileY);
+ end;
+ end;
+
blockInfo := nil;
if (SelectedTile <> nil) and (CurrentTile <> SelectedTile) then
begin
Logger.Send([lcClient, lcDebug], 'Multiple Targets');
- selectedRect := GetSelectedRect;
Logger.Send([lcClient, lcDebug], 'SelectedRect', selectedRect);
while FScreenBuffer.Iterate(blockInfo) do
if (blockInfo^.State = ssNormal) then
SetHighlight(blockInfo, IsInRect(blockInfo^.Item.X, blockInfo^.Item.Y,
- selectedRect));
+ selectedRect) and not acDraw.Checked);
end else
begin
Logger.Send([lcClient, lcDebug], 'Single Target');
while FScreenBuffer.Iterate(blockInfo) do
if blockInfo^.State = ssNormal then
- SetHighlight(blockInfo, (blockInfo^.Item = CurrentTile));
+ SetHighlight(blockInfo, (blockInfo^.Item = CurrentTile) and
+ not acDraw.Checked);
end;
end;
FSelection := selectedRect;
diff --git a/UOLib/UMap.pas b/UOLib/UMap.pas
index 5558c79..0c788fd 100644
--- a/UOLib/UMap.pas
+++ b/UOLib/UMap.pas
@@ -43,11 +43,21 @@ type
TMapCell = class(TWorldItem)
constructor Create(AOwner: TWorldBlock; AData: TStream; AX, AY: Word); overload;
constructor Create(AOwner: TWorldBlock; AData: TStream); overload;
+ protected
+ FIsGhost: Boolean;
+ FGhostZ: ShortInt;
+ FGhostID: Word;
+ function GetTileID: Word; override;
+ function GetZ: ShortInt; override;
+ public
+ property Altitude: ShortInt read GetZ write SetZ;
+ property IsGhost: Boolean read FIsGhost write FIsGhost;
+ property GhostZ: ShortInt write FGhostZ;
+ property GhostID: Word write FGhostID;
+
function Clone: TMapCell; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
- public
- property Altitude: ShortInt read FZ write FZ;
end;
TMapCellList = specialize TFPGObjectList;
@@ -58,14 +68,14 @@ type
constructor Create(AData: TStream; AX, AY: Word); overload;
constructor Create(AData: TStream); overload;
destructor Destroy; override;
- function Clone: TMapBlock; override;
- function GetSize: Integer; override;
- procedure Write(AData: TStream); override;
protected
FHeader: LongInt;
public
Cells: array[0..63] of TMapCell;
property Header: LongInt read FHeader write FHeader;
+ function Clone: TMapBlock; override;
+ function GetSize: Integer; override;
+ procedure Write(AData: TStream); override;
end;
function GetMapCellOffset(ABlock: Integer): Integer;
@@ -87,13 +97,17 @@ end;
constructor TMapCell.Create(AOwner: TWorldBlock; AData: TStream; AX, AY: Word);
begin
inherited Create(AOwner);
+
FX := AX;
FY := AY;
- if assigned(AData) then
+ if AData <> nil then
begin
AData.Read(FTileID, SizeOf(Word));
AData.Read(FZ, SizeOf(ShortInt));
end;
+
+ FIsGhost := False;
+
InitOriginalState;
end;
@@ -102,6 +116,22 @@ begin
Create(AOwner, AData, 0, 0);
end;
+function TMapCell.GetTileID: Word;
+begin
+ if FIsGhost then
+ Result := FGhostID
+ else
+ Result := FTileID;
+end;
+
+function TMapCell.GetZ: ShortInt;
+begin
+ if FIsGhost then
+ Result := FGhostZ
+ else
+ Result := FZ;
+end;
+
function TMapCell.Clone: TMapCell;
begin
Result := TMapCell.Create(nil, nil);
diff --git a/UOLib/UWorldItem.pas b/UOLib/UWorldItem.pas
index 35e716b..e7cf718 100644
--- a/UOLib/UWorldItem.pas
+++ b/UOLib/UWorldItem.pas
@@ -52,6 +52,8 @@ type
FPriority: Integer;
FPriorityBonus: ShortInt;
FPrioritySolver: Integer;
+ function GetTileID: Word; virtual;
+ function GetZ: ShortInt; virtual;
procedure SetTileID(ATileID: Word);
procedure SetX(AX: Word);
procedure SetY(AY: Word);
@@ -65,11 +67,12 @@ type
procedure UpdatePos(AX, AY: Word; AZ: ShortInt);
procedure Delete;
procedure InitOriginalState; virtual;
+
property Owner: TWorldBlock read FOwner write SetOwner;
- property TileID: Word read FTileID write SetTileID;
+ property TileID: Word read GetTileID write SetTileID;
property X: Word read FX write SetX;
property Y: Word read FY write SetY;
- property Z: ShortInt read FZ write SetZ;
+ property Z: ShortInt read GetZ write SetZ;
property Selected: Boolean read FSelected write SetSelected;
property CanBeEdited: Boolean read FCanBeEdited write FCanBeEdited;
property Locked: Boolean read FLocked write SetLocked;
@@ -77,6 +80,9 @@ type
property Priority: Integer read FPriority write FPriority;
property PriorityBonus: ShortInt read FPriorityBonus write FPriorityBonus;
property PrioritySolver: Integer read FPrioritySolver write FPrioritySolver;
+
+ property RawTileID: Word read FTileID;
+ property RawZ: ShortInt read FZ;
end;
TWorldItemList = specialize TFPGObjectList;
@@ -151,6 +157,16 @@ begin
FOwner := AOwner;
end;
+function TWorldItem.GetTileID: Word;
+begin
+ Result := FTileID;
+end;
+
+function TWorldItem.GetZ: ShortInt;
+begin
+ Result := FZ;
+end;
+
procedure TWorldItem.Delete;
begin
SetSelected(False);