- 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 * CDDL HEADER START
* *
* The contents of this file are subject to the terms of the * The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only * Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance * (the "License"). You may not use this file except in compliance
* with the License. * with the License.
* *
* You can obtain a copy of the license at * You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.php. * http://www.opensource.org/licenses/cddl1.php.
* See the License for the specific language governing permissions * See the License for the specific language governing permissions
* and limitations under the License. * and limitations under the License.
* *
* When distributing Covered Code, include this CDDL HEADER in each * When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at * file and include the License file at
* http://www.opensource.org/licenses/cddl1.php. If applicable, * http://www.opensource.org/licenses/cddl1.php. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed * add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying * information: * by brackets "[]" replaced with your own identifying * information:
* Portions Copyright [yyyy] [name of copyright owner] * Portions Copyright [yyyy] [name of copyright owner]
* *
* CDDL HEADER END * CDDL HEADER END
* *
* *
* Portions Copyright 2007 Andreas Schneider * Portions Copyright 2009 Andreas Schneider
*) *)
unit UGameResources; unit UGameResources;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
interface interface
uses uses
Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider, Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider,
ULandscape, {URadarProvider,} UHueProvider; ULandscape, UHueProvider;
type type
{ TGameResourceManager } { TGameResourceManager }
TGameResourceManager = class(TObject) TGameResourceManager = class(TObject)
constructor Create(ADataDir: string); constructor Create(ADataDir: string);
destructor Destroy; override; destructor Destroy; override;
protected protected
FDataDir: string; { Members }
FArtProvider: TArtProvider; FDataDir: string;
FTiledataProvider: TTiledataProvider; FArtProvider: TArtProvider;
FTexmapProvider: TTexmapProvider; FTiledataProvider: TTiledataProvider;
//FRadarProvider: TRadarProvider; FTexmapProvider: TTexmapProvider;
FHueProvider: THueProvider; FHueProvider: THueProvider;
FLandscape: TLandscape;
FLandscape: TLandscape; public
public { Fields }
procedure InitLandscape(AWidth, AHeight: Word); property Art: TArtProvider read FArtProvider;
function GetFile(AFileName: string): string; property Hue: THueProvider read FHueProvider;
property Landscape: TLandscape read FLandscape;
property Art: TArtProvider read FArtProvider; property Tiledata: TTiledataProvider read FTiledataProvider;
property Tiledata: TTiledataProvider read FTiledataProvider; property Texmaps: TTexmapProvider read FTexmapProvider;
property Texmaps: TTexmapProvider read FTexmapProvider;
//property Radar: TRadarProvider read FRadarProvider; { Methods }
property Hue: THueProvider read FHueProvider; function GetFile(AFileName: string): string;
property Landscape: TLandscape read FLandscape; procedure InitLandscape(AWidth, AHeight: Word);
end; end;
var var
GameResourceManager: TGameResourceManager; GameResourceManager: TGameResourceManager;
ResMan: TGameResourceManager absolute GameResourceManager; ResMan: TGameResourceManager absolute GameResourceManager;
procedure InitGameResourceManager(ADataDir: string); procedure InitGameResourceManager(ADataDir: string);
implementation implementation
procedure InitGameResourceManager(ADataDir: string); procedure InitGameResourceManager(ADataDir: string);
begin begin
if GameResourceManager <> nil then FreeAndNil(GameResourceManager); FreeAndNil(GameResourceManager);
GameResourceManager := TGameResourceManager.Create(ADataDir); GameResourceManager := TGameResourceManager.Create(ADataDir);
end; end;
{ TGameResourceManager } { TGameResourceManager }
constructor TGameResourceManager.Create(ADataDir: string); constructor TGameResourceManager.Create(ADataDir: string);
begin begin
inherited Create; inherited Create;
FDataDir := IncludeTrailingPathDelimiter(ADataDir); FDataDir := IncludeTrailingPathDelimiter(ADataDir);
FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True); FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True);
FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True); FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True);
FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'), GetFile('texidx.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);
FHueProvider := THueProvider.Create(GetFile('hues.mul'), True); end;
end;
destructor TGameResourceManager.Destroy;
destructor TGameResourceManager.Destroy; begin
begin FreeAndNil(FArtProvider);
if FArtProvider <> nil then FreeAndNil(FArtProvider); FreeAndNil(FTiledataProvider);
if FTiledataProvider <> nil then FreeAndNil(FTiledataProvider); FreeAndNil(FTexmapProvider);
if FTexmapProvider <> nil then FreeAndNil(FTexmapProvider); FreeAndNil(FHueProvider);
//if FRadarProvider <> nil then FreeAndNil(FRadarProvider); FreeAndNil(FLandscape);
if FHueProvider <> nil then FreeAndNil(FHueProvider); inherited Destroy;
if FLandscape <> nil then FreeAndNil(FLandscape); end;
inherited Destroy;
end; function TGameResourceManager.GetFile(AFileName: string): string;
begin
function TGameResourceManager.GetFile(AFileName: string): string; Result := FDataDir + AFileName;
begin end;
Result := FDataDir + AFileName;
end; procedure TGameResourceManager.InitLandscape(AWidth, AHeight: Word);
begin
procedure TGameResourceManager.InitLandscape(AWidth, AHeight: Word); FreeAndNil(FLandscape);
begin FLandscape := TLandscape.Create(AWidth, AHeight);
if FLandscape <> nil then FreeAndNil(FLandscape); end;
FLandscape := TLandscape.Create(AWidth, AHeight);
end; finalization
FreeAndNil(GameResourceManager);
finalization
begin end.
if GameResourceManager <> nil then FreeAndNil(GameResourceManager);
end;
end.

