- Added dynamic tiledata loading (everything after $4000 will be treated as static)

- Fixed server's TLandscape to validate statics and throw errors if no tiledata entry is found
This commit is contained in:
Andreas Schneider 2009-12-17 23:01:06 +01:00
parent b0b014f66a
commit bdc97b89f5
5 changed files with 2086 additions and 2054 deletions

View File

@ -34,7 +34,7 @@ uses
type
TLandTileDataArray = array[$0..$3FFF] of TLandTileData;
TStaticTileDataArray = array[$0..$3FFF] of TStaticTileData;
TStaticTileDataArray = array of TStaticTileData;
{ TTiledataProvider }
@ -45,6 +45,7 @@ type
protected
FLandTiles: TLandTileDataArray;
FStaticTiles: TStaticTileDataArray;
FStaticCount: Cardinal;
procedure InitArray;
function CalculateOffset(AID: Integer): Integer; override;
function GetData(AID, AOffset: Integer): TMulBlock; override;
@ -55,10 +56,14 @@ type
property LandTiles: TLandTileDataArray read FLandTiles;
property StaticTiles: TStaticTileDataArray read FStaticTiles;
property TileData[AID: Integer]: TTiledata read GetTileData; //all tiles, no cloning
property StaticCount: Cardinal read FStaticCount;
end;
implementation
uses
Logging;
{ TTiledataProvider }
function TTiledataProvider.CalculateOffset(AID: Integer): Integer;
@ -83,12 +88,11 @@ var
i: Integer;
begin
for i := $0 to $3FFF do
begin
FreeAndNil(FLandTiles[i]);
for i := 0 to FStaticCount - 1 do
FreeAndNil(FStaticTiles[i]);
end;
inherited;
inherited Destroy;
end;
function TTiledataProvider.GetBlock(AID: Integer): TMulBlock;
@ -111,15 +115,23 @@ procedure TTiledataProvider.InitArray;
var
i: Integer;
begin
FData.Position := 0;
Logger.Send([lcInfo], 'Loading $4000 LandTiledata Entries');
for i := $0 to $3FFF do
begin
FData.Position := GetTileDataOffset(i);
if i mod 32 = 0 then
FData.Seek(4, soFromCurrent);
FLandTiles[i] := TLandTileData.Create(FData);
end;
for i := $0 to $3FFF do
FStaticCount := ((FData.Size - FData.Position) div StaticTileGroupSize) * 32;
Logger.Send([lcInfo], 'Loading $%x StaticTiledata Entries', [FStaticCount]);
SetLength(FStaticTiles, FStaticCount);
for i := 0 to FStaticCount - 1 do
begin
FData.Position := GetTileDataOffset($4000 + i);
if i mod 32 = 0 then
FData.Seek(4, soFromCurrent);
FStaticTiles[i] := TStaticTileData.Create(FData);
end;
end;
@ -127,6 +139,9 @@ end;
procedure TTiledataProvider.SetData(AID, AOffset: Integer;
ABlock: TMulBlock);
begin
if AID >= $4000 + FStaticCount then
Exit;
if AID < $4000 then
begin
FreeAndNil(FLandTiles[AID]);

View File

