- Added TTileDataFlag enum

- Added TTileDataFlags set
- Changed TTiledata.Flags to use the TTileDataFlags set
- Added hue highlighting to TfrmMain
- Added TTextureManager.GetStaticMaterial to handle tiledata and hues
This commit is contained in:
Andreas Schneider 2009-12-03 00:04:19 +01:00
parent b90ea02421
commit d5e5510760
7 changed files with 511 additions and 464 deletions

View File

@ -56,7 +56,7 @@
<MinVersion Major="4" Minor="5" Release="1" Valid="True"/> <MinVersion Major="4" Minor="5" Release="1" Valid="True"/>
</Item5> </Item5>
</RequiredPackages> </RequiredPackages>
<Units Count="31"> <Units Count="34">
<Unit0> <Unit0>
<Filename Value="CentrED.lpr"/> <Filename Value="CentrED.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -253,6 +253,21 @@
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="Logging"/> <UnitName Value="Logging"/>
</Unit30> </Unit30>
<Unit31>
<Filename Value="../UOLib/UStatics.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="UStatics"/>
</Unit31>
<Unit32>
<Filename Value="../UOLib/UWorldItem.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="UWorldItem"/>
</Unit32>
<Unit33>
<Filename Value="../UOLib/UMap.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="UMap"/>
</Unit33>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -1,37 +1,37 @@
(* (*
* 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 2009 Andreas Schneider * Portions Copyright 2009 Andreas Schneider
*) *)
program CentrED; program CentrED;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
uses uses
{$IFDEF UNIX}{$IFDEF UseCThreads} {$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads, cthreads,
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset Interfaces, // this includes the LCL widgetset
Forms, LResources, lnetvisual, LazOpenGLContext, UdmNetwork, UfrmMain, Forms, LResources, lnetvisual, LazOpenGLContext, UdmNetwork, UfrmMain,
UfrmLogin, UfrmInitialize, UfrmAccountControl, virtualtreeview_package, UfrmLogin, UfrmInitialize, UfrmAccountControl, virtualtreeview_package,
multiloglaz, UfrmEditAccount, UfrmDrawSettings, UfrmBoundaries, multiloglaz, UfrmEditAccount, UfrmDrawSettings, UfrmBoundaries,
@ -40,14 +40,14 @@ uses
UfrmLargeScaleCommand, UfrmVirtualLayer, UfrmFilter, UfrmTileInfo, UfrmLargeScaleCommand, UfrmVirtualLayer, UfrmFilter, UfrmTileInfo,
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets, UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow, UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
Logging; Logging, UMap, UWorldItem, UStatics;
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF} {$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}
begin begin
{$I CentrED.lrs} {$I CentrED.lrs}
Application.Initialize; Application.Initialize;
Application.CreateForm(TdmNetwork, dmNetwork); Application.CreateForm(TdmNetwork, dmNetwork);
Application.Run; Application.Run;
end. end.

View File

