- Added virtual getters for Z and TileID to TWorldItem

- Added ghost information to TMap
- Added ghost tiles (currently for map tiles only)
This commit is contained in:
Andreas Schneider 2009-12-04 00:58:59 +01:00
parent 2fdbc698ac
commit be9d56f7c9
5 changed files with 183 additions and 59 deletions

View File

@ -56,7 +56,7 @@
<MinVersion Major="4" Minor="5" Release="1" Valid="True"/> <MinVersion Major="4" Minor="5" Release="1" Valid="True"/>
</Item5> </Item5>
</RequiredPackages> </RequiredPackages>
<Units Count="34"> <Units Count="35">
<Unit0> <Unit0>
<Filename Value="CentrED.lpr"/> <Filename Value="CentrED.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -268,6 +268,11 @@
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="UMap"/> <UnitName Value="UMap"/>
</Unit33> </Unit33>
<Unit34>
<Filename Value="../UOLib/UTiledata.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="UTiledata"/>
</Unit34>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -40,7 +40,7 @@ uses
UfrmLargeScaleCommand, UfrmVirtualLayer, UfrmFilter, UfrmTileInfo, UfrmLargeScaleCommand, UfrmVirtualLayer, UfrmFilter, UfrmTileInfo,
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets, UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow, UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
Logging, UMap, UWorldItem, UStatics; Logging, UMap, UWorldItem, UStatics, UTiledata;
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF} {$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}

View File

@ -541,7 +541,6 @@ var
z: ShortInt; z: ShortInt;
blockInfo: PBlockInfo; blockInfo: PBlockInfo;
targetRect: TRect; targetRect: TRect;
tileX, tileY: Word;
offsetX, offsetY: Integer; offsetX, offsetY: Integer;
tile: TWorldItem; tile: TWorldItem;
targetTiles: TWorldItemList; targetTiles: TWorldItemList;
@ -1738,7 +1737,7 @@ var
item: TWorldItem; item: TWorldItem;
drawX, drawY: Single; drawX, drawY: Single;
west, south, east: Single; west, south, east: Single;
z: SmallInt; z, rawZ: SmallInt;
staticItem: TStaticItem; staticItem: TStaticItem;
begin begin
//add normals to map tiles and materials where possible //add normals to map tiles and materials where possible
@ -1748,9 +1747,14 @@ begin
GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY); GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
if acFlat.Checked then if acFlat.Checked then
z := 0 begin
else z := 0;
rawZ := 0;
end else
begin
z := item.Z; z := item.Z;
rawZ := item.RawZ;
end;
if item is TMapCell then if item is TMapCell then
begin begin
@ -1768,7 +1772,7 @@ begin
end; end;
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial(item.TileID); 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 if ABlockInfo^.HighRes <> nil then
begin begin
@ -2074,9 +2078,6 @@ end;
procedure TfrmMain.ProcessToolState; procedure TfrmMain.ProcessToolState;
var var
node: PVirtualNode;
tileInfo: PTileInfo;
i: Integer;
blockInfo: PBlockInfo; blockInfo: PBlockInfo;
begin begin
if acSelect.Checked then if acSelect.Checked then
@ -2098,40 +2099,6 @@ begin
oglGameWindow.Cursor := crHandPoint; oglGameWindow.Cursor := crHandPoint;
end; 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; FRepaintNeeded := True;
end; end;
@ -2286,9 +2253,6 @@ begin
end; end;
procedure TfrmMain.UpdateSelection; procedure TfrmMain.UpdateSelection;
var
selectedRect: TRect;
blockInfo: PBlockInfo;
procedure SetHighlight(ABlockInfo: PBlockInfo; AHighlighted: Boolean); procedure SetHighlight(ABlockInfo: PBlockInfo; AHighlighted: Boolean);
begin begin
@ -2310,27 +2274,136 @@ var
end; end;
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 begin
Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection'); 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 if (CurrentTile <> nil) and (not acSelect.Checked) then
begin 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; blockInfo := nil;
if (SelectedTile <> nil) and (CurrentTile <> SelectedTile) then if (SelectedTile <> nil) and (CurrentTile <> SelectedTile) then
begin begin
Logger.Send([lcClient, lcDebug], 'Multiple Targets'); Logger.Send([lcClient, lcDebug], 'Multiple Targets');
selectedRect := GetSelectedRect;
Logger.Send([lcClient, lcDebug], 'SelectedRect', selectedRect); Logger.Send([lcClient, lcDebug], 'SelectedRect', selectedRect);
while FScreenBuffer.Iterate(blockInfo) do while FScreenBuffer.Iterate(blockInfo) do
if (blockInfo^.State = ssNormal) then if (blockInfo^.State = ssNormal) then
SetHighlight(blockInfo, IsInRect(blockInfo^.Item.X, blockInfo^.Item.Y, SetHighlight(blockInfo, IsInRect(blockInfo^.Item.X, blockInfo^.Item.Y,
selectedRect)); selectedRect) and not acDraw.Checked);
end else end else
begin begin
Logger.Send([lcClient, lcDebug], 'Single Target'); Logger.Send([lcClient, lcDebug], 'Single Target');
while FScreenBuffer.Iterate(blockInfo) do while FScreenBuffer.Iterate(blockInfo) do
if blockInfo^.State = ssNormal then if blockInfo^.State = ssNormal then
SetHighlight(blockInfo, (blockInfo^.Item = CurrentTile)); SetHighlight(blockInfo, (blockInfo^.Item = CurrentTile) and
not acDraw.Checked);
end; end;
end; end;
FSelection := selectedRect; FSelection := selectedRect;

