From ad4f5ec68b851b9b2dba627e3b199b93f529dc86 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Thu, 18 Jan 2018 15:33:11 +0200 Subject: [PATCH] grid: only one debug callback left (ok, let it be there for now...) --- src/game/g_grid.pas | 54 ++++++++++++++++++++++++++++++----------- src/game/g_holmes.pas | 49 ++++++++++++++++++++++++++++++++----- src/game/g_monsters.pas | 4 +++ src/game/g_weapons.pas | 21 +++++++++++++--- 4 files changed, 104 insertions(+), 24 deletions(-) diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas index 30ed8ee..a413493 100644 --- a/src/game/g_grid.pas +++ b/src/game/g_grid.pas @@ -43,6 +43,12 @@ uses const GridTileSize = 32; // must be power of two! +type + PGridCellCoord = ^TGridCellCoord; + TGridCellCoord = record + x, y: Integer; + end; + type TBodyProxyId = Integer; @@ -50,7 +56,7 @@ type public type PITP = ^ITP; - type TGridQueryCB = function (obj: ITP; tag: Integer): Boolean is nested; // return `true` to stop + //type TGridQueryCB = function (obj: ITP; tag: Integer): Boolean is nested; // return `true` to stop //type TGridRayQueryCB = function (obj: ITP; tag: Integer; x, y, prevx, prevy: Integer): Boolean is nested; // return `true` to stop type TCellQueryCB = procedure (x, y: Integer) is nested; // top-left cell corner coords @@ -235,7 +241,8 @@ type // you can set enabled/disabled flag, tho (but iterator can still return objects disabled inside it) // trace line along the grid, calling `cb` for all objects in passed cells, in no particular order //WARNING: don't change tags in callbacks here! - function forEachAlongLine (ax0, ay0, ax1, ay1: Integer; cb: TGridQueryCB; tagmask: Integer=-1; log: Boolean=false): ITP; + //function forEachAlongLine (ax0, ay0, ax1, ay1: Integer; cb: TGridQueryCB; tagmask: Integer=-1; log: Boolean=false): ITP; + function forEachAlongLine (ax0, ay0, ax1, ay1: Integer; tagmask: Integer=-1; log: Boolean=false): Integer; // trace box with the given velocity; return object hit (if any) // `cb` is used unconvetionally here: if it returns `false`, tracer will ignore the object @@ -243,8 +250,8 @@ type function traceBox (out ex, ey: Integer; const ax0, ay0, aw, ah: Integer; const dx, dy: Integer; tagmask: Integer=-1): ITP; // debug - procedure forEachBodyCell (body: TBodyProxyId; cb: TCellQueryCB); - function forEachInCell (x, y: Integer; cb: TGridQueryCB): ITP; + function forEachBodyCell (body: TBodyProxyId): Integer; // this puts `TGridCellCoord` into frame pool for each cell + function forEachInCell (x, y: Integer): Integer; procedure dumpStats (); public @@ -714,12 +721,14 @@ begin end; -procedure TBodyGridBase.forEachBodyCell (body: TBodyProxyId; cb: TCellQueryCB); +function TBodyGridBase.forEachBodyCell (body: TBodyProxyId): Integer; var g, f, ccidx: Integer; cc: PGridCell; + presobj: PGridCellCoord; begin - if (body < 0) or (body > High(mProxies)) or not assigned(cb) then exit; + result := 0; + if (body < 0) or (body > High(mProxies)) then exit; for g := 0 to High(mGrid) do begin ccidx := mGrid[g]; @@ -729,7 +738,14 @@ begin for f := 0 to GridCellBucketSize-1 do begin if (cc.bodies[f] = -1) then break; - if (cc.bodies[f] = body) then cb((g mod mWidth)*mTileSize+mMinX, (g div mWidth)*mTileSize+mMinY); + if (cc.bodies[f] = body) then + begin + presobj := PGridCellCoord(framePool.alloc(sizeof(TGridCellCoord))); + presobj^.x := (g mod mWidth)*mTileSize+mMinX; + presobj^.y := (g div mWidth)*mTileSize+mMinY; + Inc(result); + //cb((g mod mWidth)*mTileSize+mMinX, (g div mWidth)*mTileSize+mMinY); + end; end; // next cell ccidx := cc.next; @@ -738,13 +754,13 @@ begin end; -function TBodyGridBase.forEachInCell (x, y: Integer; cb: TGridQueryCB): ITP; +function TBodyGridBase.forEachInCell (x, y: Integer): Integer; var f, ccidx: Integer; cc: PGridCell; + presobj: PITP; begin - result := Default(ITP); - if not assigned(cb) then exit; + result := 0; Dec(x, mMinX); Dec(y, mMinY); if (x < 0) or (y < 0) or (x >= mWidth*mTileSize) or (y > mHeight*mTileSize) then exit; @@ -755,7 +771,11 @@ begin for f := 0 to GridCellBucketSize-1 do begin if (cc.bodies[f] = -1) then break; - if cb(mProxies[cc.bodies[f]].mObj, mProxies[cc.bodies[f]].mTag) then begin result := mProxies[cc.bodies[f]].mObj; exit; end; + //if cb(mProxies[cc.bodies[f]].mObj, mProxies[cc.bodies[f]].mTag) then begin result := mProxies[cc.bodies[f]].mObj; exit; end; + presobj := PITP(framePool.alloc(sizeof(ITP))); + //presobj^ := mProxies[cc.bodies[f]].mObj; + Move(mProxies[cc.bodies[f]].mObj, presobj^, sizeof(ITP)); + Inc(result); end; // next cell ccidx := cc.next; @@ -1536,7 +1556,7 @@ end; // ////////////////////////////////////////////////////////////////////////// // -function TBodyGridBase.forEachAlongLine (ax0, ay0, ax1, ay1: Integer; cb: TGridQueryCB; tagmask: Integer=-1; log: Boolean=false): ITP; +function TBodyGridBase.forEachAlongLine (ax0, ay0, ax1, ay1: Integer; tagmask: Integer=-1; log: Boolean=false): Integer; var lw: TLineWalker; ccidx: Integer; @@ -1549,11 +1569,12 @@ var x1, y1: Integer; cx, cy: Integer; //px0, py0, px1, py1: Integer; + presobj: PITP; begin log := false; - result := Default(ITP); + result := 0; tagmask := tagmask and TagFullMask; - if (tagmask = 0) or not assigned(cb) then exit; + if (tagmask = 0) then exit; gw := mWidth; gh := mHeight; @@ -1598,12 +1619,17 @@ begin if ((ptag and TagDisabled) = 0) and ((ptag and tagmask) <> 0) and (px.mQueryMark <> lq) then begin px.mQueryMark := lq; // mark as processed + presobj := PITP(framePool.alloc(sizeof(ITP))); + Move(px.mObj, presobj^, sizeof(ITP)); + Inc(result); + { if cb(px.mObj, ptag) then begin result := px.mObj; //mInQuery := false; exit; end; + } end; end; // next cell diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas index c4eba8b..f4fe415 100644 --- a/src/game/g_holmes.pas +++ b/src/game/g_holmes.pas @@ -972,6 +972,25 @@ procedure plrDebugDraw (); hlmContext.fillRect(cx, cy, monsGrid.tileSize, monsGrid.tileSize); end; + procedure hilightBodyCells (proxyId: Integer); + var + pmark: PoolMark; + hitcount: Integer; + pcellxy: PGridCellCoord; + begin + //monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + pmark := framePool.mark(); + hitcount := monsGrid.forEachBodyCell(proxyId); + pcellxy := PGridCellCoord(framePool.getPtr(pmark)); + while (hitcount > 0) do + begin + hilightCell(pcellxy^.x, pcellxy^.y); + Inc(pcellxy); + Dec(hitcount); + end; + framePool.release(pmark); + end; + procedure hilightCell1 (cx, cy: Integer); begin //e_WriteLog(Format('h1: (%d,%d)', [cx, cy]), MSG_NOTIFY); @@ -990,12 +1009,11 @@ procedure plrDebugDraw (); hlmContext.fillRect(pan.X, pan.Y, pan.Width, pan.Height); end; - function monsCollector (mon: TMonster; tag: Integer): Boolean; + procedure monsCollector (mon: TMonster); var ex, ey: Integer; mx, my, mw, mh: Integer; begin - result := false; mon.getMapBox(mx, my, mw, mh); hlmContext.color := TGxRGBA.Create(255, 255, 0, 160); hlmContext.rect(mx, my, mw, mh); @@ -1074,7 +1092,8 @@ procedure plrDebugDraw (); mon.getMapBox(mx, my, mw, mh); //mx += mw div 2; - monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + //monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + hilightBodyCells(mon.proxyId); if showMonsInfo then begin @@ -1113,7 +1132,8 @@ procedure plrDebugDraw (); function highlightAllMonsterCells (mon: TMonster): Boolean; begin result := false; // don't stop - monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + //monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + hilightBodyCells(mon.proxyId); end; procedure drawSelectedPlatformCells (); @@ -1123,7 +1143,8 @@ procedure plrDebugDraw (); if not showGrid then exit; pan := g_Map_PanelByGUID(platMarkedGUID); if (pan = nil) then exit; - mapGrid.forEachBodyCell(pan.proxyId, hilightCell); + //mapGrid.forEachBodyCell(pan.proxyId, hilightCell); + hilightBodyCells(pan.proxyId); hlmContext.color := TGxRGBA.Create(0, 200, 0, 200); hlmContext.rect(pan.x, pan.y, pan.width, pan.height); end; @@ -1234,6 +1255,9 @@ var mx, my, mw, mh: Integer; //pan: TPanel; //ex, ey: Integer; + pmark: PoolMark; + hitcount: Integer; + pmon: PMonster; begin if (gPlayer1 = nil) then exit; @@ -1255,7 +1279,20 @@ begin if (showGrid) then drawTileGrid(); drawOutlines(); - if (laserSet) then g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true); + if (laserSet) then + begin + //g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true); + pmark := framePool.mark(); + hitcount := monsGrid.forEachAlongLine(laserX0, laserY0, laserX1, laserY1, -1, true); + pmon := PMonster(framePool.getPtr(pmark)); + while (hitcount > 0) do + begin + monsCollector(pmon^); + Inc(pmon); + Dec(hitcount); + end; + framePool.release(pmark); + end; if (monMarkedUID <> -1) then begin diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index e2f04a6..018a693 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -273,10 +273,12 @@ function g_Mons_getNewTrapFrameId (): DWord; inline; function g_Mons_getNewMPlatFrameId (): LongWord; inline; +{ type TMonsAlongLineCB = function (mon: TMonster; tag: Integer): Boolean is nested; function g_Mons_AlongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB; log: Boolean=false): TMonster; +} var @@ -364,11 +366,13 @@ procedure TMonster.setDirty (); inline; begin mNeedSend := true; end; // ////////////////////////////////////////////////////////////////////////// // +{ function g_Mons_AlongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB; log: Boolean=false): TMonster; begin if not assigned(cb) then begin result := nil; exit; end; result := monsGrid.forEachAlongLine(x0, y0, x1, y1, cb, -1, log); end; +} //WARNING! call this after monster position was changed, or coldet will not work right! diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index 97d127a..725ab6d 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -20,7 +20,7 @@ unit g_weapons; interface uses - SysUtils, Classes, + SysUtils, Classes, mempool, g_textures, g_basic, e_graphics, g_phys, xprofiler; @@ -1440,13 +1440,12 @@ var end; end; - function sqchecker (mon: TMonster; tag: Integer): Boolean; + procedure sqchecker (mon: TMonster); var mx, my, mw, mh: Integer; inx, iny: Integer; distSq: Integer; begin - result := false; // don't stop mon.getMapBox(mx, my, mw, mh); if lineAABBIntersects(x0, y0, x2, y2, mx, my, mw, mh, inx, iny) then begin @@ -1468,6 +1467,9 @@ var {$IF DEFINED(D2F_DEBUG)} stt: UInt64; {$ENDIF} + pmark: PoolMark; + hitcount: Integer; + pmon: PMonster; begin (* if not gwep_debug_fast_trace then @@ -1522,7 +1524,18 @@ begin if playerPossibleHit() then exit; // instant hit // collect monsters - g_Mons_AlongLine(x, y, x2, y2, sqchecker); + //g_Mons_AlongLine(x, y, x2, y2, sqchecker); + + pmark := framePool.mark(); + hitcount := monsGrid.forEachAlongLine(x, y, x2, y2, -1); + pmon := PMonster(framePool.getPtr(pmark)); + while (hitcount > 0) do + begin + sqchecker(pmon^); + Inc(pmon); + Dec(hitcount); + end; + framePool.release(pmark); // here, we collected all monsters and players in `wgunHitHeap` and `wgunHitTime` // also, if `wallWasHit` is `true`, then `wallHitX` and `wallHitY` contains spark coords -- 2.29.2