@ -30,8 +30,7 @@ unit ULandscape;
interface
uses
SysUtils, Classes, math, UGenericIndex, UMap, UStatics, UTiledata,
UWorldItem, UMulBlock,
SysUtils, Classes, math, UGenericIndex, UMap, UStatics, UWorldItem, UMulBlock,
UTileDataProvider, URadarMap,
UCacheManager, ULinkedList, UBufferedStreams,
UEnhancedMemoryStream, UPacketHandlers, UPackets, UNetState, UEnums;
@ -52,7 +51,8 @@ type
public
{ Fields }
Cells: array[0..63] of TStaticItemList;
property TiledataProvider: TTiledataProvider read FTiledataProvider write FTiledataProvider;
property TiledataProvider: TTiledataProvider read FTiledataProvider
write FTiledataProvider;
{ Methods }
function Clone: TSeperatedStaticBlock; override;
@ -62,7 +62,7 @@ type
{ TBlock }
TBlock = class(TObject)
TBlock = class
constructor Create(AMap: TMapBlock; AStatics: TSeperatedStaticBlock);
destructor Destroy; override;
protected
@ -77,7 +77,7 @@ type
{ TLandscape }
TLandscape = class(TObject)
TLandscape = class
constructor Create(AMap, AStatics, AStaIdx, ATiledata, ARadarCol: string;
AWidth, AHeight: Word; var AValid: Boolean);
constructor Create(AMap, AStatics, AStaIdx, ATiledata: TStream;
@ -164,7 +164,7 @@ function PointInArea(AArea: TAreaInfo; AX, AY: Word): Boolean; inline;
implementation
uses
UCEDServer, UConnectionHandling, UConfig, ULargeScaleOperations;
UCEDServer, UConnectionHandling, UConfig, ULargeScaleOperations, Logging;
function GetID(AX, AY: Word): Integer;
begin
@ -217,7 +217,7 @@ end;
destructor TSeperatedStaticBlock.Destroy;
var
i, j: Integer;
i: Integer;
begin
FreeAndNil(FItems);
@ -230,6 +230,7 @@ end;
function TSeperatedStaticBlock.Clone: TSeperatedStaticBlock;
begin
raise Exception.Create('TSeperatedStaticBlock.Clone is not implemented (yet).');
Result := nil;
end;
function TSeperatedStaticBlock.GetSize: Integer;
@ -251,8 +252,13 @@ begin
for j := 0 to Cells[i].Count - 1 do
begin
FItems.Add(Cells[i].Items[j]);
if Cells[i].Items[j].TileID < FTiledataProvider.StaticCount then
begin
Cells[i].Items[j].UpdatePriorities(
FTiledataProvider.StaticTiles[Cells[i].Items[j].TileID], solver);
end else
Logger.Send([lcLandscape, lcServer, lcError], 'Cannot find Tiledata ' +
'for the Static Item with ID $%x.', [Cells[i].Items[j].TileID]);
Inc(solver);
end;
end;
@ -430,10 +436,15 @@ begin
tiles.Add(mapTile);
end;
for i := 0 to staticItems.Count - 1 do
begin
if staticItems[i].TileID < FTiledataProvider.StaticCount then
begin
staticItems[i].UpdatePriorities(
FTiledataProvider.StaticTiles[staticItems[i].TileID],
i + 1);
end else
Logger.Send([lcLandscape, lcServer, lcError], 'Cannot find Tiledata ' +
'for the Static Item with ID $%x.', [staticItems[i].TileID]);
tiles.Add(staticItems[i]);
end;
tiles.Sort(@CompareWorldItems);
@ -457,9 +468,14 @@ var
i: Integer;
begin
for i := 0 to AStatics.Count - 1 do
if AStatics[i].TileID < FTiledataProvider.StaticCount then
begin
AStatics[i].UpdatePriorities(
FTiledataProvider.StaticTiles[AStatics[i].TileID],
i + 1);
end else
Logger.Send([lcLandscape, lcServer, lcError], 'Cannot find Tiledata ' +
'for the Static Item with ID $%x.', [AStatics[i].TileID]);
AStatics.Sort(@CompareStaticItems);
end;

View File

@ -28,7 +28,7 @@ unit UPacketHandlers;
interface
uses
Classes, SysUtils, dzlib, math, UConfig, UNetState, UEnhancedMemoryStream, UEnums,
Classes, SysUtils, dzlib, UConfig, UNetState, UEnhancedMemoryStream, UEnums,
ULinkedList, URegions;
type

View File

@ -140,7 +140,8 @@
<LinkSmart Value="True"/>
</Linking>
<Other>
<CustomOptions Value="-FE../bin/ "/>
<CustomOptions Value="-FE../bin/
"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>

View File

@ -211,7 +211,7 @@ end;
constructor TStaticTiledata.Create(AData: TStream);
begin
SetLength(FTileName, 20);
if assigned(AData) then
if AData <> nil then
begin
AData.Read(FFlags, SizeOf(LongWord));
AData.Read(FWeight, SizeOf(Byte));