* Added CentrED+ code (thanks to StaticZ for his awesome work!)

This commit is contained in:
2015-05-01 12:23:03 +02:00
parent 2e62fd570a
commit 34637d40ce
97 changed files with 22628 additions and 4243 deletions

View File

@@ -36,9 +36,9 @@ uses
type
TArtType = (atLand, atStatic, atLandFlat);
TArt = class(TMulBlock)
constructor Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType); overload;
constructor Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AHue: THue; APartialHue: Boolean); overload;
constructor Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AArtColor: Word; AHue: THue; APartialHue: Boolean); overload;
constructor Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; OldFormat: Boolean = False); overload;
constructor Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AHue: THue; APartialHue: Boolean; OldFormat: Boolean = False); overload;
constructor Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AArtColor: Word; AHue: THue; APartialHue: Boolean; OldFormat: Boolean = False); overload;
destructor Destroy; override;
function Clone: TArt; override;
function GetSize: Integer; override;
@@ -60,19 +60,19 @@ implementation
type
PWordArray = ^TWordArray;
TWordArray = array[0..16383] of Word;
TWordArray = array[0..(MaxInt div SizeOf(Word) - 1)] of Word; // а не перебор ли?
constructor TArt.Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType);
constructor TArt.Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; OldFormat: Boolean = False);
begin
Create(AData, AIndex, AArtType, 0, nil, False);
Create(AData, AIndex, AArtType, 0, nil, False, OldFormat);
end;
constructor TArt.Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AHue: THue; APartialHue: Boolean);
constructor TArt.Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AHue: THue; APartialHue: Boolean; OldFormat: Boolean = False);
begin
Create(AData, AIndex, AArtType, 0, AHue, APartialHue);
Create(AData, AIndex, AArtType, 0, AHue, APartialHue, OldFormat);
end;
constructor TArt.Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AArtColor: Word; AHue: THue; APartialHue: Boolean);
constructor TArt.Create(AData: TStream; AIndex: TGenericIndex; AArtType: TArtType; AArtColor: Word; AHue: THue; APartialHue: Boolean; OldFormat: Boolean = False);
var
i, x, y, start: Integer;
iCurrentHeight, iCurrentWidth: Integer;
@@ -95,7 +95,7 @@ begin
block.Position := 0;
if AArtType = atLand then
begin
begin // Lands
FGraphic:= TSingleImage.CreateFromParams(44, 44, ifA1R5G5B5);
FillWord(FGraphic.Bits^, 44 * 44, AArtColor);
for y := 0 to 21 do
@@ -111,7 +111,7 @@ begin
for i := 0 to 44 * 44 - 1 do
PWordArray(FGraphic.Bits)^[i] := PWordArray(FGraphic.Bits)^[i] xor $8000; //invert alpha bit
end else if AArtType = atLandFlat then
begin
begin // Lands
FGraphic:= TSingleImage.CreateFromParams(44, 44, ifA1R5G5B5);
for i := 1 to 22 do
begin
@@ -138,7 +138,7 @@ begin
for i := 0 to 44 * 44 - 1 do
PWordArray(FGraphic.Bits)^[i] := PWordArray(FGraphic.Bits)^[i] xor $8000; //invert alpha bit
end else if AArtType = atStatic then
begin
begin // Items
block.Read(FHeader, SizeOf(LongInt));
block.Read(width, SizeOf(SmallInt));
block.Read(height, SizeOf(SmallInt));
@@ -151,25 +151,46 @@ begin
block.Read(offset, SizeOf(Word));
lookup[i] := start + (offset * 2);
end;
for iCurrentHeight := 0 to height - 1 do
begin
block.Position := lookup[iCurrentHeight];
iCurrentWidth := 0;
P := FGraphic.Bits + iCurrentHeight * width * 2;
while (block.Read(offset, SizeOf(Word)) = SizeOf(Word)) and
(block.Read(run, SizeOf(Word)) = SizeOf(Word)) and
(offset + run <> 0) do
if not OldFormat then begin // General Clients
for iCurrentHeight := 0 to height - 1 do
begin
inc(iCurrentWidth, offset);
for i := 0 to run - 1 do
block.Position := lookup[iCurrentHeight];
iCurrentWidth := 0;
P := FGraphic.Bits + iCurrentHeight * width * 2;
while (block.Read(offset, SizeOf(Word)) = SizeOf(Word)) and
(block.Read(run, SizeOf(Word)) = SizeOf(Word)) and
(offset + run <> 0) do
begin
block.Read(color, SizeOf(Word));
P^[iCurrentWidth + i] := color;
inc(iCurrentWidth, offset);
for i := 0 to run - 1 do
begin
block.Read(color, SizeOf(Word));
P^[iCurrentWidth + i] := color;
end;
inc(iCurrentWidth, run);
end;
end;
end else begin // OldFormat (Pre-Alpha Client)
for iCurrentHeight := 0 to height - 1 do
begin
block.Position := lookup[iCurrentHeight];
iCurrentWidth := 0;
P := FGraphic.Bits + iCurrentHeight * width * 2;
if (block.Read(offset, SizeOf(Word)) = SizeOf(Word)) and
(block.Read(run, SizeOf(Word)) = SizeOf(Word)) then
begin
inc(iCurrentWidth, offset);
for i := 0 to run - 1 do
begin
block.Read(color, SizeOf(Word));
if color <> $0000 then
P^[iCurrentWidth + i] := color;
end;
inc(iCurrentWidth, run);
end;
inc(iCurrentWidth, run);
end;
end;
if AHue <> nil then
begin
for i := 0 to width * height - 1 do

View File

@@ -76,8 +76,8 @@ begin
for y := 0 to Height - 1 do
for x := 0 to Width - 1 do
begin
buffer.Read(color, SizeOf(byte));
color32.R := color * 8;
buffer.Read(color, SizeOf(Byte));
color32.R := Byte(color * 8);
color32.G := color32.R;
color32.B := color32.R;
if color > 0 then

View File

@@ -46,14 +46,14 @@ type
protected
FIsGhost: Boolean;
FGhostZ: ShortInt;
FGhostID: Word;
function GetTileID: Word; override;
FGhostID: LongWord;
function GetTileID: LongWord; override;
function GetZ: ShortInt; override;
public
property Altitude: ShortInt read GetZ write SetZ;
property IsGhost: Boolean read FIsGhost write FIsGhost;
property GhostZ: ShortInt read FGhostZ write FGhostZ;
property GhostID: Word write FGhostID;
property GhostID: LongWord write FGhostID;
function Clone: TMapCell; override;
function GetSize: Integer; override;
@@ -114,7 +114,7 @@ begin
Create(AOwner, AData, 0, 0);
end;
function TMapCell.GetTileID: Word;
function TMapCell.GetTileID: LongWord;
begin
if FIsGhost then
Result := FGhostID

View File

@@ -42,6 +42,7 @@ type
protected
{ Members }
FHue: Word;
FUnknown: Cardinal; // for old pre-alpha clients only
{ Methods }
procedure SetHue(AValue: Word);
@@ -82,6 +83,11 @@ type
function CompareStaticItems(const AStatic1, AStatic2: TStaticItem): Integer;
var
UseStaticsOldFormat: Boolean; // Использование старого формата pre-Alpha
// Очень не красивое и плозое решение, но делать по уму слишком сложно, так
// как это требует переписывание большой части кода на работу с интерфейсами.
implementation
function CompareStaticItems(const AStatic1, AStatic2: TStaticItem): Integer;
@@ -100,6 +106,8 @@ begin
if AData <> nil then
begin
if UseStaticsOldFormat
then AData.Read(FUnknown, SizeOf(Cardinal));;
AData.Read(FTileID, SizeOf(SmallInt));
AData.Read(iX, SizeOf(Byte));
AData.Read(iY, SizeOf(Byte));
@@ -128,6 +136,7 @@ end;
function TStaticItem.Clone: TStaticItem;
begin
Result := TStaticItem.Create(nil, nil);
Result.FUnknown:= FUnknown;
Result.FTileID := FTileID;
Result.FX := FX;
Result.FY := FY;
@@ -137,7 +146,9 @@ end;
function TStaticItem.GetSize: Integer;
begin
Result := 7;
if not UseStaticsOldFormat
then Result := 7
else Result := 11;
end;
procedure TStaticItem.UpdatePriorities(ATileData: TStaticTiledata;
@@ -159,6 +170,8 @@ begin
iX := FX mod 8;
iY := FY mod 8;
if UseStaticsOldFormat
then AData.Write(FUnknown, SizeOf(Cardinal));;
AData.Write(FTileID, SizeOf(SmallInt));
AData.Write(iX, SizeOf(Byte));
AData.Write(iY, SizeOf(Byte));
@@ -171,7 +184,7 @@ end;
constructor TStaticBlock.Create(AData: TStream; AIndex: TGenericIndex;
AX, AY: Word);
var
i: Integer;
i, size: Integer;
block: TMemoryStream;
begin
inherited Create;
@@ -179,13 +192,16 @@ begin
FY := AY;
FItems := TStaticItemList.Create(True);
if (AData <> nil) and (AIndex.Lookup > 0) and (AIndex.Size > 0) then
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
if not UseStaticsOldFormat
then size := 7
else size := 11;
for i := 1 to (AIndex.Size div size) do
FItems.Add(TStaticItem.Create(Self, block, AX, AY));
block.Free;
end;
@@ -214,7 +230,9 @@ end;
function TStaticBlock.GetSize: Integer;
begin
Result := FItems.Count * 7;
if not UseStaticsOldFormat
then Result := FItems.Count * 7
else Result := FItems.Count * 11;
end;
procedure TStaticBlock.ReverseWrite(AData: TStream);

View File

@@ -30,7 +30,7 @@ unit UTexture;
interface
uses
Classes, Imaging, ImagingTypes, ImagingClasses, UMulBlock, UGenericIndex;
Classes, Imaging, ImagingTypes, ImagingClasses, UMulBlock, UArt, UGenericIndex;
type
TTexture = class(TMulBlock)
@@ -51,8 +51,19 @@ type
property Extra: Integer read FExtra write FExtra;
end;
TOldTexture = class(TTexture)
constructor Create(AData: TStream; AIndex: TGenericIndex); overload;
constructor Create(AExtra: Integer); overload;
constructor Create(AId: Cardinal);
private
FArtTile: TArt;
end;
implementation
uses
UGameResources;//, Logging;
constructor TTexture.Create(AData: TStream; AIndex: TGenericIndex);
var
size: Integer;
@@ -132,5 +143,30 @@ begin
argbGraphic.Free;
end;
// TOldTexture - перегрузка класса, для работы с текстурами пре альфа клиента
constructor TOldTexture.Create(AId: Cardinal);
var
extradata: Integer;
begin
FArtTile := ResMan.Art.GetArt($4000 + AId, 0, nil, False);
if (FArtTile.Graphic.Width <= 64) then extradata := 0 else extradata := 1;
inherited Create(extradata); // Клиент использует не правильные текстуры
FArtTile.Graphic.StretchTo(0,0,FArtTile.Graphic.Width,FArtTile.Graphic.Height,
FGraphic, 0,0,FGraphic.Width,FGraphic.Height, rfBilinear );
//FArtTile.Destroy; // Надо ли удалять тайл?
end;
constructor TOldTexture.Create(AData: TStream; AIndex: TGenericIndex);
begin
inherited Create(0);
end;
constructor TOldTexture.Create(AExtra: Integer);
begin
inherited Create(AExtra);
end;
end.

View File

@@ -33,9 +33,14 @@ uses
Classes, SysUtils, UMulBlock;
const
LandTileDataSize = 26;
LandOldTileDataSize = 26;
LandOldTileGroupSize = 4 + 32 * LandOldTileDataSize;
StaticOldTileDataSize = 37;
StaticOldTileGroupSize = 4 + 32 * StaticOldTileDataSize;
LandTileDataSize = 30;
LandTileGroupSize = 4 + 32 * LandTileDataSize;
StaticTileDataSize = 37;
StaticTileDataSize = 41;
StaticTileGroupSize = 4 + 32 * StaticTileDataSize;
type
@@ -54,6 +59,7 @@ type
TTiledata = class(TMulBlock)
protected
FFlags: TTileDataFlags;
FFlags2 : LongWord;
FTileName: string;
public
property Flags: TTileDataFlags read FFlags write FFlags;
@@ -63,7 +69,7 @@ type
{ TLandTiledata }
TLandTiledata = class(TTiledata)
constructor Create(AData: TStream);
constructor Create(AData: TStream); virtual;
destructor Destroy; override;
function Clone: TLandTiledata; override;
function GetSize: Integer; override;
@@ -74,10 +80,20 @@ type
property TextureID: Word read FTextureID write FTextureID;
end;
{ TLandOldTiledata }
TLandOldTiledata = class(TLandTiledata)
constructor Create(AData: TStream); overload; override;
destructor Destroy; overload; override;
function Clone: TLandTiledata; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
end;
{ TStaticTiledata }
TStaticTiledata = class(TTiledata)
constructor Create(AData: TStream);
constructor Create(AData: TStream); virtual;
destructor Destroy; override;
function Clone: TStaticTiledata; override;
function GetSize: Integer; override;
@@ -106,10 +122,19 @@ type
property Height: Byte read FHeight write FHeight;
end;
{ TStaticOldTiledata }
TStaticOldTiledata = class(TStaticTiledata)
constructor Create(AData: TStream); overload; override;
destructor Destroy; overload; override;
function Clone: TStaticTiledata; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
end;
{ TLandTileGroup }
TLandTileGroup = class(TMulBlock)
constructor Create(AData: TStream);
constructor Create(AData: TStream); virtual;
destructor Destroy; override;
function Clone: TLandTileGroup; override;
function GetSize: Integer; override;
@@ -121,10 +146,19 @@ type
property Unknown: LongInt read FUnknown write FUnknown;
end;
{ TLandOldTileGroup }
TLandOldTileGroup = class(TLandTileGroup)
constructor Create(AData: TStream); overload; override;
destructor Destroy; overload; override;
function Clone: TLandTileGroup; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
end;
{ TStaticTileGroup }
TStaticTileGroup = class(TMulBlock)
constructor Create(AData: TStream);
constructor Create(AData: TStream); virtual;
destructor Destroy; override;
function Clone: TStaticTileGroup; override;
function GetSize: Integer; override;
@@ -136,11 +170,22 @@ type
property Unknown: LongInt read FUnknown write FUnknown;
end;
function GetTileDataOffset(ABlock: Integer): Integer;
{ TStaticOldTileGroup }
TStaticOldTileGroup = class(TStaticTileGroup)
constructor Create(AData: TStream); overload; override;
destructor Destroy; overload; override;
function Clone: TStaticTileGroup; override;
function GetSize: Integer; override;
procedure Write(AData: TStream); override;
end;
function GetTileDataOffset(ABlock: Integer; OldFormat: Boolean = False): Integer;
implementation
function GetTileDataOffset(ABlock: Integer): Integer;
function GetTileDataOffset(ABlock: Integer; OldFormat: Boolean = False): Integer;
var
group, tile: Integer;
begin
@@ -150,14 +195,19 @@ begin
group := ABlock div 32;
tile := ABlock mod 32;
Result := 512 * LandTileGroupSize + group * StaticTileGroupSize + 4
+ tile * StaticTileDataSize;
if OldFormat
then Result := 512 * LandOldTileGroupSize + group * StaticOldTileGroupSize
+ 4 + tile * StaticOldTileDataSize
else 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;
if OldFormat
then Result := group * LandOldTileGroupSize + 4 + tile * LandOldTileDataSize
else Result := group * LandTileGroupSize + 4 + tile * LandTileDataSize;
end;
end;
@@ -169,6 +219,7 @@ begin
if assigned(AData) then
begin
AData.Read(FFlags, SizeOf(LongWord));
AData.Read(FFlags2, SizeOf(LongWord));
AData.Read(FTextureID, SizeOf(Word));
AData.Read(PChar(FTileName)^, 20);
end;
@@ -185,6 +236,7 @@ function TLandTiledata.Clone: TLandTiledata;
begin
Result := TLandTiledata.Create(nil);
Result.FFlags := FFlags;
Result.FFlags2:= FFlags2;
Result.FTextureID := FTextureID;
Result.FTileName := FTileName;
end;
@@ -197,6 +249,7 @@ begin
for i := Length(FTileName) to 20 do
FTileName := FTileName + #0;
AData.Write(FFlags, SizeOf(LongWord));
AData.Write(FFlags2, SizeOf(LongWord));
AData.Write(FTextureID, SizeOf(Word));
AData.Write(PChar(FTileName)^, 20);
end;
@@ -206,6 +259,53 @@ begin
GetSize := LandTileDataSize;
end;
{ TLandOldTiledata }
constructor TLandOldTiledata.Create(AData: TStream);
begin
SetLength(FTileName, 20);
if assigned(AData) then
begin
AData.Read(FFlags, SizeOf(LongWord));
FFlags2 := 0;
AData.Read(FTextureID, SizeOf(Word));
AData.Read(PChar(FTileName)^, 20);
end;
FTileName := Trim(FTileName);
end;
destructor TLandOldTiledata.Destroy;
begin
SetLength(FTileName, 0);
inherited;
end;
function TLandOldTiledata.Clone: TLandTiledata;
begin
Result := TLandOldTiledata.Create(nil);
Result.FFlags := FFlags;
Result.FFlags2:= FFlags2;
Result.FTextureID := FTextureID;
Result.FTileName := FTileName;
end;
procedure TLandOldTiledata.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 TLandOldTiledata.GetSize: Integer;
begin
GetSize := LandOldTileDataSize;
end;
{ TStaticTiledata}
constructor TStaticTiledata.Create(AData: TStream);
@@ -214,6 +314,7 @@ begin
if AData <> nil then
begin
AData.Read(FFlags, SizeOf(LongWord));
AData.Read(FFlags2, SizeOf(LongWord));
AData.Read(FWeight, SizeOf(Byte));
AData.Read(FQuality, SizeOf(Byte));
AData.Read(FUnknown1, SizeOf(Word));
@@ -239,6 +340,7 @@ function TStaticTiledata.Clone: TStaticTiledata;
begin
Result := TStaticTiledata.Create(nil);
Result.FFlags := FFlags;
Result.FFlags2:= FFlags2;
Result.FWeight := FWeight;
Result.FQuality := FQuality;
Result.FUnknown1 := FUnknown1;
@@ -260,6 +362,7 @@ begin
for i := Length(FTileName) to 20 do
FTileName := FTileName + #0;
AData.Write(FFlags, SizeOf(LongWord));
AData.Write(FFlags2, SizeOf(LongWord));
AData.Write(FWeight, SizeOf(Byte));
AData.Write(FQuality, SizeOf(Byte));
AData.Write(FUnknown1, SizeOf(Word));
@@ -278,6 +381,80 @@ begin
GetSize := StaticTileDataSize;
end;
{ TStaticOldTiledata }
constructor TStaticOldTiledata.Create(AData: TStream);
begin
SetLength(FTileName, 20);
if AData <> nil then
begin
AData.Read(FFlags, SizeOf(LongWord));
FFlags2 := 0;
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 TStaticOldTiledata.Destroy;
begin
SetLength(FTileName, 0);
inherited;
end;
function TStaticOldTiledata.Clone: TStaticTiledata;
begin
Result := TStaticOldTiledata.Create(nil);
Result.FFlags := FFlags;
Result.FFlags2:= FFlags2;
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 TStaticOldTiledata.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 TStaticOldTiledata.GetSize: Integer;
begin
GetSize := StaticOldTileDataSize;
end;
{ TLandTileGroup }
constructor TLandTileGroup.Create(AData: TStream);
@@ -325,6 +502,53 @@ begin
GetSize := LandTileGroupSize;
end;
{ TLandOldTileGroup }
constructor TLandOldTileGroup.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] := TLandOldTiledata.Create(AData);
end;
destructor TLandOldTileGroup.Destroy;
var
i: Integer;
begin
for i := 0 to 31 do
LandTileData[i].Free;
inherited;
end;
function TLandOldTileGroup.Clone: TLandTileGroup;
var
i: Integer;
begin
Result := TLandOldTileGroup.Create(nil);
Result.FUnknown := FUnknown;
for i := 0 to 31 do
Result.LandTileData[i] := LandTileData[i].Clone;
end;
procedure TLandOldTileGroup.Write(AData: TStream);
var
i: Integer;
begin
AData.Write(FUnknown, SizeOf(LongInt));
for i := 0 to 31 do
LandTileData[i].Write(AData);
end;
function TLandOldTileGroup.GetSize: Integer;
begin
GetSize := LandOldTileGroupSize;
end;
{ TStaticTileGroup }
constructor TStaticTileGroup.Create(AData: TStream);
@@ -372,5 +596,52 @@ begin
GetSize := StaticTileGroupSize;
end;
{ TStaticOldTileGroup }
constructor TStaticOldTileGroup.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] := TStaticOldTiledata.Create(AData);
end;
destructor TStaticOldTileGroup.Destroy;
var
i: Integer;
begin
for i := 0 to 31 do
StaticTileData[i].Free;
inherited;
end;
function TStaticOldTileGroup.Clone: TStaticTileGroup;
var
i: Integer;
begin
Result := TStaticOldTileGroup.Create(nil);
Result.FUnknown := FUnknown;
for i := 0 to 31 do
Result.StaticTileData[i] := StaticTileData[i].Clone;
end;
procedure TStaticOldTileGroup.Write(AData: TStream);
var
i: Integer;
begin
AData.Write(FUnknown, SizeOf(LongInt));
for i := 0 to 31 do
StaticTileData[i].Write(AData);
end;
function TStaticOldTileGroup.GetSize: Integer;
begin
GetSize := StaticOldTileGroupSize;
end;
end.

103
UOLib/UUopFile.pas Normal file
View File

@@ -0,0 +1,103 @@
(*
* CentrEd+ (c) 2013 by StaticZ <uoquint.ru>
* Base on Wyatt algoritm published on www.ruosi.org
*)
unit UUopFile;
{$mode objfpc}{$H+}
interface
uses
SysUtils, Classes, Graphics, UMulBlock;
function HashFileName(string s) : QWord;
function UopContainer()
type
TUopHeader = packed record;
Format: DWord;
Version: DWord;
Signature: DWord;
Offset: QWord;
Capacity: DWord;
Count: DWord;
end;
TUopIndex = packed record;
Offset: DWord;
Length: DWord;
Uncomp: DWord;
Append: DWord;
end;
implementation
{ THue }
function HashFileName(string s) : QWord;
var
i, stl, eax, ecx, edx, ebx, esi, edi : DWord;
begin
i := 0; stl := Length(s);
eax := 0; ebx := $DEADBEEF + stl;
ecx := 0; edi := $DEADBEEF + stl;
edx := 0; esi := $DEADBEEF + stl;
while i < stl do begin
edi := (uint)((ord(s[i+ 7])shl 24)or(ord(s[i+ 6])shl 16)or(ord(s[i+ 5])shl 8)or ord(s[i+ 4]))+edi;
esi := (uint)((ord(s[i+11])shl 24)or(ord(s[i+10])shl 16)or(ord(s[i+ 9])shl 8)or ord(s[i+ 8]))+esi;
edx := (uint)((ord(s[i+ 3])shl 24)or(ord(s[i+ 2])shl 16)or(ord(s[i+ 1])shl 8)or ord(s[i ]))-esi;
edx := (edx + ebx)xor(esi shr 28)xor(esi shl 4);
inc(esi, edi);
edi := (edi - edx)xor(edx shr 26)xor(edx shl 6);
inc(edx, esi);
esi := (esi - edi)xor(edi shr 24)xor(edi shl 8);
inc(edi, edx);
ebx := (edx - esi)xor(esi shr 16)xor(esi shl 16);
inc(esi, edi);
edi := (edi - ebx)xor(ebx shr 13)xor(ebx shl 19);
inc(ebx, esi);
esi := (esi - edi)xor(edi shr 28)xor(edi shl 4);
inc(edi, ebx);
inc(i, 12);
end;
if (stl - i) > 0 then begin
if (stl - i) <= 12 then inc(esi, DWord(ord(s[i+11])shl 24));
if (stl - i) <= 11 then inc(esi, DWord(ord(s[i+10])shl 16));
if (stl - i) <= 10 then inc(esi, DWord(ord(s[i+ 9])shl 8));
if (stl - i) <= 9 then inc(esi, DWord(ord(s[i+ 8]) ));
if (stl - i) <= 8 then inc(edi, DWord(ord(s[i+ 7])shl 24));
if (stl - i) <= 7 then inc(edi, DWord(ord(s[i+ 6])shl 16));
if (stl - i) <= 6 then inc(edi, DWord(ord(s[i+ 5])shl 8));
if (stl - i) <= 5 then inc(edi, DWord(ord(s[i+ 4]) ));
if (stl - i) <= 4 then inc(ebx, DWord(ord(s[i+ 3])shl 24));
if (stl - i) <= 3 then inc(ebx, DWord(ord(s[i+ 2])shl 16));
if (stl - i) <= 2 then inc(ebx, DWord(ord(s[i+ 1])shl 8));
if (stl - i) <= 1 then inc(ebx, DWord(ord(s[i+ 0]) ));
esi := (esi xor edi) - ((edi shr 18)xor(edi shl 14));
ecx := (esi xor ebx) - ((esi shr 21)xor(esi shl 11));
edi := (edi xor ecx) - ((ecx shr 7)xor(ecx shl 25));
esi := (esi xor edi) - ((edi shr 16)xor(edi shl 16));
edx := (esi xor ecx) - ((esi shr 28)xor(esi shl 4));
edi := (edi xor edx) - ((edx shr 18)xor(edx shl 14));
eax := (esi xor edi) - ((edi shr 8)xor(edi shl 24));
Result := (QWord(edi) shl 32) or eax;
end else begin
Result := (QWord(esi) shl 32) or eax;
end;
end;
end.

