From b79ddd98d923ee15f4bfd1db5111e669fc19964a Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Tue, 22 Aug 2017 22:54:19 +0300 Subject: [PATCH] raycast jumper (bad) --- src/game/g_grid.pas | 58 +++++++++++++++++++++++++++++++++-------- src/game/g_monsters.pas | 6 ++--- src/game/g_player.pas | 2 +- src/game/g_weapons.pas | 2 +- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas index 6ff288c..925fb80 100644 --- a/src/game/g_grid.pas +++ b/src/game/g_grid.pas @@ -34,7 +34,7 @@ type private const - GridDefaultTileSize = 32; + GridDefaultTileSize = 32; // must be power of two! GridCellBucketSize = 8; // WARNING! can't be less than 2! private @@ -137,7 +137,7 @@ type //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) // trace line along the grid, calling `cb` for all objects in passed cells, in no particular order - function forEachAlongLine (x0, y0, x1, y1: Integer; cb: TGridAlongQueryCB; tagmask: Integer=-1): ITP; + function forEachAlongLine (x0, y0, x1, y1: Integer; cb: TGridAlongQueryCB; tagmask: Integer=-1; log: Boolean=false): ITP; procedure dumpStats (); @@ -157,9 +157,12 @@ type // if result is `false`, `inx` and `iny` are undefined function lineAABBIntersects (x0, y0, x1, y1: Integer; bx, by, bw, bh: Integer; out inx, iny: Integer): Boolean; -procedure swapInt (var a: Integer; var b: Integer); inline; function distanceSq (x0, y0, x1, y1: Integer): Integer; inline; +procedure swapInt (var a: Integer; var b: Integer); inline; +function minInt (a, b: Integer): Integer; inline; +function maxInt (a, b: Integer): Integer; inline; + implementation @@ -169,6 +172,8 @@ uses // ////////////////////////////////////////////////////////////////////////// // procedure swapInt (var a: Integer; var b: Integer); inline; var t: Integer; begin t := a; a := b; b := t; end; +function minInt (a, b: Integer): Integer; inline; begin if (a < b) then result := a else result := b; end; +function maxInt (a, b: Integer): Integer; inline; begin if (a > b) then result := a else result := b; end; function distanceSq (x0, y0, x1, y1: Integer): Integer; inline; begin result := (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0); end; @@ -1290,7 +1295,7 @@ end; // ////////////////////////////////////////////////////////////////////////// // //FIXME! optimize this with real tile walking -function TBodyGridBase.forEachAlongLine (x0, y0, x1, y1: Integer; cb: TGridAlongQueryCB; tagmask: Integer=-1): ITP; +function TBodyGridBase.forEachAlongLine (x0, y0, x1, y1: Integer; cb: TGridAlongQueryCB; tagmask: Integer=-1; log: Boolean=false): ITP; const tsize = mTileSize; var @@ -1311,11 +1316,11 @@ var ptag: Integer; lastWasInGrid: Boolean; tbcross: Boolean; - f: Integer; + f, tedist: Integer; begin result := Default(ITP); tagmask := tagmask and TagFullMask; - if (tagmask = 0) then exit; + if (tagmask = 0) or not assigned(cb) then exit; minx := mMinX; miny := mMinY; @@ -1362,9 +1367,13 @@ begin xerr := -d; yerr := -d; + if (log) then e_WriteLog(Format('tracing: (%d,%d)-(%d,%d)', [x, y, x1-minx, y1-miny]), MSG_NOTIFY); + // now trace - for i := 1 to d do + i := 0; + while (i < d) do begin + Inc(i); // do one step xerr += dx; yerr += dy; @@ -1395,6 +1404,33 @@ begin begin // setup new cell index ccidx := mGrid[(y div tsize)*gw+(x div tsize)]; + if (log) then e_WriteLog(Format(' stepped to new tile (%d,%d) -- (%d,%d)', [(x div tsize), (y div tsize), x, y]), MSG_NOTIFY); + end + else + if (ccidx = -1) then + begin + // we have nothing interesting here anymore, jump directly to tile edge + // get minimal distance to tile edges + if (incx < 0) then tedist := x-(x and (not tsize)) else if (incx > 0) then tedist := (x or (tsize+1))-x else tedist := 0; + {$IF DEFINED(D2F_DEBUG)} + if (tedist < 0) then raise Exception.Create('internal bug in grid raycaster (2.x)'); + {$ENDIF} + if (incy < 0) then f := y-(y and (not tsize)) else if (incy > 0) then f := (y or (tsize+1))-y else f := 0; + {$IF DEFINED(D2F_DEBUG)} + if (f < 0) then raise Exception.Create('internal bug in grid raycaster (2.y)'); + {$ENDIF} + if (tedist = 0) then tedist := f else if (f <> 0) then tedist := minInt(tedist, f); + // do jump + if (tedist > 1) then + begin + if (log) then e_WriteLog(Format(' doing jump from tile (%d,%d) - (%d,%d) by %d steps', [(x div tsize), (y div tsize), x, y, tedist]), MSG_NOTIFY); + xerr += dx*tedist; + yerr += dy*tedist; + if (xerr >= 0) then begin x += incx*((xerr div d)+1); xerr := (xerr mod d)-d; end; + if (yerr >= 0) then begin y += incy*((yerr div d)+1); yerr := (yerr mod d)-d; end; + Inc(i, tedist); + if (log) then e_WriteLog(Format(' jumped to tile (%d,%d) - (%d,%d) by %d steps', [(x div tsize), (y div tsize), x, y, tedist]), MSG_NOTIFY); + end; end; end else @@ -1410,8 +1446,8 @@ begin // process cell curci := ccidx; // convert coords to map (to avoid ajdusting coords inside the loop) - Inc(x, minx); - Inc(y, miny); + //Inc(x, minx); + //Inc(y, miny); // process cell list while (curci <> -1) do begin @@ -1432,8 +1468,8 @@ begin end; ccidx := -1; // don't process this anymore // convert coords to grid - Dec(x, minx); - Dec(y, miny); + //Dec(x, minx); + //Dec(y, miny); end; end; end; diff --git a/src/game/g_monsters.pas b/src/game/g_monsters.pas index dcb8dc0..a52ddf1 100644 --- a/src/game/g_monsters.pas +++ b/src/game/g_monsters.pas @@ -208,7 +208,7 @@ function g_Mons_getNewTrapFrameId (): DWord; type TMonsAlongLineCB = function (mon: TMonster; tag: Integer): Boolean is nested; -function g_Mons_alongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB): TMonster; +function g_Mons_AlongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB; log: Boolean=false): TMonster; var @@ -285,10 +285,10 @@ var monsGrid: TMonsterGrid = nil; -function g_Mons_alongLine (x0, y0, x1, y1: Integer; cb: TMonsAlongLineCB): TMonster; +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); + result := monsGrid.forEachAlongLine(x0, y0, x1, y1, cb, -1, log); end; diff --git a/src/game/g_player.pas b/src/game/g_player.pas index 8720e07..8981721 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -2353,7 +2353,7 @@ procedure TPlayer.DrawAim(); end; } - g_Mons_alongLine(ax0, ay0, ax1, ay1, monsCollector); + g_Mons_AlongLine(ax0, ay0, ax1, ay1, monsCollector, true); end; var diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas index 88670fd..ca4630e 100644 --- a/src/game/g_weapons.pas +++ b/src/game/g_weapons.pas @@ -1528,7 +1528,7 @@ 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); // 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