- Changed rendering to build the draw list for the whole range

- Added CanBeEdited flag to TWorldItem
- Changed list sorting from custom heap sort implementation to the FCL standard (QuickSort)
This commit is contained in:
Andreas Schneider 2009-05-15 23:37:10 +02:00
parent c20a160543
commit 2f560a7738
6 changed files with 627 additions and 664 deletions

View File

@ -253,10 +253,8 @@
</CodeGeneration> </CodeGeneration>
<Linking> <Linking>
<Debugging> <Debugging>
<UseLineInfoUnit Value="False"/> <GenerateDebugInfo Value="True"/>
<StripSymbols Value="True"/>
</Debugging> </Debugging>
<LinkSmart Value="True"/>
<Options> <Options>
<Win32> <Win32>
<GraphicApplication Value="True"/> <GraphicApplication Value="True"/>

View File

@ -21,7 +21,7 @@
* CDDL HEADER END * CDDL HEADER END
* *
* *
* Portions Copyright 2007 Andreas Schneider * Portions Copyright 2009 Andreas Schneider
*) *)
unit ULandscape; unit ULandscape;
@ -103,6 +103,7 @@ type
constructor Create(AWidth, AHeight: Word); constructor Create(AWidth, AHeight: Word);
destructor Destroy; override; destructor Destroy; override;
protected protected
{ Members }
FWidth: Word; FWidth: Word;
FHeight: Word; FHeight: Word;
FCellWidth: Word; FCellWidth: Word;
@ -110,7 +111,7 @@ type
FBlockCache: TCacheManager; FBlockCache: TCacheManager;
FOnChange: TLandscapeChangeEvent; FOnChange: TLandscapeChangeEvent;
FOpenRequests: array of Boolean; FOpenRequests: array of Boolean;
function Compare(left, right: TObject): Integer; { Methods }
function GetNormals(AX, AY: Word): TNormals; function GetNormals(AX, AY: Word): TNormals;
function GetMapCell(AX, AY: Word): TMapCell; function GetMapCell(AX, AY: Word): TMapCell;
function GetStaticList(AX, AY: Word): TList; function GetStaticList(AX, AY: Word): TList;
@ -118,7 +119,6 @@ type
function GetStaticBlock(AX, AY: Word): TSeperatedStaticBlock; function GetStaticBlock(AX, AY: Word): TSeperatedStaticBlock;
procedure UpdateStaticsPriority(AStaticItem: TStaticItem; procedure UpdateStaticsPriority(AStaticItem: TStaticItem;
APrioritySolver: Integer); APrioritySolver: Integer);
procedure OnBlockChanged(ABlock: TMulBlock);
procedure OnRemoveCachedObject(AObject: TObject); procedure OnRemoveCachedObject(AObject: TObject);
procedure OnBlocksPacket(ABuffer: TEnhancedMemoryStream); procedure OnBlocksPacket(ABuffer: TEnhancedMemoryStream);
@ -129,6 +129,7 @@ type
procedure OnMoveStaticPacket(ABuffer: TEnhancedMemoryStream); procedure OnMoveStaticPacket(ABuffer: TEnhancedMemoryStream);
procedure OnHueStaticPacket(ABuffer: TEnhancedMemoryStream); procedure OnHueStaticPacket(ABuffer: TEnhancedMemoryStream);
public public
{ Fields }
property Width: Word read FWidth; property Width: Word read FWidth;
property Height: Word read FHeight; property Height: Word read FHeight;
property CellWidth: Word read FCellWidth; property CellWidth: Word read FCellWidth;
@ -137,10 +138,11 @@ type
property StaticList[X, Y: Word]: TList read GetStaticList; property StaticList[X, Y: Word]: TList read GetStaticList;
property Normals[X, Y: Word]: TNormals read GetNormals; property Normals[X, Y: Word]: TNormals read GetNormals;
property OnChange: TLandscapeChangeEvent read FOnChange write FOnChange; property OnChange: TLandscapeChangeEvent read FOnChange write FOnChange;
{ Methods }
function GetDrawList(AX, AY: Word; AMinZ, AMaxZ: ShortInt; function GetDrawList(AX, AY, AWidth, AHeight: Word; AMinZ, AMaxZ: ShortInt;
AGhostTile: TWorldItem; AVirtualLayer: TStaticItem; AMap, AGhostTile: TWorldItem; AVirtualLayer: TStaticItem; AMap,
AStatics: Boolean; ANoDraw:Boolean; AStaticsFilter: TStaticFilter): TList; AStatics: Boolean; ANoDraw:Boolean; AStaticsFilter: TStaticFilter): TList;
procedure UpdateDrawListItems(AList: TList);
function GetEffectiveAltitude(ATile: TMapCell): ShortInt; function GetEffectiveAltitude(ATile: TMapCell): ShortInt;
function GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt; function GetLandAlt(AX, AY: Word; ADefault: ShortInt): ShortInt;
@ -204,15 +206,6 @@ begin
Result := ((AX and $7FFF) shl 15) or (AY and $7FFF); Result := ((AX and $7FFF) shl 15) or (AY and $7FFF);
end; end;
{operator=(AStaticItem: TStaticItem; AStaticInfo: TStaticInfo): Boolean;
begin
Result := (AStaticItem.X = AStaticInfo.X) and
(AStaticItem.Y = AStaticInfo.Y) and
(AStaticItem.Z = AStaticInfo.Z) and
(AStaticItem.TileID = AStaticInfo.TileID) and
(AStaticItem.Hue = AStaticInfo.Hue);
end;}
{ TLandTextureManager } { TLandTextureManager }
constructor TLandTextureManager.Create; constructor TLandTextureManager.Create;
@ -410,88 +403,113 @@ begin
end; end;
end; end;
function TLandscape.Compare(left, right: TObject): Integer; function Compare(AItem1, AItem2: Pointer): Integer;
begin begin
Result := TWorldItem(right).Priority - TWorldItem(left).Priority; if TWorldItem(AItem1).X <> TWorldItem(AItem2).X then
Exit(TWorldItem(AItem1).X - TWorldItem(AItem2).X);
if TWorldItem(AItem1).Y <> TWorldItem(AItem2).Y then
Exit(TWorldItem(AItem1).Y - TWorldItem(AItem2).Y);
Result := TWorldItem(AItem1).Priority - TWorldItem(AItem2).Priority;
if Result = 0 then if Result = 0 then
begin begin
if (left is TMapCell) and (right is TStaticItem) then if (TObject(AItem1) is TMapCell) and (TObject(AItem2) is TStaticItem) then
Result := 1 Result := -1
else if (left is TStaticItem) and (right is TMapCell) then else if (TObject(AItem1) is TStaticItem) and (TObject(AItem2) is TMapCell) then
Result := -1; Result := 1;
end; end;
if Result = 0 then if Result = 0 then
Result := TWorldItem(right).PriorityBonus - TWorldItem(left).PriorityBonus; Result := TWorldItem(AItem1).PriorityBonus - TWorldItem(AItem2).PriorityBonus;
if Result = 0 then if Result = 0 then
Result := TWorldItem(right).PrioritySolver - TWorldItem(left).PrioritySolver; Result := TWorldItem(AItem1).PrioritySolver - TWorldItem(AItem2).PrioritySolver;
end; end;
function TLandscape.GetDrawList(AX, AY: Word; AMinZ, AMaxZ: ShortInt; function TLandscape.GetDrawList(AX, AY, AWidth, AHeight: Word;
AGhostTile: TWorldItem; AVirtualLayer: TStaticItem; AMap, AMinZ, AMaxZ: ShortInt; AGhostTile: TWorldItem; AVirtualLayer: TStaticItem;
AStatics: Boolean; ANoDraw:Boolean; AStaticsFilter: TStaticFilter): TList; AMap, AStatics: Boolean; ANoDraw: Boolean;
AStaticsFilter: TStaticFilter): TList;
var var
landAlt: ShortInt; landAlt: ShortInt;
drawMapCell: TMapCell; drawMapCell: TMapCell;
drawStatics: TList; drawStatics: TList;
i: Integer; i, x, y: Integer;
begin begin
Result := TList.Create; Result := TList.Create;
if AMap then for x := AX to AX + AWidth do
begin for y := AY to AY + AWidth do
landAlt := GetLandAlt(AX, AY, 0);
if (landAlt >= AMinZ) and (landAlt <= AMaxZ) then
begin begin
drawMapCell := GetMapCell(AX, AY); if AMap then
if (drawMapCell <> nil) and (ANoDraw or (drawMapCell.TileID > 2)) then
begin begin
drawMapCell.Priority := GetEffectiveAltitude(drawMapCell); landAlt := GetLandAlt(x, y, 0);
drawMapCell.PriorityBonus := 0; if (landAlt >= AMinZ) and (landAlt <= AMaxZ) then
drawMapCell.PrioritySolver := 0;
Result.Add(drawMapCell);
end;
if AGhostTile is TMapCell then
begin
AGhostTile.X := AX;
AGhostTile.Y := AY;
AGhostTile.Priority := GetEffectiveAltitude(TMapCell(AGhostTile));
AGhostTile.PriorityBonus := 0;
AGhostTile.PrioritySolver := 0;
Result.Add(AGhostTile);
end;
end;
end;
if AStatics then
begin
drawStatics := GetStaticList(AX, AY);
if drawStatics <> nil then
for i := 0 to drawStatics.Count - 1 do
if (TStaticItem(drawStatics[i]).Z >= AMinZ) and
(TStaticItem(drawStatics[i]).Z <= AMaxZ) and
((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then
begin begin
UpdateStaticsPriority(TStaticItem(drawStatics[i]), i + 1); drawMapCell := GetMapCell(x, y);
Result.Add(Pointer(drawStatics[i])); if (drawMapCell <> nil) and (ANoDraw or (drawMapCell.TileID > 2)) then
end; begin
drawMapCell.Priority := GetEffectiveAltitude(drawMapCell);
drawMapCell.PriorityBonus := 0;
drawMapCell.PrioritySolver := 0;
Result.Add(drawMapCell);
end;
if AGhostTile is TStaticItem then if AGhostTile is TMapCell then
begin begin
UpdateStaticsPriority(TStaticItem(AGhostTile), MaxInt); AGhostTile.X := x;
Result.Add(AGhostTile); AGhostTile.Y := y;
AGhostTile.Priority := GetEffectiveAltitude(TMapCell(AGhostTile));
AGhostTile.PriorityBonus := 0;
AGhostTile.PrioritySolver := 0;
Result.Add(AGhostTile);
end;
end;
end;
if AStatics then
begin
drawStatics := GetStaticList(x, y);
if drawStatics <> nil then
for i := 0 to drawStatics.Count - 1 do
if (TStaticItem(drawStatics[i]).Z >= AMinZ) and
(TStaticItem(drawStatics[i]).Z <= AMaxZ) and
((AStaticsFilter = nil) or AStaticsFilter(TStaticItem(drawStatics[i]))) then
begin
UpdateStaticsPriority(TStaticItem(drawStatics[i]), i + 1);
Result.Add(Pointer(drawStatics[i]));
end;
if AGhostTile is TStaticItem then
begin
UpdateStaticsPriority(TStaticItem(AGhostTile), MaxInt);
Result.Add(AGhostTile);
end;
end;
//TODO : re add virtual layer
{if AVirtualLayer <> nil then
begin
UpdateStaticsPriority(AVirtualLayer, MaxInt-1);
Result.Add(AVirtualLayer);
end;}
end; end;
end;
Result.Sort(@Compare);
if AVirtualLayer <> nil then //ListSort(Result, @Compare);
end;
procedure TLandscape.UpdateDrawListItems(AList: TList);
var
worldItem: TWorldItem;
i: Integer;
begin
for i := 0 to AList.Count - 1 do
begin begin
UpdateStaticsPriority(AVirtualLayer, MaxInt-1); worldItem := TWorldItem(AList.Items[i]);
Result.Add(AVirtualLayer); worldItem.CanBeEdited := dmNetwork.CanWrite(worldItem.X, worldItem.Y);
end; end;
ListSort(Result, @Compare);
end; end;
function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt; function TLandscape.GetEffectiveAltitude(ATile: TMapCell): ShortInt;
@ -591,37 +609,6 @@ begin
Result[3] := VectorNorm(VectorAdd(VectorAdd(VectorAdd(north, west), east), south)); Result[3] := VectorNorm(VectorAdd(VectorAdd(VectorAdd(north, west), east), south));
end; end;
procedure TLandscape.OnBlockChanged(ABlock: TMulBlock);
var
block, old: TWorldBlock;
mode: Byte;
id, blockID: Integer;
begin
{block := ABlock as TWorldBlock;
if block <> nil then
begin
if block is TSeperatedStaticBlock then
mode := mStatics
else
mode := mMap;
id := GetID(block.X, block.Y, mode);
blockID := (block.X * FHeight) + block.Y;
if block.Changed or (block.RefCount > 0) then
begin
if FPersistentBlocks[blockID][mode] = nil then
begin
FPersistentBlocks[blockID][mode] := block;
FBlockCache.DiscardID(id);
end;
end else
begin
FPersistentBlocks[blockID][mode] := nil;
if not FBlockCache.QueryID(id, TObject(old)) then
FBlockCache.StoreID(id, block);
end;
end;}
end;
procedure TLandscape.MoveStatic(AStatic: TStaticItem; AX, AY: Word); procedure TLandscape.MoveStatic(AStatic: TStaticItem; AX, AY: Word);
var var
sourceBlock, targetBlock: TSeperatedStaticBlock; sourceBlock, targetBlock: TSeperatedStaticBlock;
@ -639,7 +626,8 @@ begin
targetStaticList.Add(AStatic); targetStaticList.Add(AStatic);
for i := 0 to targetStaticList.Count - 1 do for i := 0 to targetStaticList.Count - 1 do
UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i); UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i);
ListSort(targetStaticList, @Compare); targetStaticList.Sort(@Compare);
//ListSort(targetStaticList, @Compare);
AStatic.UpdatePos(AX, AY, AStatic.Z); AStatic.UpdatePos(AX, AY, AStatic.Z);
AStatic.Owner := targetBlock; AStatic.Owner := targetBlock;
end; end;
@ -788,7 +776,8 @@ begin
targetStaticList.Add(staticItem); targetStaticList.Add(staticItem);
for i := 0 to targetStaticList.Count - 1 do for i := 0 to targetStaticList.Count - 1 do
UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i); UpdateStaticsPriority(TStaticItem(targetStaticList.Items[i]), i);
ListSort(targetStaticList, @Compare); targetStaticList.Sort(@Compare);
//ListSort(targetStaticList, @Compare);
staticItem.Owner := block; staticItem.Owner := block;
if Assigned(FOnChange) then FOnChange; if Assigned(FOnChange) then FOnChange;
end; end;
@ -846,7 +835,8 @@ 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
UpdateStaticsPriority(TStaticItem(statics.Items[j]), j); UpdateStaticsPriority(TStaticItem(statics.Items[j]), j);
ListSort(statics, @Compare); statics.Sort(@Compare);
//ListSort(statics, @Compare);
if Assigned(FOnChange) then FOnChange; if Assigned(FOnChange) then FOnChange;
Break; Break;
end; end;
@ -906,7 +896,8 @@ begin
statics.Add(staticItem); statics.Add(staticItem);
for i := 0 to statics.Count - 1 do for i := 0 to statics.Count - 1 do
UpdateStaticsPriority(TStaticItem(statics.Items[i]), i); UpdateStaticsPriority(TStaticItem(statics.Items[i]), i);
ListSort(statics, @Compare); statics.Sort(@Compare);
//ListSort(statics, @Compare);
staticItem.Owner := targetBlock; staticItem.Owner := targetBlock;
end; end;
@ -987,7 +978,6 @@ var
pixel: TColor32Rec; pixel: TColor32Rec;
begin begin
Result := False; Result := False;
//writeln(FGraphic.Width, ',', FGraphic.Height, ',', AX, ',', AY);
if InRange(AX, 0, FGraphic.Width - 1) and if InRange(AX, 0, FGraphic.Width - 1) and
InRange(AY, 0, FGraphic.Height - 1) then InRange(AY, 0, FGraphic.Height - 1) then
begin begin

View File

@ -1,7 +1,7 @@
object frmMain: TfrmMain object frmMain: TfrmMain
Left = 247 Left = 236
Height = 603 Height = 603
Top = 91 Top = 126
Width = 766 Width = 766
ActiveControl = pcLeft ActiveControl = pcLeft
Caption = 'UO CentrED' Caption = 'UO CentrED'
@ -41,7 +41,7 @@ object frmMain: TfrmMain
Left = 88 Left = 88
Height = 14 Height = 14
Top = 7 Top = 7
Width = 11 Width = 10
Caption = 'Y:' Caption = 'Y:'
ParentColor = False ParentColor = False
end end
@ -54,10 +54,10 @@ object frmMain: TfrmMain
ParentColor = False ParentColor = False
end end
object lblTip: TLabel object lblTip: TLabel
Left = 554 Left = 528
Height = 31 Height = 31
Top = 0 Top = 0
Width = 204 Width = 230
Align = alRight Align = alRight
Alignment = taRightJustify Alignment = taRightJustify
BorderSpacing.Right = 8 BorderSpacing.Right = 8
@ -66,10 +66,10 @@ object frmMain: TfrmMain
ParentColor = False ParentColor = False
end end
object lblTipC: TLabel object lblTipC: TLabel
Left = 530 Left = 498
Height = 31 Height = 31
Top = 0 Top = 0
Width = 24 Width = 30
Align = alRight Align = alRight
Caption = 'Tip: ' Caption = 'Tip: '
Font.Height = -11 Font.Height = -11
@ -80,7 +80,7 @@ object frmMain: TfrmMain
end end
object edX: TSpinEdit object edX: TSpinEdit
Left = 24 Left = 24
Height = 23 Height = 19
Top = 3 Top = 3
Width = 55 Width = 55
MaxValue = 100000 MaxValue = 100000
@ -88,7 +88,7 @@ object frmMain: TfrmMain
end end
object edY: TSpinEdit object edY: TSpinEdit
Left = 104 Left = 104
Height = 23 Height = 19
Top = 3 Top = 3
Width = 52 Width = 52
MaxValue = 100000 MaxValue = 100000
@ -116,31 +116,31 @@ object frmMain: TfrmMain
TabOrder = 1 TabOrder = 1
object tsTiles: TTabSheet object tsTiles: TTabSheet
Caption = 'Tiles' Caption = 'Tiles'
ClientHeight = 492 ClientHeight = 500
ClientWidth = 218 ClientWidth = 222
object pnlTileListSettings: TPanel object pnlTileListSettings: TPanel
Left = 0 Left = 0
Height = 56 Height = 56
Top = 0 Top = 0
Width = 218 Width = 222
Align = alTop Align = alTop
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 56 ClientHeight = 56
ClientWidth = 218 ClientWidth = 222
TabOrder = 0 TabOrder = 0
object lblFilter: TLabel object lblFilter: TLabel
Left = 84 Left = 84
Height = 14 Height = 14
Top = 8 Top = 8
Width = 29 Width = 30
Caption = 'Filter:' Caption = 'Filter:'
ParentColor = False ParentColor = False
end end
object cbTerrain: TCheckBox object cbTerrain: TCheckBox
Left = 4 Left = 4
Height = 22 Height = 18
Top = 8 Top = 8
Width = 60 Width = 57
Caption = 'Terrain' Caption = 'Terrain'
Checked = True Checked = True
OnChange = cbTerrainChange OnChange = cbTerrainChange
@ -149,9 +149,9 @@ object frmMain: TfrmMain
end end
object cbStatics: TCheckBox object cbStatics: TCheckBox
Left = 4 Left = 4
Height = 22 Height = 18
Top = 32 Top = 32
Width = 60 Width = 56
Caption = 'Statics' Caption = 'Statics'
Checked = True Checked = True
OnChange = cbStaticsChange OnChange = cbStaticsChange
@ -160,7 +160,7 @@ object frmMain: TfrmMain
end end
object edFilter: TEdit object edFilter: TEdit
Left = 84 Left = 84
Height = 23 Height = 19
Top = 24 Top = 24
Width = 112 Width = 112
OnEditingDone = edFilterEditingDone OnEditingDone = edFilterEditingDone
@ -170,9 +170,9 @@ object frmMain: TfrmMain
object vdtTiles: TVirtualDrawTree object vdtTiles: TVirtualDrawTree
Tag = 1 Tag = 1
Left = 0 Left = 0
Height = 238 Height = 246
Top = 56 Top = 56
Width = 218 Width = 222
Align = alClient Align = alClient
DefaultNodeHeight = 44 DefaultNodeHeight = 44
DragMode = dmAutomatic DragMode = dmAutomatic
@ -193,6 +193,7 @@ object frmMain: TfrmMain
Text = 'Name' Text = 'Name'
Width = 100 Width = 100
end> end>
Header.DefaultHeight = 17
Header.MainColumn = 2 Header.MainColumn = 2
Header.Options = [hoVisible] Header.Options = [hoVisible]
Header.ParentFont = True Header.ParentFont = True
@ -215,12 +216,12 @@ object frmMain: TfrmMain
object gbRandom: TGroupBox object gbRandom: TGroupBox
Left = 0 Left = 0
Height = 193 Height = 193
Top = 299 Top = 307
Width = 218 Width = 222
Align = alBottom Align = alBottom
Caption = 'Random pool' Caption = 'Random pool'
ClientHeight = 179 ClientHeight = 179
ClientWidth = 216 ClientWidth = 220
TabOrder = 2 TabOrder = 2
object vdtRandom: TVirtualDrawTree object vdtRandom: TVirtualDrawTree
Tag = 1 Tag = 1
@ -228,7 +229,7 @@ object frmMain: TfrmMain
Left = 0 Left = 0
Height = 127 Height = 127
Top = 22 Top = 22
Width = 216 Width = 220
Align = alClient Align = alClient
DefaultNodeHeight = 44 DefaultNodeHeight = 44
DragType = dtVCL DragType = dtVCL
@ -248,6 +249,7 @@ object frmMain: TfrmMain
Text = 'Name' Text = 'Name'
Width = 100 Width = 100
end> end>
Header.DefaultHeight = 17
Header.Options = [hoColumnResize, hoDrag, hoVisible] Header.Options = [hoColumnResize, hoDrag, hoVisible]
Header.ParentFont = True Header.ParentFont = True
Header.Style = hsFlatButtons Header.Style = hsFlatButtons
@ -265,11 +267,11 @@ object frmMain: TfrmMain
Left = 0 Left = 0
Height = 22 Height = 22
Top = 0 Top = 0
Width = 216 Width = 220
Align = alTop Align = alTop
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 22 ClientHeight = 22
ClientWidth = 216 ClientWidth = 220
TabOrder = 1 TabOrder = 1
object btnAddRandom: TSpeedButton object btnAddRandom: TSpeedButton
Left = 2 Left = 2
@ -420,12 +422,12 @@ object frmMain: TfrmMain
Left = 4 Left = 4
Height = 22 Height = 22
Top = 153 Top = 153
Width = 208 Width = 212
Align = alBottom Align = alBottom
BorderSpacing.Around = 4 BorderSpacing.Around = 4
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 22 ClientHeight = 22
ClientWidth = 208 ClientWidth = 212
TabOrder = 2 TabOrder = 2
object btnRandomPresetSave: TSpeedButton object btnRandomPresetSave: TSpeedButton
Left = 158 Left = 158
@ -527,7 +529,7 @@ object frmMain: TfrmMain
end end
object cbRandomPreset: TComboBox object cbRandomPreset: TComboBox
Left = 0 Left = 0
Height = 29 Height = 25
Top = 0 Top = 0
Width = 152 Width = 152
AutoComplete = False AutoComplete = False
@ -543,14 +545,14 @@ object frmMain: TfrmMain
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 5 Height = 5
Top = 294 Top = 302
Width = 218 Width = 222
Align = alBottom Align = alBottom
ResizeAnchor = akBottom ResizeAnchor = akBottom
end end
object edSearchID: TEdit object edSearchID: TEdit
Left = 118 Left = 118
Height = 23 Height = 19
Hint = 'Append S or T to restrict the search to Statics or Terrain.' Hint = 'Append S or T to restrict the search to Statics or Terrain.'
Top = 256 Top = 256
Width = 96 Width = 96
@ -565,13 +567,13 @@ object frmMain: TfrmMain
end end
object tsClients: TTabSheet object tsClients: TTabSheet
Caption = 'Clients' Caption = 'Clients'
ClientHeight = 492 ClientHeight = 500
ClientWidth = 218 ClientWidth = 222
object lbClients: TListBox object lbClients: TListBox
Left = 0 Left = 0
Height = 492 Height = 500
Top = 0 Top = 0
Width = 218 Width = 222
Align = alClient Align = alClient
ItemHeight = 0 ItemHeight = 0
OnDblClick = mnuGoToClientClick OnDblClick = mnuGoToClientClick
@ -583,14 +585,14 @@ object frmMain: TfrmMain
end end
object tsLocations: TTabSheet object tsLocations: TTabSheet
Caption = 'Locations' Caption = 'Locations'
ClientHeight = 492 ClientHeight = 500
ClientWidth = 218 ClientWidth = 222
object vstLocations: TVirtualStringTree object vstLocations: TVirtualStringTree
Cursor = 63 Cursor = 63
Left = 4 Left = 4
Height = 456 Height = 464
Top = 4 Top = 4
Width = 210 Width = 214
Align = alClient Align = alClient
BorderSpacing.Around = 4 BorderSpacing.Around = 4
BorderStyle = bsSingle BorderStyle = bsSingle
@ -607,6 +609,7 @@ object frmMain: TfrmMain
Text = 'Name' Text = 'Name'
Width = 135 Width = 135
end> end>
Header.DefaultHeight = 17
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoVisible] Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoVisible]
Header.ParentFont = True Header.ParentFont = True
Header.Style = hsFlatButtons Header.Style = hsFlatButtons
@ -624,13 +627,13 @@ object frmMain: TfrmMain
object pnlLocationControls: TPanel object pnlLocationControls: TPanel
Left = 4 Left = 4
Height = 24 Height = 24
Top = 464 Top = 472
Width = 210 Width = 214
Align = alBottom Align = alBottom
BorderSpacing.Around = 4 BorderSpacing.Around = 4
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 24 ClientHeight = 24
ClientWidth = 210 ClientWidth = 214
TabOrder = 1 TabOrder = 1
object btnClearLocations: TSpeedButton object btnClearLocations: TSpeedButton
Left = 112 Left = 112
@ -1010,7 +1013,7 @@ object frmMain: TfrmMain
object vstChat: TVirtualStringTree object vstChat: TVirtualStringTree
Cursor = 63 Cursor = 63
Left = 0 Left = 0
Height = 99 Height = 103
Top = 0 Top = 0
Width = 542 Width = 542
Align = alClient Align = alClient
@ -1032,6 +1035,7 @@ object frmMain: TfrmMain
Text = 'Message' Text = 'Message'
Width = 392 Width = 392
end> end>
Header.DefaultHeight = 17
Header.MainColumn = 2 Header.MainColumn = 2
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoVisible] Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoVisible]
Header.ParentFont = True Header.ParentFont = True
@ -1047,8 +1051,8 @@ object frmMain: TfrmMain
end end
object edChat: TEdit object edChat: TEdit
Left = 0 Left = 0
Height = 23 Height = 19
Top = 99 Top = 103
Width = 542 Width = 542
Align = alBottom Align = alBottom
OnKeyPress = edChatKeyPress OnKeyPress = edChatKeyPress
@ -1343,7 +1347,6 @@ object frmMain: TfrmMain
end end
end end
object ImageList1: TImageList object ImageList1: TImageList
Masked = False
left = 264 left = 264
top = 32 top = 32
Bitmap = { Bitmap = {
@ -1991,7 +1994,7 @@ object frmMain: TfrmMain
} }
end end
object pmTileList: TPopupMenu object pmTileList: TPopupMenu
left = 184 left = 185
top = 128 top = 128
object mnuAddToRandom: TMenuItem object mnuAddToRandom: TMenuItem
Caption = 'Add to random pool' Caption = 'Add to random pool'
@ -1999,13 +2002,6 @@ object frmMain: TfrmMain
end end
end end
object ApplicationProperties1: TApplicationProperties object ApplicationProperties1: TApplicationProperties
CaptureExceptions = True
HintColor = clInfoBk
HintHidePause = 2500
HintPause = 500
HintShortCuts = True
HintShortPause = 0
ShowHint = True
OnIdle = ApplicationProperties1Idle OnIdle = ApplicationProperties1Idle
left = 295 left = 295
top = 33 top = 33
@ -2375,7 +2371,6 @@ object frmMain: TfrmMain
Category = 'Tools' Category = 'Tools'
Caption = 'Select' Caption = 'Select'
Checked = True Checked = True
DisableIfNoHandler = True
GroupIndex = 1 GroupIndex = 1
Hint = 'Select' Hint = 'Select'
ImageIndex = 4 ImageIndex = 4
@ -2385,7 +2380,6 @@ object frmMain: TfrmMain
object acDraw: TAction object acDraw: TAction
Category = 'Tools' Category = 'Tools'
Caption = 'Draw tiles' Caption = 'Draw tiles'
DisableIfNoHandler = True
GroupIndex = 1 GroupIndex = 1
Hint = 'Draw tiles' Hint = 'Draw tiles'
ImageIndex = 5 ImageIndex = 5
@ -2395,7 +2389,6 @@ object frmMain: TfrmMain
object acMove: TAction object acMove: TAction
Category = 'Tools' Category = 'Tools'
Caption = 'Move tiles' Caption = 'Move tiles'
DisableIfNoHandler = True
GroupIndex = 1 GroupIndex = 1
Hint = 'Move tiles' Hint = 'Move tiles'
ImageIndex = 6 ImageIndex = 6
@ -2405,7 +2398,6 @@ object frmMain: TfrmMain
object acElevate: TAction object acElevate: TAction
Category = 'Tools' Category = 'Tools'
Caption = 'Elevate tiles' Caption = 'Elevate tiles'
DisableIfNoHandler = True
GroupIndex = 1 GroupIndex = 1
Hint = 'Elevate tiles' Hint = 'Elevate tiles'
ImageIndex = 7 ImageIndex = 7
@ -2415,7 +2407,6 @@ object frmMain: TfrmMain
object acDelete: TAction object acDelete: TAction
Category = 'Tools' Category = 'Tools'
Caption = 'Delete tiles' Caption = 'Delete tiles'
DisableIfNoHandler = True
GroupIndex = 1 GroupIndex = 1
Hint = 'Delete tiles' Hint = 'Delete tiles'
ImageIndex = 8 ImageIndex = 8
@ -2425,7 +2416,6 @@ object frmMain: TfrmMain
object acHue: TAction object acHue: TAction
Category = 'Tools' Category = 'Tools'
Caption = 'Hue tiles' Caption = 'Hue tiles'
DisableIfNoHandler = True
GroupIndex = 1 GroupIndex = 1
Hint = 'Hue tiles' Hint = 'Hue tiles'
ImageIndex = 12 ImageIndex = 12
@ -2435,7 +2425,6 @@ object frmMain: TfrmMain
object acBoundaries: TAction object acBoundaries: TAction
Category = 'Settings' Category = 'Settings'
Caption = 'Boundaries' Caption = 'Boundaries'
DisableIfNoHandler = True
Hint = 'Boundaries' Hint = 'Boundaries'
ImageIndex = 9 ImageIndex = 9
OnExecute = acBoundariesExecute OnExecute = acBoundariesExecute
@ -2445,7 +2434,6 @@ object frmMain: TfrmMain
Category = 'Settings' Category = 'Settings'
AutoCheck = True AutoCheck = True
Caption = 'Filter' Caption = 'Filter'
DisableIfNoHandler = True
Hint = 'Filter' Hint = 'Filter'
ImageIndex = 16 ImageIndex = 16
OnExecute = acFilterExecute OnExecute = acFilterExecute
@ -2453,7 +2441,6 @@ object frmMain: TfrmMain
object acVirtualLayer: TAction object acVirtualLayer: TAction
Category = 'Settings' Category = 'Settings'
Caption = 'Virtual Layer' Caption = 'Virtual Layer'
DisableIfNoHandler = True
Hint = 'Virtual Layer' Hint = 'Virtual Layer'
ImageIndex = 15 ImageIndex = 15
OnExecute = acVirtualLayerExecute OnExecute = acVirtualLayerExecute
@ -2462,7 +2449,6 @@ object frmMain: TfrmMain
object acFlat: TAction object acFlat: TAction
Category = 'Settings' Category = 'Settings'
Caption = 'Flat view' Caption = 'Flat view'
DisableIfNoHandler = True
Hint = 'Flat view' Hint = 'Flat view'
ImageIndex = 17 ImageIndex = 17
OnExecute = acFlatExecute OnExecute = acFlatExecute
@ -2471,7 +2457,6 @@ object frmMain: TfrmMain
Category = 'Settings' Category = 'Settings'
Caption = 'NoDraw' Caption = 'NoDraw'
Checked = True Checked = True
DisableIfNoHandler = True
Hint = 'Display "No Draw" tiles' Hint = 'Display "No Draw" tiles'
ImageIndex = 18 ImageIndex = 18
OnExecute = acNoDrawExecute OnExecute = acNoDrawExecute

