- 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:
parent
b0b014f66a
commit
bdc97b89f5
|
@ -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]);
|
||||
|
|
|
@ -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]);
|
||||
Cells[i].Items[j].UpdatePriorities(
|
||||
FTiledataProvider.StaticTiles[Cells[i].Items[j].TileID], solver);
|
||||
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;
|
||||
|
@ -431,9 +437,14 @@ begin
|
|||
end;
|
||||
for i := 0 to staticItems.Count - 1 do
|
||||
begin
|
||||
staticItems[i].UpdatePriorities(
|
||||
FTiledataProvider.StaticTiles[staticItems[i].TileID],
|
||||
i + 1);
|
||||
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
|
||||
AStatics[i].UpdatePriorities(
|
||||
FTiledataProvider.StaticTiles[AStatics[i].TileID],
|
||||
i + 1);
|
||||
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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
<LinkSmart Value="True"/>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-FE../bin/
"/>
|
||||
<CustomOptions Value="-FE../bin/
|
||||
"/>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue