diff --git a/Client/CentrED.lpi b/Client/CentrED.lpi index 3e266af..32e3936 100644 --- a/Client/CentrED.lpi +++ b/Client/CentrED.lpi @@ -56,7 +56,7 @@ - + @@ -253,6 +253,21 @@ + + + + + + + + + + + + + + + diff --git a/Client/CentrED.lpr b/Client/CentrED.lpr index 7f7a689..dd85129 100644 --- a/Client/CentrED.lpr +++ b/Client/CentrED.lpr @@ -1,37 +1,37 @@ -(* - * 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 - *) -program CentrED; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset +(* + * 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 + *) +program CentrED; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Interfaces, // this includes the LCL widgetset Forms, LResources, lnetvisual, LazOpenGLContext, UdmNetwork, UfrmMain, UfrmLogin, UfrmInitialize, UfrmAccountControl, virtualtreeview_package, multiloglaz, UfrmEditAccount, UfrmDrawSettings, UfrmBoundaries, @@ -40,14 +40,14 @@ uses UfrmLargeScaleCommand, UfrmVirtualLayer, UfrmFilter, UfrmTileInfo, UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets, UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow, - Logging; - -{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF} - -begin - {$I CentrED.lrs} - Application.Initialize; - Application.CreateForm(TdmNetwork, dmNetwork); - Application.Run; -end. - + Logging, UMap, UWorldItem, UStatics; + +{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF} + +begin + {$I CentrED.lrs} + Application.Initialize; + Application.CreateForm(TdmNetwork, dmNetwork); + Application.Run; +end. + diff --git a/Client/ULandscape.pas b/Client/ULandscape.pas index f919a74..d40cd4f 100644 --- a/Client/ULandscape.pas +++ b/Client/ULandscape.pas @@ -72,15 +72,18 @@ type TLandTextureManager = class constructor Create; 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 FArtCache: TCacheManager; FFlatLandArtCache: 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; { TSeperatedStaticBlock } @@ -205,6 +208,7 @@ type Normals: PNormals; State: TScreenState; Highlighted: Boolean; + HueOverride: Boolean; Next: PBlockInfo; end; @@ -290,7 +294,8 @@ begin end; end; -function TLandTextureManager.GetArtMaterial(ATileID: Word; AHue: THue; APartialHue: Boolean): TMaterial; +function TLandTextureManager.GetArtMaterial(ATileID: Word; AHue: THue; + APartialHue: Boolean): TMaterial; var artEntry: TArt; id: Integer; @@ -330,6 +335,25 @@ begin 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; var texEntry: TTexture; @@ -706,8 +730,8 @@ begin (staticItem.Hue = staticInfo.Hue) then begin if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem); - statics.Delete(i); staticItem.Delete; + statics.Delete(i); Break; end; @@ -785,8 +809,8 @@ begin if staticItem <> nil then begin if Assigned(FOnStaticDeleted) then FOnStaticDeleted(staticItem); - statics.Remove(staticItem); staticItem.Delete; + statics.Remove(staticItem); end; end; diff --git a/Client/UfrmMain.pas b/Client/UfrmMain.pas index 3fbd020..4205bb3 100644 --- a/Client/UfrmMain.pas +++ b/Client/UfrmMain.pas @@ -1733,8 +1733,6 @@ var west, south, east: Single; z: SmallInt; staticItem: TStaticItem; - hue: THue; - staticTiledata: TStaticTiledata; begin //add normals to map tiles and materials where possible @@ -1806,13 +1804,8 @@ begin begin staticItem := TStaticItem(item); - staticTiledata := ResMan.Tiledata.StaticTiles[staticItem.TileID]; - if staticItem.Hue > 0 then - hue := ResMan.Hue.Hues[staticItem.Hue - 1] - else - hue := nil; - - ABlockInfo^.LowRes := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue); + ABlockInfo^.LowRes := FTextureManager.GetStaticMaterial(staticItem); + ABlockInfo^.HueOverride := False; ABlockInfo^.ScreenRect := Bounds(Trunc(drawX - ABlockInfo^.LowRes.RealWidth / 2), Trunc(drawY + 44 - ABlockInfo^.LowRes.RealHeight - z * 4), ABlockInfo^.LowRes.RealWidth, @@ -2292,6 +2285,27 @@ procedure TfrmMain.UpdateSelection; var selectedRect: TRect; 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 Logger.EnterMethod([lcClient, lcDebug], 'UpdateSelection'); if (CurrentTile <> nil) and (not acSelect.Checked) then @@ -2303,14 +2317,15 @@ begin selectedRect := GetSelectedRect; Logger.Send([lcClient, lcDebug], 'SelectedRect', selectedRect); while FScreenBuffer.Iterate(blockInfo) do - if blockInfo^.State = ssNormal then - blockInfo^.Highlighted := PtInRect(selectedRect, Point(blockInfo^.Item.X, blockInfo^.Item.Y)); + if (blockInfo^.State = ssNormal) then + SetHighlight(blockInfo, PtInRect(selectedRect, + Point(blockInfo^.Item.X, blockInfo^.Item.Y))); end else begin Logger.Send([lcClient, lcDebug], 'Single Target'); while FScreenBuffer.Iterate(blockInfo) do if blockInfo^.State = ssNormal then - blockInfo^.Highlighted := (blockInfo^.Item = CurrentTile); + SetHighlight(blockInfo, (blockInfo^.Item = CurrentTile)); end; end; Logger.ExitMethod([lcClient, lcDebug], 'UpdateSelection'); diff --git a/Client/UfrmTileInfo.pas b/Client/UfrmTileInfo.pas index 74efbe8..f888e24 100644 --- a/Client/UfrmTileInfo.pas +++ b/Client/UfrmTileInfo.pas @@ -80,9 +80,9 @@ var tileData: TTiledata; prefix, flags: string; - procedure UpdateFlags(AFlag: LongWord; AName: string); + procedure UpdateFlags(AFlag: TTileDataFlag; AName: string); begin - if tileData.HasFlag(AFlag) then + if AFlag in tileData.Flags then begin if flags <> '' then flags := flags + ', ' + AName @@ -111,9 +111,9 @@ begin tileData := ResMan.Tiledata.StaticTiles[ATileID]; end; - if tileData.HasFlag(tdfArticleA) then + if tdfArticleA in tileData.Flags then prefix := 'a ' - else if tileData.HasFlag(tdfArticleAn) then + else if tdfArticleAn in tileData.Flags then prefix := 'an ' else prefix := ''; diff --git a/UOLib/UStatics.pas b/UOLib/UStatics.pas index bcd4a75..08dab96 100644 --- a/UOLib/UStatics.pas +++ b/UOLib/UStatics.pas @@ -36,7 +36,8 @@ type { TStaticItem } 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; protected { Members } @@ -63,7 +64,8 @@ type { TStaticBlock} 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; destructor Destroy; override; protected @@ -92,12 +94,14 @@ end; { TStaticItem } -constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX, ABlockY: Word); +constructor TStaticItem.Create(AOwner: TWorldBlock; AData: TStream; ABlockX, + ABlockY: Word); var iX, iY: Byte; begin inherited Create(AOwner); - if assigned(AData) then + + if AData <> nil then begin AData.Read(FTileID, SizeOf(SmallInt)); AData.Read(iX, SizeOf(Byte)); @@ -108,6 +112,7 @@ begin FX := ABlockX * 8 + iX; FY := ABlockY * 8 + iY; end; + InitOriginalState; end; @@ -152,7 +157,7 @@ procedure TStaticItem.UpdatePriorities(ATileData: TStaticTiledata; ASolver: Integer); begin FPriorityBonus := 0; - if not ((ATileData.Flags and tdfBackground) = tdfBackground) then + if not (tdfBackground in ATileData.Flags) then Inc(FPriorityBonus); if ATileData.Height > 0 then Inc(FPriorityBonus); @@ -176,7 +181,8 @@ end; { TStaticBlock } -constructor TStaticBlock.Create(AData: TStream; AIndex: TGenericIndex; AX, AY: Word); +constructor TStaticBlock.Create(AData: TStream; AIndex: TGenericIndex; + AX, AY: Word); var i: Integer; block: TMemoryStream; diff --git a/UOLib/UTiledata.pas b/UOLib/UTiledata.pas index 8be8587..f95b8f3 100644 --- a/UOLib/UTiledata.pas +++ b/UOLib/UTiledata.pas @@ -1,388 +1,375 @@ -(* - * 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 2008 Andreas Schneider - *) -unit UTiledata; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, UMulBlock; - -const - tdfBackground = $00000001; - tdfWeapon = $00000002; - tdfTransparent = $00000004; - tdfTranslucent = $00000008; - tdfWall = $00000010; - tdfDamaging = $00000020; - tdfImpassable = $00000040; - tdfWet = $00000080; - tdfUnknown1 = $00000100; - tdfSurface = $00000200; - tdfBridge = $00000400; - tdfGeneric = $00000800; - tdfWindow = $00001000; - tdfNoShoot = $00002000; - tdfArticleA = $00004000; - tdfArticleAn = $00008000; - tdfInternal = $00010000; - tdfFoliage = $00020000; - tdfPartialHue = $00040000; - tdfUnknown2 = $00080000; - tdfMap = $00100000; - tdfContainer = $00200000; - tdfWearable = $00400000; - tdfLightSource = $00800000; - tdfAnimation = $01000000; - tdfNoDiagonal = $02000000; - tdfArtUsed = $04000000; - tdfArmor = $08000000; - tdfRoof = $10000000; - tdfDoor = $20000000; - tdfStairBack = $40000000; - tdfStairRight = $80000000; - - LandTileDataSize = 26; - LandTileGroupSize = 4 + 32 * LandTileDataSize; - StaticTileDataSize = 37; - StaticTileGroupSize = 4 + 32 * StaticTileDataSize; - -type - - { TTiledata } - - TTiledata = class(TMulBlock) - protected - FFlags: LongWord; - FTileName: string; - public - property Flags: LongWord read FFlags write FFlags; - property TileName: string read FTileName write FTileName; - - function HasFlag(AFlag: LongWord): Boolean; - end; - TLandTiledata = class(TTiledata) - constructor Create(AData: TStream); - destructor Destroy; override; - function Clone: TLandTiledata; override; - function GetSize: Integer; override; - procedure Write(AData: TStream); override; - protected - FTextureID: Word; - public - property TextureID: Word read FTextureID write FTextureID; - end; - TStaticTiledata = class(TTiledata) - constructor Create(AData: TStream); - destructor Destroy; override; - function Clone: TStaticTiledata; override; - function GetSize: Integer; override; - procedure Write(AData: TStream); override; - protected - FWeight: Byte; - FQuality: Byte; - FUnknown1: Word; - FUnknown2: Byte; - FQuantity: Byte; - FAnimID: Word; - FUnknown3: Byte; - FHue: Byte; - FUnknown4: Word; - FHeight: Byte; - public - property Weight: Byte read FWeight write FWeight; - property Quality: Byte read FQuality write FQuality; - property Unknown1: Word read FUnknown1 write FUnknown1; - property Unknown2: Byte read FUnknown2 write FUnknown2; - property Quantity: Byte read FQuantity write FQuantity; - property AnimID: Word read FAnimID write FAnimID; - property Unknown3: Byte read FUnknown3 write FUnknown3; - property Hue: Byte read FHue write FHue; - property Unknown4: Word read FUnknown4 write FUnknown4; - property Height: Byte read FHeight write FHeight; - end; - TLandTileGroup = class(TMulBlock) - constructor Create(AData: TStream); - destructor Destroy; override; - function Clone: TLandTileGroup; override; - function GetSize: Integer; override; - procedure Write(AData: TStream); override; - protected - FUnknown: LongInt; - public - LandTileData: array[0..31] of TLandTiledata; - property Unknown: LongInt read FUnknown write FUnknown; - end; - TStaticTileGroup = class(TMulBlock) - constructor Create(AData: TStream); - destructor Destroy; override; - function Clone: TStaticTileGroup; override; - function GetSize: Integer; override; - procedure Write(AData: TStream); override; - protected - FUnknown: LongInt; - public - StaticTileData: array[0..31] of TStaticTiledata; - property Unknown: LongInt read FUnknown write FUnknown; - end; - -function GetTileDataOffset(ABlock: Integer): Integer; - -implementation - -function GetTileDataOffset(ABlock: Integer): Integer; -var - group, tile: Integer; -begin - if ABlock > $3FFF then - begin - ABlock := ABlock - $4000; - group := ABlock div 32; - tile := ABlock mod 32; - - Result := 512 * LandTileGroupSize + group * StaticTileGroupSize + 4 + tile * StaticTileDataSize; - end else - begin - group := ABlock div 32; - tile := ABlock mod 32; - - Result := group * LandTileGroupSize + 4 + tile * LandTileDataSize; - end; -end; - -constructor TLandTiledata.Create(AData: TStream); -begin - SetLength(FTileName, 20); - if assigned(AData) then - begin - AData.Read(FFlags, SizeOf(LongWord)); - AData.Read(FTextureID, SizeOf(Word)); - AData.Read(PChar(FTileName)^, 20); - end; - FTileName := Trim(FTileName); -end; - -destructor TLandTiledata.Destroy; -begin - SetLength(FTileName, 0); - inherited; -end; - -function TLandTiledata.Clone: TLandTiledata; -begin - Result := TLandTiledata.Create(nil); - Result.FFlags := FFlags; - Result.FTextureID := FTextureID; - Result.FTileName := FTileName; -end; - -procedure TLandTiledata.Write(AData: TStream); -var - i: Integer; -begin - if Length(FTileName) < 20 then - for i := Length(FTileName) to 20 do - FTileName := FTileName + #0; - AData.Write(FFlags, SizeOf(LongWord)); - AData.Write(FTextureID, SizeOf(Word)); - AData.Write(PChar(FTileName)^, 20); -end; - -function TLandTiledata.GetSize: Integer; -begin - GetSize := LandTileDataSize; -end; - -constructor TStaticTiledata.Create(AData: TStream); -begin - SetLength(FTileName, 20); - if assigned(AData) then - begin - AData.Read(FFlags, SizeOf(LongWord)); - AData.Read(FWeight, SizeOf(Byte)); - AData.Read(FQuality, SizeOf(Byte)); - AData.Read(FUnknown1, SizeOf(Word)); - AData.Read(FUnknown2, SizeOf(Byte)); - AData.Read(FQuantity, SizeOf(Byte)); - AData.Read(FAnimID, SizeOf(Word)); - AData.Read(FUnknown3, SizeOf(Byte)); - AData.Read(FHue, SizeOf(Byte)); - AData.Read(FUnknown4, SizeOf(Word)); - AData.Read(FHeight, SizeOf(Byte)); - AData.Read(PChar(FTileName)^, 20); - end; - FTileName := Trim(FTileName); -end; - -destructor TStaticTiledata.Destroy; -begin - SetLength(FTileName, 0); - inherited; -end; - -function TStaticTiledata.Clone: TStaticTiledata; -begin - Result := TStaticTiledata.Create(nil); - Result.FFlags := FFlags; - Result.FWeight := FWeight; - Result.FQuality := FQuality; - Result.FUnknown1 := FUnknown1; - Result.FUnknown2 := FUnknown2; - Result.FQuantity := FQuantity; - Result.FAnimID := FAnimID; - Result.FUnknown3 := FUnknown3; - Result.FHue := FHue; - Result.FUnknown4 := FUnknown4; - Result.FHeight := FHeight; - Result.FTileName := FTileName; -end; - -procedure TStaticTiledata.Write(AData: TStream); -var - i: Integer; -begin - if Length(FTileName) < 20 then - for i := Length(FTileName) to 20 do - FTileName := FTileName + #0; - AData.Write(FFlags, SizeOf(LongWord)); - AData.Write(FWeight, SizeOf(Byte)); - AData.Write(FQuality, SizeOf(Byte)); - AData.Write(FUnknown1, SizeOf(Word)); - AData.Write(FUnknown2, SizeOf(Byte)); - AData.Write(FQuantity, SizeOf(Byte)); - AData.Write(FAnimID, SizeOf(Word)); - AData.Write(FUnknown3, SizeOf(Byte)); - AData.Write(FHue, SizeOf(Byte)); - AData.Write(FUnknown4, SizeOf(Word)); - AData.Write(FHeight, SizeOf(Byte)); - AData.Write(PChar(FTileName)^, 20); -end; - -function TStaticTiledata.GetSize: Integer; -begin - GetSize := StaticTileDataSize; -end; - -constructor TLandTileGroup.Create(AData: TStream); -var - i: Integer; -begin - if assigned(AData) then - begin - AData.Read(FUnknown, SizeOf(LongInt)); - end; - for i := 0 to 31 do - LandTileData[i] := TLandTiledata.Create(AData); -end; - -destructor TLandTileGroup.Destroy; -var - i: Integer; -begin - for i := 0 to 31 do - LandTileData[i].Free; - inherited; -end; - -function TLandTileGroup.Clone: TLandTileGroup; -var - i: Integer; -begin - Result := TLandTileGroup.Create(nil); - Result.FUnknown := FUnknown; - for i := 0 to 31 do - Result.LandTileData[i] := LandTileData[i].Clone; -end; - -procedure TLandTileGroup.Write(AData: TStream); -var - i: Integer; -begin - AData.Write(FUnknown, SizeOf(LongInt)); - for i := 0 to 31 do - LandTileData[i].Write(AData); -end; - -function TLandTileGroup.GetSize: Integer; -begin - GetSize := LandTileGroupSize; -end; - -constructor TStaticTileGroup.Create(AData: TStream); -var - i: Integer; -begin - if assigned(AData) then - begin - AData.Read(FUnknown, SizeOf(LongInt)); - end; - for i := 0 to 31 do - StaticTileData[i] := TStaticTiledata.Create(AData); -end; - -destructor TStaticTileGroup.Destroy; -var - i: Integer; -begin - for i := 0 to 31 do - StaticTileData[i].Free; - inherited; -end; - -function TStaticTileGroup.Clone: TStaticTileGroup; -var - i: Integer; -begin - Result := TStaticTileGroup.Create(nil); - Result.FUnknown := FUnknown; - for i := 0 to 31 do - Result.StaticTileData[i] := StaticTileData[i].Clone; -end; - -procedure TStaticTileGroup.Write(AData: TStream); -var - i: Integer; -begin - AData.Write(FUnknown, SizeOf(LongInt)); - for i := 0 to 31 do - StaticTileData[i].Write(AData); -end; - -function TStaticTileGroup.GetSize: Integer; -begin - GetSize := StaticTileGroupSize; -end; - -{ TTiledata } - -function TTiledata.HasFlag(AFlag: LongWord): Boolean; -begin - Result := (FFlags and AFlag) = AFlag; -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 UTiledata; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, UMulBlock; + +const + LandTileDataSize = 26; + LandTileGroupSize = 4 + 32 * LandTileDataSize; + StaticTileDataSize = 37; + StaticTileGroupSize = 4 + 32 * StaticTileDataSize; + +type + TTileDataFlag = (tdfBackground, tdfWeapon, tdfTransparent, tdfTranslucent, + tdfWall, tdfDamaging, tdfImpassable, tdfWet, tdfUnknown1, + tdfSurface, tdfBridge, tdfGeneric, tdfWindow, tdfNoShoot, + tdfArticleA, tdfArticleAn, tdfInternal, tdfFoliage, + tdfPartialHue, tdfUnknown2, tdfMap, tdfContainer, + tdfWearable, tdfLightSource, tdfAnimation, tdfNoDiagonal, + tdfArtUsed, tdfArmor, tdfRoof, tdfDoor, tdfStairBack, + tdfStairRight); + TTileDataFlags = set of TTileDataFlag; + + { TTiledata } + + TTiledata = class(TMulBlock) + protected + FFlags: TTileDataFlags; + FTileName: string; + public + property Flags: TTileDataFlags read FFlags write FFlags; + property TileName: string read FTileName write FTileName; + end; + + { TLandTiledata } + + TLandTiledata = class(TTiledata) + constructor Create(AData: TStream); + destructor Destroy; override; + function Clone: TLandTiledata; override; + function GetSize: Integer; override; + procedure Write(AData: TStream); override; + protected + FTextureID: Word; + public + property TextureID: Word read FTextureID write FTextureID; + end; + + { TStaticTiledata } + + TStaticTiledata = class(TTiledata) + constructor Create(AData: TStream); + destructor Destroy; override; + function Clone: TStaticTiledata; override; + function GetSize: Integer; override; + procedure Write(AData: TStream); override; + protected + FWeight: Byte; + FQuality: Byte; + FUnknown1: Word; + FUnknown2: Byte; + FQuantity: Byte; + FAnimID: Word; + FUnknown3: Byte; + FHue: Byte; + FUnknown4: Word; + FHeight: Byte; + public + property Weight: Byte read FWeight write FWeight; + property Quality: Byte read FQuality write FQuality; + property Unknown1: Word read FUnknown1 write FUnknown1; + property Unknown2: Byte read FUnknown2 write FUnknown2; + property Quantity: Byte read FQuantity write FQuantity; + property AnimID: Word read FAnimID write FAnimID; + property Unknown3: Byte read FUnknown3 write FUnknown3; + property Hue: Byte read FHue write FHue; + property Unknown4: Word read FUnknown4 write FUnknown4; + property Height: Byte read FHeight write FHeight; + end; + + { TLandTileGroup } + + TLandTileGroup = class(TMulBlock) + constructor Create(AData: TStream); + destructor Destroy; override; + function Clone: TLandTileGroup; override; + function GetSize: Integer; override; + procedure Write(AData: TStream); override; + protected + FUnknown: LongInt; + public + LandTileData: array[0..31] of TLandTiledata; + property Unknown: LongInt read FUnknown write FUnknown; + end; + + { TStaticTileGroup } + + TStaticTileGroup = class(TMulBlock) + constructor Create(AData: TStream); + destructor Destroy; override; + function Clone: TStaticTileGroup; override; + function GetSize: Integer; override; + procedure Write(AData: TStream); override; + protected + FUnknown: LongInt; + public + StaticTileData: array[0..31] of TStaticTiledata; + property Unknown: LongInt read FUnknown write FUnknown; + end; + +function GetTileDataOffset(ABlock: Integer): Integer; + +implementation + +function GetTileDataOffset(ABlock: Integer): Integer; +var + group, tile: Integer; +begin + if ABlock > $3FFF then + begin + ABlock := ABlock - $4000; + group := ABlock div 32; + tile := ABlock mod 32; + + Result := 512 * LandTileGroupSize + group * StaticTileGroupSize + 4 + tile * StaticTileDataSize; + end else + begin + group := ABlock div 32; + tile := ABlock mod 32; + + Result := group * LandTileGroupSize + 4 + tile * LandTileDataSize; + end; +end; + +{ TLandTiledata } + +constructor TLandTiledata.Create(AData: TStream); +begin + SetLength(FTileName, 20); + if assigned(AData) then + begin + AData.Read(FFlags, SizeOf(LongWord)); + AData.Read(FTextureID, SizeOf(Word)); + AData.Read(PChar(FTileName)^, 20); + end; + FTileName := Trim(FTileName); +end; + +destructor TLandTiledata.Destroy; +begin + SetLength(FTileName, 0); + inherited; +end; + +function TLandTiledata.Clone: TLandTiledata; +begin + Result := TLandTiledata.Create(nil); + Result.FFlags := FFlags; + Result.FTextureID := FTextureID; + Result.FTileName := FTileName; +end; + +procedure TLandTiledata.Write(AData: TStream); +var + i: Integer; +begin + if Length(FTileName) < 20 then + for i := Length(FTileName) to 20 do + FTileName := FTileName + #0; + AData.Write(FFlags, SizeOf(LongWord)); + AData.Write(FTextureID, SizeOf(Word)); + AData.Write(PChar(FTileName)^, 20); +end; + +function TLandTiledata.GetSize: Integer; +begin + GetSize := LandTileDataSize; +end; + +{ TStaticTiledata} + +constructor TStaticTiledata.Create(AData: TStream); +begin + SetLength(FTileName, 20); + if assigned(AData) then + begin + AData.Read(FFlags, SizeOf(LongWord)); + AData.Read(FWeight, SizeOf(Byte)); + AData.Read(FQuality, SizeOf(Byte)); + AData.Read(FUnknown1, SizeOf(Word)); + AData.Read(FUnknown2, SizeOf(Byte)); + AData.Read(FQuantity, SizeOf(Byte)); + AData.Read(FAnimID, SizeOf(Word)); + AData.Read(FUnknown3, SizeOf(Byte)); + AData.Read(FHue, SizeOf(Byte)); + AData.Read(FUnknown4, SizeOf(Word)); + AData.Read(FHeight, SizeOf(Byte)); + AData.Read(PChar(FTileName)^, 20); + end; + FTileName := Trim(FTileName); +end; + +destructor TStaticTiledata.Destroy; +begin + SetLength(FTileName, 0); + inherited; +end; + +function TStaticTiledata.Clone: TStaticTiledata; +begin + Result := TStaticTiledata.Create(nil); + Result.FFlags := FFlags; + Result.FWeight := FWeight; + Result.FQuality := FQuality; + Result.FUnknown1 := FUnknown1; + Result.FUnknown2 := FUnknown2; + Result.FQuantity := FQuantity; + Result.FAnimID := FAnimID; + Result.FUnknown3 := FUnknown3; + Result.FHue := FHue; + Result.FUnknown4 := FUnknown4; + Result.FHeight := FHeight; + Result.FTileName := FTileName; +end; + +procedure TStaticTiledata.Write(AData: TStream); +var + i: Integer; +begin + if Length(FTileName) < 20 then + for i := Length(FTileName) to 20 do + FTileName := FTileName + #0; + AData.Write(FFlags, SizeOf(LongWord)); + AData.Write(FWeight, SizeOf(Byte)); + AData.Write(FQuality, SizeOf(Byte)); + AData.Write(FUnknown1, SizeOf(Word)); + AData.Write(FUnknown2, SizeOf(Byte)); + AData.Write(FQuantity, SizeOf(Byte)); + AData.Write(FAnimID, SizeOf(Word)); + AData.Write(FUnknown3, SizeOf(Byte)); + AData.Write(FHue, SizeOf(Byte)); + AData.Write(FUnknown4, SizeOf(Word)); + AData.Write(FHeight, SizeOf(Byte)); + AData.Write(PChar(FTileName)^, 20); +end; + +function TStaticTiledata.GetSize: Integer; +begin + GetSize := StaticTileDataSize; +end; + +{ TLandTileGroup } + +constructor TLandTileGroup.Create(AData: TStream); +var + i: Integer; +begin + if assigned(AData) then + begin + AData.Read(FUnknown, SizeOf(LongInt)); + end; + for i := 0 to 31 do + LandTileData[i] := TLandTiledata.Create(AData); +end; + +destructor TLandTileGroup.Destroy; +var + i: Integer; +begin + for i := 0 to 31 do + LandTileData[i].Free; + inherited; +end; + +function TLandTileGroup.Clone: TLandTileGroup; +var + i: Integer; +begin + Result := TLandTileGroup.Create(nil); + Result.FUnknown := FUnknown; + for i := 0 to 31 do + Result.LandTileData[i] := LandTileData[i].Clone; +end; + +procedure TLandTileGroup.Write(AData: TStream); +var + i: Integer; +begin + AData.Write(FUnknown, SizeOf(LongInt)); + for i := 0 to 31 do + LandTileData[i].Write(AData); +end; + +function TLandTileGroup.GetSize: Integer; +begin + GetSize := LandTileGroupSize; +end; + +{ TStaticTileGroup } + +constructor TStaticTileGroup.Create(AData: TStream); +var + i: Integer; +begin + if assigned(AData) then + begin + AData.Read(FUnknown, SizeOf(LongInt)); + end; + for i := 0 to 31 do + StaticTileData[i] := TStaticTiledata.Create(AData); +end; + +destructor TStaticTileGroup.Destroy; +var + i: Integer; +begin + for i := 0 to 31 do + StaticTileData[i].Free; + inherited; +end; + +function TStaticTileGroup.Clone: TStaticTileGroup; +var + i: Integer; +begin + Result := TStaticTileGroup.Create(nil); + Result.FUnknown := FUnknown; + for i := 0 to 31 do + Result.StaticTileData[i] := StaticTileData[i].Clone; +end; + +procedure TStaticTileGroup.Write(AData: TStream); +var + i: Integer; +begin + AData.Write(FUnknown, SizeOf(LongInt)); + for i := 0 to 31 do + StaticTileData[i].Write(AData); +end; + +function TStaticTileGroup.GetSize: Integer; +begin + GetSize := StaticTileGroupSize; +end; + +end. +