summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 35579eb)
raw | patch | inline | side by side (parent: 35579eb)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Wed, 30 Aug 2017 10:42:57 +0000 (13:42 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Wed, 30 Aug 2017 11:14:40 +0000 (14:14 +0300) |
src/game/g_grid.pas | patch | blob | history |
diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas
index 346770246cfd96eb4bb196e9471360ef95763d13..442a776ea831b8fc1a103001c51331cecf7e4a3b 100644 (file)
--- a/src/game/g_grid.pas
+++ b/src/game/g_grid.pas
property height: Integer read mHeight;
property tag: Integer read getTag write setTag;
property enabled: Boolean read getEnabled write setEnabled;
+ property obj: ITP read mObj;
end;
private
next: Integer; // in this cell; index in mCells
end;
+ TCellArray = array of TGridCell;
+
TGridInternalCB = function (grida: Integer; bodyId: TBodyProxyId): Boolean of object; // return `true` to stop
private
//mTileSize: Integer;
const mTileSize = GridDefaultTileSize;
+ type TGetProxyFn = function (pxidx: Integer): PBodyProxyRec of object;
public
const tileSize = mTileSize;
+ type
+ TAtPointEnumerator = record
+ private
+ mCells: TCellArray;
+ curidx, curbki: Integer;
+ getpx: TGetProxyFn;
+ public
+ constructor Create (acells: TCellArray; aidx: Integer; agetpx: TGetProxyFn);
+ function MoveNext (): Boolean; inline;
+ function getCurrent (): PBodyProxyRec; inline;
+ property Current: PBodyProxyRec read getCurrent;
+ end;
+
private
mMinX, mMinY: Integer; // so grids can start at any origin
mWidth, mHeight: Integer; // in tiles
mGrid: array of Integer; // mWidth*mHeight, index in mCells
- mCells: array of TGridCell; // cell pool
+ mCells: TCellArray; // cell pool
mFreeCell: Integer; // first free cell index or -1
mLastQuery: LongWord;
mUsedCells: Integer;
// no callback: return object on the first hit or nil
function forEachAtPoint (x, y: Integer; cb: TGridQueryCB; tagmask: Integer=-1; exittag: PInteger=nil): ITP;
+ function atPoint (x, y: Integer): TAtPointEnumerator;
+
//WARNING: don't modify grid while any query is in progress (no checks are made!)
// you can set enabled/disabled flag, tho (but iterator can still return objects disabled inside it)
// cb with `(nil)` will be called before processing new tile
end;
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TBodyGridBase.TAtPointEnumerator.Create (acells: TCellArray; aidx: Integer; agetpx: TGetProxyFn);
+begin
+ mCells := acells;
+ curidx := aidx;
+ curbki := -1;
+ getpx := agetpx;
+end;
+
+
+function TBodyGridBase.TAtPointEnumerator.MoveNext (): Boolean; inline;
+begin
+ while (curidx <> -1) do
+ begin
+ while (curbki < GridCellBucketSize) do
+ begin
+ Inc(curbki);
+ if (mCells[curidx].bodies[curbki] = -1) then break;
+ result := true;
+ exit;
+ end;
+ curidx := mCells[curidx].next;
+ curbki := -1;
+ end;
+ result := false;
+end;
+
+
+function TBodyGridBase.TAtPointEnumerator.getCurrent (): PBodyProxyRec; inline;
+begin
+ result := getpx(mCells[curidx].bodies[curbki]);
+end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
constructor TBodyGridBase.Create (aMinPixX, aMinPixY, aPixWidth, aPixHeight: Integer{; aTileSize: Integer=GridDefaultTileSize});
var
end;
+// ////////////////////////////////////////////////////////////////////////// //
+function TBodyGridBase.atPoint (x, y: Integer): TAtPointEnumerator;
+var
+ cidx: Integer = -1;
+begin
+ Dec(x, mMinX);
+ Dec(y, mMinY);
+ if (x >= 0) and (y >= 0) and (x < mWidth*mTileSize) and (y < mHeight*mTileSize) then cidx := mGrid[(y div mTileSize)*mWidth+(x div mTileSize)];
+ result := TAtPointEnumerator.Create(mCells, cidx, getProxyById);
+end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
// no callback: return `true` on the first hit
function TBodyGridBase.forEachAtPoint (x, y: Integer; cb: TGridQueryCB; tagmask: Integer=-1; exittag: PInteger=nil): ITP;