diff --git a/Client/UGameResources.pas b/Client/UGameResources.pas index c615762..2b8863b 100644 --- a/Client/UGameResources.pas +++ b/Client/UGameResources.pas @@ -1,120 +1,116 @@ -(* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at - * http://www.opensource.org/licenses/cddl1.php. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at - * http://www.opensource.org/licenses/cddl1.php. If applicable, - * add the following below this CDDL HEADER, with the fields enclosed - * by brackets "[]" replaced with your own identifying * information: - * Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * - * Portions Copyright 2007 Andreas Schneider - *) -unit UGameResources; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider, - ULandscape, {URadarProvider,} UHueProvider; - -type - - { TGameResourceManager } - - TGameResourceManager = class(TObject) - constructor Create(ADataDir: string); - destructor Destroy; override; - protected - FDataDir: string; - FArtProvider: TArtProvider; - FTiledataProvider: TTiledataProvider; - FTexmapProvider: TTexmapProvider; - //FRadarProvider: TRadarProvider; - FHueProvider: THueProvider; - - FLandscape: TLandscape; - public - procedure InitLandscape(AWidth, AHeight: Word); - function GetFile(AFileName: string): string; - - property Art: TArtProvider read FArtProvider; - property Tiledata: TTiledataProvider read FTiledataProvider; - property Texmaps: TTexmapProvider read FTexmapProvider; - //property Radar: TRadarProvider read FRadarProvider; - property Hue: THueProvider read FHueProvider; - property Landscape: TLandscape read FLandscape; - end; - -var - GameResourceManager: TGameResourceManager; - ResMan: TGameResourceManager absolute GameResourceManager; - -procedure InitGameResourceManager(ADataDir: string); - -implementation - -procedure InitGameResourceManager(ADataDir: string); -begin - if GameResourceManager <> nil then FreeAndNil(GameResourceManager); - GameResourceManager := TGameResourceManager.Create(ADataDir); -end; - -{ TGameResourceManager } - -constructor TGameResourceManager.Create(ADataDir: string); -begin - inherited Create; - FDataDir := IncludeTrailingPathDelimiter(ADataDir); - - FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True); - FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True); - FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'), GetFile('texidx.mul'), True); - //FRadarProvider := TRadarProvider.Create(GetFile('radarcol.mul')); - FHueProvider := THueProvider.Create(GetFile('hues.mul'), True); -end; - -destructor TGameResourceManager.Destroy; -begin - if FArtProvider <> nil then FreeAndNil(FArtProvider); - if FTiledataProvider <> nil then FreeAndNil(FTiledataProvider); - if FTexmapProvider <> nil then FreeAndNil(FTexmapProvider); - //if FRadarProvider <> nil then FreeAndNil(FRadarProvider); - if FHueProvider <> nil then FreeAndNil(FHueProvider); - if FLandscape <> nil then FreeAndNil(FLandscape); - inherited Destroy; -end; - -function TGameResourceManager.GetFile(AFileName: string): string; -begin - Result := FDataDir + AFileName; -end; - -procedure TGameResourceManager.InitLandscape(AWidth, AHeight: Word); -begin - if FLandscape <> nil then FreeAndNil(FLandscape); - FLandscape := TLandscape.Create(AWidth, AHeight); -end; - -finalization -begin - if GameResourceManager <> nil then FreeAndNil(GameResourceManager); -end; - -end. - +(* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at + * http://www.opensource.org/licenses/cddl1.php. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at + * http://www.opensource.org/licenses/cddl1.php. If applicable, + * add the following below this CDDL HEADER, with the fields enclosed + * by brackets "[]" replaced with your own identifying * information: + * Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * + * Portions Copyright 2009 Andreas Schneider + *) +unit UGameResources; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider, + ULandscape, UHueProvider; + +type + + { TGameResourceManager } + + TGameResourceManager = class(TObject) + constructor Create(ADataDir: string); + destructor Destroy; override; + protected + { Members } + FDataDir: string; + FArtProvider: TArtProvider; + FTiledataProvider: TTiledataProvider; + FTexmapProvider: TTexmapProvider; + FHueProvider: THueProvider; + FLandscape: TLandscape; + public + { Fields } + property Art: TArtProvider read FArtProvider; + property Hue: THueProvider read FHueProvider; + property Landscape: TLandscape read FLandscape; + property Tiledata: TTiledataProvider read FTiledataProvider; + property Texmaps: TTexmapProvider read FTexmapProvider; + + { Methods } + function GetFile(AFileName: string): string; + procedure InitLandscape(AWidth, AHeight: Word); + end; + +var + GameResourceManager: TGameResourceManager; + ResMan: TGameResourceManager absolute GameResourceManager; + +procedure InitGameResourceManager(ADataDir: string); + +implementation + +procedure InitGameResourceManager(ADataDir: string); +begin + FreeAndNil(GameResourceManager); + GameResourceManager := TGameResourceManager.Create(ADataDir); +end; + +{ TGameResourceManager } + +constructor TGameResourceManager.Create(ADataDir: string); +begin + inherited Create; + FDataDir := IncludeTrailingPathDelimiter(ADataDir); + + FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True); + FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True); + FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'), GetFile('texidx.mul'), True); + FHueProvider := THueProvider.Create(GetFile('hues.mul'), True); +end; + +destructor TGameResourceManager.Destroy; +begin + FreeAndNil(FArtProvider); + FreeAndNil(FTiledataProvider); + FreeAndNil(FTexmapProvider); + FreeAndNil(FHueProvider); + FreeAndNil(FLandscape); + inherited Destroy; +end; + +function TGameResourceManager.GetFile(AFileName: string): string; +begin + Result := FDataDir + AFileName; +end; + +procedure TGameResourceManager.InitLandscape(AWidth, AHeight: Word); +begin + FreeAndNil(FLandscape); + FLandscape := TLandscape.Create(AWidth, AHeight); +end; + +finalization + FreeAndNil(GameResourceManager); + +end. + diff --git a/Client/ULandscape.pas b/Client/ULandscape.pas index 25c6585..e84cf38 100644 --- a/Client/ULandscape.pas +++ b/Client/ULandscape.pas @@ -81,6 +81,20 @@ type FFlatLandArtCache: TCacheManager; FTexCache: TCacheManager; end; + + { TSeperatedStaticBlock } + + TSeperatedStaticBlock = class(TStaticBlock) + constructor Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); overload; + constructor Create(AData: TStream; AIndex: TGenericIndex); overload; + destructor Destroy; override; + public + Cells: array[0..63] of TList; + { Methods } + function Clone: TSeperatedStaticBlock; override; + function GetSize: Integer; override; + procedure RebuildList; + end; { TBlock } @@ -314,6 +328,104 @@ begin end; end; +{ TSeperatedStaticBlock } + +constructor TSeperatedStaticBlock.Create(AData: TStream; AIndex: TGenericIndex; + AX, AY: Word); +var + i: Integer; + item: TStaticItem; + block: TMemoryStream; +begin + inherited Create; + FItems := TList.Create; + + FX := AX; + FY := AY; + + for i := 0 to 63 do + Cells[i] := TList.Create; + + if (AData <> nil) and (AIndex.Lookup > 0) and (AIndex.Size > 0) then + begin + AData.Position := AIndex.Lookup; + block := TMemoryStream.Create; + block.CopyFrom(AData, AIndex.Size); + block.Position := 0; + for i := 1 to (AIndex.Size div 7) do + begin + item := TStaticItem.Create(Self, block, AX, AY); + Cells[(item.Y mod 8) * 8 + (item.X mod 8)].Add(item); + end; + block.Free; + end; +end; + +constructor TSeperatedStaticBlock.Create(AData: TStream; AIndex: TGenericIndex); +begin + Create(AData, AIndex, 0, 0); +end; + +destructor TSeperatedStaticBlock.Destroy; +var + i, j: Integer; +begin + FreeAndNil(FItems); + + for i := 0 to 63 do + begin + if Cells[i] <> nil then + begin + for j := 0 to Cells[i].Count - 1 do + begin + if Cells[i][j] <> nil then + begin + TStaticItem(Cells[i][j]).Free; + Cells[i][j] := nil; + end; + end; + Cells[i].Free; + Cells[i] := nil; + end; + end; + + inherited Destroy; +end; + +function TSeperatedStaticBlock.Clone: TSeperatedStaticBlock; +begin + raise Exception.Create('TSeperatedStaticBlock.Clone is not implemented (yet).'); +end; + +function TSeperatedStaticBlock.GetSize: Integer; +begin + RebuildList; + Result := inherited GetSize; +end; + +procedure TSeperatedStaticBlock.RebuildList; +var + i, j, solver: Integer; +begin + FItems.Clear; + solver := 0; + for i := 0 to 63 do + begin + if Cells[i] <> nil then + begin + for j := 0 to Cells[i].Count - 1 do + begin + FItems.Add(Cells[i].Items[j]); + TStaticItem(Cells[i].Items[j]).UpdatePriorities( + ResMan.Tiledata.StaticTiles[TStaticItem(Cells[i].Items[j]).TileID], + solver); + Inc(solver); + end; + end; + end; + Sort; +end; + { TBlock } constructor TBlock.Create(AMap: TMapBlock; AStatics: TStaticBlock); @@ -367,7 +479,7 @@ begin FBlockCache := TCacheManager.Create(256); FBlockCache.OnRemoveObject := @OnRemoveCachedObject; - SetLength(FOpenRequests, FWidth * FHeight); + SetLength(FOpenRequests, FWidth * FHeight); //TODO : TBits? for blockID := 0 to Length(FOpenRequests) - 1 do FOpenRequests[blockID] := False; @@ -535,9 +647,12 @@ begin targetStaticList := block.Cells[(y mod 8) * 8 + x mod 8]; targetStaticList.Add(staticItem); for i := 0 to targetStaticList.Count - 1 do - TStaticItem(targetStaticList.Items[i]).UpdatePriorities(i); + TStaticItem(targetStaticList.Items[i]).UpdatePriorities( + ResMan.Tiledata.StaticTiles[TStaticItem(targetStaticList.Items[i]).TileID], + i); targetStaticList.Sort(@CompareWorldItems); staticItem.Owner := block; + staticItem.CanBeEdited := dmNetwork.CanWrite(x, y); if Assigned(FOnChange) then FOnChange; end; end; @@ -593,7 +708,9 @@ begin begin staticItem.Z := ABuffer.ReadShortInt; for j := 0 to statics.Count - 1 do - TStaticItem(statics.Items[j]).UpdatePriorities(j); + TStaticItem(statics.Items[j]).UpdatePriorities( + ResMan.Tiledata.StaticTiles[TStaticItem(statics.Items[j]).TileID], + j); statics.Sort(@CompareWorldItems); if Assigned(FOnChange) then FOnChange; Break; @@ -652,7 +769,9 @@ begin statics := targetBlock.Cells[(newY mod 8) * 8 + newX mod 8]; statics.Add(staticItem); for i := 0 to statics.Count - 1 do - TStaticItem(statics.Items[i]).UpdatePriorities(i); + TStaticItem(statics.Items[i]).UpdatePriorities( + ResMan.Tiledata.StaticTiles[TStaticItem(statics.Items[i]).TileID], + i); statics.Sort(@CompareWorldItems); staticItem.Owner := targetBlock; end; @@ -726,7 +845,9 @@ begin (TStaticItem(drawStatics[i]).Z <= AMaxZ) and ((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then begin - TStaticItem(drawStatics[i]).UpdatePriorities(ADrawList.GetSerial); + TStaticItem(drawStatics[i]).UpdatePriorities( + ResMan.Tiledata.StaticTiles[TStaticItem(drawStatics[i]).TileID], + ADrawList.GetSerial); ADrawList.Add(TWorldItem(drawStatics[i])); end; end; @@ -859,7 +980,9 @@ begin targetStaticList := targetBlock.Cells[(AY mod 8) * 8 + AX mod 8]; targetStaticList.Add(AStatic); for i := 0 to targetStaticList.Count - 1 do - TStaticItem(targetStaticList.Items[i]).UpdatePriorities(i); + TStaticItem(targetStaticList.Items[i]).UpdatePriorities( + ResMan.Tiledata.StaticTiles[TStaticItem(targetStaticList.Items[i]).TileID], + i); targetStaticList.Sort(@CompareWorldItems); AStatic.UpdatePos(AX, AY, AStatic.Z); AStatic.Owner := targetBlock; diff --git a/Server/ULandscape.pas b/Server/ULandscape.pas index c7dfaa2..56eab5c 100644 --- a/Server/ULandscape.pas +++ b/Server/ULandscape.pas @@ -33,25 +33,44 @@ uses SysUtils, Classes, math, UGenericIndex, UMap, UStatics, UTiledata, UWorldItem, UMulBlock, UTileDataProvider, URadarMap, - UListSort, UCacheManager, ULinkedList, UBufferedStreams, + UCacheManager, ULinkedList, UBufferedStreams, UEnhancedMemoryStream, UPacketHandlers, UPackets, UNetState, UEnums; type PRadarBlock = ^TRadarBlock; TRadarBlock = array[0..7, 0..7] of Word; TBlockSubscriptions = array of TLinkedList; + + { TSeperatedStaticBlock } + + TSeperatedStaticBlock = class(TStaticBlock) + constructor Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); overload; + constructor Create(AData: TStream; AIndex: TGenericIndex); overload; + destructor Destroy; override; + protected + FTiledataProvider: TTiledataProvider; + public + { Fields } + Cells: array[0..63] of TList; + property TiledataProvider: TTiledataProvider read FTiledataProvider write FTiledataProvider; + + { Methods } + function Clone: TSeperatedStaticBlock; override; + function GetSize: Integer; override; + procedure RebuildList; + end; { TBlock } TBlock = class(TObject) - constructor Create(AMap: TMapBlock; AStatics: TStaticBlock); + constructor Create(AMap: TMapBlock; AStatics: TSeperatedStaticBlock); destructor Destroy; override; protected FMapBlock: TMapBlock; - FStaticBlock: TStaticBlock; + FStaticBlock: TSeperatedStaticBlock; public property Map: TMapBlock read FMapBlock; - property Static: TStaticBlock read FStaticBlock; + property Static: TSeperatedStaticBlock read FStaticBlock; end; { TLandscape } @@ -76,14 +95,11 @@ type FRadarMap: TRadarMap; FBlockCache: TCacheManager; FBlockSubscriptions: TBlockSubscriptions; - function Compare(left, right: TObject): Integer; procedure OnBlockChanged(ABlock: TMulBlock); procedure OnRemoveCachedObject(AObject: TObject); function GetMapCell(AX, AY: Word): TMapCell; function GetStaticList(AX, AY: Word): TList; function GetBlockSubscriptions(AX, AY: Word): TLinkedList; - procedure UpdateStaticsPriority(AStaticItem: TStaticItem; - APrioritySolver: Integer); procedure OnDrawMapPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState); @@ -159,9 +175,107 @@ begin InRange(AY, AArea.Top, AArea.Bottom); end; +{ TSeperatedStaticBlock } + +constructor TSeperatedStaticBlock.Create(AData: TStream; AIndex: TGenericIndex; + AX, AY: Word); +var + i: Integer; + item: TStaticItem; + block: TMemoryStream; +begin + inherited Create; + FItems := TList.Create; + + FX := AX; + FY := AY; + + for i := 0 to 63 do + Cells[i] := TList.Create; + + if (AData <> nil) and (AIndex.Lookup > 0) and (AIndex.Size > 0) then + begin + AData.Position := AIndex.Lookup; + block := TMemoryStream.Create; + block.CopyFrom(AData, AIndex.Size); + block.Position := 0; + for i := 1 to (AIndex.Size div 7) do + begin + item := TStaticItem.Create(Self, block, AX, AY); + Cells[(item.Y mod 8) * 8 + (item.X mod 8)].Add(item); + end; + block.Free; + end; +end; + +constructor TSeperatedStaticBlock.Create(AData: TStream; AIndex: TGenericIndex); +begin + Create(AData, AIndex, 0, 0); +end; + +destructor TSeperatedStaticBlock.Destroy; +var + i, j: Integer; +begin + FreeAndNil(FItems); + + for i := 0 to 63 do + begin + if Cells[i] <> nil then + begin + for j := 0 to Cells[i].Count - 1 do + begin + if Cells[i][j] <> nil then + begin + TStaticItem(Cells[i][j]).Free; + Cells[i][j] := nil; + end; + end; + Cells[i].Free; + Cells[i] := nil; + end; + end; + + inherited Destroy; +end; + +function TSeperatedStaticBlock.Clone: TSeperatedStaticBlock; +begin + raise Exception.Create('TSeperatedStaticBlock.Clone is not implemented (yet).'); +end; + +function TSeperatedStaticBlock.GetSize: Integer; +begin + RebuildList; + Result := inherited GetSize; +end; + +procedure TSeperatedStaticBlock.RebuildList; +var + i, j, solver: Integer; +begin + FItems.Clear; + solver := 0; + for i := 0 to 63 do + begin + if Cells[i] <> nil then + begin + for j := 0 to Cells[i].Count - 1 do + begin + FItems.Add(Cells[i].Items[j]); + TStaticItem(Cells[i].Items[j]).UpdatePriorities( + FTiledataProvider.StaticTiles[TStaticItem(Cells[i].Items[j]).TileID], + solver); + Inc(solver); + end; + end; + end; + Sort; +end; + { TBlock } -constructor TBlock.Create(AMap: TMapBlock; AStatics: TStaticBlock); +constructor TBlock.Create(AMap: TMapBlock; AStatics: TSeperatedStaticBlock); begin inherited Create; FMapBlock := AMap; @@ -170,8 +284,8 @@ end; destructor TBlock.Destroy; begin - if FMapBlock <> nil then FreeAndNil(FMapBlock); - if FStaticBlock <> nil then FreeAndNil(FStaticBlock); + FreeAndNil(FMapBlock); + FreeAndNil(FStaticBlock); inherited Destroy; end; @@ -306,24 +420,6 @@ begin end; end; -function TLandscape.Compare(left, right: TObject): Integer; -begin - Result := TWorldItem(right).Priority - TWorldItem(left).Priority; - if Result = 0 then - begin - if (left is TMapCell) and (right is TStaticItem) then - Result := 1 - else if (left is TStaticItem) and (right is TMapCell) then - Result := -1; - end; - - if Result = 0 then - Result := TWorldItem(right).PriorityBonus - TWorldItem(left).PriorityBonus; - - if Result = 0 then - Result := TWorldItem(right).PrioritySolver - TWorldItem(left).PrioritySolver; -end; - procedure TLandscape.UpdateRadar(AX, AY: Word); var mapTile: TMapCell; @@ -347,10 +443,12 @@ begin end; for i := 0 to staticItems.Count - 1 do begin - UpdateStaticsPriority(TStaticItem(staticItems.Items[i]), i + 1); + TStaticItem(staticItems.Items[i]).UpdatePriorities( + FTiledataProvider.StaticTiles[TStaticItem(staticItems.Items[i]).TileID], + i + 1); tiles.Add(staticItems.Items[i]); end; - ListSort(tiles, @Compare); + tiles.Sort(@CompareWorldItems); if tiles.Count > 0 then begin @@ -371,8 +469,10 @@ var i: Integer; begin for i := 0 to AStatics.Count - 1 do - UpdateStaticsPriority(TStaticItem(AStatics.Items[i]), i + 1); - ListSort(AStatics, @Compare); + TStaticItem(AStatics.Items[i]).UpdatePriorities( + FTiledataProvider.StaticTiles[TStaticItem(AStatics.Items[i]).TileID], + i + 1); + AStatics.Sort(@CompareWorldItems); end; function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt; @@ -438,7 +538,7 @@ end; function TLandscape.LoadBlock(AX, AY: Word): TBlock; var map: TMapBlock; - statics: TStaticBlock; + statics: TSeperatedStaticBlock; index: TGenericIndex; begin FMap.Position := ((AX * FHeight) + AY) * 196; @@ -449,6 +549,7 @@ begin index := TGenericIndex.Create(FStaIdx); statics := TSeperatedStaticBlock.Create(FStatics, index, AX, AY); statics.OnChanged := @OnBlockChanged; + statics.TiledataProvider := FTiledataProvider; index.Free; Result := TBlock.Create(map, statics); @@ -511,21 +612,6 @@ begin Result := (FMap.Size = (blocks * 196)) and (FStaIdx.Position = (blocks * 12)); end; -procedure TLandscape.UpdateStaticsPriority(AStaticItem: TStaticItem; - APrioritySolver: Integer); -var - staticTileData: TStaticTileData; -begin - staticTileData := FTiledataProvider.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; - procedure TLandscape.OnDrawMapPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState); var diff --git a/UOLib/UListSort.pas b/UOLib/UListSort.pas deleted file mode 100644 index 25eab8b..0000000 --- a/UOLib/UListSort.pas +++ /dev/null @@ -1,87 +0,0 @@ -(* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at - * http://www.opensource.org/licenses/cddl1.php. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at - * http://www.opensource.org/licenses/cddl1.php. If applicable, - * add the following below this CDDL HEADER, with the fields enclosed - * by brackets "[]" replaced with your own identifying * information: - * Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * - * Portions Copyright 2007 Andreas Schneider - *) -unit UListSort; - -{$mode objfpc}{$H+} - -interface - -uses - Classes; - -type - TListSortCompare = function(Left, Right: TObject): Integer of object; - -procedure ListSort(List: TList; Compare: TListSortCompare); - -implementation - -procedure ListSort(List: TList; Compare: TListSortCompare); -var - iMin, iMax: Integer; - Temp: Pointer; - - procedure sift; - var - i, j: integer; - begin - i := iMin; - j := 2 * i; - Temp := Pointer(List[i]); - while j <= iMax do - begin - if j < iMax then - if Compare(TObject(List[j]), TObject(List[j + 1])) > 0 then inc(j); - if Compare(TObject(Temp), TObject(List[j])) <= 0 then break; - List[i] := Pointer(List[j]); - i := j; - j := 2 * i; - end; - List[i] := Temp; - end; - -begin - if List.Count > 0 then - begin - iMax := List.Count - 1; - iMin := iMax div 2 + 1; - while iMin > 0 do - begin - dec(iMin); - sift; - end; - while iMax > 0 do - begin - Temp := Pointer(List[iMin]); - List[iMin] := Pointer(List[iMax]); - List[iMax] := Temp; - dec(iMax); - sift; - end; - end; -end; - -end. diff --git a/UOLib/UStatics.pas b/UOLib/UStatics.pas index 1c10e5e..0a4b9ef 100644 --- a/UOLib/UStatics.pas +++ b/UOLib/UStatics.pas @@ -42,17 +42,19 @@ type { Members } FHue: Word; FOrgHue: Word; + { Methods } function HasChanged: Boolean; override; procedure SetHue(AHue: Word); public { Fields } property Hue: Word read FHue write SetHue; + { Methods } function Clone: TStaticItem; override; function GetSize: Integer; override; procedure InitOriginalState; override; - procedure UpdatePriorities(ASolver: Integer); + procedure UpdatePriorities(ATileData: TStaticTiledata; ASolver: Integer); procedure Write(AData: TStream); override; end; @@ -68,6 +70,7 @@ type public { Fields } property Items: TList read FItems write FItems; + { Methods } function Clone: TStaticBlock; override; function GetSize: Integer; override; @@ -76,25 +79,8 @@ type procedure Write(AData: TStream); override; end; - { TSeperatedStaticBlock } - - TSeperatedStaticBlock = class(TStaticBlock) - constructor Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); overload; - constructor Create(AData: TStream; AIndex: TGenericIndex); overload; - destructor Destroy; override; - public - Cells: array[0..63] of TList; - { Methods } - function Clone: TSeperatedStaticBlock; override; - function GetSize: Integer; override; - procedure RebuildList; - end; - implementation -uses - UGameResources; //Used for priority calculation - { TStaticItem } constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX, ABlockY: Word); @@ -153,15 +139,13 @@ begin inherited InitOriginalState; end; -procedure TStaticItem.UpdatePriorities(ASolver: Integer); -var - staticTileData: TStaticTileData; +procedure TStaticItem.UpdatePriorities(ATileData: TStaticTiledata; + ASolver: Integer); begin - staticTileData := ResMan.Tiledata.StaticTiles[FTileID]; FPriorityBonus := 0; - if not ((staticTileData.Flags and tdfBackground) = tdfBackground) then + if not ((ATileData.Flags and tdfBackground) = tdfBackground) then Inc(FPriorityBonus); - if staticTileData.Height > 0 then + if ATileData.Height > 0 then Inc(FPriorityBonus); FPriority := Z + FPriorityBonus; FPrioritySolver := ASolver; @@ -265,104 +249,5 @@ begin TStaticItem(FItems[i]).Write(AData); end; -{ TSeperatedStaticBlock } - -constructor TSeperatedStaticBlock.Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); -var - i: Integer; - item: TStaticItem; - block: TMemoryStream; -begin - inherited Create; - FItems := TList.Create; - - FX := AX; - FY := AY; - - for i := 0 to 63 do - Cells[i] := TList.Create; - - if (AData <> nil) and (AIndex.Lookup > 0) and (AIndex.Size > 0) then - begin - AData.Position := AIndex.Lookup; - block := TMemoryStream.Create; - block.CopyFrom(AData, AIndex.Size); - block.Position := 0; - for i := 1 to (AIndex.Size div 7) do - begin - item := TStaticItem.Create(Self, block, AX, AY); - Cells[(item.Y mod 8) * 8 + (item.X mod 8)].Add(item); - end; - block.Free; - end; -end; - -constructor TSeperatedStaticBlock.Create(AData: TStream; AIndex: TGenericIndex); -begin - Create(AData, AIndex, 0, 0); -end; - -destructor TSeperatedStaticBlock.Destroy; -var - i, j: Integer; -begin - if Assigned(FItems) then FreeAndNil(FItems); - for i := 0 to 63 do - begin - if Cells[i] <> nil then - begin - for j := 0 to Cells[i].Count - 1 do - begin - if Cells[i][j] <> nil then - begin - TStaticItem(Cells[i][j]).Free; - Cells[i][j] := nil; - end; - end; - Cells[i].Free; - Cells[i] := nil; - end; - end; - inherited Destroy; -end; - -procedure TSeperatedStaticBlock.RebuildList; -var - i, j, solver: Integer; -begin - FItems.Clear; - solver := 0; - for i := 0 to 63 do - begin - if Cells[i] <> nil then - begin - for j := 0 to Cells[i].Count - 1 do - begin - FItems.Add(Cells[i].Items[j]); - TStaticItem(Cells[i].Items[j]).UpdatePriorities(solver); - Inc(solver); - end; - end; - end; - Sort; -end; - -function TSeperatedStaticBlock.Clone: TSeperatedStaticBlock; -var - i, j: Integer; -begin - Result := TSeperatedStaticBlock.Create(nil, nil, FX, FY); - - for i := 0 to 63 do - for j := 0 to Cells[i].Count - 1 do - Result.Cells[i].Add(TSeperatedStaticBlock(Cells[i].Items[j]).Clone); -end; - -function TSeperatedStaticBlock.GetSize: Integer; -begin - RebuildList; - Result := inherited GetSize; -end; - end.