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

View File

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

View File

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

View File

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

View File

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