- Extracted TfrmMain.PrepareScreenBlock from RebuildScreenBuffer

- Added events for OnStatic-Inserted, -Deleted and -Elevated
This commit is contained in:
Andreas Schneider 2009-08-02 20:45:23 +02:00
parent fbbe988dd6
commit 2e16269397
3 changed files with 171 additions and 100 deletions

View File

@ -73,7 +73,8 @@ type
constructor Create;
destructor Destroy; override;
function GetArtMaterial(ATileID: Word): TMaterial; overload;
function GetArtMaterial(ATileID: Word; AHue: THue; APartialHue: Boolean): TMaterial; overload;
function GetArtMaterial(ATileID: Word; AHue: THue;
APartialHue: Boolean): TMaterial; overload;
function GetFlatLandMaterial(ATileID: Word): TMaterial;
function GetTexMaterial(ATileID: Word): TMaterial;
protected
@ -114,6 +115,8 @@ type
end;
TLandscapeChangeEvent = procedure of object;
TNewBlockEvent = procedure(ABlock: TBlock) of object;
TStaticChangedEvent = procedure(AStaticItem: TStaticItem) of object;
TStaticFilter = function(AStatic: TStaticItem): Boolean of object;
TScreenBuffer = class;
@ -131,6 +134,11 @@ type
FCellHeight: Word;
FBlockCache: TCacheManager;
FOnChange: TLandscapeChangeEvent;
FOnNewBlock: TNewBlockEvent;
FOnStaticInserted: TStaticChangedEvent;
FOnStaticDeleted: TStaticChangedEvent;
FOnStaticElevated: TStaticChangedEvent;
FOnStaticHued: TStaticChangedEvent;
FOpenRequests: array of Boolean;
{ Methods }
function GetMapBlock(AX, AY: Word): TMapBlock;
@ -157,6 +165,15 @@ type
property StaticList[X, Y: Word]: TList read GetStaticList;
property Normals[X, Y: Word]: TNormals read GetNormals;
property OnChange: TLandscapeChangeEvent read FOnChange write FOnChange;
property OnNewBlock: TNewBlockEvent read FOnNewBlock write FOnNewBlock;
property OnStaticInserted: TStaticChangedEvent read FOnStaticInserted
write FOnStaticInserted;
property OnStaticDeleted: TStaticChangedEvent read FOnStaticDeleted
write FOnStaticDeleted;
property OnStaticElevated: TStaticChangedEvent read FOnStaticElevated
write FOnStaticElevated;
property OnStaticHued: TStaticChangedEvent read FOnStaticHued
write FOnStaticHued;
{ Methods }
procedure FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth,
AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean;
@ -478,6 +495,12 @@ begin
FCellHeight := FHeight * 8;
FBlockCache := TCacheManager.Create(256);
FBlockCache.OnRemoveObject := @OnRemoveCachedObject;
FOnChange := nil;
FOnStaticDeleted := nil;
FOnStaticElevated := nil;
FOnStaticHued := nil;
FOnStaticInserted := nil;
SetLength(FOpenRequests, FWidth * FHeight); //TODO : TBits?
for blockID := 0 to Length(FOpenRequests) - 1 do
@ -653,7 +676,8 @@ begin
targetStaticList.Sort(@CompareWorldItems);
staticItem.Owner := block;
staticItem.CanBeEdited := dmNetwork.CanWrite(x, y);
if Assigned(FOnChange) then FOnChange;
if Assigned(FOnStaticInserted) then FOnStaticInserted(staticItem);
end;
end;
@ -677,9 +701,10 @@ begin
(staticItem.TileID = staticInfo.TileID) and
(staticItem.Hue = staticInfo.Hue) then
begin
if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem);
statics.Delete(i);
staticItem.Delete;
if Assigned(FOnChange) then FOnChange;
Break;
end;
end;
@ -712,7 +737,9 @@ begin
ResMan.Tiledata.StaticTiles[TStaticItem(statics.Items[j]).TileID],
j);
statics.Sort(@CompareWorldItems);
if Assigned(FOnChange) then FOnChange;
if Assigned(FOnStaticElevated) then FOnStaticElevated(staticItem);
Break;
end;
end;
@ -753,6 +780,7 @@ begin
if staticItem <> nil then
begin
if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem);
statics.Remove(staticItem);
staticItem.Delete;
end;
@ -774,9 +802,10 @@ begin
i);
statics.Sort(@CompareWorldItems);
staticItem.Owner := targetBlock;
end;
staticItem.CanBeEdited := dmNetwork.CanWrite(newX, newY);
if Assigned(FOnChange) then FOnChange;
if Assigned(FOnStaticInserted) then FOnStaticInserted(staticItem);
end;
end;
procedure TLandscape.OnHueStaticPacket(ABuffer: TEnhancedMemoryStream);
@ -800,7 +829,7 @@ begin
(staticItem.Hue = staticInfo.Hue) then
begin
staticItem.Hue := ABuffer.ReadWord;
if Assigned(FOnChange) then FOnChange;
if Assigned(FOnStaticHued) then FOnStaticHued(staticItem);
Break;
end;
end;
@ -1224,7 +1253,7 @@ begin
Result^.State := ssNormal;
Result^.Highlighted := False;
if (FShortCuts[0] = nil) or (CompareWorldItems(AItem, FShortCuts[0]) > 0) then
if (FShortCuts[0] = nil) or (CompareWorldItems(AItem, FShortCuts[0]) < 0) then
begin
//TODO : update last element if necessary
Result^.Next := FShortCuts[0];
@ -1234,7 +1263,7 @@ begin
//find best entry point
shortcut := 0;
while (shortcut <= 10) and (FShortCuts[shortcut] <> nil) and
(CompareWorldItems(AItem, FShortCuts[shortcut]) <= 0) do
(CompareWorldItems(AItem, FShortCuts[shortcut]) >= 0) do
begin
current := FShortCuts[shortcut];
Inc(shortcut);