@ -72,15 +72,18 @@ type
TLandTextureManager = class TLandTextureManager = class
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
function GetArtMaterial(ATileID: Word): TMaterial; overload;
function GetArtMaterial(ATileID: Word; AHue: THue;
APartialHue: Boolean): TMaterial; overload;
function GetFlatLandMaterial(ATileID: Word): TMaterial;
function GetTexMaterial(ATileID: Word): TMaterial;
protected protected
FArtCache: TCacheManager; FArtCache: TCacheManager;
FFlatLandArtCache: TCacheManager; FFlatLandArtCache: TCacheManager;
FTexCache: TCacheManager; FTexCache: TCacheManager;
public
function GetArtMaterial(ATileID: Word): TMaterial; overload;
function GetArtMaterial(ATileID: Word; AHue: THue;
APartialHue: Boolean): TMaterial; overload;
function GetFlatLandMaterial(ATileID: Word): TMaterial;
function GetStaticMaterial(AStaticItem: TStaticItem;
AOverrideHue: Integer = -1): TMaterial;
function GetTexMaterial(ATileID: Word): TMaterial;
end; end;
{ TSeperatedStaticBlock } { TSeperatedStaticBlock }
@ -205,6 +208,7 @@ type
Normals: PNormals; Normals: PNormals;
State: TScreenState; State: TScreenState;
Highlighted: Boolean; Highlighted: Boolean;
HueOverride: Boolean;
Next: PBlockInfo; Next: PBlockInfo;
end; end;
@ -290,7 +294,8 @@ begin
end; end;
end; end;
function TLandTextureManager.GetArtMaterial(ATileID: Word; AHue: THue; APartialHue: Boolean): TMaterial; function TLandTextureManager.GetArtMaterial(ATileID: Word; AHue: THue;
APartialHue: Boolean): TMaterial;
var var
artEntry: TArt; artEntry: TArt;
id: Integer; id: Integer;
@ -330,6 +335,25 @@ begin
end; end;
end; end;
function TLandTextureManager.GetStaticMaterial(AStaticItem: TStaticItem;
AOverrideHue: Integer = -1): TMaterial;
var
staticTiledata: TStaticTiledata;
hue: THue;
begin
staticTiledata := ResMan.Tiledata.StaticTiles[AStaticItem.TileID];
if AOverrideHue < 0 then
AOverrideHue := AStaticItem.Hue;
if AOverrideHue > 0 then
hue := ResMan.Hue.Hues[AOverrideHue]
else
hue := nil;
Result := GetArtMaterial($4000 + AStaticItem.TileID, hue,
tdfPartialHue in staticTiledata.Flags);
end;
function TLandTextureManager.GetTexMaterial(ATileID: Word): TMaterial; function TLandTextureManager.GetTexMaterial(ATileID: Word): TMaterial;
var var
texEntry: TTexture; texEntry: TTexture;
@ -706,8 +730,8 @@ begin
(staticItem.Hue = staticInfo.Hue) then (staticItem.Hue = staticInfo.Hue) then
begin begin
if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem); if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem);
statics.Delete(i);
staticItem.Delete; staticItem.Delete;
statics.Delete(i);
Break; Break;
end; end;
@ -785,8 +809,8 @@ begin
if staticItem <> nil then if staticItem <> nil then
begin begin
if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem); if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem);
statics.Remove(staticItem);
staticItem.Delete; staticItem.Delete;
statics.Remove(staticItem);
end; end;
end; end;

View File

@ -1733,8 +1733,6 @@ var
west, south, east: Single; west, south, east: Single;
z: SmallInt; z: SmallInt;
staticItem: TStaticItem; staticItem: TStaticItem;
hue: THue;
staticTiledata: TStaticTiledata;
begin begin
//add normals to map tiles and materials where possible //add normals to map tiles and materials where possible
@ -1806,13 +1804,8 @@ begin
begin begin
staticItem := TStaticItem(item); staticItem := TStaticItem(item);
staticTiledata := ResMan.Tiledata.StaticTiles[staticItem.TileID]; ABlockInfo^.LowRes := FTextureManager.GetStaticMaterial(staticItem);
if staticItem.Hue > 0 then ABlockInfo^.HueOverride := False;
hue := ResMan.Hue.Hues[staticItem.Hue - 1]
else
hue := nil;
ABlockInfo^.LowRes := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue);
ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - ABlockInfo^.LowRes.RealWidth / 2), ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - ABlockInfo^.LowRes.RealWidth / 2),
Trunc(drawY + 44 - ABlockInfo^.LowRes.RealHeight - z * 4), Trunc(drawY + 44 - ABlockInfo^.LowRes.RealHeight - z * 4),
ABlockInfo^.LowRes.RealWidth, ABlockInfo^.LowRes.RealWidth,
@ -2292,6 +2285,27 @@ procedure TfrmMain.UpdateSelection;
var var
selectedRect: TRect; selectedRect: TRect;
blockInfo: PBlockInfo; blockInfo: PBlockInfo;
procedure SetHighlight(ABlockInfo: PBlockInfo; AHighlighted: Boolean);
begin
if (ABlockInfo^.Item is TStaticItem) and acHue.Checked then
begin
if ABlockInfo^.HueOverride <> AHighlighted then
begin
ABlockInfo^.HueOverride := AHighlighted;
if AHighlighted then
ABlockInfo^.LowRes := FTextureManager.GetStaticMaterial(
TStaticItem(ABlockInfo^.Item), frmHueSettings.lbHue.ItemIndex)
else
ABlockInfo^.LowRes := FTextureManager.GetStaticMaterial(
TStaticItem(ABlockInfo^.Item));
end;
end else
begin
ABlockInfo^.Highlighted := AHighlighted;
end;
end;
begin begin
Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection'); Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection');
if (CurrentTile <> nil) and (not acSelect.Checked) then if (CurrentTile <> nil) and (not acSelect.Checked) then
@ -2303,14 +2317,15 @@ begin
selectedRect := GetSelectedRect; selectedRect := GetSelectedRect;
Logger.Send([lcClient, lcDebug], 'SelectedRect', selectedRect); Logger.Send([lcClient, lcDebug], 'SelectedRect', selectedRect);
while FScreenBuffer.Iterate(blockInfo) do while FScreenBuffer.Iterate(blockInfo) do
if blockInfo^.State = ssNormal then if (blockInfo^.State = ssNormal) then
blockInfo^.Highlighted := PtInRect(selectedRect, Point(blockInfo^.Item.X, blockInfo^.Item.Y)); SetHighlight(blockInfo, PtInRect(selectedRect,
Point(blockInfo^.Item.X, blockInfo^.Item.Y)));
end else end else
begin begin
Logger.Send([lcClient, lcDebug], 'Single Target'); Logger.Send([lcClient, lcDebug], 'Single Target');
while FScreenBuffer.Iterate(blockInfo) do while FScreenBuffer.Iterate(blockInfo) do
if blockInfo^.State = ssNormal then if blockInfo^.State = ssNormal then
blockInfo^.Highlighted := (blockInfo^.Item = CurrentTile); SetHighlight(blockInfo, (blockInfo^.Item = CurrentTile));
end; end;
end; end;
Logger.ExitMethod([lcClient, lcDebug], 'UpdateSelection'); Logger.ExitMethod([lcClient, lcDebug], 'UpdateSelection');

