⚡️ Speed up preview rendering
This commit is contained in:
parent
9f66004c44
commit
6aa6496429
|
@ -322,6 +322,19 @@ type
|
|||
|
||||
TGhostTile = class(TStaticItem);
|
||||
|
||||
{ TMovableGhostTile }
|
||||
|
||||
TMovableGhostTile = class(TGhostTile)
|
||||
private
|
||||
FOriginalX: Word;
|
||||
FOriginalY: Word;
|
||||
FOriginalZ: ShortInt;
|
||||
public
|
||||
property OriginalX: Word read FOriginalX write FOriginalX;
|
||||
property OriginalY: Word read FOriginalY write FOriginalY;
|
||||
property OriginalZ: ShortInt read FOriginalZ write FOriginalZ;
|
||||
end;
|
||||
|
||||
operator enumerator(AScreenBuffer: TScreenBuffer): TScreenBufferItemEnumerator;
|
||||
|
||||
implementation
|
||||
|
|
|
@ -368,6 +368,7 @@ type
|
|||
FUoaDesigns: TUoaDesigns;
|
||||
FCurrentUoaDesign: TUoaDesign;
|
||||
FCurrentUoaDesignAnchor: TWorldItem;
|
||||
FCurrentUoaTiles: TStaticItemList;
|
||||
{ Methods }
|
||||
procedure BuildTileList;
|
||||
function ConfirmAction: Boolean;
|
||||
|
@ -383,6 +384,7 @@ type
|
|||
procedure LoadRandomPresets;
|
||||
procedure LoadUoaDesigns;
|
||||
procedure MoveBy(AOffsetX, AOffsetY: Integer); inline;
|
||||
procedure MoveUoaDesign(AX, AY: Word; AZ: ShortInt);
|
||||
procedure PlaceUoaDesign(AWorldItem: TWorldItem);
|
||||
procedure PrepareMapCell(AMapCell: TMapCell);
|
||||
procedure PrepareScreenBlock(ABlockInfo: PBlockInfo);
|
||||
|
@ -2006,6 +2008,8 @@ end;
|
|||
procedure TfrmMain.vstUoaDesignsDblClick(Sender: TObject);
|
||||
var
|
||||
selectedNode: PVirtualNode;
|
||||
designTile: TStaticItem;
|
||||
virtualTile: TMovableGhostTile;
|
||||
begin
|
||||
// Make sure to reset the current view first.
|
||||
PreviewUoaDesign(nil);
|
||||
|
@ -2020,7 +2024,25 @@ begin
|
|||
Exit;
|
||||
|
||||
FreeAndNil(FCurrentUoaDesign);
|
||||
FreeAndNil(FCurrentUoaTiles);
|
||||
FCurrentUoaDesign := FUoaDesigns.LoadDesign(FUoaDesigns.Headers[selectedNode^.Index]);
|
||||
FCurrentUoaTiles := TStaticItemList.Create(False);
|
||||
|
||||
for designTile in FCurrentUoaDesign.Tiles do
|
||||
begin
|
||||
virtualTile := TMovableGhostTile.Create(nil, nil, 0, 0);
|
||||
virtualTile.X := designTile.X;
|
||||
virtualTile.Y := designTile.Y;
|
||||
virtualTile.Z := designTile.Z;
|
||||
virtualTile.OriginalX := designTile.X;
|
||||
virtualTile.OriginalY := designTile.Y;
|
||||
virtualTile.OriginalZ := designTile.Z;
|
||||
virtualTile.TileID := designTile.TileID;
|
||||
virtualTile.Hue := designTile.Hue;
|
||||
FCurrentUoaTiles.Add(virtualTile);
|
||||
FVirtualTiles.Add(virtualTile);
|
||||
end;
|
||||
MoveUoaDesign(FX, FY, FLandscape.GetLandAlt(FX, FY, 0));
|
||||
|
||||
RegisterSelectionListener(@PlaceUoaDesign);
|
||||
RegisterHoverListener(@PreviewUoaDesign);
|
||||
|
@ -2328,6 +2350,39 @@ begin
|
|||
UpdateCurrentTile;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.MoveUoaDesign(AX, AY: Word; AZ: ShortInt);
|
||||
var
|
||||
offsetX, offsetY, offsetZ, maxZ: Integer;
|
||||
item: TStaticItem;
|
||||
begin
|
||||
maxZ := Low(Integer);
|
||||
for item in FCurrentUoaDesign.Tiles do
|
||||
if item.Z > maxZ then
|
||||
maxZ := item.Z;
|
||||
|
||||
offsetX := AX - FCurrentUoaDesign.Header.Width div 2;
|
||||
offsetY := AY - FCurrentUoaDesign.Header.Height div 2;
|
||||
offsetZ := EnsureRange(AZ, -128, 127);
|
||||
|
||||
if offsetX < 0 then offsetX := 0;
|
||||
if offsetX + FCurrentUoaDesign.Header.Width > FLandscape.CellWidth then
|
||||
offsetX := FLandscape.CellWidth - FCurrentUoaDesign.Header.Width;
|
||||
if offsetY < 0 then offsetY := 0;
|
||||
if offsetY + FCurrentUoaDesign.Header.Height > FLandscape.CellHeight then
|
||||
offsetY := FLandscape.CellHeight - FCurrentUoaDesign.Header.Height;
|
||||
if offsetZ + maxZ > 127 then
|
||||
offsetZ := 127 - maxZ;
|
||||
|
||||
for item in FCurrentUoaTiles do
|
||||
begin
|
||||
item.X := TMovableGhostTile(item).OriginalX + offsetX;
|
||||
item.Y := TMovableGhostTile(item).OriginalY + offsetY;
|
||||
item.Z := TMovableGhostTile(item).OriginalZ + offsetZ;
|
||||
end;
|
||||
|
||||
InvalidateScreenBuffer;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.PlaceUoaDesign(AWorldItem: TWorldItem);
|
||||
var
|
||||
selectedNode: PVirtualNode;
|
||||
|
@ -2338,6 +2393,7 @@ begin
|
|||
UnregisterSelectionListener(@PlaceUoaDesign);
|
||||
UnregisterHoverListener(@PreviewUoaDesign);
|
||||
FreeAndNil(FCurrentUoaDesign);
|
||||
FreeAndNil(FCurrentUoaTiles);
|
||||
FCurrentUoaDesignAnchor := nil;
|
||||
vstUoaDesigns.Enabled := True;
|
||||
btnCancelUOAPlacement.Visible := False;
|
||||
|
@ -2637,59 +2693,20 @@ begin
|
|||
end;
|
||||
|
||||
procedure TfrmMain.PreviewUoaDesign(AWorldItem: TWorldItem);
|
||||
var
|
||||
offsetX, offsetY, offsetZ: Integer;
|
||||
newX, newY, newZ: Integer;
|
||||
i: Integer;
|
||||
designTile, virtualTile: TStaticItem;
|
||||
blockInfo: PBlockInfo;
|
||||
begin
|
||||
// If nothing has changed, we can keep this short.
|
||||
if FCurrentUoaDesignAnchor = AWorldItem then
|
||||
Exit;
|
||||
FCurrentUoaDesignAnchor := AWorldItem;
|
||||
|
||||
// No design selected? Well then.
|
||||
if FCurrentUoaDesign = nil then
|
||||
Exit;
|
||||
|
||||
for i := FVirtualTiles.Count - 1 downto 0 do
|
||||
begin
|
||||
if FVirtualTiles[i] is TGhostTile then
|
||||
begin
|
||||
FScreenBuffer.Delete(FVirtualTiles[i]);
|
||||
FVirtualTiles.Delete(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
if AWorldItem = nil then
|
||||
Exit;
|
||||
|
||||
offsetX := AWorldItem.X - FCurrentUoaDesign.Header.Width div 2;
|
||||
offsetY := AWorldItem.Y - FCurrentUoaDesign.Header.Height div 2;
|
||||
offsetZ := AWorldItem.Z;
|
||||
|
||||
for designTile in FCurrentUoaDesign.Tiles do
|
||||
begin
|
||||
newX := designTile.X + offsetX;
|
||||
newY := designTile.Y + offsetY;
|
||||
newZ := designTile.Z + offsetZ;
|
||||
|
||||
if (newX < 0) or (newX >= FLandscape.CellWidth) or
|
||||
(newY < 0) or (newY >= FLandscape.CellHeight) or
|
||||
(newZ < -128) or (newZ > 127) then
|
||||
// We can't render this tile. Skip it.
|
||||
continue;
|
||||
|
||||
virtualTile := TGhostTile.Create(nil, nil, 0, 0);
|
||||
virtualTile.X := newX;
|
||||
virtualTile.Y := newY;
|
||||
virtualTile.Z := newZ;
|
||||
virtualTile.TileID := designTile.TileID;
|
||||
virtualTile.Hue := designTile.Hue;
|
||||
FVirtualTiles.Add(virtualTile);
|
||||
end;
|
||||
|
||||
InvalidateScreenBuffer;
|
||||
MoveUoaDesign(AWorldItem.X, AWorldItem.Y, AWorldItem.Z);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.Render;
|
||||
|
@ -3406,7 +3423,9 @@ begin
|
|||
|
||||
// If the current tile is nil, but we still have a selected tile, the
|
||||
// procedure is pointless - the selection should stay intact.
|
||||
if (CurrentTile <> nil) or (SelectedTile = nil) then
|
||||
// Same if we are currently placing a UOA design, since we reuse the virtual
|
||||
// tile and just update its position.
|
||||
if ((CurrentTile <> nil) or (SelectedTile = nil)) and (FCurrentUoaTiles = nil) then
|
||||
begin
|
||||
if CurrentTile = nil then
|
||||
selectedRect := Rect(-1, -1, -1, -1)
|
||||
|
|
Loading…
Reference in New Issue