View File

@ -81,6 +81,20 @@ type
FFlatLandArtCache: TCacheManager; FFlatLandArtCache: TCacheManager;
FTexCache: TCacheManager; FTexCache: TCacheManager;
end; 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 } { TBlock }
@ -314,6 +328,104 @@ begin
end; end;
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 } { TBlock }
constructor TBlock.Create(AMap: TMapBlock; AStatics: TStaticBlock); constructor TBlock.Create(AMap: TMapBlock; AStatics: TStaticBlock);
@ -367,7 +479,7 @@ begin
FBlockCache := TCacheManager.Create(256); FBlockCache := TCacheManager.Create(256);
FBlockCache.OnRemoveObject := @OnRemoveCachedObject; FBlockCache.OnRemoveObject := @OnRemoveCachedObject;
SetLength(FOpenRequests, FWidth * FHeight); SetLength(FOpenRequests, FWidth * FHeight); //TODO : TBits?
for blockID := 0 to Length(FOpenRequests) - 1 do for blockID := 0 to Length(FOpenRequests) - 1 do
FOpenRequests[blockID] := False; FOpenRequests[blockID] := False;
@ -535,9 +647,12 @@ begin
targetStaticList := block.Cells[(y mod 8) * 8 + x mod 8]; targetStaticList := block.Cells[(y mod 8) * 8 + x mod 8];
targetStaticList.Add(staticItem); targetStaticList.Add(staticItem);
for i := 0 to targetStaticList.Count - 1 do 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); targetStaticList.Sort(@CompareWorldItems);
staticItem.Owner := block; staticItem.Owner := block;
staticItem.CanBeEdited := dmNetwork.CanWrite(x, y);
if Assigned(FOnChange) then FOnChange; if Assigned(FOnChange) then FOnChange;
end; end;
end; end;
@ -593,7 +708,9 @@ begin
begin begin
staticItem.Z := ABuffer.ReadShortInt; staticItem.Z := ABuffer.ReadShortInt;
for j := 0 to statics.Count - 1 do 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); statics.Sort(@CompareWorldItems);
if Assigned(FOnChange) then FOnChange; if Assigned(FOnChange) then FOnChange;
Break; Break;
@ -652,7 +769,9 @@ begin
statics := targetBlock.Cells[(newY mod 8) * 8 + newX mod 8]; statics := targetBlock.Cells[(newY mod 8) * 8 + newX mod 8];
statics.Add(staticItem); statics.Add(staticItem);
for i := 0 to statics.Count - 1 do 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); statics.Sort(@CompareWorldItems);
staticItem.Owner := targetBlock; staticItem.Owner := targetBlock;
end; end;
@ -726,7 +845,9 @@ begin
(TStaticItem(drawStatics[i]).Z <= AMaxZ) and (TStaticItem(drawStatics[i]).Z <= AMaxZ) and
((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then ((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then
begin 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])); ADrawList.Add(TWorldItem(drawStatics[i]));
end; end;
end; end;
@ -859,7 +980,9 @@ begin
targetStaticList := targetBlock.Cells[(AY mod 8) * 8 + AX mod 8]; targetStaticList := targetBlock.Cells[(AY mod 8) * 8 + AX mod 8];
targetStaticList.Add(AStatic); targetStaticList.Add(AStatic);
for i := 0 to targetStaticList.Count - 1 do 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); targetStaticList.Sort(@CompareWorldItems);
AStatic.UpdatePos(AX, AY, AStatic.Z); AStatic.UpdatePos(AX, AY, AStatic.Z);
AStatic.Owner := targetBlock; AStatic.Owner := targetBlock;

View File

