summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e3b318e)
raw | patch | inline | side by side (parent: e3b318e)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Tue, 22 Aug 2017 19:54:19 +0000 (22:54 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Wed, 23 Aug 2017 18:23:55 +0000 (21:23 +0300) |
src/game/g_grid.pas | patch | blob | history | |
src/game/g_monsters.pas | patch | blob | history | |
src/game/g_player.pas | patch | blob | history | |
src/game/g_weapons.pas | patch | blob | history |
diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas
index 6ff288c5de2d2549fc98e0dd4a8be0e7e67bd2cf..925fb80ca042470d6b78acb7cb623952ef2d77cb 100644 (file)
--- a/src/game/g_grid.pas
+++ b/src/game/g_grid.pas
private
const
- GridDefaultTileSize = 32;
+ GridDefaultTileSize = 32; // must be power of two!
GridCellBucketSize = 8; // WARNING! can't be less than 2!
private
//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 ();
// 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
// ////////////////////////////////////////////////////////////////////////// //
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;
// ////////////////////////////////////////////////////////////////////////// //
//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
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;
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;
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
// 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
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;
index dcb8dc09b68a6c8afb434b4f4c3cbabcb1e347f7..a52ddf1738be26e9b78ebd1e22cbd34ba76cbc55 100644 (file)
--- a/src/game/g_monsters.pas
+++ b/src/game/g_monsters.pas
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
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 8720e077261d47014e69aaeacca1b95157f3b570..8981721df6bbddeb5e0cde76baa242b1e8c0cab6 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
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 88670fdb5a59ccf102cfa252b8ff235e816020d3..ca4630ed2023d55edc648994e9021a736d8b9b53 100644 (file)
--- a/src/game/g_weapons.pas
+++ b/src/game/g_weapons.pas
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