View File

@ -80,9 +80,9 @@ var
tileData: TTiledata; tileData: TTiledata;
prefix, flags: string; prefix, flags: string;
procedure UpdateFlags(AFlag: LongWord; AName: string); procedure UpdateFlags(AFlag: TTileDataFlag; AName: string);
begin begin
if tileData.HasFlag(AFlag) then if AFlag in tileData.Flags then
begin begin
if flags <> '' then if flags <> '' then
flags := flags + ', ' + AName flags := flags + ', ' + AName
@ -111,9 +111,9 @@ begin
tileData := ResMan.Tiledata.StaticTiles[ATileID]; tileData := ResMan.Tiledata.StaticTiles[ATileID];
end; end;
if tileData.HasFlag(tdfArticleA) then if tdfArticleA in tileData.Flags then
prefix := 'a ' prefix := 'a '
else if tileData.HasFlag(tdfArticleAn) then else if tdfArticleAn in tileData.Flags then
prefix := 'an ' prefix := 'an '
else else
prefix := ''; prefix := '';

View File

@ -36,7 +36,8 @@ type
{ TStaticItem } { TStaticItem }
TStaticItem = class(TWorldItem) TStaticItem = class(TWorldItem)
constructor Create(AOwner: TWorldBlock; AData: TStream; ABlockX, ABlockY: Word); overload; constructor Create(AOwner: TWorldBlock; AData: TStream; ABlockX,
ABlockY: Word); overload;
constructor Create(AOwner: TWorldBlock; AData: TStream); overload; constructor Create(AOwner: TWorldBlock; AData: TStream); overload;
protected protected
{ Members } { Members }
@ -63,7 +64,8 @@ type
{ TStaticBlock} { TStaticBlock}
TStaticBlock = class(TWorldBlock) TStaticBlock = class(TWorldBlock)
constructor Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); overload; constructor Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word);
overload;
constructor Create(AData: TStream; AIndex: TGenericIndex); overload; constructor Create(AData: TStream; AIndex: TGenericIndex); overload;
destructor Destroy; override; destructor Destroy; override;
protected protected
@ -92,12 +94,14 @@ end;
{ TStaticItem } { TStaticItem }
constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX, ABlockY: Word); constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX,
ABlockY: Word);
var var
iX, iY: Byte; iX, iY: Byte;
begin begin
inherited Create(AOwner); inherited Create(AOwner);
if assigned(AData) then
if AData <> nil then
begin begin
AData.Read(FTileID, SizeOf(SmallInt)); AData.Read(FTileID, SizeOf(SmallInt));
AData.Read(iX, SizeOf(Byte)); AData.Read(iX, SizeOf(Byte));
@ -108,6 +112,7 @@ begin
FX := ABlockX * 8 + iX; FX := ABlockX * 8 + iX;
FY := ABlockY * 8 + iY; FY := ABlockY * 8 + iY;
end; end;
InitOriginalState; InitOriginalState;
end; end;
@ -152,7 +157,7 @@ procedure TStaticItem.UpdatePriorities(ATileData: TStaticTiledata;
ASolver: Integer); ASolver: Integer);
begin begin
FPriorityBonus := 0; FPriorityBonus := 0;
if not ((ATileData.Flags and tdfBackground) = tdfBackground) then if not (tdfBackground in ATileData.Flags) then
Inc(FPriorityBonus); Inc(FPriorityBonus);
if ATileData.Height > 0 then if ATileData.Height > 0 then
Inc(FPriorityBonus); Inc(FPriorityBonus);
@ -176,7 +181,8 @@ end;
{ TStaticBlock } { TStaticBlock }
constructor TStaticBlock.Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); constructor TStaticBlock.Create(AData: TStream; AIndex: TGenericIndex;
AX, AY: Word);
var var
i: Integer; i: Integer;
block: TMemoryStream; block: TMemoryStream;