View File

@ -21,7 +21,7 @@
* CDDL HEADER END * CDDL HEADER END
* *
* *
* Portions Copyright 2008 Andreas Schneider * Portions Copyright 2009 Andreas Schneider
*) *)
unit UfrmMain; unit UfrmMain;
@ -1624,7 +1624,6 @@ end;
procedure TfrmMain.Render; procedure TfrmMain.Render;
var var
drawDistance: Integer; drawDistance: Integer;
offsetX, offsetY: Integer;
lowOffX, lowOffY, highOffX, highOffY: Integer; lowOffX, lowOffY, highOffX, highOffY: Integer;
z: ShortInt; z: ShortInt;
mat: TMaterial; mat: TMaterial;
@ -1645,6 +1644,7 @@ var
staticsFilter: TStaticFilter; staticsFilter: TStaticFilter;
editing: Boolean; editing: Boolean;
intensity: GLfloat; intensity: GLfloat;
item: TWorldItem;
procedure GetMapDrawOffset(x, y: Integer; out drawX, drawY: Single); procedure GetMapDrawOffset(x, y: Integer; out drawX, drawY: Single);
begin begin
@ -1670,223 +1670,209 @@ begin
rangeX := highOffX - lowOffX; rangeX := highOffX - lowOffX;
rangeY := highOffY - lowOffY; rangeY := highOffY - lowOffY;
if acFilter.Checked then {if acFilter.Checked then
staticsFilter := @frmFilter.Filter staticsFilter := @frmFilter.Filter
else else
staticsFilter := nil; staticsFilter := nil;} //TODO : update list on change
for j := 0 to rangeX + rangeY - 2 do draw := FLandscape.GetDrawList(FX + lowOffX, FY + lowOffY, rangeX, rangeY,
frmBoundaries.tbMinZ.Position, frmBoundaries.tbMaxZ.Position,
nil, nil, tbTerrain.Down, tbStatics.Down, //TODO : ghost tile and virtual tile!
acNoDraw.Checked, nil); //TODO : statics filter!
for i := 0 to draw.Count - 1 do
begin begin
if j > rangeY then item := TWorldItem(draw[i]);
GetMapDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
singleTarget := (CurrentTile <> nil) and
(item.X = CurrentTile.X) and
(item.Y = CurrentTile.Y);
multiTarget := (CurrentTile <> nil) and
(SelectedTile <> nil) and
(CurrentTile <> SelectedTile) and
PtInRect(tileRect, Point(item.X, item.Y));
if acSelect.Checked or item.CanBeEdited then
begin begin
startOffX := j - rangeY + 1; editing := True;
endOffX := rangeX; intensity := 1.0;
SetNormalLights;
end else end else
begin begin
startOffX := 0; editing := False;
endOffX := j; intensity := 0.5;
SetDarkLights;
end; end;
for k := startOffX to endOffX do
{if editing and acDraw.Checked and (singleTarget or multiTarget) then
begin begin
offsetY := j - k + lowOffY; ghostTile := FGhostTile;
offsetX := k + lowOffX; if (ghostTile is TMapCell) and (not frmDrawSettings.cbForceAltitude.Checked) then
GetMapDrawOffset(offsetX, offsetY, drawX, drawY); ghostTile.Z := FLandscape.MapCell[item.X, item.Y].Z;
end else
ghostTile := nil;} //TODO : re add Ghost Tile
singleTarget := (CurrentTile <> nil) and {if frmVirtualLayer.cbShowLayer.Checked then
(FX + offsetX = CurrentTile.X) and begin
(FY + offsetY = CurrentTile.Y); virtualTile := FVirtualLayer[k, j - k];
multiTarget := (CurrentTile <> nil) and virtualTile.X := FX + offsetX;
(SelectedTile <> nil) and virtualTile.Y := FY + offsetY;
(CurrentTile <> SelectedTile) and virtualTile.Z := frmVirtualLayer.seZ.Value;
PtInRect(tileRect, Point(FX + offsetX, FY + offsetY)); end else
virtualTile := nil;}
if acSelect.Checked or dmNetwork.CanWrite(FX + offsetX, FY + offsetY) then if not editing then
highlight := False
{else if item = virtualTile then
highlight := False} //todo virtual tile
else if acDelete.Checked and multiTarget and (item is TStaticItem) then
highlight := True
else if ((acElevate.Checked) or (acMove.Checked)) and multiTarget then
highlight := True
else if (acHue.Checked and multiTarget and (item is TMapCell)) then
highlight := True
else
highlight := (not acSelect.Checked) and
(not acHue.Checked) and
(item = CurrentTile) or
((item is TMapCell) and (item = ghostTile));
if highlight then
begin
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_COPY_INVERTED);
end;
if acFlat.Checked then
z := 0
else
z := item.Z;
glColor4f(intensity, intensity, intensity, 1.0);
{if TObject(draw[i]) = virtualTile then
begin
glBindTexture(GL_TEXTURE_2D, FVLayerMaterial.Texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2d(drawX - 22, drawY - z * 4);
glTexCoord2f(1, 0); glVertex2d(drawX - 22 + FVLayerMaterial.Width, drawY - z * 4);
glTexCoord2f(1, 1); glVertex2d(drawX - 22 + FVLayerMaterial.Width, drawY + FVLayerMaterial.Height - z * 4);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + FVLayerMaterial.Height - z * 4);
glEnd;
FScreenBuffer.Store(Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44), virtualTile, FVLayerMaterial);
end else} if item is TMapCell then //TODO : virtual tile!
begin
cell := TMapCell(item);
{if ResMan.Tiledata.LandTiles[cell.TileID].HasFlag(tdfTranslucent) then
glColor4f(intensity, intensity, intensity, 0.5);} //Possible, but probably not like the OSI client
mat := nil;
if not acFlat.Checked then
begin begin
editing := True; west := FLandscape.GetLandAlt(item.X, item.Y + 1, z);
intensity := 1.0; south := FLandscape.GetLandAlt(item.X + 1, item.Y + 1, z);
SetNormalLights; east := FLandscape.GetLandAlt(item.X + 1, item.Y, z);
end else
begin if (west <> z) or (south <> z) or (east <> z) then
editing := False; begin
intensity := 0.5; mat := FTextureManager.GetTexMaterial(cell.TileID);
SetDarkLights; end;
end; end;
if editing and acDraw.Checked and (singleTarget or multiTarget) then if mat = nil then
begin begin
ghostTile := FGhostTile; mat := FTextureManager.GetArtMaterial(cell.TileID);
if (ghostTile is TMapCell) and (not frmDrawSettings.cbForceAltitude.Checked) then if (not (ghostTile is TMapCell)) or
ghostTile.Z := FLandscape.MapCell[FX + offsetX, FY + offsetY].Z; (item = ghostTile) then //when we have a ghosttile, only draw that, but still store the real one
end else
ghostTile := nil;
if frmVirtualLayer.cbShowLayer.Checked then
begin
virtualTile := FVirtualLayer[k, j - k];
virtualTile.X := FX + offsetX;
virtualTile.Y := FY + offsetY;
virtualTile.Z := frmVirtualLayer.seZ.Value;
end else
virtualTile := nil;
draw := FLandscape.GetDrawList(FX + offsetX, FY + offsetY,
frmBoundaries.tbMinZ.Position, frmBoundaries.tbMaxZ.Position,
ghostTile, virtualTile, tbTerrain.Down, tbStatics.Down,
acNoDraw.Checked, staticsFilter);
for i := 0 to draw.Count - 1 do
begin
if not editing then
highlight := False
else if TObject(draw[i]) = virtualTile then
highlight := False
else if acDelete.Checked and multiTarget and (TObject(draw[i]) is TStaticItem) then
highlight := True
else if ((acElevate.Checked) or (acMove.Checked)) and multiTarget then
highlight := True
else if (acHue.Checked and multiTarget and (TObject(draw[i]) is TMapCell)) then
highlight := True
else
highlight := (not acSelect.Checked) and
(not acHue.Checked) and
((TObject(draw[i]) = CurrentTile) or
((TObject(draw[i]) is TMapCell) and (TObject(draw[i]) = ghostTile)));
if highlight then
begin begin
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_COPY_INVERTED);
end;
if acFlat.Checked then
z := 0
else
z := TWorldItem(draw[i]).Z;
glColor4f(intensity, intensity, intensity, 1.0);
if TObject(draw[i]) = virtualTile then
begin
glBindTexture(GL_TEXTURE_2D, FVLayerMaterial.Texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2d(drawX - 22, drawY - z * 4);
glTexCoord2f(1, 0); glVertex2d(drawX - 22 + FVLayerMaterial.Width, drawY - z * 4);
glTexCoord2f(1, 1); glVertex2d(drawX - 22 + FVLayerMaterial.Width, drawY + FVLayerMaterial.Height - z * 4);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + FVLayerMaterial.Height - z * 4);
glEnd;
FScreenBuffer.Store(Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44), virtualTile, FVLayerMaterial);
end else if TObject(draw[i]) is TMapCell then
begin
cell := TMapCell(draw[i]);
{if ResMan.Tiledata.LandTiles[cell.TileID].HasFlag(tdfTranslucent) then
glColor4f(intensity, intensity, intensity, 0.5);} //Possible, but probably not like the OSI client
mat := nil;
if not acFlat.Checked then
begin
west := FLandscape.GetLandAlt(FX + offsetX, FY + offsetY + 1, z);
south := FLandscape.GetLandAlt(FX + offsetX + 1, FY + offsetY + 1, z);
east := FLandscape.GetLandAlt(FX + offsetX + 1, FY + offsetY, z);
if (west <> z) or (south <> z) or (east <> z) then
begin
mat := FTextureManager.GetTexMaterial(cell.TileID);
end;
end;
if mat = nil then
begin
mat := FTextureManager.GetArtMaterial(cell.TileID);
if (not (ghostTile is TMapCell)) or
(TObject(draw[i]) = ghostTile) then //when we have a ghosttile, only draw that, but still store the real one
begin
glBindTexture(GL_TEXTURE_2D, mat.Texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2d(drawX - 22, drawY - z * 4);
glTexCoord2f(1, 0); glVertex2d(drawX - 22 + mat.Width, drawY - z * 4);
glTexCoord2f(1, 1); glVertex2d(drawX - 22 + mat.Width, drawY + mat.Height - z * 4);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + mat.Height - z * 4);
glEnd;
end;
if TObject(draw[i]) <> ghostTile then
FScreenBuffer.Store(Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44), cell, mat);
end else // Texture found
begin
if (not (ghostTile is TMapCell)) or
(TObject(draw[i]) = ghostTile) then //when we have a ghosttile, only draw that, but still store the real one
begin
glBindTexture(GL_TEXTURE_2D, mat.Texture);
//if (not cell.Selected) and (intensity = 1.0) then
if not cell.Selected then
glEnable(GL_LIGHTING);
normals := FLandscape.Normals[offsetX, offsetY];
glBegin(GL_TRIANGLES);
glNormal3f(normals[3].X, normals[3].Y, normals[3].Z);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + 22 - west * 4);
glNormal3f(normals[0].X, normals[0].Y, normals[0].Z);
glTexCoord2f(0, 0); glVertex2d(drawX, drawY - z * 4);
glNormal3f(normals[1].X, normals[1].Y, normals[1].Z);
glTexCoord2f(1, 0); glVertex2d(drawX + 22, drawY + 22 - east * 4);
glNormal3f(normals[1].X, normals[1].Y, normals[1].Z);
glTexCoord2f(1, 0); glVertex2d(drawX + 22, drawY + 22 - east * 4);
glNormal3f(normals[2].X, normals[2].Y, normals[2].Z);
glTexCoord2f(1, 1); glVertex2d(drawX, drawY + 44 - south * 4);
glNormal3f(normals[3].X, normals[3].Y, normals[3].Z);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + 22 - west * 4);
glEnd;
//if (not cell.Selected) and (intensity = 1.0) then
if not cell.Selected then
glDisable(GL_LIGHTING);
end;
if TObject(draw[i]) <> ghostTile then
FScreenBuffer.Store(Rect(Trunc(drawX - 22), Trunc(drawY - z * 4), Trunc(drawX + 22), Trunc(drawY + 44 - south * 4)), cell, mat);
end;
end else if TObject(draw[i]) is TStaticItem then
begin
staticItem := TStaticItem(draw[i]);
staticTileData := ResMan.Tiledata.StaticTiles[staticItem.TileID];
if tbSetHue.Down and ((singleTarget and (TObject(draw[i]) = CurrentTile)) or multiTarget) then
begin
if frmHueSettings.lbHue.ItemIndex > 0 then
hue := ResMan.Hue.Hues[frmHueSettings.lbHue.ItemIndex - 1]
else
hue := nil;
end else if staticItem.Hue > 0 then
hue := ResMan.Hue.Hues[staticItem.Hue - 1]
else
hue := nil;
if staticTileData.HasFlag(tdfTranslucent) then
glColor4f(intensity, intensity, intensity, 0.5);
mat := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue);
south := mat.RealHeight;
east := mat.RealWidth div 2;
glBindTexture(GL_TEXTURE_2D, mat.Texture); glBindTexture(GL_TEXTURE_2D, mat.Texture);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2d(drawX - east, drawY + 44 - south - z * 4); glTexCoord2f(0, 0); glVertex2d(drawX - 22, drawY - z * 4);
glTexCoord2f(1, 0); glVertex2d(drawX - east + mat.Width, drawY + 44 - south - z * 4); glTexCoord2f(1, 0); glVertex2d(drawX - 22 + mat.Width, drawY - z * 4);
glTexCoord2f(1, 1); glVertex2d(drawX - east + mat.Width, drawY + 44 - south + mat.Height - z * 4); glTexCoord2f(1, 1); glVertex2d(drawX - 22 + mat.Width, drawY + mat.Height - z * 4);
glTexCoord2f(0, 1); glVertex2d(drawX - east, drawY + 44 - south + mat.Height - z * 4); glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + mat.Height - z * 4);
glEnd; glEnd;
if TObject(draw[i]) <> ghostTile then
FScreenBuffer.Store(Bounds(Trunc(drawX - east), Trunc(drawY + 44 - south - z * 4), mat.RealWidth, Trunc(south)), staticItem, mat);
end; end;
if highlight then if item <> ghostTile then
glDisable(GL_COLOR_LOGIC_OP); FScreenBuffer.Store(Bounds(Trunc(drawX - 22), Trunc(drawY - z * 4), 44, 44), cell, mat);
end else // Texture found
begin
if (not (ghostTile is TMapCell)) or
(item = ghostTile) then //when we have a ghosttile, only draw that, but still store the real one
begin
glBindTexture(GL_TEXTURE_2D, mat.Texture);
//if (not cell.Selected) and (intensity = 1.0) then
if not cell.Selected then
glEnable(GL_LIGHTING);
normals := FLandscape.Normals[item.X, item.Y];
glBegin(GL_TRIANGLES);
glNormal3f(normals[3].X, normals[3].Y, normals[3].Z);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + 22 - west * 4);
glNormal3f(normals[0].X, normals[0].Y, normals[0].Z);
glTexCoord2f(0, 0); glVertex2d(drawX, drawY - z * 4);
glNormal3f(normals[1].X, normals[1].Y, normals[1].Z);
glTexCoord2f(1, 0); glVertex2d(drawX + 22, drawY + 22 - east * 4);
glNormal3f(normals[1].X, normals[1].Y, normals[1].Z);
glTexCoord2f(1, 0); glVertex2d(drawX + 22, drawY + 22 - east * 4);
glNormal3f(normals[2].X, normals[2].Y, normals[2].Z);
glTexCoord2f(1, 1); glVertex2d(drawX, drawY + 44 - south * 4);
glNormal3f(normals[3].X, normals[3].Y, normals[3].Z);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + 22 - west * 4);
glEnd;
//if (not cell.Selected) and (intensity = 1.0) then
if not cell.Selected then
glDisable(GL_LIGHTING);
end;
if item <> ghostTile then
FScreenBuffer.Store(Rect(Trunc(drawX - 22), Trunc(drawY - z * 4), Trunc(drawX + 22), Trunc(drawY + 44 - south * 4)), cell, mat);
end; end;
draw.Free; end else if item is TStaticItem then
begin
staticItem := TStaticItem(item);
staticTileData := ResMan.Tiledata.StaticTiles[staticItem.TileID];
if tbSetHue.Down and ((singleTarget and (item = CurrentTile)) or multiTarget) then
begin
if frmHueSettings.lbHue.ItemIndex > 0 then
hue := ResMan.Hue.Hues[frmHueSettings.lbHue.ItemIndex - 1]
else
hue := nil;
end else if staticItem.Hue > 0 then
hue := ResMan.Hue.Hues[staticItem.Hue - 1]
else
hue := nil;
if staticTileData.HasFlag(tdfTranslucent) then
glColor4f(intensity, intensity, intensity, 0.5);
mat := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue);
south := mat.RealHeight;
east := mat.RealWidth div 2;
glBindTexture(GL_TEXTURE_2D, mat.Texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2d(drawX - east, drawY + 44 - south - z * 4);
glTexCoord2f(1, 0); glVertex2d(drawX - east + mat.Width, drawY + 44 - south - z * 4);
glTexCoord2f(1, 1); glVertex2d(drawX - east + mat.Width, drawY + 44 - south + mat.Height - z * 4);
glTexCoord2f(0, 1); glVertex2d(drawX - east, drawY + 44 - south + mat.Height - z * 4);
glEnd;
if TObject(draw[i]) <> ghostTile then
FScreenBuffer.Store(Bounds(Trunc(drawX - east), Trunc(drawY + 44 - south - z * 4), mat.RealWidth, Trunc(south)), staticItem, mat);
end; end;
if highlight then
glDisable(GL_COLOR_LOGIC_OP);
end; end;
draw.Free;
FOverlayUI.Draw(oglGameWindow); FOverlayUI.Draw(oglGameWindow);
end; end;

View File

@ -48,7 +48,7 @@ object frmRegionControl: TfrmRegionControl
TabOrder = 0 TabOrder = 0
object lblX: TLabel object lblX: TLabel
Left = 4 Left = 4
Height = 13 Height = 14
Top = 32 Top = 32
Width = 8 Width = 8
Caption = 'X' Caption = 'X'
@ -57,7 +57,7 @@ object frmRegionControl: TfrmRegionControl
end end
object lblY: TLabel object lblY: TLabel
Left = 4 Left = 4
Height = 13 Height = 14
Top = 60 Top = 60
Width = 8 Width = 8
Caption = 'Y' Caption = 'Y'
@ -213,7 +213,7 @@ object frmRegionControl: TfrmRegionControl
end end
object seX1: TSpinEdit object seX1: TSpinEdit
Left = 20 Left = 20
Height = 23 Height = 19
Top = 29 Top = 29
Width = 50 Width = 50
Enabled = False Enabled = False
@ -222,7 +222,7 @@ object frmRegionControl: TfrmRegionControl
end end
object seX2: TSpinEdit object seX2: TSpinEdit
Left = 84 Left = 84
Height = 23 Height = 19
Top = 29 Top = 29
Width = 50 Width = 50
Enabled = False Enabled = False
@ -231,7 +231,7 @@ object frmRegionControl: TfrmRegionControl
end end
object seY1: TSpinEdit object seY1: TSpinEdit
Left = 20 Left = 20
Height = 23 Height = 19
Top = 56 Top = 56
Width = 50 Width = 50
Enabled = False Enabled = False
@ -240,7 +240,7 @@ object frmRegionControl: TfrmRegionControl
end end
object seY2: TSpinEdit object seY2: TSpinEdit
Left = 84 Left = 84
Height = 23 Height = 19
Top = 56 Top = 56
Width = 50 Width = 50
Enabled = False Enabled = False
@ -261,6 +261,7 @@ object frmRegionControl: TfrmRegionControl
DefaultText = 'Node' DefaultText = 'Node'
Header.AutoSizeIndex = 0 Header.AutoSizeIndex = 0
Header.Columns = <> Header.Columns = <>
Header.DefaultHeight = 17
Header.MainColumn = -1 Header.MainColumn = -1
Header.Options = [hoColumnResize, hoDrag] Header.Options = [hoColumnResize, hoDrag]
TabOrder = 1 TabOrder = 1
@ -304,6 +305,7 @@ object frmRegionControl: TfrmRegionControl
Text = 'Regions' Text = 'Regions'
Width = 158 Width = 158
end> end>
Header.DefaultHeight = 17
Header.Options = [hoAutoResize, hoVisible] Header.Options = [hoAutoResize, hoVisible]
Header.ParentFont = True Header.ParentFont = True
Header.Style = hsFlatButtons Header.Style = hsFlatButtons
@ -442,8 +444,8 @@ object frmRegionControl: TfrmRegionControl
Top = 1 Top = 1
Width = 458 Width = 458
Align = alClient Align = alClient
ClientHeight = 378 ClientHeight = 374
ClientWidth = 458 ClientWidth = 454
TabOrder = 0 TabOrder = 0
object pbArea: TPaintBox object pbArea: TPaintBox
Left = 0 Left = 0

View File

@ -1,282 +1,284 @@
(* (*
* 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 2007 Andreas Schneider
*) *)
unit UWorldItem; unit UWorldItem;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
interface interface
uses uses
Classes, UMulBlock; Classes, UMulBlock;
type type
TWorldBlock = class; TWorldBlock = class;
TWorldItem = class(TMulBlock) TWorldItem = class(TMulBlock)
constructor Create(AOwner: TWorldBlock); constructor Create(AOwner: TWorldBlock);
protected protected
FOwner, FOrgOwner: TWorldBlock; FOwner, FOrgOwner: TWorldBlock;
FTileID, FOrgTileID: Word; FTileID, FOrgTileID: Word;
FX, FOrgX: Word; FX, FOrgX: Word;
FY, FOrgY: Word; FY, FOrgY: Word;
FZ, FOrgZ: ShortInt; FZ, FOrgZ: ShortInt;
FSelected: Boolean; FSelected: Boolean;
FLocked: Boolean; FCanBeEdited: Boolean;
FChanged: Boolean; FLocked: Boolean;
FPriority: Integer; FChanged: Boolean;
FPriorityBonus: ShortInt; FPriority: Integer;
FPrioritySolver: Integer; FPriorityBonus: ShortInt;
procedure SetTileID(ATileID: Word); FPrioritySolver: Integer;
procedure SetX(AX: Word); procedure SetTileID(ATileID: Word);
procedure SetY(AY: Word); procedure SetX(AX: Word);
procedure SetZ(AZ: ShortInt); procedure SetY(AY: Word);
procedure SetSelected(ASelected: Boolean); procedure SetZ(AZ: ShortInt);
procedure SetOwner(AOwner: TWorldBlock); procedure SetSelected(ASelected: Boolean);
procedure SetLocked(ALocked: Boolean); procedure SetOwner(AOwner: TWorldBlock);
procedure DoChanged; procedure SetLocked(ALocked: Boolean);
function HasChanged: Boolean; virtual; procedure DoChanged;
public function HasChanged: Boolean; virtual;
procedure UpdatePos(AX, AY: Word; AZ: ShortInt); public
procedure Delete; procedure UpdatePos(AX, AY: Word; AZ: ShortInt);
procedure InitOriginalState; virtual; procedure Delete;
property Owner: TWorldBlock read FOwner write SetOwner; procedure InitOriginalState; virtual;
property TileID: Word read FTileID write SetTileID; property Owner: TWorldBlock read FOwner write SetOwner;
property X: Word read FX write SetX; property TileID: Word read FTileID write SetTileID;
property Y: Word read FY write SetY; property X: Word read FX write SetX;
property Z: ShortInt read FZ write SetZ; property Y: Word read FY write SetY;
property Selected: Boolean read FSelected write SetSelected; property Z: ShortInt read FZ write SetZ;
property Locked: Boolean read FLocked write SetLocked; property Selected: Boolean read FSelected write SetSelected;
property Changed: Boolean read FChanged; property CanBeEdited: Boolean read FCanBeEdited write FCanBeEdited;
property Priority: Integer read FPriority write FPriority; property Locked: Boolean read FLocked write SetLocked;
property PriorityBonus: ShortInt read FPriorityBonus write FPriorityBonus; property Changed: Boolean read FChanged;
property PrioritySolver: Integer read FPrioritySolver write FPrioritySolver; property Priority: Integer read FPriority write FPriority;
end; property PriorityBonus: ShortInt read FPriorityBonus write FPriorityBonus;
TWorldBlock = class(TMulBlock) property PrioritySolver: Integer read FPrioritySolver write FPrioritySolver;
constructor Create; end;
protected TWorldBlock = class(TMulBlock)
FX: Word; constructor Create;
FY: Word; protected
FRefCount: Integer; FX: Word;
FChanges: Integer; FY: Word;
function GetChanged: Boolean; FRefCount: Integer;
procedure SetChanged(AChanged: Boolean); FChanges: Integer;
procedure DoStateChanged; function GetChanged: Boolean;
public procedure SetChanged(AChanged: Boolean);
property X: Word read FX write FX; procedure DoStateChanged;
property Y: Word read FY write FY; public
property RefCount: Integer read FRefCount; property X: Word read FX write FX;
property Changed: Boolean read GetChanged write SetChanged; property Y: Word read FY write FY;
procedure AddRef; property RefCount: Integer read FRefCount;
procedure RemoveRef; property Changed: Boolean read GetChanged write SetChanged;
procedure CleanUp; procedure AddRef;
end; procedure RemoveRef;
procedure CleanUp;
implementation end;
{ TWorldItem } implementation
constructor TWorldItem.Create(AOwner: TWorldBlock); { TWorldItem }
begin
inherited Create; constructor TWorldItem.Create(AOwner: TWorldBlock);
FSelected := False; begin
FLocked := False; inherited Create;
FChanged := False; FSelected := False;
FOwner := AOwner; FLocked := False;
end; FChanged := False;
FOwner := AOwner;
procedure TWorldItem.Delete; end;
begin
SetSelected(False); procedure TWorldItem.Delete;
SetLocked(False); begin
if (FOwner <> FOrgOwner) then SetSelected(False);
FOwner.Changed := False SetLocked(False);
else if Assigned(FOrgOwner) and (not FChanged) then if (FOwner <> FOrgOwner) then
FOrgOwner.Changed := True; FOwner.Changed := False
Free; else if Assigned(FOrgOwner) and (not FChanged) then
end; FOrgOwner.Changed := True;
Free;
procedure TWorldItem.DoChanged; end;
var
blockChanged: Boolean; procedure TWorldItem.DoChanged;
begin var
blockChanged := HasChanged; blockChanged: Boolean;
if Assigned(FOwner) then begin
begin blockChanged := HasChanged;
if FChanged and (not blockChanged) then if Assigned(FOwner) then
FOwner.Changed := False begin
else if (not FChanged) and blockChanged then if FChanged and (not blockChanged) then
FOwner.Changed := True; FOwner.Changed := False
end; else if (not FChanged) and blockChanged then
FChanged := blockChanged; FOwner.Changed := True;
if Assigned(FOnChanged) then end;
FOnChanged(Self); FChanged := blockChanged;
end; if Assigned(FOnChanged) then
FOnChanged(Self);
function TWorldItem.HasChanged: Boolean; end;
begin
Result := (FX <> FOrgX) or (FY <> FOrgY) or (FZ <> FOrgZ) or function TWorldItem.HasChanged: Boolean;
(FTileID <> FOrgTileID) or (FOrgOwner <> FOwner); begin
end; Result := (FX <> FOrgX) or (FY <> FOrgY) or (FZ <> FOrgZ) or
(FTileID <> FOrgTileID) or (FOrgOwner <> FOwner);
procedure TWorldItem.InitOriginalState; end;
begin
{if Assigned(FOrgOwner) and (FOwner <> FOrgOwner) then procedure TWorldItem.InitOriginalState;
FOrgOwner.Changed := False;} begin
FOrgOwner := FOwner; {if Assigned(FOrgOwner) and (FOwner <> FOrgOwner) then
FOrgTileID := FTileID; FOrgOwner.Changed := False;}
FOrgX := FX; FOrgOwner := FOwner;
FOrgY := FY; FOrgTileID := FTileID;
FOrgZ := FZ; FOrgX := FX;
DoChanged; FOrgY := FY;
end; FOrgZ := FZ;
DoChanged;
procedure TWorldItem.SetLocked(ALocked: Boolean); end;
begin
if FLocked <> ALocked then procedure TWorldItem.SetLocked(ALocked: Boolean);
begin begin
FLocked := ALocked; if FLocked <> ALocked then
if Assigned(FOwner) then begin
if FLocked then FLocked := ALocked;
FOwner.AddRef if Assigned(FOwner) then
else if FLocked then
FOwner.RemoveRef; FOwner.AddRef
end; else
end; FOwner.RemoveRef;
end;
procedure TWorldItem.SetOwner(AOwner: TWorldBlock); end;
begin
if FOwner <> AOwner then procedure TWorldItem.SetOwner(AOwner: TWorldBlock);
begin begin
if Assigned(FOwner) then if FOwner <> AOwner then
begin begin
if FOwner <> FOrgOwner then if Assigned(FOwner) then
FOwner.Changed := False; begin
if FLocked then FOwner.RemoveRef; if FOwner <> FOrgOwner then
if FSelected then FOwner.RemoveRef; FOwner.Changed := False;
end; if FLocked then FOwner.RemoveRef;
FOwner := AOwner; if FSelected then FOwner.RemoveRef;
if Assigned(FOwner) then end;
begin FOwner := AOwner;
if FOwner <> FOrgOwner then if Assigned(FOwner) then
FOwner.Changed := True; begin
if FLocked then FOwner.AddRef; if FOwner <> FOrgOwner then
if FSelected then FOwner.AddRef; FOwner.Changed := True;
end; if FLocked then FOwner.AddRef;
DoChanged; if FSelected then FOwner.AddRef;
end; end;
end; DoChanged;
end;
procedure TWorldItem.SetSelected(ASelected: Boolean); end;
begin
if (FOwner <> nil) and (ASelected <> FSelected) then procedure TWorldItem.SetSelected(ASelected: Boolean);
if ASelected then begin
FOwner.AddRef if (FOwner <> nil) and (ASelected <> FSelected) then
else if ASelected then
FOwner.RemoveRef; FOwner.AddRef
FSelected := ASelected; else
end; FOwner.RemoveRef;
FSelected := ASelected;
procedure TWorldItem.SetTileID(ATileID: Word); end;
begin
FTileID := ATileID; procedure TWorldItem.SetTileID(ATileID: Word);
DoChanged; begin
end; FTileID := ATileID;
DoChanged;
procedure TWorldItem.SetX(AX: Word); end;
begin
FX := AX; procedure TWorldItem.SetX(AX: Word);
DoChanged; begin
end; FX := AX;
DoChanged;
procedure TWorldItem.SetY(AY: Word); end;
begin
FY := AY; procedure TWorldItem.SetY(AY: Word);
DoChanged begin
end; FY := AY;
DoChanged
procedure TWorldItem.SetZ(AZ: ShortInt); end;
begin
FZ := AZ; procedure TWorldItem.SetZ(AZ: ShortInt);
DoChanged; begin
end; FZ := AZ;
DoChanged;
procedure TWorldItem.UpdatePos(AX, AY: Word; AZ: ShortInt); end;
begin
FX := AX; procedure TWorldItem.UpdatePos(AX, AY: Word; AZ: ShortInt);
FY := AY; begin
FZ := AZ; FX := AX;
DoChanged; FY := AY;
end; FZ := AZ;
DoChanged;
{ TWorldBlock } end;
procedure TWorldBlock.AddRef; { TWorldBlock }
begin
Inc(FRefCount); procedure TWorldBlock.AddRef;
DoStateChanged; begin
end; Inc(FRefCount);
DoStateChanged;
procedure TWorldBlock.CleanUp; end;
begin
FChanges := 0; procedure TWorldBlock.CleanUp;
DoStateChanged; begin
end; FChanges := 0;
DoStateChanged;
constructor TWorldBlock.Create; end;
begin
inherited Create; constructor TWorldBlock.Create;
FRefCount := 0; begin
FChanges := 0; inherited Create;
end; FRefCount := 0;
FChanges := 0;
procedure TWorldBlock.DoStateChanged; end;
begin
if Assigned(FOnChanged) then procedure TWorldBlock.DoStateChanged;
FOnChanged(Self); begin
end; if Assigned(FOnChanged) then
FOnChanged(Self);
function TWorldBlock.GetChanged: Boolean; end;
begin
Result := (FChanges <> 0); function TWorldBlock.GetChanged: Boolean;
end; begin
Result := (FChanges <> 0);
procedure TWorldBlock.RemoveRef; end;
begin
if FRefCount > 0 then procedure TWorldBlock.RemoveRef;
Dec(FRefCount); begin
DoStateChanged; if FRefCount > 0 then
end; Dec(FRefCount);
DoStateChanged;
procedure TWorldBlock.SetChanged(AChanged: Boolean); end;
begin
if AChanged then procedure TWorldBlock.SetChanged(AChanged: Boolean);
Inc(FChanges) begin
else if AChanged then
Dec(FChanges); Inc(FChanges)
DoStateChanged; else
end; Dec(FChanges);
DoStateChanged;
end. end;
end.