root / Server / ULargeScaleOperations.pas @ 13:c78b5eafa10e
History | View | Annotate | Download (9.9 kB)
| 1 | (*
|
|---|---|
| 2 | * CDDL HEADER START |
| 3 | * |
| 4 | * The contents of this file are subject to the terms of the |
| 5 | * Common Development and Distribution License, Version 1.0 only |
| 6 | * (the "License"). You may not use this file except in compliance |
| 7 | * with the License. |
| 8 | * |
| 9 | * You can obtain a copy of the license at |
| 10 | * http://www.opensource.org/licenses/cddl1.php. |
| 11 | * See the License for the specific language governing permissions |
| 12 | * and limitations under the License. |
| 13 | * |
| 14 | * When distributing Covered Code, include this CDDL HEADER in each |
| 15 | * file and include the License file at |
| 16 | * http://www.opensource.org/licenses/cddl1.php. If applicable, |
| 17 | * add the following below this CDDL HEADER, with the fields enclosed |
| 18 | * by brackets "[]" replaced with your own identifying * information: |
| 19 | * Portions Copyright [yyyy] [name of copyright owner] |
| 20 | * |
| 21 | * CDDL HEADER END |
| 22 | * |
| 23 | * |
| 24 | * Portions Copyright 2007 Andreas Schneider |
| 25 | *) |
| 26 | unit ULargeScaleOperations;
|
| 27 | |
| 28 | {$mode objfpc}{$H+} |
| 29 | |
| 30 | interface
|
| 31 | |
| 32 | uses
|
| 33 | Classes, SysUtils, UMap, UStatics, UEnhancedMemoryStream, math, |
| 34 | ULandscape; |
| 35 | |
| 36 | type
|
| 37 | |
| 38 | TCopyMoveType = (cmCopy = 0, cmMove = 1); |
| 39 | TSetAltitudeType = (saTerrain = 1, saRelative = 2); |
| 40 | TStaticsPlacement = (spTerrain = 1, spTop = 2, spFix = 3); |
| 41 | |
| 42 | { TLargeScaleOperation }
|
| 43 | |
| 44 | TLargeScaleOperation = class(TObject)
|
| 45 | constructor Init(AData: TEnhancedMemoryStream; ALandscape: TLandscape); virtual; |
| 46 | protected
|
| 47 | FLandscape: TLandscape; |
| 48 | public
|
| 49 | procedure Apply(AMapCell: TMapCell; AStatics: TList;
|
| 50 | AAdditionalAffectedBlocks: TBits); virtual; abstract; |
| 51 | end;
|
| 52 | |
| 53 | { TLSCopyMove }
|
| 54 | |
| 55 | TLSCopyMove = class(TLargeScaleOperation)
|
| 56 | constructor Init(AData: TEnhancedMemoryStream; ALandscape: TLandscape); override; |
| 57 | protected
|
| 58 | FType: TCopyMoveType; |
| 59 | FOffsetX: Integer; |
| 60 | FOffsetY: Integer; |
| 61 | FErase: Boolean; |
| 62 | public
|
| 63 | property OffsetX: Integer read FOffsetX; |
| 64 | property OffsetY: Integer read FOffsetY; |
| 65 | procedure Apply(AMapCell: TMapCell; AStatics: TList;
|
| 66 | AAdditionalAffectedBlocks: TBits); override;
|
| 67 | end;
|
| 68 | |
| 69 | { TLSSetAltitude }
|
| 70 | |
| 71 | TLSSetAltitude = class(TLargeScaleOperation)
|
| 72 | constructor Init(AData: TEnhancedMemoryStream; ALandscape: TLandscape); override; |
| 73 | protected
|
| 74 | FType: TSetAltitudeType; |
| 75 | FMinZ: ShortInt; |
| 76 | FMaxZ: ShortInt; |
| 77 | FRelativeZ: ShortInt; |
| 78 | public
|
| 79 | procedure Apply(AMapCell: TMapCell; AStatics: TList;
|
| 80 | AAdditionalAffectedBlocks: TBits); override;
|
| 81 | end;
|
| 82 | |
| 83 | { TLSDrawTerrain }
|
| 84 | |
| 85 | TLSDrawTerrain = class(TLargeScaleOperation)
|
| 86 | constructor Init(AData: TEnhancedMemoryStream; ALandscape: TLandscape); override; |
| 87 | protected
|
| 88 | FTileIDs: array of Word; |
| 89 | public
|
| 90 | procedure Apply(AMapCell: TMapCell; AStatics: TList;
|
| 91 | AAdditionalAffectedBlocks: TBits); override;
|
| 92 | end;
|
| 93 | |
| 94 | { TLSDeleteStatics }
|
| 95 | |
| 96 | TLSDeleteStatics = class(TLargeScaleOperation)
|
| 97 | constructor Init(AData: TEnhancedMemoryStream; ALandscape: TLandscape); override; |
| 98 | protected
|
| 99 | FTileIDs: array of Word; |
| 100 | FMinZ: ShortInt; |
| 101 | FMaxZ: ShortInt; |
| 102 | public
|
| 103 | procedure Apply(AMapCell: TMapCell; AStatics: TList;
|
| 104 | AAdditionalAffectedBlocks: TBits); override;
|
| 105 | end;
|
| 106 | |
| 107 | { TLSInsertStatics }
|
| 108 | |
| 109 | TLSInsertStatics = class(TLargeScaleOperation)
|
| 110 | constructor Init(AData: TEnhancedMemoryStream; ALandscape: TLandscape); override; |
| 111 | protected
|
| 112 | FTileIDs: array of Word; |
| 113 | FProbability: Byte; |
| 114 | FPlacementType: TStaticsPlacement; |
| 115 | FFixZ: ShortInt; |
| 116 | public
|
| 117 | procedure Apply(AMapCell: TMapCell; AStatics: TList;
|
| 118 | AAdditionalAffectedBlocks: TBits); override;
|
| 119 | end;
|
| 120 | |
| 121 | |
| 122 | implementation
|
| 123 | |
| 124 | uses
|
| 125 | UCEDServer; |
| 126 | |
| 127 | { TLargeScaleOperation }
|
| 128 | |
| 129 | constructor TLargeScaleOperation.Init(AData: TEnhancedMemoryStream;
|
| 130 | ALandscape: TLandscape); |
| 131 | begin
|
| 132 | inherited Create;
|
| 133 | FLandscape := ALandscape; |
| 134 | end;
|
| 135 | |
| 136 | { TLSCopyMove }
|
| 137 | |
| 138 | constructor TLSCopyMove.Init(AData: TEnhancedMemoryStream;
|
| 139 | ALandscape: TLandscape); |
| 140 | begin
|
| 141 | inherited Init(AData, ALandscape);
|
| 142 | FType := TCopyMoveType(AData.ReadByte); |
| 143 | FOffsetX := AData.ReadInteger; |
| 144 | FOffsetY := AData.ReadInteger; |
| 145 | FErase := AData.ReadBoolean; |
| 146 | end;
|
| 147 | |
| 148 | procedure TLSCopyMove.Apply(AMapCell: TMapCell; AStatics: TList;
|
| 149 | AAdditionalAffectedBlocks: TBits); |
| 150 | var
|
| 151 | x, y: Word; |
| 152 | targetCell: TMapCell; |
| 153 | targetStatics: TList; |
| 154 | targetStaticsBlock: TSeperatedStaticBlock; |
| 155 | i: Integer; |
| 156 | staticItem: TStaticItem; |
| 157 | begin
|
| 158 | x := EnsureRange(AMapCell.X + FOffsetX, 0, FLandscape.CellWidth - 1); |
| 159 | y := EnsureRange(AMapCell.Y + FOffsetY, 0, FLandscape.CellHeight - 1); |
| 160 | //writeln('target: ', x, ',', y);
|
| 161 | targetCell := FLandscape.MapCell[x, y]; |
| 162 | targetStaticsBlock := FLandscape.GetStaticBlock(x div 8, y div 8); |
| 163 | targetStatics := targetStaticsBlock.Cells[(y mod 8) * 8 + (x mod 8)]; |
| 164 | if FErase then |
| 165 | begin
|
| 166 | for i := 0 to targetStatics.Count - 1 do |
| 167 | begin
|
| 168 | TStaticItem(targetStatics.Items[i]).Delete; |
| 169 | end;
|
| 170 | targetStatics.Clear; |
| 171 | end;
|
| 172 | targetCell.TileID := AMapCell.TileID; |
| 173 | targetCell.Z := AMapCell.Z; |
| 174 | |
| 175 | if FType = cmCopy then |
| 176 | begin
|
| 177 | for i := 0 to AStatics.Count - 1 do |
| 178 | begin
|
| 179 | staticItem := TStaticItem.Create(nil, nil, 0, 0); |
| 180 | staticItem.X := x; |
| 181 | staticItem.Y := y; |
| 182 | staticItem.Z := TStaticItem(AStatics.Items[i]).Z; |
| 183 | staticItem.TileID := TStaticItem(AStatics.Items[i]).TileID; |
| 184 | staticItem.Hue := TStaticItem(AStatics.Items[i]).Hue; |
| 185 | staticItem.Owner := targetStaticsBlock; |
| 186 | targetStatics.Add(staticItem); |
| 187 | end;
|
| 188 | end else |
| 189 | begin
|
| 190 | {for i := 0 to AStatics.Count - 1 do}
|
| 191 | while AStatics.Count > 0 do |
| 192 | begin
|
| 193 | targetStatics.Add(AStatics.Items[0]);
|
| 194 | TStaticItem(AStatics.Items[0]).UpdatePos(x, y, TStaticItem(AStatics.Items[0]).Z); |
| 195 | TStaticItem(AStatics.Items[0]).Owner := targetStaticsBlock;
|
| 196 | AStatics.Delete(0);
|
| 197 | end;
|
| 198 | //AStatics.Clear;
|
| 199 | end;
|
| 200 | |
| 201 | FLandscape.SortStaticsList(targetStatics); |
| 202 | AAdditionalAffectedBlocks.Bits[(x div 8) * FLandscape.Height + (y div 8)] := True; |
| 203 | end;
|
| 204 | |
| 205 | { TLSSetAltitude }
|
| 206 | |
| 207 | constructor TLSSetAltitude.Init(AData: TEnhancedMemoryStream;
|
| 208 | ALandscape: TLandscape); |
| 209 | begin
|
| 210 | inherited Init(AData, ALandscape);
|
| 211 | FType := TSetAltitudeType(AData.ReadByte); |
| 212 | case FType of |
| 213 | saTerrain: |
| 214 | begin
|
| 215 | FMinZ := AData.ReadShortInt; |
| 216 | FMaxZ := AData.ReadShortInt; |
| 217 | end;
|
| 218 | saRelative: |
| 219 | begin
|
| 220 | FRelativeZ := AData.ReadShortInt; |
| 221 | end;
|
| 222 | end;
|
| 223 | end;
|
| 224 | |
| 225 | procedure TLSSetAltitude.Apply(AMapCell: TMapCell; AStatics: TList;
|
| 226 | AAdditionalAffectedBlocks: TBits); |
| 227 | var
|
| 228 | i: Integer; |
| 229 | newZ: ShortInt; |
| 230 | diff: ShortInt; |
| 231 | static: TStaticItem; |
| 232 | begin
|
| 233 | if FType = saTerrain then |
| 234 | begin
|
| 235 | newZ := FMinZ + Random(FMaxZ - FMinZ + 1);
|
| 236 | diff := newZ - AMapCell.Z; |
| 237 | AMapCell.Z := newZ; |
| 238 | end else |
| 239 | begin
|
| 240 | diff := FRelativeZ; |
| 241 | AMapCell.Z := EnsureRange(AMapCell.Z + diff, -128, 127); |
| 242 | end;
|
| 243 | |
| 244 | for i := 0 to AStatics.Count - 1 do |
| 245 | begin
|
| 246 | static := TStaticItem(AStatics.Items[i]); |
| 247 | static.Z := EnsureRange(static.Z + diff, -128, 127); |
| 248 | end;
|
| 249 | end;
|
| 250 | |
| 251 | { TLSDrawTerrain }
|
| 252 | |
| 253 | constructor TLSDrawTerrain.Init(AData: TEnhancedMemoryStream;
|
| 254 | ALandscape: TLandscape); |
| 255 | var
|
| 256 | count: Word; |
| 257 | begin
|
| 258 | inherited Init(AData, ALandscape);
|
| 259 | count := AData.ReadWord; |
| 260 | SetLength(FTileIDs, count); |
| 261 | AData.Read(FTileIDs[0], count * SizeOf(Word));
|
| 262 | end;
|
| 263 | |
| 264 | procedure TLSDrawTerrain.Apply(AMapCell: TMapCell; AStatics: TList;
|
| 265 | AAdditionalAffectedBlocks: TBits); |
| 266 | begin
|
| 267 | if Length(FTileIDs) > 0 then |
| 268 | AMapCell.TileID := FTileIDs[Random(Length(FTileIDs))]; |
| 269 | end;
|
| 270 | |
| 271 | { TLSDeleteStatics }
|
| 272 | |
| 273 | constructor TLSDeleteStatics.Init(AData: TEnhancedMemoryStream;
|
| 274 | ALandscape: TLandscape); |
| 275 | var
|
| 276 | count: Word; |
| 277 | begin
|
| 278 | inherited Init(AData, ALandscape);
|
| 279 | count := AData.ReadWord; |
| 280 | SetLength(FTileIDs, count); |
| 281 | AData.Read(FTileIDs[0], count * SizeOf(Word));
|
| 282 | FMinZ := AData.ReadShortInt; |
| 283 | FMaxZ := AData.ReadShortInt; |
| 284 | end;
|
| 285 | |
| 286 | procedure TLSDeleteStatics.Apply(AMapCell: TMapCell; AStatics: TList;
|
| 287 | AAdditionalAffectedBlocks: TBits); |
| 288 | var
|
| 289 | i, j: Integer; |
| 290 | static: TStaticItem; |
| 291 | begin
|
| 292 | i := 0;
|
| 293 | while i < AStatics.Count do |
| 294 | begin
|
| 295 | static := TStaticItem(AStatics.Items[i]); |
| 296 | if InRange(static.Z, FMinZ, FMaxZ) then |
| 297 | begin
|
| 298 | if Length(FTileIDs) > 0 then |
| 299 | begin
|
| 300 | for j := Low(FTileIDs) to High(FTileIDs) do |
| 301 | begin
|
| 302 | if static.TileID = FTileIDs[j] - $4000 then |
| 303 | begin
|
| 304 | AStatics.Delete(i); |
| 305 | static.Delete; |
| 306 | Dec(i); |
| 307 | Break; |
| 308 | end;
|
| 309 | end;
|
| 310 | Inc(i); |
| 311 | end else |
| 312 | begin
|
| 313 | AStatics.Delete(i); |
| 314 | static.Delete; |
| 315 | end;
|
| 316 | end else |
| 317 | Inc(i); |
| 318 | end;
|
| 319 | end;
|
| 320 | |
| 321 | { TLSInsertStatics }
|
| 322 | |
| 323 | constructor TLSInsertStatics.Init(AData: TEnhancedMemoryStream;
|
| 324 | ALandscape: TLandscape); |
| 325 | var
|
| 326 | count: Word; |
| 327 | begin
|
| 328 | inherited Init(AData, ALandscape);
|
| 329 | count := AData.ReadWord; |
| 330 | SetLength(FTileIDs, count); |
| 331 | AData.Read(FTileIDs[0], count * SizeOf(Word));
|
| 332 | FProbability := AData.ReadByte; |
| 333 | FPlacementType := TStaticsPlacement(AData.ReadByte); |
| 334 | if FPlacementType = spFix then |
| 335 | FFixZ := AData.ReadShortInt; |
| 336 | end;
|
| 337 | |
| 338 | procedure TLSInsertStatics.Apply(AMapCell: TMapCell; AStatics: TList;
|
| 339 | AAdditionalAffectedBlocks: TBits); |
| 340 | var
|
| 341 | staticItem, static: TStaticItem; |
| 342 | topZ, staticTop: ShortInt; |
| 343 | i: Integer; |
| 344 | begin
|
| 345 | if (Length(FTileIDs) = 0) or (Random(100) >= FProbability) then Exit; |
| 346 | |
| 347 | staticItem := TStaticItem.Create(nil, nil, 0, 0); |
| 348 | staticItem.X := AMapCell.X; |
| 349 | staticItem.Y := AMapCell.Y; |
| 350 | staticItem.TileID := FTileIDs[Random(Length(FTileIDs))] - $4000;
|
| 351 | staticItem.Hue := 0;
|
| 352 | |
| 353 | case FPlacementType of |
| 354 | spTerrain: |
| 355 | begin
|
| 356 | staticItem.Z := AMapCell.Z; |
| 357 | end;
|
| 358 | spTop: |
| 359 | begin
|
| 360 | topZ := AMapCell.Z; |
| 361 | for i := 0 to AStatics.Count - 1 do |
| 362 | begin
|
| 363 | static := TStaticItem(AStatics.Items[i]); |
| 364 | staticTop := EnsureRange(static.Z + CEDServerInstance.Landscape.TiledataProvider.StaticTiles[static.TileID].Height, -128, 127); |
| 365 | if staticTop > topZ then topZ := staticTop; |
| 366 | end;
|
| 367 | end;
|
| 368 | spFix: |
| 369 | begin
|
| 370 | staticItem.Z := FFixZ; |
| 371 | end;
|
| 372 | end;
|
| 373 | |
| 374 | AStatics.Add(staticItem); |
| 375 | staticItem.Owner := CEDServerInstance.Landscape.GetStaticBlock(staticItem.X div 8, |
| 376 | staticItem.Y div 8); |
| 377 | end;
|
| 378 | |
| 379 | end.
|
| 380 |