View File

@ -1,388 +1,375 @@
(* (*
* 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 2008 Andreas Schneider * Portions Copyright 2009 Andreas Schneider
*) *)
unit UTiledata; unit UTiledata;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
interface interface
uses uses
Classes, SysUtils, UMulBlock; Classes, SysUtils, UMulBlock;
const const
tdfBackground = $00000001; LandTileDataSize = 26;
tdfWeapon = $00000002; LandTileGroupSize = 4 + 32 * LandTileDataSize;
tdfTransparent = $00000004; StaticTileDataSize = 37;
tdfTranslucent = $00000008; StaticTileGroupSize = 4 + 32 * StaticTileDataSize;
tdfWall = $00000010;
tdfDamaging = $00000020; type
tdfImpassable = $00000040; TTileDataFlag = (tdfBackground, tdfWeapon, tdfTransparent, tdfTranslucent,
tdfWet = $00000080; tdfWall, tdfDamaging, tdfImpassable, tdfWet, tdfUnknown1,
tdfUnknown1 = $00000100; tdfSurface, tdfBridge, tdfGeneric, tdfWindow, tdfNoShoot,
tdfSurface = $00000200; tdfArticleA, tdfArticleAn, tdfInternal, tdfFoliage,
tdfBridge = $00000400; tdfPartialHue, tdfUnknown2, tdfMap, tdfContainer,
tdfGeneric = $00000800; tdfWearable, tdfLightSource, tdfAnimation, tdfNoDiagonal,
tdfWindow = $00001000; tdfArtUsed, tdfArmor, tdfRoof, tdfDoor, tdfStairBack,
tdfNoShoot = $00002000; tdfStairRight);
tdfArticleA = $00004000; TTileDataFlags = set of TTileDataFlag;
tdfArticleAn = $00008000;
tdfInternal = $00010000; { TTiledata }
tdfFoliage = $00020000;
tdfPartialHue = $00040000; TTiledata = class(TMulBlock)
tdfUnknown2 = $00080000; protected
tdfMap = $00100000; FFlags: TTileDataFlags;
tdfContainer = $00200000; FTileName: string;
tdfWearable = $00400000; public
tdfLightSource = $00800000; property Flags: TTileDataFlags read FFlags write FFlags;
tdfAnimation = $01000000; property TileName: string read FTileName write FTileName;
tdfNoDiagonal = $02000000; end;
tdfArtUsed = $04000000;
tdfArmor = $08000000; { TLandTiledata }
tdfRoof = $10000000;
tdfDoor = $20000000; TLandTiledata = class(TTiledata)
tdfStairBack = $40000000; constructor Create(AData: TStream);
tdfStairRight = $80000000; destructor Destroy; override;
function Clone: TLandTiledata; override;
LandTileDataSize = 26; function GetSize: Integer; override;
LandTileGroupSize = 4 + 32 * LandTileDataSize; procedure Write(AData: TStream); override;
StaticTileDataSize = 37; protected
StaticTileGroupSize = 4 + 32 * StaticTileDataSize; FTextureID: Word;
public
type property TextureID: Word read FTextureID write FTextureID;
end;
{ TTiledata }
{ TStaticTiledata }
TTiledata = class(TMulBlock)
protected TStaticTiledata = class(TTiledata)
FFlags: LongWord; constructor Create(AData: TStream);
FTileName: string; destructor Destroy; override;
public function Clone: TStaticTiledata; override;
property Flags: LongWord read FFlags write FFlags; function GetSize: Integer; override;
property TileName: string read FTileName write FTileName; procedure Write(AData: TStream); override;
protected
function HasFlag(AFlag: LongWord): Boolean; FWeight: Byte;
end; FQuality: Byte;
TLandTiledata = class(TTiledata) FUnknown1: Word;
constructor Create(AData: TStream); FUnknown2: Byte;
destructor Destroy; override; FQuantity: Byte;
function Clone: TLandTiledata; override; FAnimID: Word;
function GetSize: Integer; override; FUnknown3: Byte;
procedure Write(AData: TStream); override; FHue: Byte;
protected FUnknown4: Word;
FTextureID: Word; FHeight: Byte;
public public
property TextureID: Word read FTextureID write FTextureID; property Weight: Byte read FWeight write FWeight;
end; property Quality: Byte read FQuality write FQuality;
TStaticTiledata = class(TTiledata) property Unknown1: Word read FUnknown1 write FUnknown1;
constructor Create(AData: TStream); property Unknown2: Byte read FUnknown2 write FUnknown2;
destructor Destroy; override; property Quantity: Byte read FQuantity write FQuantity;
function Clone: TStaticTiledata; override; property AnimID: Word read FAnimID write FAnimID;
function GetSize: Integer; override; property Unknown3: Byte read FUnknown3 write FUnknown3;
procedure Write(AData: TStream); override; property Hue: Byte read FHue write FHue;
protected property Unknown4: Word read FUnknown4 write FUnknown4;
FWeight: Byte; property Height: Byte read FHeight write FHeight;
FQuality: Byte; end;
FUnknown1: Word;
FUnknown2: Byte; { TLandTileGroup }
FQuantity: Byte;
FAnimID: Word; TLandTileGroup = class(TMulBlock)
FUnknown3: Byte; constructor Create(AData: TStream);
FHue: Byte; destructor Destroy; override;
FUnknown4: Word; function Clone: TLandTileGroup; override;
FHeight: Byte; function GetSize: Integer; override;
public procedure Write(AData: TStream); override;
property Weight: Byte read FWeight write FWeight; protected
property Quality: Byte read FQuality write FQuality; FUnknown: LongInt;
property Unknown1: Word read FUnknown1 write FUnknown1; public
property Unknown2: Byte read FUnknown2 write FUnknown2; LandTileData: array[0..31] of TLandTiledata;
property Quantity: Byte read FQuantity write FQuantity; property Unknown: LongInt read FUnknown write FUnknown;
property AnimID: Word read FAnimID write FAnimID; end;
property Unknown3: Byte read FUnknown3 write FUnknown3;
property Hue: Byte read FHue write FHue; { TStaticTileGroup }
property Unknown4: Word read FUnknown4 write FUnknown4;
property Height: Byte read FHeight write FHeight; TStaticTileGroup = class(TMulBlock)
end; constructor Create(AData: TStream);
TLandTileGroup = class(TMulBlock) destructor Destroy; override;
constructor Create(AData: TStream); function Clone: TStaticTileGroup; override;
destructor Destroy; override; function GetSize: Integer; override;
function Clone: TLandTileGroup; override; procedure Write(AData: TStream); override;
function GetSize: Integer; override; protected
procedure Write(AData: TStream); override; FUnknown: LongInt;
protected public
FUnknown: LongInt; StaticTileData: array[0..31] of TStaticTiledata;
public property Unknown: LongInt read FUnknown write FUnknown;
LandTileData: array[0..31] of TLandTiledata; end;
property Unknown: LongInt read FUnknown write FUnknown;
end; function GetTileDataOffset(ABlock: Integer): Integer;
TStaticTileGroup = class(TMulBlock)
constructor Create(AData: TStream); implementation
destructor Destroy; override;
function Clone: TStaticTileGroup; override; function GetTileDataOffset(ABlock: Integer): Integer;
function GetSize: Integer; override; var
procedure Write(AData: TStream); override; group, tile: Integer;
protected begin
FUnknown: LongInt; if ABlock > $3FFF then
public begin
StaticTileData: array[0..31] of TStaticTiledata; ABlock := ABlock - $4000;
property Unknown: LongInt read FUnknown write FUnknown; group := ABlock div 32;
end; tile := ABlock mod 32;
function GetTileDataOffset(ABlock: Integer): Integer; Result := 512 * LandTileGroupSize + group * StaticTileGroupSize + 4 + tile * StaticTileDataSize;
end else
implementation begin
group := ABlock div 32;
function GetTileDataOffset(ABlock: Integer): Integer; tile := ABlock mod 32;
var
group, tile: Integer; Result := group * LandTileGroupSize + 4 + tile * LandTileDataSize;
begin end;
if ABlock > $3FFF then end;
begin
ABlock := ABlock - $4000; { TLandTiledata }
group := ABlock div 32;
tile := ABlock mod 32; constructor TLandTiledata.Create(AData: TStream);
begin
Result := 512 * LandTileGroupSize + group * StaticTileGroupSize + 4 + tile * StaticTileDataSize; SetLength(FTileName, 20);
end else if assigned(AData) then
begin begin
group := ABlock div 32; AData.Read(FFlags, SizeOf(LongWord));
tile := ABlock mod 32; AData.Read(FTextureID, SizeOf(Word));
AData.Read(PChar(FTileName)^, 20);
Result := group * LandTileGroupSize + 4 + tile * LandTileDataSize; end;
end; FTileName := Trim(FTileName);
end; end;
constructor TLandTiledata.Create(AData: TStream); destructor TLandTiledata.Destroy;
begin begin
SetLength(FTileName, 20); SetLength(FTileName, 0);
if assigned(AData) then inherited;
begin end;
AData.Read(FFlags, SizeOf(LongWord));
AData.Read(FTextureID, SizeOf(Word)); function TLandTiledata.Clone: TLandTiledata;
AData.Read(PChar(FTileName)^, 20); begin
end; Result := TLandTiledata.Create(nil);
FTileName := Trim(FTileName); Result.FFlags := FFlags;
end; Result.FTextureID := FTextureID;
Result.FTileName := FTileName;
destructor TLandTiledata.Destroy; end;
begin
SetLength(FTileName, 0); procedure TLandTiledata.Write(AData: TStream);
inherited; var
end; i: Integer;
begin
function TLandTiledata.Clone: TLandTiledata; if Length(FTileName) < 20 then
begin for i := Length(FTileName) to 20 do
Result := TLandTiledata.Create(nil); FTileName := FTileName + #0;
Result.FFlags := FFlags; AData.Write(FFlags, SizeOf(LongWord));
Result.FTextureID := FTextureID; AData.Write(FTextureID, SizeOf(Word));
Result.FTileName := FTileName; AData.Write(PChar(FTileName)^, 20);
end; end;
procedure TLandTiledata.Write(AData: TStream); function TLandTiledata.GetSize: Integer;
var begin
i: Integer; GetSize := LandTileDataSize;
begin end;
if Length(FTileName) < 20 then
for i := Length(FTileName) to 20 do { TStaticTiledata}
FTileName := FTileName + #0;
AData.Write(FFlags, SizeOf(LongWord)); constructor TStaticTiledata.Create(AData: TStream);
AData.Write(FTextureID, SizeOf(Word)); begin
AData.Write(PChar(FTileName)^, 20); SetLength(FTileName, 20);
end; if assigned(AData) then
begin
function TLandTiledata.GetSize: Integer; AData.Read(FFlags, SizeOf(LongWord));
begin AData.Read(FWeight, SizeOf(Byte));
GetSize := LandTileDataSize; AData.Read(FQuality, SizeOf(Byte));
end; AData.Read(FUnknown1, SizeOf(Word));
AData.Read(FUnknown2, SizeOf(Byte));
constructor TStaticTiledata.Create(AData: TStream); AData.Read(FQuantity, SizeOf(Byte));
begin AData.Read(FAnimID, SizeOf(Word));
SetLength(FTileName, 20); AData.Read(FUnknown3, SizeOf(Byte));
if assigned(AData) then AData.Read(FHue, SizeOf(Byte));
begin AData.Read(FUnknown4, SizeOf(Word));
AData.Read(FFlags, SizeOf(LongWord)); AData.Read(FHeight, SizeOf(Byte));
AData.Read(FWeight, SizeOf(Byte)); AData.Read(PChar(FTileName)^, 20);
AData.Read(FQuality, SizeOf(Byte)); end;
AData.Read(FUnknown1, SizeOf(Word)); FTileName := Trim(FTileName);
AData.Read(FUnknown2, SizeOf(Byte)); end;
AData.Read(FQuantity, SizeOf(Byte));
AData.Read(FAnimID, SizeOf(Word)); destructor TStaticTiledata.Destroy;
AData.Read(FUnknown3, SizeOf(Byte)); begin
AData.Read(FHue, SizeOf(Byte)); SetLength(FTileName, 0);
AData.Read(FUnknown4, SizeOf(Word)); inherited;
AData.Read(FHeight, SizeOf(Byte)); end;
AData.Read(PChar(FTileName)^, 20);
end; function TStaticTiledata.Clone: TStaticTiledata;
FTileName := Trim(FTileName); begin
end; Result := TStaticTiledata.Create(nil);
Result.FFlags := FFlags;
destructor TStaticTiledata.Destroy; Result.FWeight := FWeight;
begin Result.FQuality := FQuality;
SetLength(FTileName, 0); Result.FUnknown1 := FUnknown1;
inherited; Result.FUnknown2 := FUnknown2;
end; Result.FQuantity := FQuantity;
Result.FAnimID := FAnimID;
function TStaticTiledata.Clone: TStaticTiledata; Result.FUnknown3 := FUnknown3;
begin Result.FHue := FHue;
Result := TStaticTiledata.Create(nil); Result.FUnknown4 := FUnknown4;
Result.FFlags := FFlags; Result.FHeight := FHeight;
Result.FWeight := FWeight; Result.FTileName := FTileName;
Result.FQuality := FQuality; end;
Result.FUnknown1 := FUnknown1;
Result.FUnknown2 := FUnknown2; procedure TStaticTiledata.Write(AData: TStream);
Result.FQuantity := FQuantity; var
Result.FAnimID := FAnimID; i: Integer;
Result.FUnknown3 := FUnknown3; begin
Result.FHue := FHue; if Length(FTileName) < 20 then
Result.FUnknown4 := FUnknown4; for i := Length(FTileName) to 20 do
Result.FHeight := FHeight; FTileName := FTileName + #0;
Result.FTileName := FTileName; AData.Write(FFlags, SizeOf(LongWord));
end; AData.Write(FWeight, SizeOf(Byte));
AData.Write(FQuality, SizeOf(Byte));
procedure TStaticTiledata.Write(AData: TStream); AData.Write(FUnknown1, SizeOf(Word));
var AData.Write(FUnknown2, SizeOf(Byte));
i: Integer; AData.Write(FQuantity, SizeOf(Byte));
begin AData.Write(FAnimID, SizeOf(Word));
if Length(FTileName) < 20 then AData.Write(FUnknown3, SizeOf(Byte));
for i := Length(FTileName) to 20 do AData.Write(FHue, SizeOf(Byte));
FTileName := FTileName + #0; AData.Write(FUnknown4, SizeOf(Word));
AData.Write(FFlags, SizeOf(LongWord)); AData.Write(FHeight, SizeOf(Byte));
AData.Write(FWeight, SizeOf(Byte)); AData.Write(PChar(FTileName)^, 20);
AData.Write(FQuality, SizeOf(Byte)); end;
AData.Write(FUnknown1, SizeOf(Word));
AData.Write(FUnknown2, SizeOf(Byte)); function TStaticTiledata.GetSize: Integer;
AData.Write(FQuantity, SizeOf(Byte)); begin
AData.Write(FAnimID, SizeOf(Word)); GetSize := StaticTileDataSize;
AData.Write(FUnknown3, SizeOf(Byte)); end;
AData.Write(FHue, SizeOf(Byte));
AData.Write(FUnknown4, SizeOf(Word)); { TLandTileGroup }
AData.Write(FHeight, SizeOf(Byte));
AData.Write(PChar(FTileName)^, 20); constructor TLandTileGroup.Create(AData: TStream);
end; var
i: Integer;
function TStaticTiledata.GetSize: Integer; begin
begin if assigned(AData) then
GetSize := StaticTileDataSize; begin
end; AData.Read(FUnknown, SizeOf(LongInt));
end;
constructor TLandTileGroup.Create(AData: TStream); for i := 0 to 31 do
var LandTileData[i] := TLandTiledata.Create(AData);
i: Integer; end;
begin
if assigned(AData) then destructor TLandTileGroup.Destroy;
begin var
AData.Read(FUnknown, SizeOf(LongInt)); i: Integer;
end; begin
for i := 0 to 31 do for i := 0 to 31 do
LandTileData[i] := TLandTiledata.Create(AData); LandTileData[i].Free;
end; inherited;
end;
destructor TLandTileGroup.Destroy;
var function TLandTileGroup.Clone: TLandTileGroup;
i: Integer; var
begin i: Integer;
for i := 0 to 31 do begin
LandTileData[i].Free; Result := TLandTileGroup.Create(nil);
inherited; Result.FUnknown := FUnknown;
end; for i := 0 to 31 do
Result.LandTileData[i] := LandTileData[i].Clone;
function TLandTileGroup.Clone: TLandTileGroup; end;
var
i: Integer; procedure TLandTileGroup.Write(AData: TStream);
begin var
Result := TLandTileGroup.Create(nil); i: Integer;
Result.FUnknown := FUnknown; begin
for i := 0 to 31 do AData.Write(FUnknown, SizeOf(LongInt));
Result.LandTileData[i] := LandTileData[i].Clone; for i := 0 to 31 do
end; LandTileData[i].Write(AData);
end;
procedure TLandTileGroup.Write(AData: TStream);
var function TLandTileGroup.GetSize: Integer;
i: Integer; begin
begin GetSize := LandTileGroupSize;
AData.Write(FUnknown, SizeOf(LongInt)); end;
for i := 0 to 31 do
LandTileData[i].Write(AData); { TStaticTileGroup }
end;
constructor TStaticTileGroup.Create(AData: TStream);
function TLandTileGroup.GetSize: Integer; var
begin i: Integer;
GetSize := LandTileGroupSize; begin
end; if assigned(AData) then
begin
constructor TStaticTileGroup.Create(AData: TStream); AData.Read(FUnknown, SizeOf(LongInt));
var end;
i: Integer; for i := 0 to 31 do
begin StaticTileData[i] := TStaticTiledata.Create(AData);
if assigned(AData) then end;
begin
AData.Read(FUnknown, SizeOf(LongInt)); destructor TStaticTileGroup.Destroy;
end; var
for i := 0 to 31 do i: Integer;
StaticTileData[i] := TStaticTiledata.Create(AData); begin
end; for i := 0 to 31 do
StaticTileData[i].Free;
destructor TStaticTileGroup.Destroy; inherited;
var end;
i: Integer;
begin function TStaticTileGroup.Clone: TStaticTileGroup;
for i := 0 to 31 do var
StaticTileData[i].Free; i: Integer;
inherited; begin
end; Result := TStaticTileGroup.Create(nil);
Result.FUnknown := FUnknown;
function TStaticTileGroup.Clone: TStaticTileGroup; for i := 0 to 31 do
var Result.StaticTileData[i] := StaticTileData[i].Clone;
i: Integer; end;
begin
Result := TStaticTileGroup.Create(nil); procedure TStaticTileGroup.Write(AData: TStream);
Result.FUnknown := FUnknown; var
for i := 0 to 31 do i: Integer;
Result.StaticTileData[i] := StaticTileData[i].Clone; begin
end; AData.Write(FUnknown, SizeOf(LongInt));
for i := 0 to 31 do
procedure TStaticTileGroup.Write(AData: TStream); StaticTileData[i].Write(AData);
var end;
i: Integer;
begin function TStaticTileGroup.GetSize: Integer;
AData.Write(FUnknown, SizeOf(LongInt)); begin
for i := 0 to 31 do GetSize := StaticTileGroupSize;
StaticTileData[i].Write(AData); end;
end;
end.
function TStaticTileGroup.GetSize: Integer;
begin
GetSize := StaticTileGroupSize;
end;
{ TTiledata }
function TTiledata.HasFlag(AFlag: LongWord): Boolean;
begin
Result := (FFlags and AFlag) = AFlag;
end;
end.