- Replaced usages of UListSort with TList.Sort

- Removed now obsolete UListSort.pas
- Removed GameResourceManager dependency from TStatics
- Moved TSeperatedStaticBlock to the according ULandscape units
- Cleanup some unnecessary <> nil checks
This commit is contained in:
Andreas Schneider 2009-08-02 19:08:56 +02:00
parent dc932985e2
commit fbbe988dd6
5 changed files with 387 additions and 384 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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.