🚧 Preview design placement
This commit is contained in:
parent
cd983844fa
commit
1753c38eea
|
@ -320,6 +320,8 @@ type
|
|||
Hue: Word;
|
||||
end;
|
||||
|
||||
TGhostTile = class(TStaticItem);
|
||||
|
||||
operator enumerator(AScreenBuffer: TScreenBuffer): TScreenBufferItemEnumerator;
|
||||
|
||||
implementation
|
||||
|
@ -996,6 +998,7 @@ var
|
|||
i, x, y: Integer;
|
||||
tempDrawList: TWorldItemList;
|
||||
staticTileData: TStaticTiledata;
|
||||
blockInfo: PBlockInfo;
|
||||
begin
|
||||
ADrawList.Clear;
|
||||
tempDrawList := TWorldItemList.Create(False);;
|
||||
|
@ -1042,7 +1045,11 @@ begin
|
|||
|
||||
tempDrawList.Sort(@CompareWorldItems);
|
||||
for i := 0 to tempDrawList.Count - 1 do
|
||||
ADrawList.Add(TWorldItem(tempDrawList[i]));
|
||||
begin
|
||||
blockInfo := ADrawList.Add(TWorldItem(tempDrawList[i]));
|
||||
if tempDrawList[i] is TGhostTile then
|
||||
blockInfo^.State := ssGhost;
|
||||
end;
|
||||
tempDrawList.Free;
|
||||
end;
|
||||
|
||||
|
|
|
@ -32,6 +32,19 @@ type
|
|||
constructor CreateFromStream(AStream: TStream);
|
||||
end;
|
||||
|
||||
TUoaDesign = class
|
||||
private
|
||||
FHeader: TUoaDesignHeader;
|
||||
FTiles: TStaticItemList;
|
||||
|
||||
constructor Create(AHeader: TUoaDesignHeader; AData: TStream);
|
||||
public
|
||||
property Header: TUoaDesignHeader read FHeader;
|
||||
property Tiles: TStaticItemList read Ftiles;
|
||||
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
{ TUoaDesigns }
|
||||
|
||||
TUoaDesigns = class
|
||||
|
@ -42,8 +55,7 @@ type
|
|||
constructor Create(AIdxFile, ABinFile: String);
|
||||
destructor Destroy; override;
|
||||
|
||||
function LoadTiles(AHeader: TUoaDesignHeader; AOffsetX, AOffsetY: Word;
|
||||
AOffsetZ: ShortInt): TStaticItemList;
|
||||
function LoadDesign(AHeader: TUoaDesignHeader): TUoaDesign;
|
||||
public
|
||||
property Headers: TUoaDesignHeaders read FHeaders;
|
||||
end;
|
||||
|
@ -65,6 +77,49 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
{ TUoaDesign }
|
||||
|
||||
constructor TUoaDesign.Create(AHeader: TUoaDesignHeader; AData: TStream);
|
||||
var
|
||||
i: Integer;
|
||||
tile: TStaticItem;
|
||||
version: Int32;
|
||||
|
||||
function ReadInt: Int32;
|
||||
begin
|
||||
AData.Read(Result, SizeOf(Result));
|
||||
end;
|
||||
|
||||
begin
|
||||
FHeader := AHeader;
|
||||
FTiles := TStaticItemList.Create(True);
|
||||
AData.Seek(FHeader.FilePosition, soFromBeginning);
|
||||
for i := 0 to FHeader.TileCount - 1 do
|
||||
begin
|
||||
AData.Read(version, SizeOf(version));
|
||||
if (version < 0) or (version > 1) then
|
||||
raise Exception.Create('Unsupported binary version');
|
||||
|
||||
tile := TStaticItem.Create(nil);
|
||||
tile.TileID := ReadInt;
|
||||
tile.X := ReadInt;
|
||||
tile.Y := ReadInt;
|
||||
tile.Z := ReadInt;
|
||||
ReadInt; // Level; unused
|
||||
|
||||
if version = 1 then
|
||||
tile.Hue := ReadInt;
|
||||
|
||||
FTiles.Add(tile);
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TUoaDesign.Destroy;
|
||||
begin
|
||||
FTiles.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TUoaDesignHeaders }
|
||||
|
||||
constructor TUoaDesignHeaders.CreateFromStream(AStream: TStream);
|
||||
|
@ -120,39 +175,9 @@ begin
|
|||
Headers.Free;
|
||||
end;
|
||||
|
||||
function TUoaDesigns.LoadTiles(AHeader: TUoaDesignHeader; AOffsetX,
|
||||
AOffsetY: Word; AOffsetZ: ShortInt): TStaticItemList;
|
||||
var
|
||||
i: Integer;
|
||||
tile: TStaticItem;
|
||||
version: Int32;
|
||||
|
||||
function ReadInt: Int32;
|
||||
begin
|
||||
FData.Read(Result, SizeOf(Result));
|
||||
end;
|
||||
|
||||
function TUoaDesigns.LoadDesign(AHeader: TUoaDesignHeader): TUoaDesign;
|
||||
begin
|
||||
Result := TStaticItemList.Create(True);
|
||||
FData.Seek(AHeader.FilePosition, soFromBeginning);
|
||||
for i := 0 to AHeader.TileCount - 1 do
|
||||
begin
|
||||
FData.Read(version, SizeOf(version));
|
||||
if (version < 0) or (version > 1) then
|
||||
raise Exception.Create('Unsupported binary version');
|
||||
|
||||
tile := TStaticItem.Create(nil);
|
||||
tile.TileID := ReadInt;
|
||||
tile.X := AOffsetX + ReadInt;
|
||||
tile.Y := AOffsetY + ReadInt;
|
||||
tile.Z := AOffsetZ + ReadInt;
|
||||
ReadInt; // TODO: Level??
|
||||
|
||||
if version = 1 then
|
||||
tile.Hue := ReadInt;
|
||||
|
||||
Result.Add(tile);
|
||||
end;
|
||||
Result := TUoaDesign.Create(AHeader, FData);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
@ -47,7 +47,6 @@ type
|
|||
|
||||
TBlockInfoList = specialize TFPGList<PBlockInfo>;
|
||||
|
||||
TGhostTile = class(TStaticItem);
|
||||
TPacketList = specialize TFPGObjectList<TPacket>;
|
||||
TAccessChangedListeners = specialize TFPGList<TAccessChangedListener>;
|
||||
TSelectionListeners = specialize TFPGList<TSelectionListener>;
|
||||
|
@ -360,10 +359,13 @@ type
|
|||
FUndoList: TPacketList;
|
||||
FGLFont: TGLFont;
|
||||
FSelectionListeners: TSelectionListeners;
|
||||
FHoverListeners: TSelectionListeners;
|
||||
FTileHint: TTileHintInfo;
|
||||
FLightManager: TLightManager;
|
||||
FTileFilter: TTileDataFlags;
|
||||
FUoaDesigns: TUoaDesigns;
|
||||
FCurrentUoaDesign: TUoaDesign;
|
||||
FCurrentUoaDesignAnchor: TWorldItem;
|
||||
{ Methods }
|
||||
procedure BuildTileList;
|
||||
function ConfirmAction: Boolean;
|
||||
|
@ -381,6 +383,7 @@ type
|
|||
procedure PlaceUoaDesign(AWorldItem: TWorldItem);
|
||||
procedure PrepareMapCell(AMapCell: TMapCell);
|
||||
procedure PrepareScreenBlock(ABlockInfo: PBlockInfo);
|
||||
procedure PreviewUoaDesign(AWorldItem: TWorldItem);
|
||||
procedure ProcessToolState;
|
||||
procedure ProcessAccessLevel;
|
||||
procedure RebuildScreenBuffer;
|
||||
|
@ -420,10 +423,12 @@ type
|
|||
procedure InvalidateFilter;
|
||||
procedure InvalidateScreenBuffer;
|
||||
procedure RegisterAccessChangedListener(AListener: TAccessChangedListener);
|
||||
procedure RegisterHoverListener(AListener: TSelectionListener);
|
||||
procedure RegisterSelectionListener(AListener: TSelectionListener);
|
||||
procedure SetPos(AX, AY: Word);
|
||||
procedure SwitchToSelection;
|
||||
procedure UnregisterAccessChangedListener(AListener: TAccessChangedListener);
|
||||
procedure UnregisterHoverListener(AListener: TSelectionListener);
|
||||
procedure UnregisterSelectionListener(AListener: TSelectionListener);
|
||||
end;
|
||||
|
||||
|
@ -1038,6 +1043,7 @@ begin
|
|||
pnlBottom.DoubleBuffered := True;
|
||||
|
||||
FAccessChangedListeners := TAccessChangedListeners.Create;
|
||||
FHoverListeners := TSelectionListeners.Create;
|
||||
FSelectionListeners := TSelectionListeners.Create;
|
||||
|
||||
FLastDraw := Now;
|
||||
|
@ -1408,6 +1414,7 @@ begin
|
|||
FreeAndNil(FGLFont);
|
||||
FreeAndNil(FRandomPresetsDoc);
|
||||
FreeAndNil(FAccessChangedListeners);
|
||||
FreeAndNil(FHoverListeners);
|
||||
FreeAndNil(FSelectionListeners);
|
||||
FreeAndNil(FUoaDesigns);
|
||||
|
||||
|
@ -1989,8 +1996,24 @@ begin
|
|||
end;
|
||||
|
||||
procedure TfrmMain.vstUoaDesignsDblClick(Sender: TObject);
|
||||
var
|
||||
selectedNode: PVirtualNode;
|
||||
begin
|
||||
// Make sure to reset the current view first.
|
||||
PreviewUoaDesign(nil);
|
||||
|
||||
UnregisterSelectionListener(@PlaceUoaDesign);
|
||||
UnregisterHoverListener(@PreviewUoaDesign);
|
||||
|
||||
selectedNode := vstUoaDesigns.GetFirstSelected();
|
||||
if selectedNode = nil then
|
||||
Exit;
|
||||
|
||||
FreeAndNil(FCurrentUoaDesign);
|
||||
FCurrentUoaDesign := FUoaDesigns.LoadDesign(FUoaDesigns.Headers[selectedNode^.Index]);
|
||||
|
||||
RegisterSelectionListener(@PlaceUoaDesign);
|
||||
RegisterHoverListener(@PreviewUoaDesign);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.vstUoaDesignsGetText(Sender: TBaseVirtualTree;
|
||||
|
@ -2065,6 +2088,12 @@ begin
|
|||
FAccessChangedListeners.Add(AListener);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.RegisterHoverListener(AListener: TSelectionListener);
|
||||
begin
|
||||
if FHoverListeners.IndexOf(AListener) = -1 then
|
||||
FHoverListeners.Add(AListener);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.RegisterSelectionListener(AListener: TSelectionListener);
|
||||
begin
|
||||
if FSelectionListeners.IndexOf(AListener) = -1 then
|
||||
|
@ -2077,6 +2106,11 @@ begin
|
|||
FAccessChangedListeners.Remove(AListener);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.UnregisterHoverListener(AListener: TSelectionListener);
|
||||
begin
|
||||
FHoverListeners.Remove(Alistener);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.UnregisterSelectionListener(AListener: TSelectionListener);
|
||||
begin
|
||||
FSelectionListeners.Remove(AListener);
|
||||
|
@ -2294,7 +2328,9 @@ begin
|
|||
if selectedNode = nil then
|
||||
Exit;
|
||||
|
||||
header := FUoaDesigns.Headers[selectedNode^.Index];
|
||||
vstUoaDesigns.ClearSelection;
|
||||
|
||||
{header := FUoaDesigns.Headers[selectedNode^.Index];
|
||||
tiles := FUoaDesigns.LoadTiles(header, AWorldItem.X, AWorldItem.Y, AWorldItem.Z);
|
||||
try
|
||||
FUndoList.Clear;
|
||||
|
@ -2305,7 +2341,7 @@ begin
|
|||
end;
|
||||
finally
|
||||
tiles.Free;
|
||||
end;
|
||||
end;}
|
||||
end;
|
||||
|
||||
procedure TfrmMain.PrepareMapCell(AMapCell: TMapCell);
|
||||
|
@ -2568,6 +2604,62 @@ begin
|
|||
end;
|
||||
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;
|
||||
|
||||
// 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;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.Render;
|
||||
var
|
||||
highlight: Boolean;
|
||||
|
@ -3060,6 +3152,7 @@ end;
|
|||
procedure TfrmMain.UpdateCurrentTile(AX, AY: Integer);
|
||||
var
|
||||
blockInfo: PBlockInfo;
|
||||
listener: TSelectionListener;
|
||||
begin
|
||||
//Logger.EnterMethod([lcClient, lcDebug], 'UpdateCurrentTile');
|
||||
FOverlayUI.ActiveArrow := FOverlayUI.HitTest(AX, AY);
|
||||
|
@ -3077,6 +3170,9 @@ begin
|
|||
else
|
||||
CurrentTile := nil;
|
||||
|
||||
for listener in FHoverListeners do
|
||||
listener(CurrentTile);
|
||||
|
||||
//Logger.ExitMethod([lcClient, lcDebug], 'UpdateCurrentTile');
|
||||
end;
|
||||
|
||||
|
|
Loading…
Reference in New Issue