View File

@ -43,11 +43,21 @@ type
TMapCell = class(TWorldItem) TMapCell = class(TWorldItem)
constructor Create(AOwner: TWorldBlock; AData: TStream; AX, AY: Word); overload; constructor Create(AOwner: TWorldBlock; AData: TStream; AX, AY: Word); overload;
constructor Create(AOwner: TWorldBlock; AData: TStream); 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 Clone: TMapCell; override;
function GetSize: Integer; override; function GetSize: Integer; override;
procedure Write(AData: TStream); override; procedure Write(AData: TStream); override;
public
property Altitude: ShortInt read FZ write FZ;
end; end;
TMapCellList = specialize TFPGObjectList<TMapCell>; TMapCellList = specialize TFPGObjectList<TMapCell>;
@ -58,14 +68,14 @@ type
constructor Create(AData: TStream; AX, AY: Word); overload; constructor Create(AData: TStream; AX, AY: Word); overload;
constructor Create(AData: TStream); overload; constructor Create(AData: TStream); overload;
destructor Destroy; override; destructor Destroy; override;
function Clone: TMapBlock; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
protected protected
FHeader: LongInt; FHeader: LongInt;
public public
Cells: array[0..63] of TMapCell; Cells: array[0..63] of TMapCell;
property Header: LongInt read FHeader write FHeader; property Header: LongInt read FHeader write FHeader;
function Clone: TMapBlock; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
end; end;
function GetMapCellOffset(ABlock: Integer): Integer; function GetMapCellOffset(ABlock: Integer): Integer;
@ -87,13 +97,17 @@ end;
constructor TMapCell.Create(AOwner: TWorldBlock; AData: TStream; AX, AY: Word); constructor TMapCell.Create(AOwner: TWorldBlock; AData: TStream; AX, AY: Word);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
FX := AX; FX := AX;
FY := AY; FY := AY;
if assigned(AData) then if AData <> nil then
begin begin
AData.Read(FTileID, SizeOf(Word)); AData.Read(FTileID, SizeOf(Word));
AData.Read(FZ, SizeOf(ShortInt)); AData.Read(FZ, SizeOf(ShortInt));
end; end;
FIsGhost := False;
InitOriginalState; InitOriginalState;
end; end;
@ -102,6 +116,22 @@ begin
Create(AOwner, AData, 0, 0); Create(AOwner, AData, 0, 0);
end; 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; function TMapCell.Clone: TMapCell;
begin begin
Result := TMapCell.Create(nil, nil); Result := TMapCell.Create(nil, nil);

View File

@ -52,6 +52,8 @@ type
FPriority: Integer; FPriority: Integer;
FPriorityBonus: ShortInt; FPriorityBonus: ShortInt;
FPrioritySolver: Integer; FPrioritySolver: Integer;
function GetTileID: Word; virtual;
function GetZ: ShortInt; virtual;
procedure SetTileID(ATileID: Word); procedure SetTileID(ATileID: Word);
procedure SetX(AX: Word); procedure SetX(AX: Word);
procedure SetY(AY: Word); procedure SetY(AY: Word);
@ -65,11 +67,12 @@ type
procedure UpdatePos(AX, AY: Word; AZ: ShortInt); procedure UpdatePos(AX, AY: Word; AZ: ShortInt);
procedure Delete; procedure Delete;
procedure InitOriginalState; virtual; procedure InitOriginalState; virtual;
property Owner: TWorldBlock read FOwner write SetOwner; 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 X: Word read FX write SetX;
property Y: Word read FY write SetY; 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 Selected: Boolean read FSelected write SetSelected;
property CanBeEdited: Boolean read FCanBeEdited write FCanBeEdited; property CanBeEdited: Boolean read FCanBeEdited write FCanBeEdited;
property Locked: Boolean read FLocked write SetLocked; property Locked: Boolean read FLocked write SetLocked;
@ -77,6 +80,9 @@ type
property Priority: Integer read FPriority write FPriority; property Priority: Integer read FPriority write FPriority;
property PriorityBonus: ShortInt read FPriorityBonus write FPriorityBonus; property PriorityBonus: ShortInt read FPriorityBonus write FPriorityBonus;
property PrioritySolver: Integer read FPrioritySolver write FPrioritySolver; property PrioritySolver: Integer read FPrioritySolver write FPrioritySolver;
property RawTileID: Word read FTileID;
property RawZ: ShortInt read FZ;
end; end;
TWorldItemList = specialize TFPGObjectList<TWorldItem>; TWorldItemList = specialize TFPGObjectList<TWorldItem>;
@ -151,6 +157,16 @@ begin
FOwner := AOwner; FOwner := AOwner;
end; end;
function TWorldItem.GetTileID: Word;
begin
Result := FTileID;
end;
function TWorldItem.GetZ: ShortInt;
begin
Result := FZ;
end;
procedure TWorldItem.Delete; procedure TWorldItem.Delete;
begin begin
SetSelected(False); SetSelected(False);