View File

@@ -41,7 +41,7 @@ type
constructor Create(AOwner: TWorldBlock);
protected
FOwner: TWorldBlock;
FTileID: Word;
FTileID: LongWord;
FX: Word;
FY: Word;
FZ: ShortInt;
@@ -52,12 +52,12 @@ type
FPriorityBonus: ShortInt;
FPrioritySolver: Integer;
procedure DoChanged;
function GetTileID: Word; virtual;
function GetTileID: LongWord; virtual;
function GetZ: ShortInt; virtual;
procedure SetLocked(ALocked: Boolean);
procedure SetOwner(AOwner: TWorldBlock);
procedure SetSelected(ASelected: Boolean);
procedure SetTileID(AValue: Word);
procedure SetTileID(AValue: LongWord);
procedure SetX(AValue: Word);
procedure SetY(AValue: Word);
procedure SetZ(AValue: ShortInt);
@@ -66,7 +66,7 @@ type
procedure Delete;
property Owner: TWorldBlock read FOwner write SetOwner;
property TileID: Word read GetTileID write SetTileID;
property TileID: LongWord read GetTileID write SetTileID;
property X: Word read FX write SetX;
property Y: Word read FY write SetY;
property Z: ShortInt read GetZ write SetZ;
@@ -77,7 +77,7 @@ type
property PriorityBonus: ShortInt read FPriorityBonus write FPriorityBonus;
property PrioritySolver: Integer read FPrioritySolver write FPrioritySolver;
property RawTileID: Word read FTileID;
property RawTileID: LongWord read FTileID;
property RawZ: ShortInt read FZ;
end;
@@ -151,7 +151,7 @@ begin
FOwner.Changed := True;
end;
function TWorldItem.GetTileID: Word;
function TWorldItem.GetTileID: LongWord;
begin
Result := FTileID;
end;
@@ -211,7 +211,7 @@ begin
FSelected := ASelected;
end;
procedure TWorldItem.SetTileID(AValue: Word);
procedure TWorldItem.SetTileID(AValue: LongWord);
begin
if FTileID = AValue then
Exit;