@ -33,25 +33,44 @@ uses
SysUtils, Classes, math, UGenericIndex, UMap, UStatics, UTiledata, SysUtils, Classes, math, UGenericIndex, UMap, UStatics, UTiledata,
UWorldItem, UMulBlock, UWorldItem, UMulBlock,
UTileDataProvider, URadarMap, UTileDataProvider, URadarMap,
UListSort, UCacheManager, ULinkedList, UBufferedStreams, UCacheManager, ULinkedList, UBufferedStreams,
UEnhancedMemoryStream, UPacketHandlers, UPackets, UNetState, UEnums; UEnhancedMemoryStream, UPacketHandlers, UPackets, UNetState, UEnums;
type type
PRadarBlock = ^TRadarBlock; PRadarBlock = ^TRadarBlock;
TRadarBlock = array[0..7, 0..7] of Word; TRadarBlock = array[0..7, 0..7] of Word;
TBlockSubscriptions = array of TLinkedList; 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 }
TBlock = class(TObject) TBlock = class(TObject)
constructor Create(AMap: TMapBlock; AStatics: TStaticBlock); constructor Create(AMap: TMapBlock; AStatics: TSeperatedStaticBlock);
destructor Destroy; override; destructor Destroy; override;
protected protected
FMapBlock: TMapBlock; FMapBlock: TMapBlock;
FStaticBlock: TStaticBlock; FStaticBlock: TSeperatedStaticBlock;
public public
property Map: TMapBlock read FMapBlock; property Map: TMapBlock read FMapBlock;
property Static: TStaticBlock read FStaticBlock; property Static: TSeperatedStaticBlock read FStaticBlock;
end; end;
{ TLandscape } { TLandscape }
@ -76,14 +95,11 @@ type
FRadarMap: TRadarMap; FRadarMap: TRadarMap;
FBlockCache: TCacheManager; FBlockCache: TCacheManager;
FBlockSubscriptions: TBlockSubscriptions; FBlockSubscriptions: TBlockSubscriptions;
function Compare(left, right: TObject): Integer;
procedure OnBlockChanged(ABlock: TMulBlock); procedure OnBlockChanged(ABlock: TMulBlock);
procedure OnRemoveCachedObject(AObject: TObject); procedure OnRemoveCachedObject(AObject: TObject);
function GetMapCell(AX, AY: Word): TMapCell; function GetMapCell(AX, AY: Word): TMapCell;
function GetStaticList(AX, AY: Word): TList; function GetStaticList(AX, AY: Word): TList;
function GetBlockSubscriptions(AX, AY: Word): TLinkedList; function GetBlockSubscriptions(AX, AY: Word): TLinkedList;
procedure UpdateStaticsPriority(AStaticItem: TStaticItem;
APrioritySolver: Integer);
procedure OnDrawMapPacket(ABuffer: TEnhancedMemoryStream; procedure OnDrawMapPacket(ABuffer: TEnhancedMemoryStream;
ANetState: TNetState); ANetState: TNetState);
@ -159,9 +175,107 @@ begin
InRange(AY, AArea.Top, AArea.Bottom); InRange(AY, AArea.Top, AArea.Bottom);
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(
FTiledataProvider.StaticTiles[TStaticItem(Cells[i].Items[j]).TileID],
solver);
Inc(solver);
end;
end;
end;
Sort;
end;
{ TBlock } { TBlock }
constructor TBlock.Create(AMap: TMapBlock; AStatics: TStaticBlock); constructor TBlock.Create(AMap: TMapBlock; AStatics: TSeperatedStaticBlock);
begin begin
inherited Create; inherited Create;
FMapBlock := AMap; FMapBlock := AMap;
@ -170,8 +284,8 @@ end;
destructor TBlock.Destroy; destructor TBlock.Destroy;
begin begin
if FMapBlock <> nil then FreeAndNil(FMapBlock); FreeAndNil(FMapBlock);
if FStaticBlock <> nil then FreeAndNil(FStaticBlock); FreeAndNil(FStaticBlock);
inherited Destroy; inherited Destroy;
end; end;
@ -306,24 +420,6 @@ begin
end; end;
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); procedure TLandscape.UpdateRadar(AX, AY: Word);
var var
mapTile: TMapCell; mapTile: TMapCell;
@ -347,10 +443,12 @@ begin
end; end;
for i := 0 to staticItems.Count - 1 do for i := 0 to staticItems.Count - 1 do
begin 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]); tiles.Add(staticItems.Items[i]);
end; end;
ListSort(tiles, @Compare); tiles.Sort(@CompareWorldItems);
if tiles.Count > 0 then if tiles.Count > 0 then
begin begin
@ -371,8 +469,10 @@ var
i: Integer; i: Integer;
begin begin
for i := 0 to AStatics.Count - 1 do for i := 0 to AStatics.Count - 1 do
UpdateStaticsPriority(TStaticItem(AStatics.Items[i]), i + 1); TStaticItem(AStatics.Items[i]).UpdatePriorities(
ListSort(AStatics, @Compare); FTiledataProvider.StaticTiles[TStaticItem(AStatics.Items[i]).TileID],
i + 1);
AStatics.Sort(@CompareWorldItems);
end; end;
function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt; function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt;
@ -438,7 +538,7 @@ end;
function TLandscape.LoadBlock(AX, AY: Word): TBlock; function TLandscape.LoadBlock(AX, AY: Word): TBlock;
var var
map: TMapBlock; map: TMapBlock;
statics: TStaticBlock; statics: TSeperatedStaticBlock;
index: TGenericIndex; index: TGenericIndex;
begin begin
FMap.Position := ((AX * FHeight) + AY) * 196; FMap.Position := ((AX * FHeight) + AY) * 196;
@ -449,6 +549,7 @@ begin
index := TGenericIndex.Create(FStaIdx); index := TGenericIndex.Create(FStaIdx);
statics := TSeperatedStaticBlock.Create(FStatics, index, AX, AY); statics := TSeperatedStaticBlock.Create(FStatics, index, AX, AY);
statics.OnChanged := @OnBlockChanged; statics.OnChanged := @OnBlockChanged;
statics.TiledataProvider := FTiledataProvider;
index.Free; index.Free;
Result := TBlock.Create(map, statics); Result := TBlock.Create(map, statics);
@ -511,21 +612,6 @@ begin
Result := (FMap.Size = (blocks * 196)) and (FStaIdx.Position = (blocks * 12)); Result := (FMap.Size = (blocks * 196)) and (FStaIdx.Position = (blocks * 12));
end; 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; procedure TLandscape.OnDrawMapPacket(ABuffer: TEnhancedMemoryStream;
ANetState: TNetState); ANetState: TNetState);
var 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 } { Members }
FHue: Word; FHue: Word;
FOrgHue: Word; FOrgHue: Word;
{ Methods } { Methods }
function HasChanged: Boolean; override; function HasChanged: Boolean; override;
procedure SetHue(AHue: Word); procedure SetHue(AHue: Word);
public public
{ Fields } { Fields }
property Hue: Word read FHue write SetHue; property Hue: Word read FHue write SetHue;
{ Methods } { Methods }
function Clone: TStaticItem; override; function Clone: TStaticItem; override;
function GetSize: Integer; override; function GetSize: Integer; override;
procedure InitOriginalState; override; procedure InitOriginalState; override;
procedure UpdatePriorities(ASolver: Integer); procedure UpdatePriorities(ATileData: TStaticTiledata; ASolver: Integer);
procedure Write(AData: TStream); override; procedure Write(AData: TStream); override;
end; end;
@ -68,6 +70,7 @@ type
public public
{ Fields } { Fields }
property Items: TList read FItems write FItems; property Items: TList read FItems write FItems;
{ Methods } { Methods }
function Clone: TStaticBlock; override; function Clone: TStaticBlock; override;
function GetSize: Integer; override; function GetSize: Integer; override;
@ -76,25 +79,8 @@ type
procedure Write(AData: TStream); override; procedure Write(AData: TStream); override;
end; 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 implementation
uses
UGameResources; //Used for priority calculation
{ TStaticItem } { TStaticItem }
constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX, ABlockY: Word); constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX, ABlockY: Word);
@ -153,15 +139,13 @@ begin
inherited InitOriginalState; inherited InitOriginalState;
end; end;
procedure TStaticItem.UpdatePriorities(ASolver: Integer); procedure TStaticItem.UpdatePriorities(ATileData: TStaticTiledata;
var ASolver: Integer);
staticTileData: TStaticTileData;
begin begin
staticTileData := ResMan.Tiledata.StaticTiles[FTileID];
FPriorityBonus := 0; FPriorityBonus := 0;
if not ((staticTileData.Flags and tdfBackground) = tdfBackground) then if not ((ATileData.Flags and tdfBackground) = tdfBackground) then
Inc(FPriorityBonus); Inc(FPriorityBonus);
if staticTileData.Height > 0 then if ATileData.Height > 0 then
Inc(FPriorityBonus); Inc(FPriorityBonus);
FPriority := Z + FPriorityBonus; FPriority := Z + FPriorityBonus;
FPrioritySolver := ASolver; FPrioritySolver := ASolver;
@ -265,104 +249,5 @@ begin
TStaticItem(FItems[i]).Write(AData); TStaticItem(FItems[i]).Write(AData);
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
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. end.