View File

@ -549,14 +549,14 @@ object frmMain: TfrmMain
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = vdtTiles
AnchorSideBottom.Side = asrBottom
Left = 114
Left = 110
Height = 19
Hint = 'Append S or T to restrict the search to Statics or Terrain.'
Top = 283
Top = 279
Width = 96
Anchors = [akRight, akBottom]
BorderSpacing.Right = 4
BorderSpacing.Bottom = 4
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
CharCase = ecUppercase
OnExit = edSearchIDExit
OnKeyPress = edSearchIDKeyPress

View File

@ -275,6 +275,7 @@ type
FTextureManager: TLandTextureManager;
FScreenBuffer: TScreenBuffer;
FScreenBufferValid: Boolean;
FScreenBufferSorted: Boolean;
FCurrentTile: TWorldItem;
FSelectedTile: TWorldItem;
FGhostTile: TWorldItem;
@ -296,6 +297,7 @@ type
procedure InitRender;
procedure InitSize;
procedure InvalidateScreenBuffer;
procedure PrepareScreenBlock(ABlockInfo: PBlockInfo);
procedure PrepareVirtualLayer(AWidth, AHeight: Word);
procedure ProcessToolState;
procedure ProcessAccessLevel;
@ -314,6 +316,9 @@ type
{ Events }
procedure OnClientHandlingPacket(ABuffer: TEnhancedMemoryStream);
procedure OnLandscapeChanged;
procedure OnStaticDeleted(AStaticItem: TStaticItem);
procedure OnStaticElevated(AStaticItem: TStaticItem);
procedure OnStaticInserted(AStaticItem: TStaticItem);
procedure OnTileRemoved(ATile: TMulBlock);
public
{ Fields }
@ -717,6 +722,10 @@ var
begin
FLandscape := ResMan.Landscape;
FLandscape.OnChange := @OnLandscapeChanged;
FLandscape.OnStaticDeleted := @OnStaticDeleted;
FLandscape.OnStaticElevated := @OnStaticElevated;
FLandscape.OnStaticInserted := @OnStaticInserted;
FTextureManager := TLandTextureManager.Create;
FScreenBuffer := TScreenBuffer.Create;
FScreenBufferValid := False;
@ -1650,6 +1659,97 @@ begin
FScreenBufferValid := False;
end;
procedure TfrmMain.PrepareScreenBlock(ABlockInfo: PBlockInfo);
var
item: TWorldItem;
drawX, drawY: Single;
west, south, east: Single;
z: SmallInt;
staticItem: TStaticItem;
hue: THue;
staticTiledata: TStaticTiledata;
begin
//add normals to map tiles and materials where possible
item := ABlockInfo^.Item;
GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
if acFlat.Checked then
z := 0
else
z := item.Z;
if item is TMapCell then
begin
if not acFlat.Checked then
begin
west := FLandscape.GetLandAlt(item.X, item.Y + 1, z);
south := FLandscape.GetLandAlt(item.X + 1, item.Y + 1, z);
east := FLandscape.GetLandAlt(item.X + 1, item.Y, z);
if (west <> z) or (south <> z) or (east <> z) then
begin
ABlockInfo^.HighRes := FTextureManager.GetTexMaterial(item.TileID);
end;
end;
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial(item.TileID);
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44);
if ABlockInfo^.HighRes <> nil then
begin
New(ABlockInfo^.Normals);
FLandscape.GetNormals(item.X, item.Y, ABlockInfo^.Normals^);
ABlockInfo^.DrawQuad[0][0] := drawX;
ABlockInfo^.DrawQuad[0][1] := drawY - z * 4;
ABlockInfo^.DrawQuad[1][0] := drawX + 22;
ABlockInfo^.DrawQuad[1][1] := drawY + 22 - east * 4;
ABlockInfo^.DrawQuad[2][0] := drawX;
ABlockInfo^.DrawQuad[2][1] := drawY + 44 - south * 4;
ABlockInfo^.DrawQuad[3][0] := drawX - 22;
ABlockInfo^.DrawQuad[3][1] := drawY + 22 - west * 4;
end else
begin
ABlockInfo^.DrawQuad[0][0] := drawX - 22;
ABlockInfo^.DrawQuad[0][1] := drawY - z * 4;
ABlockInfo^.DrawQuad[1][0] := drawX - 22 + ABlockInfo^.LowRes.Width;
ABlockInfo^.DrawQuad[1][1] := drawY - z * 4;
ABlockInfo^.DrawQuad[2][0] := drawX - 22 + ABlockInfo^.LowRes.Width;
ABlockInfo^.DrawQuad[2][1] := drawY + ABlockInfo^.LowRes.Height - z * 4;
ABlockInfo^.DrawQuad[3][0] := drawX - 22;
ABlockInfo^.DrawQuad[3][1] := drawY + ABlockInfo^.LowRes.Height - z * 4;
end;
end else
begin
staticItem := TStaticItem(item);
staticTiledata := ResMan.Tiledata.StaticTiles[staticItem.TileID];
if staticItem.Hue > 0 then
hue := ResMan.Hue.Hues[staticItem.Hue - 1]
else
hue := nil;
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue);
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - ABlockInfo^.LowRes.RealWidth / 2),
Trunc(drawY + 44 - ABlockInfo^.LowRes.RealHeight - z * 4),
ABlockInfo^.LowRes.RealWidth,
ABlockInfo^.LowRes.RealHeight);
south := ABlockInfo^.LowRes.RealHeight;
east := ABlockInfo^.LowRes.RealWidth div 2;
ABlockInfo^.DrawQuad[0][0] := drawX - east;
ABlockInfo^.DrawQuad[0][1] := drawY + 44 - south - z * 4;
ABlockInfo^.DrawQuad[1][0] := drawX - east + ABlockInfo^.LowRes.Width;
ABlockInfo^.DrawQuad[1][1] := drawY + 44 - south - z * 4;
ABlockInfo^.DrawQuad[2][0] := drawX - east + ABlockInfo^.LowRes.Width;
ABlockInfo^.DrawQuad[2][1] := drawY + 44 - south + ABlockInfo^.LowRes.Height - z * 4;
ABlockInfo^.DrawQuad[3][0] := drawX - east;
ABlockInfo^.DrawQuad[3][1] := drawY + 44 - south + ABlockInfo^.LowRes.Height - z * 4;
end;
end;
procedure TfrmMain.Render;
var
z: ShortInt;
@ -1670,6 +1770,12 @@ begin
if not FScreenBufferValid then
RebuildScreenBuffer;
if not FScreenBufferSorted then
begin
FScreenBuffer.Sort;
FScreenBufferSorted := True;
end;
{if acFilter.Checked then
staticsFilter := @frmFilter.Filter
@ -1919,6 +2025,26 @@ begin
UpdateCurrentTile;
end;
procedure TfrmMain.OnStaticDeleted(AStaticItem: TStaticItem);
begin
FScreenBuffer.Delete(AStaticItem);
end;
procedure TfrmMain.OnStaticElevated(AStaticItem: TStaticItem);
begin
FScreenBufferSorted := False;
end;
procedure TfrmMain.OnStaticInserted(AStaticItem: TStaticItem);
begin
if (AStaticItem.X >= FX + FLowOffsetX) and (AStaticItem.X <= FX + FHighOffsetX) and
(AStaticItem.Y >= FY + FLowOffsetY) and (AStaticItem.Y <= FY + FHighOffsetY) then
begin
AStaticItem.PrioritySolver := FScreenBuffer.GetSerial;
PrepareScreenBlock(FScreenBuffer.Insert(AStaticItem));
end;
end;
procedure TfrmMain.BuildTileList;
var
minID, maxID, i, lastID: Integer;
@ -2035,13 +2161,6 @@ end;
procedure TfrmMain.RebuildScreenBuffer;
var
blockInfo: PBlockInfo;
item: TWorldItem;
drawX, drawY: Single;
west, south, east: Single;
z: SmallInt;
staticItem: TStaticItem;
hue: THue;
staticTiledata: TStaticTiledata;
begin
FDrawDistance := Trunc(Sqrt(oglGameWindow.Width * oglGameWindow.Width + oglGamewindow.Height * oglGamewindow.Height) / 44);
@ -2066,91 +2185,14 @@ begin
acNoDraw.Checked, nil); //TODO : statics filter
//TODO : ghost tile
//Pre-process the buffer - add normals to map tiles and materials where possible
//Pre-process the buffer
blockInfo := nil;
while FScreenBuffer.Iterate(blockInfo) do
begin
item := blockInfo^.Item;
GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
if acFlat.Checked then
z := 0
else
z := item.Z;
if item is TMapCell then
begin
if not acFlat.Checked then
begin
west := FLandscape.GetLandAlt(item.X, item.Y + 1, z);
south := FLandscape.GetLandAlt(item.X + 1, item.Y + 1, z);
east := FLandscape.GetLandAlt(item.X + 1, item.Y, z);
if (west <> z) or (south <> z) or (east <> z) then
begin
blockInfo^.HighRes := FTextureManager.GetTexMaterial(item.TileID);
end;
end;
blockInfo^.LowRes := FTextureManager.GetArtMaterial(item.TileID);
blockInfo^.ScreenRect := Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44);
if blockInfo^.HighRes <> nil then
begin
New(blockInfo^.Normals);
FLandscape.GetNormals(item.X, item.Y, blockInfo^.Normals^);
blockInfo^.DrawQuad[0][0] := drawX;
blockInfo^.DrawQuad[0][1] := drawY - z * 4;
blockInfo^.DrawQuad[1][0] := drawX + 22;
blockInfo^.DrawQuad[1][1] := drawY + 22 - east * 4;
blockInfo^.DrawQuad[2][0] := drawX;
blockInfo^.DrawQuad[2][1] := drawY + 44 - south * 4;
blockInfo^.DrawQuad[3][0] := drawX - 22;
blockInfo^.DrawQuad[3][1] := drawY + 22 - west * 4;
end else
begin
blockInfo^.DrawQuad[0][0] := drawX - 22;
blockInfo^.DrawQuad[0][1] := drawY - z * 4;
blockInfo^.DrawQuad[1][0] := drawX - 22 + blockInfo^.LowRes.Width;
blockInfo^.DrawQuad[1][1] := drawY - z * 4;
blockInfo^.DrawQuad[2][0] := drawX - 22 + blockInfo^.LowRes.Width;
blockInfo^.DrawQuad[2][1] := drawY + blockInfo^.LowRes.Height - z * 4;
blockInfo^.DrawQuad[3][0] := drawX - 22;
blockInfo^.DrawQuad[3][1] := drawY + blockInfo^.LowRes.Height - z * 4;
end;
end else
begin
staticItem := TStaticItem(item);
staticTiledata := ResMan.Tiledata.StaticTiles[staticItem.TileID];
if staticItem.Hue > 0 then
hue := ResMan.Hue.Hues[staticItem.Hue - 1]
else
hue := nil;
blockInfo^.LowRes := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue);
blockInfo^.ScreenRect := Bounds(Trunc(drawX - blockInfo^.LowRes.RealWidth / 2),
Trunc(drawY + 44 - blockInfo^.LowRes.RealHeight - z * 4),
blockInfo^.LowRes.RealWidth,
blockInfo^.LowRes.RealHeight);
south := blockInfo^.LowRes.RealHeight;
east := blockInfo^.LowRes.RealWidth div 2;
blockInfo^.DrawQuad[0][0] := drawX - east;
blockInfo^.DrawQuad[0][1] := drawY + 44 - south - z * 4;
blockInfo^.DrawQuad[1][0] := drawX - east + blockInfo^.LowRes.Width;
blockInfo^.DrawQuad[1][1] := drawY + 44 - south - z * 4;
blockInfo^.DrawQuad[2][0] := drawX - east + blockInfo^.LowRes.Width;
blockInfo^.DrawQuad[2][1] := drawY + 44 - south + blockInfo^.LowRes.Height - z * 4;
blockInfo^.DrawQuad[3][0] := drawX - east;
blockInfo^.DrawQuad[3][1] := drawY + 44 - south + blockInfo^.LowRes.Height - z * 4;
end;
end;
PrepareScreenBlock(blockInfo);
FScreenBuffer.UpdateShortcuts;
FScreenBufferValid := True;
FScreenBufferSorted := True;
end;
procedure TfrmMain.UpdateCurrentTile;