- Cleanup in ULandscape.pas
- Removed unncessary virtual and ghost tile handling from FillDrawList - Added serial generation and tracking to TScreenBuffer - Added editing state tracking to TScreenBuffer - Changed TScreenBuffer.Store to perform an InsertSort - Changed TScreenBuffer.Store to handle only the most necessary parameters
This commit is contained in:
parent
2f560a7738
commit
61db743ee5
|
@ -30,12 +30,12 @@ unit ULandscape;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes, math, contnrs, LCLIntf, GL, GLU, ImagingOpenGL,
|
SysUtils, Classes, math, LCLIntf, GL, GLU, ImagingOpenGL, Imaging,
|
||||||
Imaging, ImagingClasses, ImagingTypes, ImagingUtility,
|
ImagingClasses, ImagingTypes, ImagingUtility,
|
||||||
UGenericIndex, UMap, UStatics, UArt, UTexture, UTiledata, UHue, UWorldItem,
|
UGenericIndex, UMap, UStatics, UArt, UTexture, UTiledata, UHue, UWorldItem,
|
||||||
UMulBlock,
|
UMulBlock,
|
||||||
UListSort, UVector, UEnhancedMemoryStream,
|
UVector, UEnhancedMemoryStream,
|
||||||
UCacheManager, ULinkedList;
|
UCacheManager;
|
||||||
|
|
||||||
type
|
type
|
||||||
TNormals = array[0..3] of TVector;
|
TNormals = array[0..3] of TVector;
|
||||||
|
@ -97,6 +97,8 @@ type
|
||||||
TLandscapeChangeEvent = procedure of object;
|
TLandscapeChangeEvent = procedure of object;
|
||||||
TStaticFilter = function(AStatic: TStaticItem): Boolean of object;
|
TStaticFilter = function(AStatic: TStaticItem): Boolean of object;
|
||||||
|
|
||||||
|
TScreenBuffer = class;
|
||||||
|
|
||||||
{ TLandscape }
|
{ TLandscape }
|
||||||
|
|
||||||
TLandscape = class(TObject)
|
TLandscape = class(TObject)
|
||||||
|
@ -112,15 +114,13 @@ type
|
||||||
FOnChange: TLandscapeChangeEvent;
|
FOnChange: TLandscapeChangeEvent;
|
||||||
FOpenRequests: array of Boolean;
|
FOpenRequests: array of Boolean;
|
||||||
{ Methods }
|
{ Methods }
|
||||||
function GetNormals(AX, AY: Word): TNormals;
|
|
||||||
function GetMapCell(AX, AY: Word): TMapCell;
|
|
||||||
function GetStaticList(AX, AY: Word): TList;
|
|
||||||
function GetMapBlock(AX, AY: Word): TMapBlock;
|
function GetMapBlock(AX, AY: Word): TMapBlock;
|
||||||
|
function GetMapCell(AX, AY: Word): TMapCell;
|
||||||
|
function GetNormals(AX, AY: Word): TNormals;
|
||||||
function GetStaticBlock(AX, AY: Word): TSeperatedStaticBlock;
|
function GetStaticBlock(AX, AY: Word): TSeperatedStaticBlock;
|
||||||
procedure UpdateStaticsPriority(AStaticItem: TStaticItem;
|
function GetStaticList(AX, AY: Word): TList;
|
||||||
APrioritySolver: Integer);
|
{ Events }
|
||||||
procedure OnRemoveCachedObject(AObject: TObject);
|
procedure OnRemoveCachedObject(AObject: TObject);
|
||||||
|
|
||||||
procedure OnBlocksPacket(ABuffer: TEnhancedMemoryStream);
|
procedure OnBlocksPacket(ABuffer: TEnhancedMemoryStream);
|
||||||
procedure OnDrawMapPacket(ABuffer: TEnhancedMemoryStream);
|
procedure OnDrawMapPacket(ABuffer: TEnhancedMemoryStream);
|
||||||
procedure OnInsertStaticPacket(ABuffer: TEnhancedMemoryStream);
|
procedure OnInsertStaticPacket(ABuffer: TEnhancedMemoryStream);
|
||||||
|
@ -139,21 +139,22 @@ type
|
||||||
property Normals[X, Y: Word]: TNormals read GetNormals;
|
property Normals[X, Y: Word]: TNormals read GetNormals;
|
||||||
property OnChange: TLandscapeChangeEvent read FOnChange write FOnChange;
|
property OnChange: TLandscapeChangeEvent read FOnChange write FOnChange;
|
||||||
{ Methods }
|
{ Methods }
|
||||||
function GetDrawList(AX, AY, AWidth, AHeight: Word; AMinZ, AMaxZ: ShortInt;
|
procedure FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth,
|
||||||
AGhostTile: TWorldItem; AVirtualLayer: TStaticItem; AMap,
|
AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean;
|
||||||
AStatics: Boolean; ANoDraw:Boolean; AStaticsFilter: TStaticFilter): TList;
|
ANoDraw: Boolean; AStaticsFilter: TStaticFilter);
|
||||||
procedure UpdateDrawListItems(AList: TList);
|
|
||||||
function GetEffectiveAltitude(ATile: TMapCell): ShortInt;
|
function GetEffectiveAltitude(ATile: TMapCell): ShortInt;
|
||||||
function GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt;
|
function GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt;
|
||||||
|
|
||||||
procedure MoveStatic(AStatic: TStaticItem; AX, AY: Word);
|
procedure MoveStatic(AStatic: TStaticItem; AX, AY: Word);
|
||||||
procedure PrepareBlocks(AX1, AY1, AX2, AY2: Word);
|
procedure PrepareBlocks(AX1, AY1, AX2, AY2: Word);
|
||||||
|
procedure UpdateStaticsPriority(AStaticItem: TStaticItem;
|
||||||
|
APrioritySolver: Integer);
|
||||||
end;
|
end;
|
||||||
PBlockInfo = ^TBlockInfo;
|
PBlockInfo = ^TBlockInfo;
|
||||||
TBlockInfo = record
|
TBlockInfo = record
|
||||||
ScreenRect: TRect;
|
ScreenRect: TRect;
|
||||||
Item: TWorldItem;
|
Item: TWorldItem;
|
||||||
Material: TMaterial;
|
Material: TMaterial;
|
||||||
|
Ghost: Boolean;
|
||||||
Next: PBlockInfo;
|
Next: PBlockInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -163,9 +164,11 @@ type
|
||||||
constructor Create; virtual;
|
constructor Create; virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
protected
|
protected
|
||||||
|
{ Fields }
|
||||||
FFirst: PBlockInfo;
|
FFirst: PBlockInfo;
|
||||||
FLastBlock: PBlockInfo;
|
FLastBlock: PBlockInfo;
|
||||||
public
|
public
|
||||||
|
{ Methods }
|
||||||
procedure Clear; virtual;
|
procedure Clear; virtual;
|
||||||
function Iterate(var ABlockInfo: PBlockInfo): Boolean; virtual;
|
function Iterate(var ABlockInfo: PBlockInfo): Boolean; virtual;
|
||||||
procedure Add(AItem: TWorldItem); virtual;
|
procedure Add(AItem: TWorldItem); virtual;
|
||||||
|
@ -176,11 +179,19 @@ type
|
||||||
{ TScreenBuffer }
|
{ TScreenBuffer }
|
||||||
|
|
||||||
TScreenBuffer = class(TTileList)
|
TScreenBuffer = class(TTileList)
|
||||||
|
constructor Create; override;
|
||||||
|
protected
|
||||||
|
{ Members }
|
||||||
|
FSerial: Cardinal;
|
||||||
public
|
public
|
||||||
procedure OnTileRemoved(ATile: TMulBlock);
|
{ Methods }
|
||||||
procedure Clear; override;
|
procedure Clear; override;
|
||||||
function Find(AScreenPosition: TPoint): PBlockInfo;
|
function Find(AScreenPosition: TPoint): PBlockInfo;
|
||||||
procedure Store(AScreenRect: TRect; AItem: TWorldItem; AMaterial: TMaterial);
|
function GetSerial: Cardinal;
|
||||||
|
procedure Store(AItem: TWorldItem; AMaterial: TMaterial = nil;
|
||||||
|
AGhost: Boolean = False);
|
||||||
|
{ Events }
|
||||||
|
procedure OnTileRemoved(ATile: TMulBlock);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TStaticInfo = packed record
|
TStaticInfo = packed record
|
||||||
|
@ -190,7 +201,6 @@ type
|
||||||
TileID: Word;
|
TileID: Word;
|
||||||
Hue: Word;
|
Hue: Word;
|
||||||
end;
|
end;
|
||||||
//operator=(AStaticItem: TStaticItem; AStaticInfo: TStaticInfo): Boolean;
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -206,6 +216,30 @@ begin
|
||||||
Result := ((AX and $7FFF) shl 15) or (AY and $7FFF);
|
Result := ((AX and $7FFF) shl 15) or (AY and $7FFF);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CompareWorldItems(AItem1, AItem2: Pointer): Integer;
|
||||||
|
begin
|
||||||
|
if TWorldItem(AItem1).X <> TWorldItem(AItem2).X then
|
||||||
|
Exit(TWorldItem(AItem1).X - TWorldItem(AItem2).X);
|
||||||
|
|
||||||
|
if TWorldItem(AItem1).Y <> TWorldItem(AItem2).Y then
|
||||||
|
Exit(TWorldItem(AItem1).Y - TWorldItem(AItem2).Y);
|
||||||
|
|
||||||
|
Result := TWorldItem(AItem1).Priority - TWorldItem(AItem2).Priority;
|
||||||
|
if Result = 0 then
|
||||||
|
begin
|
||||||
|
if (TObject(AItem1) is TMapCell) and (TObject(AItem2) is TStaticItem) then
|
||||||
|
Result := -1
|
||||||
|
else if (TObject(AItem1) is TStaticItem) and (TObject(AItem2) is TMapCell) then
|
||||||
|
Result := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Result = 0 then
|
||||||
|
Result := TWorldItem(AItem1).PriorityBonus - TWorldItem(AItem2).PriorityBonus;
|
||||||
|
|
||||||
|
if Result = 0 then
|
||||||
|
Result := TWorldItem(AItem1).PrioritySolver - TWorldItem(AItem2).PrioritySolver;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TLandTextureManager }
|
{ TLandTextureManager }
|
||||||
|
|
||||||
constructor TLandTextureManager.Create;
|
constructor TLandTextureManager.Create;
|
||||||
|
@ -335,7 +369,7 @@ begin
|
||||||
SetLength(FOpenRequests, FWidth * FHeight);
|
SetLength(FOpenRequests, FWidth * FHeight);
|
||||||
for blockID := 0 to Length(FOpenRequests) - 1 do
|
for blockID := 0 to Length(FOpenRequests) - 1 do
|
||||||
FOpenRequests[blockID] := False;
|
FOpenRequests[blockID] := False;
|
||||||
|
|
||||||
RegisterPacketHandler($04, TPacketHandler.Create(0, @OnBlocksPacket));
|
RegisterPacketHandler($04, TPacketHandler.Create(0, @OnBlocksPacket));
|
||||||
RegisterPacketHandler($06, TPacketHandler.Create(8, @OnDrawMapPacket));
|
RegisterPacketHandler($06, TPacketHandler.Create(8, @OnDrawMapPacket));
|
||||||
RegisterPacketHandler($07, TPacketHandler.Create(10, @OnInsertStaticPacket));
|
RegisterPacketHandler($07, TPacketHandler.Create(10, @OnInsertStaticPacket));
|
||||||
|
@ -346,8 +380,6 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TLandscape.Destroy;
|
destructor TLandscape.Destroy;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
if FBlockCache <> nil then
|
if FBlockCache <> nil then
|
||||||
begin
|
begin
|
||||||
|
@ -366,6 +398,18 @@ begin
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TLandscape.GetMapBlock(AX, AY: Word): TMapBlock;
|
||||||
|
var
|
||||||
|
block: TBlock;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
if (AX >= 0) and (AX < FWidth) and (AY >= 0) and (AY < FHeight) then
|
||||||
|
begin
|
||||||
|
if FBlockCache.QueryID(GetID(AX, AY), TObject(block)) then
|
||||||
|
Result := block.Map;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TLandscape.GetMapCell(AX, AY: Word): TMapCell;
|
function TLandscape.GetMapCell(AX, AY: Word): TMapCell;
|
||||||
var
|
var
|
||||||
block: TMapBlock;
|
block: TMapBlock;
|
||||||
|
@ -379,154 +423,6 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TLandscape.GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt;
|
|
||||||
var
|
|
||||||
cell: TMapCell;
|
|
||||||
begin
|
|
||||||
cell := MapCell[AX, AY];
|
|
||||||
if cell <> nil then
|
|
||||||
Result := cell.Altitude
|
|
||||||
else
|
|
||||||
Result := ADefault;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLandscape.GetStaticList(AX, AY: Word): TList;
|
|
||||||
var
|
|
||||||
block: TSeperatedStaticBlock;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
if (AX >= 0) and (AX <= FCellWidth) and (AY >= 0) and (AY <= FCellHeight) then
|
|
||||||
begin
|
|
||||||
block := GetStaticBlock(AX div 8, AY div 8);
|
|
||||||
if block <> nil then
|
|
||||||
Result := block.Cells[(AY mod 8) * 8 + AX mod 8];
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function Compare(AItem1, AItem2: Pointer): Integer;
|
|
||||||
begin
|
|
||||||
if TWorldItem(AItem1).X <> TWorldItem(AItem2).X then
|
|
||||||
Exit(TWorldItem(AItem1).X - TWorldItem(AItem2).X);
|
|
||||||
|
|
||||||
if TWorldItem(AItem1).Y <> TWorldItem(AItem2).Y then
|
|
||||||
Exit(TWorldItem(AItem1).Y - TWorldItem(AItem2).Y);
|
|
||||||
|
|
||||||
Result := TWorldItem(AItem1).Priority - TWorldItem(AItem2).Priority;
|
|
||||||
if Result = 0 then
|
|
||||||
begin
|
|
||||||
if (TObject(AItem1) is TMapCell) and (TObject(AItem2) is TStaticItem) then
|
|
||||||
Result := -1
|
|
||||||
else if (TObject(AItem1) is TStaticItem) and (TObject(AItem2) is TMapCell) then
|
|
||||||
Result := 1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if Result = 0 then
|
|
||||||
Result := TWorldItem(AItem1).PriorityBonus - TWorldItem(AItem2).PriorityBonus;
|
|
||||||
|
|
||||||
if Result = 0 then
|
|
||||||
Result := TWorldItem(AItem1).PrioritySolver - TWorldItem(AItem2).PrioritySolver;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLandscape.GetDrawList(AX, AY, AWidth, AHeight: Word;
|
|
||||||
AMinZ, AMaxZ: ShortInt; AGhostTile: TWorldItem; AVirtualLayer: TStaticItem;
|
|
||||||
AMap, AStatics: Boolean; ANoDraw: Boolean;
|
|
||||||
AStaticsFilter: TStaticFilter): TList;
|
|
||||||
var
|
|
||||||
landAlt: ShortInt;
|
|
||||||
drawMapCell: TMapCell;
|
|
||||||
drawStatics: TList;
|
|
||||||
i, x, y: Integer;
|
|
||||||
begin
|
|
||||||
Result := TList.Create;
|
|
||||||
for x := AX to AX + AWidth do
|
|
||||||
for y := AY to AY + AWidth do
|
|
||||||
begin
|
|
||||||
if AMap then
|
|
||||||
begin
|
|
||||||
landAlt := GetLandAlt(x, y, 0);
|
|
||||||
if (landAlt >= AMinZ) and (landAlt <= AMaxZ) then
|
|
||||||
begin
|
|
||||||
drawMapCell := GetMapCell(x, y);
|
|
||||||
if (drawMapCell <> nil) and (ANoDraw or (drawMapCell.TileID > 2)) then
|
|
||||||
begin
|
|
||||||
drawMapCell.Priority := GetEffectiveAltitude(drawMapCell);
|
|
||||||
drawMapCell.PriorityBonus := 0;
|
|
||||||
drawMapCell.PrioritySolver := 0;
|
|
||||||
Result.Add(drawMapCell);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if AGhostTile is TMapCell then
|
|
||||||
begin
|
|
||||||
AGhostTile.X := x;
|
|
||||||
AGhostTile.Y := y;
|
|
||||||
AGhostTile.Priority := GetEffectiveAltitude(TMapCell(AGhostTile));
|
|
||||||
AGhostTile.PriorityBonus := 0;
|
|
||||||
AGhostTile.PrioritySolver := 0;
|
|
||||||
Result.Add(AGhostTile);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if AStatics then
|
|
||||||
begin
|
|
||||||
drawStatics := GetStaticList(x, y);
|
|
||||||
if drawStatics <> nil then
|
|
||||||
for i := 0 to drawStatics.Count - 1 do
|
|
||||||
if (TStaticItem(drawStatics[i]).Z >= AMinZ) and
|
|
||||||
(TStaticItem(drawStatics[i]).Z <= AMaxZ) and
|
|
||||||
((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then
|
|
||||||
begin
|
|
||||||
UpdateStaticsPriority(TStaticItem(drawStatics[i]), i + 1);
|
|
||||||
Result.Add(Pointer(drawStatics[i]));
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
if AGhostTile is TStaticItem then
|
|
||||||
begin
|
|
||||||
UpdateStaticsPriority(TStaticItem(AGhostTile), MaxInt);
|
|
||||||
Result.Add(AGhostTile);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
//TODO : re add virtual layer
|
|
||||||
{if AVirtualLayer <> nil then
|
|
||||||
begin
|
|
||||||
UpdateStaticsPriority(AVirtualLayer, MaxInt-1);
|
|
||||||
Result.Add(AVirtualLayer);
|
|
||||||
end;}
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result.Sort(@Compare);
|
|
||||||
//ListSort(Result, @Compare);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TLandscape.UpdateDrawListItems(AList: TList);
|
|
||||||
var
|
|
||||||
worldItem: TWorldItem;
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
for i := 0 to AList.Count - 1 do
|
|
||||||
begin
|
|
||||||
worldItem := TWorldItem(AList.Items[i]);
|
|
||||||
worldItem.CanBeEdited := dmNetwork.CanWrite(worldItem.X, worldItem.Y);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt;
|
|
||||||
var
|
|
||||||
north, west, south, east: ShortInt;
|
|
||||||
begin
|
|
||||||
north := ATile.Altitude;
|
|
||||||
west := GetLandAlt(ATile.X, ATile.Y + 1, north);
|
|
||||||
south := GetLandAlt(ATile.X + 1, ATile.Y + 1, north);
|
|
||||||
east := GetLandAlt(ATile.X + 1, ATile.Y, north);
|
|
||||||
|
|
||||||
if Abs(north - south) > Abs(west - east) then
|
|
||||||
Result := (north + south) div 2
|
|
||||||
else
|
|
||||||
Result := (west + east) div 2;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLandscape.GetNormals(AX, AY: Word): TNormals;
|
function TLandscape.GetNormals(AX, AY: Word): TNormals;
|
||||||
var
|
var
|
||||||
cells: array[0..2, 0..2] of TNormals;
|
cells: array[0..2, 0..2] of TNormals;
|
||||||
|
@ -609,74 +505,6 @@ begin
|
||||||
Result[3] := VectorNorm(VectorAdd(VectorAdd(VectorAdd(north, west), east), south));
|
Result[3] := VectorNorm(VectorAdd(VectorAdd(VectorAdd(north, west), east), south));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLandscape.MoveStatic(AStatic: TStaticItem; AX, AY: Word);
|
|
||||||
var
|
|
||||||
sourceBlock, targetBlock: TSeperatedStaticBlock;
|
|
||||||
targetStaticList: TList;
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
if (AX >= 0) and (AX <= FCellWidth) and (AY >= 0) and (AY <= FCellHeight) then
|
|
||||||
begin
|
|
||||||
sourceBlock := AStatic.Owner as TSeperatedStaticBlock;
|
|
||||||
targetBlock := GetStaticBlock(AX div 8, AY div 8);
|
|
||||||
if (sourceBlock <> nil) and (targetBlock <> nil) then
|
|
||||||
begin
|
|
||||||
sourceBlock.Cells[(AStatic.Y mod 8) * 8 + AStatic.X mod 8].Remove(AStatic);
|
|
||||||
targetStaticList := targetBlock.Cells[(AY mod 8) * 8 + AX mod 8];
|
|
||||||
targetStaticList.Add(AStatic);
|
|
||||||
for i := 0 to targetStaticList.Count - 1 do
|
|
||||||
UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i);
|
|
||||||
targetStaticList.Sort(@Compare);
|
|
||||||
//ListSort(targetStaticList, @Compare);
|
|
||||||
AStatic.UpdatePos(AX, AY, AStatic.Z);
|
|
||||||
AStatic.Owner := targetBlock;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TLandscape.PrepareBlocks(AX1, AY1, AX2, AY2: Word);
|
|
||||||
var
|
|
||||||
x, y, i, mapID, staticID: Integer;
|
|
||||||
coords: TBlockCoordsArray;
|
|
||||||
obj: TObject;
|
|
||||||
begin
|
|
||||||
AX1 := EnsureRange(AX1, 0, FWidth - 1);
|
|
||||||
AY1 := EnsureRange(AY1, 0, FHeight - 1);
|
|
||||||
AX2 := EnsureRange(AX2, 0, FWidth - 1);
|
|
||||||
AY2 := EnsureRange(AY2, 0, FHeight - 1);
|
|
||||||
|
|
||||||
SetLength(coords, 0);
|
|
||||||
for x := AX1 to AX2 do
|
|
||||||
begin
|
|
||||||
for y := AY1 to AY2 do
|
|
||||||
begin
|
|
||||||
if (not FOpenRequests[y * FWidth + x]) and
|
|
||||||
(not FBlockCache.QueryID(GetID(x, y), obj)) then
|
|
||||||
begin
|
|
||||||
SetLength(coords, Length(coords) + 1);
|
|
||||||
i := High(coords);
|
|
||||||
coords[i].X := x;
|
|
||||||
coords[i].Y := y;
|
|
||||||
FOpenRequests[y * FWidth + x] := True;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if Length(coords) > 0 then
|
|
||||||
dmNetwork.Send(TRequestBlocksPacket.Create(coords));
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLandscape.GetMapBlock(AX, AY: Word): TMapBlock;
|
|
||||||
var
|
|
||||||
block: TBlock;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
if (AX >= 0) and (AX < FWidth) and (AY >= 0) and (AY < FHeight) then
|
|
||||||
begin
|
|
||||||
if FBlockCache.QueryID(GetID(AX, AY), TObject(block)) then
|
|
||||||
Result := block.Map;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLandscape.GetStaticBlock(AX, AY: Word): TSeperatedStaticBlock;
|
function TLandscape.GetStaticBlock(AX, AY: Word): TSeperatedStaticBlock;
|
||||||
var
|
var
|
||||||
block: TBlock;
|
block: TBlock;
|
||||||
|
@ -689,19 +517,26 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLandscape.UpdateStaticsPriority(AStaticItem: TStaticItem;
|
function TLandscape.GetStaticList(AX, AY: Word): TList;
|
||||||
APrioritySolver: Integer);
|
|
||||||
var
|
var
|
||||||
staticTileData: TStaticTileData;
|
block: TSeperatedStaticBlock;
|
||||||
begin
|
begin
|
||||||
staticTileData := ResMan.Tiledata.StaticTiles[AStaticItem.TileID];
|
Result := nil;
|
||||||
AStaticItem.PriorityBonus := 0;
|
if (AX >= 0) and (AX <= FCellWidth) and (AY >= 0) and (AY <= FCellHeight) then
|
||||||
if not ((staticTileData.Flags and tdfBackground) = tdfBackground) then
|
begin
|
||||||
AStaticItem.PriorityBonus := AStaticItem.PriorityBonus + 1;
|
block := GetStaticBlock(AX div 8, AY div 8);
|
||||||
if staticTileData.Height > 0 then
|
if block <> nil then
|
||||||
AStaticItem.PriorityBonus := AStaticItem.PriorityBonus + 1;
|
Result := block.Cells[(AY mod 8) * 8 + AX mod 8];
|
||||||
AStaticItem.Priority := AStaticItem.Z + AStaticItem.PriorityBonus;
|
end;
|
||||||
AStaticItem.PrioritySolver := APrioritySolver;
|
end;
|
||||||
|
|
||||||
|
procedure TLandscape.OnRemoveCachedObject(AObject: TObject);
|
||||||
|
var
|
||||||
|
block: TBlock;
|
||||||
|
begin
|
||||||
|
block := AObject as TBlock;
|
||||||
|
if block <> nil then
|
||||||
|
dmNetwork.Send(TFreeBlockPacket.Create(block.Map.X, block.Map.Y));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLandscape.OnBlocksPacket(ABuffer: TEnhancedMemoryStream);
|
procedure TLandscape.OnBlocksPacket(ABuffer: TEnhancedMemoryStream);
|
||||||
|
@ -718,19 +553,19 @@ begin
|
||||||
begin
|
begin
|
||||||
ABuffer.Read(coords, SizeOf(TBlockCoords));
|
ABuffer.Read(coords, SizeOf(TBlockCoords));
|
||||||
id := GetID(coords.X, coords.Y);
|
id := GetID(coords.X, coords.Y);
|
||||||
|
|
||||||
map := TMapBlock.Create(ABuffer, coords.X, coords.Y);
|
map := TMapBlock.Create(ABuffer, coords.X, coords.Y);
|
||||||
count := ABuffer.ReadWord;
|
count := ABuffer.ReadWord;
|
||||||
if count > 0 then
|
if count > 0 then
|
||||||
index.Lookup := ABuffer.Position
|
index.Lookup := ABuffer.Position
|
||||||
else
|
else
|
||||||
index.Lookup := $FFFFFFFF;
|
index.Lookup := -1;
|
||||||
index.Size := count * 7;
|
index.Size := count * 7;
|
||||||
statics := TSeperatedStaticBlock.Create(ABuffer, index, coords.X, coords.Y);
|
statics := TSeperatedStaticBlock.Create(ABuffer, index, coords.X, coords.Y);
|
||||||
|
|
||||||
FBlockCache.RemoveID(id);
|
FBlockCache.RemoveID(id);
|
||||||
FBlockCache.StoreID(id, TBlock.Create(map, statics));
|
FBlockCache.StoreID(id, TBlock.Create(map, statics));
|
||||||
|
|
||||||
FOpenRequests[coords.Y * FWidth + coords.X] := False;
|
FOpenRequests[coords.Y * FWidth + coords.X] := False;
|
||||||
end;
|
end;
|
||||||
index.Free;
|
index.Free;
|
||||||
|
@ -776,8 +611,7 @@ begin
|
||||||
targetStaticList.Add(staticItem);
|
targetStaticList.Add(staticItem);
|
||||||
for i := 0 to targetStaticList.Count - 1 do
|
for i := 0 to targetStaticList.Count - 1 do
|
||||||
UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i);
|
UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i);
|
||||||
targetStaticList.Sort(@Compare);
|
targetStaticList.Sort(@CompareWorldItems);
|
||||||
//ListSort(targetStaticList, @Compare);
|
|
||||||
staticItem.Owner := block;
|
staticItem.Owner := block;
|
||||||
if Assigned(FOnChange) then FOnChange;
|
if Assigned(FOnChange) then FOnChange;
|
||||||
end;
|
end;
|
||||||
|
@ -835,8 +669,7 @@ begin
|
||||||
staticItem.Z := ABuffer.ReadShortInt;
|
staticItem.Z := ABuffer.ReadShortInt;
|
||||||
for j := 0 to statics.Count - 1 do
|
for j := 0 to statics.Count - 1 do
|
||||||
UpdateStaticsPriority(TStaticItem(statics.Items[j]), j);
|
UpdateStaticsPriority(TStaticItem(statics.Items[j]), j);
|
||||||
statics.Sort(@Compare);
|
statics.Sort(@CompareWorldItems);
|
||||||
//ListSort(statics, @Compare);
|
|
||||||
if Assigned(FOnChange) then FOnChange;
|
if Assigned(FOnChange) then FOnChange;
|
||||||
Break;
|
Break;
|
||||||
end;
|
end;
|
||||||
|
@ -852,7 +685,6 @@ var
|
||||||
staticInfo: TStaticInfo;
|
staticInfo: TStaticInfo;
|
||||||
staticItem: TStaticItem;
|
staticItem: TStaticItem;
|
||||||
newX, newY: Word;
|
newX, newY: Word;
|
||||||
item: PLinkedItem;
|
|
||||||
begin
|
begin
|
||||||
staticItem := nil;
|
staticItem := nil;
|
||||||
ABuffer.Read(staticInfo, SizeOf(TStaticInfo));
|
ABuffer.Read(staticInfo, SizeOf(TStaticInfo));
|
||||||
|
@ -883,7 +715,7 @@ begin
|
||||||
staticItem.Delete;
|
staticItem.Delete;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if targetBlock <> nil then
|
if targetBlock <> nil then
|
||||||
begin
|
begin
|
||||||
staticItem := TStaticItem.Create(nil, nil, 0, 0);
|
staticItem := TStaticItem.Create(nil, nil, 0, 0);
|
||||||
|
@ -896,18 +728,17 @@ begin
|
||||||
statics.Add(staticItem);
|
statics.Add(staticItem);
|
||||||
for i := 0 to statics.Count - 1 do
|
for i := 0 to statics.Count - 1 do
|
||||||
UpdateStaticsPriority(TStaticItem(statics.Items[i]), i);
|
UpdateStaticsPriority(TStaticItem(statics.Items[i]), i);
|
||||||
statics.Sort(@Compare);
|
statics.Sort(@CompareWorldItems);
|
||||||
//ListSort(statics, @Compare);
|
|
||||||
staticItem.Owner := targetBlock;
|
staticItem.Owner := targetBlock;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Assigned(FOnChange) then FOnChange;
|
if Assigned(FOnChange) then FOnChange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLandscape.OnHueStaticPacket(ABuffer: TEnhancedMemoryStream);
|
procedure TLandscape.OnHueStaticPacket(ABuffer: TEnhancedMemoryStream);
|
||||||
var
|
var
|
||||||
block: TSeperatedStaticBlock;
|
block: TSeperatedStaticBlock;
|
||||||
i,j : Integer;
|
i : Integer;
|
||||||
statics: TList;
|
statics: TList;
|
||||||
staticInfo: TStaticInfo;
|
staticInfo: TStaticInfo;
|
||||||
staticItem: TStaticItem;
|
staticItem: TStaticItem;
|
||||||
|
@ -932,13 +763,145 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLandscape.OnRemoveCachedObject(AObject: TObject);
|
procedure TLandscape.FillDrawList(ADrawList: TScreenBuffer; AX, AY, AWidth,
|
||||||
|
AHeight: Word; AMinZ, AMaxZ: ShortInt; AMap, AStatics: Boolean;
|
||||||
|
ANoDraw: Boolean; AStaticsFilter: TStaticFilter);
|
||||||
var
|
var
|
||||||
block: TBlock;
|
landAlt: ShortInt;
|
||||||
|
drawMapCell: TMapCell;
|
||||||
|
drawStatics: TList;
|
||||||
|
i, x, y: Integer;
|
||||||
begin
|
begin
|
||||||
block := AObject as TBlock;
|
ADrawList.Clear;
|
||||||
if block <> nil then
|
for x := AX to AX + AWidth do
|
||||||
dmNetwork.Send(TFreeBlockPacket.Create(block.Map.X, block.Map.Y));
|
for y := AY to AY + AWidth do
|
||||||
|
begin
|
||||||
|
if AMap then
|
||||||
|
begin
|
||||||
|
landAlt := GetLandAlt(x, y, 0);
|
||||||
|
if (landAlt >= AMinZ) and (landAlt <= AMaxZ) then
|
||||||
|
begin
|
||||||
|
drawMapCell := GetMapCell(x, y);
|
||||||
|
if (drawMapCell <> nil) and (ANoDraw or (drawMapCell.TileID > 2)) then
|
||||||
|
begin
|
||||||
|
drawMapCell.Priority := GetEffectiveAltitude(drawMapCell);
|
||||||
|
drawMapCell.PriorityBonus := 0;
|
||||||
|
drawMapCell.PrioritySolver := 0;
|
||||||
|
ADrawList.Store(drawMapCell);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if AStatics then
|
||||||
|
begin
|
||||||
|
drawStatics := GetStaticList(x, y);
|
||||||
|
if drawStatics <> nil then
|
||||||
|
for i := 0 to drawStatics.Count - 1 do
|
||||||
|
if (TStaticItem(drawStatics[i]).Z >= AMinZ) and
|
||||||
|
(TStaticItem(drawStatics[i]).Z <= AMaxZ) and
|
||||||
|
((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then
|
||||||
|
begin
|
||||||
|
UpdateStaticsPriority(TStaticItem(drawStatics[i]), ADrawList.GetSerial);
|
||||||
|
ADrawList.Store(TWorldItem(drawStatics[i]));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt;
|
||||||
|
var
|
||||||
|
north, west, south, east: ShortInt;
|
||||||
|
begin
|
||||||
|
north := ATile.Altitude;
|
||||||
|
west := GetLandAlt(ATile.X, ATile.Y + 1, north);
|
||||||
|
south := GetLandAlt(ATile.X + 1, ATile.Y + 1, north);
|
||||||
|
east := GetLandAlt(ATile.X + 1, ATile.Y, north);
|
||||||
|
|
||||||
|
if Abs(north - south) > Abs(west - east) then
|
||||||
|
Result := (north + south) div 2
|
||||||
|
else
|
||||||
|
Result := (west + east) div 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLandscape.GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt;
|
||||||
|
var
|
||||||
|
cell: TMapCell;
|
||||||
|
begin
|
||||||
|
cell := MapCell[AX, AY];
|
||||||
|
if cell <> nil then
|
||||||
|
Result := cell.Altitude
|
||||||
|
else
|
||||||
|
Result := ADefault;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLandscape.MoveStatic(AStatic: TStaticItem; AX, AY: Word);
|
||||||
|
var
|
||||||
|
sourceBlock, targetBlock: TSeperatedStaticBlock;
|
||||||
|
targetStaticList: TList;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if (AX >= 0) and (AX <= FCellWidth) and (AY >= 0) and (AY <= FCellHeight) then
|
||||||
|
begin
|
||||||
|
sourceBlock := AStatic.Owner as TSeperatedStaticBlock;
|
||||||
|
targetBlock := GetStaticBlock(AX div 8, AY div 8);
|
||||||
|
if (sourceBlock <> nil) and (targetBlock <> nil) then
|
||||||
|
begin
|
||||||
|
sourceBlock.Cells[(AStatic.Y mod 8) * 8 + AStatic.X mod 8].Remove(AStatic);
|
||||||
|
targetStaticList := targetBlock.Cells[(AY mod 8) * 8 + AX mod 8];
|
||||||
|
targetStaticList.Add(AStatic);
|
||||||
|
for i := 0 to targetStaticList.Count - 1 do
|
||||||
|
UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i);
|
||||||
|
targetStaticList.Sort(@CompareWorldItems);
|
||||||
|
AStatic.UpdatePos(AX, AY, AStatic.Z);
|
||||||
|
AStatic.Owner := targetBlock;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLandscape.PrepareBlocks(AX1, AY1, AX2, AY2: Word);
|
||||||
|
var
|
||||||
|
x, y, i: Integer;
|
||||||
|
coords: TBlockCoordsArray;
|
||||||
|
obj: TObject;
|
||||||
|
begin
|
||||||
|
AX1 := EnsureRange(AX1, 0, FWidth - 1);
|
||||||
|
AY1 := EnsureRange(AY1, 0, FHeight - 1);
|
||||||
|
AX2 := EnsureRange(AX2, 0, FWidth - 1);
|
||||||
|
AY2 := EnsureRange(AY2, 0, FHeight - 1);
|
||||||
|
|
||||||
|
SetLength(coords, 0);
|
||||||
|
for x := AX1 to AX2 do
|
||||||
|
begin
|
||||||
|
for y := AY1 to AY2 do
|
||||||
|
begin
|
||||||
|
if (not FOpenRequests[y * FWidth + x]) and
|
||||||
|
(not FBlockCache.QueryID(GetID(x, y), obj)) then
|
||||||
|
begin
|
||||||
|
SetLength(coords, Length(coords) + 1);
|
||||||
|
i := High(coords);
|
||||||
|
coords[i].X := x;
|
||||||
|
coords[i].Y := y;
|
||||||
|
FOpenRequests[y * FWidth + x] := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Length(coords) > 0 then
|
||||||
|
dmNetwork.Send(TRequestBlocksPacket.Create(coords));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLandscape.UpdateStaticsPriority(AStaticItem: TStaticItem;
|
||||||
|
APrioritySolver: Integer);
|
||||||
|
var
|
||||||
|
staticTileData: TStaticTileData;
|
||||||
|
begin
|
||||||
|
staticTileData := ResMan.Tiledata.StaticTiles[AStaticItem.TileID];
|
||||||
|
AStaticItem.PriorityBonus := 0;
|
||||||
|
if not ((staticTileData.Flags and tdfBackground) = tdfBackground) then
|
||||||
|
AStaticItem.PriorityBonus := AStaticItem.PriorityBonus + 1;
|
||||||
|
if staticTileData.Height > 0 then
|
||||||
|
AStaticItem.PriorityBonus := AStaticItem.PriorityBonus + 1;
|
||||||
|
AStaticItem.Priority := AStaticItem.Z + AStaticItem.PriorityBonus;
|
||||||
|
AStaticItem.PrioritySolver := APrioritySolver;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TMaterial }
|
{ TMaterial }
|
||||||
|
@ -993,8 +956,6 @@ begin
|
||||||
|
|
||||||
FTexture := CreateGLTextureFromImage(FGraphic.ImageDataPointer^, 0, 0, False, ifUnknown, @FWidth, @FHeight);
|
FTexture := CreateGLTextureFromImage(FGraphic.ImageDataPointer^, 0, 0, False, ifUnknown, @FWidth, @FHeight);
|
||||||
glBindTexture(GL_TEXTURE_2D, FTexture);
|
glBindTexture(GL_TEXTURE_2D, FTexture);
|
||||||
{glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, @FWidth);
|
|
||||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, @FHeight);}
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
@ -1076,6 +1037,90 @@ end;
|
||||||
|
|
||||||
{ TScreenBuffer }
|
{ TScreenBuffer }
|
||||||
|
|
||||||
|
constructor TScreenBuffer.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FSerial := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TScreenBuffer.Clear;
|
||||||
|
var
|
||||||
|
current, next: PBlockInfo;
|
||||||
|
begin
|
||||||
|
current := FFirst;
|
||||||
|
while current <> nil do
|
||||||
|
begin
|
||||||
|
next := current^.Next;
|
||||||
|
current^.Item.Locked := False;
|
||||||
|
current^.Item.OnDestroy.UnregisterEvent(@OnTileRemoved);
|
||||||
|
Dispose(current);
|
||||||
|
current := next;
|
||||||
|
end;
|
||||||
|
FFirst := nil;
|
||||||
|
FLastBlock := nil;
|
||||||
|
|
||||||
|
FSerial := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TScreenBuffer.Find(AScreenPosition: TPoint): PBlockInfo;
|
||||||
|
var
|
||||||
|
current: PBlockInfo;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
current := FFirst;
|
||||||
|
while (current <> nil) and (Result = nil) do
|
||||||
|
begin
|
||||||
|
if (not current^.Ghost) and PtInRect(current^.ScreenRect, AScreenPosition) and
|
||||||
|
current^.Material.HitTest(AScreenPosition.x - current^.ScreenRect.Left,
|
||||||
|
AScreenPosition.y - current^.ScreenRect.Top) then
|
||||||
|
begin
|
||||||
|
Result := current;
|
||||||
|
end;
|
||||||
|
current := current^.Next;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TScreenBuffer.GetSerial: Cardinal;
|
||||||
|
begin
|
||||||
|
Result := FSerial
|
||||||
|
Inc(FSerial);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TScreenBuffer.Store(AItem: TWorldItem; AMaterial: TMaterial = nil;
|
||||||
|
AGhost: Boolean = False);
|
||||||
|
var
|
||||||
|
current, existing: PBlockInfo;
|
||||||
|
begin
|
||||||
|
New(current);
|
||||||
|
AItem.Locked := True;
|
||||||
|
AItem.OnDestroy.RegisterEvent(@OnTileRemoved);
|
||||||
|
current^.Item := AItem;
|
||||||
|
current^.Material := AMaterial;
|
||||||
|
current^.Ghost := AGhost;
|
||||||
|
|
||||||
|
if (FFirst = nil) or (CompareWorldItems(AItem, FFirst) > 0) then
|
||||||
|
begin
|
||||||
|
current^.Next := FFirst;
|
||||||
|
if FFirst = nil then
|
||||||
|
FLastBlock := current;
|
||||||
|
FFirst := current;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
existing := FFirst;
|
||||||
|
while (existing^.Next = nil) and
|
||||||
|
(CompareWorldItems(AItem, existing^.Next^.Item) > 0) do
|
||||||
|
begin
|
||||||
|
existing := existing^.Next;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if existing^.Next = nil then
|
||||||
|
FLastBlock := current;
|
||||||
|
|
||||||
|
current^.Next := existing^.Next;
|
||||||
|
existing^.Next := current;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TScreenBuffer.OnTileRemoved(ATile: TMulBlock);
|
procedure TScreenBuffer.OnTileRemoved(ATile: TMulBlock);
|
||||||
var
|
var
|
||||||
currentItem, lastItem, nextItem: PBlockInfo;
|
currentItem, lastItem, nextItem: PBlockInfo;
|
||||||
|
@ -1098,56 +1143,5 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TScreenBuffer.Clear;
|
|
||||||
var
|
|
||||||
current, next: PBlockInfo;
|
|
||||||
begin
|
|
||||||
current := FFirst;
|
|
||||||
while current <> nil do
|
|
||||||
begin
|
|
||||||
next := current^.Next;
|
|
||||||
current^.Item.Locked := False;
|
|
||||||
current^.Item.OnDestroy.UnregisterEvent(@OnTileRemoved);
|
|
||||||
Dispose(current);
|
|
||||||
current := next;
|
|
||||||
end;
|
|
||||||
FFirst := nil;
|
|
||||||
FLastBlock := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TScreenBuffer.Find(AScreenPosition: TPoint): PBlockInfo;
|
|
||||||
var
|
|
||||||
current: PBlockInfo;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
current := FFirst;
|
|
||||||
while (current <> nil) and (Result = nil) do
|
|
||||||
begin
|
|
||||||
if PtInRect(current^.ScreenRect, AScreenPosition) and
|
|
||||||
current^.Material.HitTest(AScreenPosition.x - current^.ScreenRect.Left,
|
|
||||||
AScreenPosition.y - current^.ScreenRect.Top) then
|
|
||||||
begin
|
|
||||||
Result := current;
|
|
||||||
end;
|
|
||||||
current := current^.Next;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TScreenBuffer.Store(AScreenRect: TRect; AItem: TWorldItem;
|
|
||||||
AMaterial: TMaterial);
|
|
||||||
var
|
|
||||||
current: PBlockInfo;
|
|
||||||
begin
|
|
||||||
New(current);
|
|
||||||
AItem.Locked := True;
|
|
||||||
AItem.OnDestroy.RegisterEvent(@OnTileRemoved);
|
|
||||||
current^.ScreenRect := AScreenRect;
|
|
||||||
current^.Item := AItem;
|
|
||||||
current^.Material := AMaterial;
|
|
||||||
current^.Next := FFirst;
|
|
||||||
FFirst := current;
|
|
||||||
if FLastBlock = nil then FLastBlock := current;
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
object frmMain: TfrmMain
|
object frmMain: TfrmMain
|
||||||
Left = 236
|
Left = 232
|
||||||
Height = 603
|
Height = 603
|
||||||
Top = 126
|
Top = 126
|
||||||
Width = 766
|
Width = 766
|
||||||
|
|
|
@ -1675,7 +1675,7 @@ begin
|
||||||
else
|
else
|
||||||
staticsFilter := nil;} //TODO : update list on change
|
staticsFilter := nil;} //TODO : update list on change
|
||||||
|
|
||||||
draw := FLandscape.GetDrawList(FX + lowOffX, FY + lowOffY, rangeX, rangeY,
|
{draw := FLandscape.GetDrawList(FX + lowOffX, FY + lowOffY, rangeX, rangeY,
|
||||||
frmBoundaries.tbMinZ.Position, frmBoundaries.tbMaxZ.Position,
|
frmBoundaries.tbMinZ.Position, frmBoundaries.tbMaxZ.Position,
|
||||||
nil, nil, tbTerrain.Down, tbStatics.Down, //TODO : ghost tile and virtual tile!
|
nil, nil, tbTerrain.Down, tbStatics.Down, //TODO : ghost tile and virtual tile!
|
||||||
acNoDraw.Checked, nil); //TODO : statics filter!
|
acNoDraw.Checked, nil); //TODO : statics filter!
|
||||||
|
@ -1871,7 +1871,7 @@ begin
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
draw.Free;
|
draw.Free;}
|
||||||
|
|
||||||
FOverlayUI.Draw(oglGameWindow);
|
FOverlayUI.Draw(oglGameWindow);
|
||||||
end;
|
end;
|
||||||
|
|
Loading…
Reference in New Issue