Place UOA design #4
|
@ -322,6 +322,19 @@ type
|
||||||
|
|
||||||
TGhostTile = class(TStaticItem);
|
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;
|
operator enumerator(AScreenBuffer: TScreenBuffer): TScreenBufferItemEnumerator;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
|
@ -368,6 +368,7 @@ type
|
||||||
FUoaDesigns: TUoaDesigns;
|
FUoaDesigns: TUoaDesigns;
|
||||||
FCurrentUoaDesign: TUoaDesign;
|
FCurrentUoaDesign: TUoaDesign;
|
||||||
FCurrentUoaDesignAnchor: TWorldItem;
|
FCurrentUoaDesignAnchor: TWorldItem;
|
||||||
|
FCurrentUoaTiles: TStaticItemList;
|
||||||
{ Methods }
|
{ Methods }
|
||||||
procedure BuildTileList;
|
procedure BuildTileList;
|
||||||
function ConfirmAction: Boolean;
|
function ConfirmAction: Boolean;
|
||||||
|
@ -383,6 +384,7 @@ type
|
||||||
procedure LoadRandomPresets;
|
procedure LoadRandomPresets;
|
||||||
procedure LoadUoaDesigns;
|
procedure LoadUoaDesigns;
|
||||||
procedure MoveBy(AOffsetX, AOffsetY: Integer); inline;
|
procedure MoveBy(AOffsetX, AOffsetY: Integer); inline;
|
||||||
|
procedure MoveUoaDesign(AX, AY: Word; AZ: ShortInt);
|
||||||
procedure PlaceUoaDesign(AWorldItem: TWorldItem);
|
procedure PlaceUoaDesign(AWorldItem: TWorldItem);
|
||||||
procedure PrepareMapCell(AMapCell: TMapCell);
|
procedure PrepareMapCell(AMapCell: TMapCell);
|
||||||
procedure PrepareScreenBlock(ABlockInfo: PBlockInfo);
|
procedure PrepareScreenBlock(ABlockInfo: PBlockInfo);
|
||||||
|
@ -2006,6 +2008,8 @@ end;
|
||||||
procedure TfrmMain.vstUoaDesignsDblClick(Sender: TObject);
|
procedure TfrmMain.vstUoaDesignsDblClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
selectedNode: PVirtualNode;
|
selectedNode: PVirtualNode;
|
||||||
|
designTile: TStaticItem;
|
||||||
|
virtualTile: TMovableGhostTile;
|
||||||
begin
|
begin
|
||||||
// Make sure to reset the current view first.
|
// Make sure to reset the current view first.
|
||||||
PreviewUoaDesign(nil);
|
PreviewUoaDesign(nil);
|
||||||
|
@ -2020,7 +2024,25 @@ begin
|
||||||
Exit;
|
Exit;
|
||||||
|
|
||||||
FreeAndNil(FCurrentUoaDesign);
|
FreeAndNil(FCurrentUoaDesign);
|
||||||
|
FreeAndNil(FCurrentUoaTiles);
|
||||||
FCurrentUoaDesign := FUoaDesigns.LoadDesign(FUoaDesigns.Headers[selectedNode^.Index]);
|
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);
|
RegisterSelectionListener(@PlaceUoaDesign);
|
||||||
RegisterHoverListener(@PreviewUoaDesign);
|
RegisterHoverListener(@PreviewUoaDesign);
|
||||||
|
@ -2328,6 +2350,39 @@ begin
|
||||||
UpdateCurrentTile;
|
UpdateCurrentTile;
|
||||||
end;
|
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);
|
procedure TfrmMain.PlaceUoaDesign(AWorldItem: TWorldItem);
|
||||||
var
|
var
|
||||||
selectedNode: PVirtualNode;
|
selectedNode: PVirtualNode;
|
||||||
|
@ -2338,6 +2393,7 @@ begin
|
||||||
UnregisterSelectionListener(@PlaceUoaDesign);
|
UnregisterSelectionListener(@PlaceUoaDesign);
|
||||||
UnregisterHoverListener(@PreviewUoaDesign);
|
UnregisterHoverListener(@PreviewUoaDesign);
|
||||||
FreeAndNil(FCurrentUoaDesign);
|
FreeAndNil(FCurrentUoaDesign);
|
||||||
|
FreeAndNil(FCurrentUoaTiles);
|
||||||
FCurrentUoaDesignAnchor := nil;
|
FCurrentUoaDesignAnchor := nil;
|
||||||
vstUoaDesigns.Enabled := True;
|
vstUoaDesigns.Enabled := True;
|
||||||
btnCancelUOAPlacement.Visible := False;
|
btnCancelUOAPlacement.Visible := False;
|
||||||
|
@ -2637,59 +2693,20 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TfrmMain.PreviewUoaDesign(AWorldItem: TWorldItem);
|
procedure TfrmMain.PreviewUoaDesign(AWorldItem: TWorldItem);
|
||||||
var
|
|
||||||
offsetX, offsetY, offsetZ: Integer;
|
|
||||||
newX, newY, newZ: Integer;
|
|
||||||
i: Integer;
|
|
||||||
designTile, virtualTile: TStaticItem;
|
|
||||||
blockInfo: PBlockInfo;
|
|
||||||
begin
|
begin
|
||||||
// If nothing has changed, we can keep this short.
|
// If nothing has changed, we can keep this short.
|
||||||
if FCurrentUoaDesignAnchor = AWorldItem then
|
if FCurrentUoaDesignAnchor = AWorldItem then
|
||||||
Exit;
|
Exit;
|
||||||
|
FCurrentUoaDesignAnchor := AWorldItem;
|
||||||
|
|
||||||
// No design selected? Well then.
|
// No design selected? Well then.
|
||||||
if FCurrentUoaDesign = nil then
|
if FCurrentUoaDesign = nil then
|
||||||
Exit;
|
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
|
if AWorldItem = nil then
|
||||||
Exit;
|
Exit;
|
||||||
|
|
||||||
offsetX := AWorldItem.X - FCurrentUoaDesign.Header.Width div 2;
|
MoveUoaDesign(AWorldItem.X, AWorldItem.Y, AWorldItem.Z);
|
||||||
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;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TfrmMain.Render;
|
procedure TfrmMain.Render;
|
||||||
|
@ -3404,9 +3421,11 @@ var
|
||||||
begin
|
begin
|
||||||
//Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection');
|
//Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection');
|
||||||
|
|
||||||
//If the current tile is nil, but we still have a selected tile, the
|
// If the current tile is nil, but we still have a selected tile, the
|
||||||
//procedure is pointless - the selection should stay intact.
|
// 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
|
begin
|
||||||
if CurrentTile = nil then
|
if CurrentTile = nil then
|
||||||
selectedRect := Rect(-1, -1, -1, -1)
|
selectedRect := Rect(-1, -1, -1, -1)
|
||||||
|
|
Loading…
Reference in New Issue