summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4caa735)
raw | patch | inline | side by side (parent: 4caa735)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Thu, 24 Aug 2017 02:23:12 +0000 (05:23 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Thu, 24 Aug 2017 02:41:18 +0000 (05:41 +0300) |
src/game/g_gfx.pas | patch | blob | history | |
src/game/g_grid.pas | patch | blob | history | |
src/game/g_map.pas | patch | blob | history |
diff --git a/src/game/g_gfx.pas b/src/game/g_gfx.pas
index ab895762d3cae8f6b59ed2cc18fe77fc87ed3650..bbdc4329cd2ee406e874f82158a40f61651f5c8e 100644 (file)
--- a/src/game/g_gfx.pas
+++ b/src/game/g_gfx.pas
offsetX, offsetY: ShortInt;
// for bubbles
liquidTopY: Integer; // don't float higher than this
+ // for water
+ stickDX: Integer;
//k8: sorry, i have to emulate virtual methods this way, 'cause i haet `Object`
end;
-// ////////////////////////////////////////////////////////////////////////// //
-procedure TParticle.thinkerBubble ();
-var
- h: Integer;
- dY: SmallInt;
- b: Integer;
- s: ShortInt;
-begin
- h := gMapInfo.Height;
-
- dY := Round(VelY);
-
- if dY <> 0 then
- begin
- if dY > 0 then
- s := 1
- else
- s := -1;
-
- for b := 1 to Abs(dY) do
- begin
- if (Y+s >= h) or (Y+s <= 0) then begin die(); break; end;
-
- (*
- if not isLiquidAt(X, Y+s) {ByteBool(gCollideMap[Y+s, X] and MARK_LIQUID)} then
- begin // Óæå íå æèäêîñòü
- State := STATE_FREE;
- Break;
- end;
- *)
- // we traced liquid before, so don't bother checking
- if (Y+s <= liquidTopY) then begin die(); break; end;
-
- Y := Y+s;
- end;
- end;
-
- if VelY > -4 then
- VelY := VelY + AccelY;
-
- Time := Time + 1;
-end;
-
-
// ////////////////////////////////////////////////////////////////////////// //
procedure TParticle.thinkerWater ();
var
- w, h: Integer;
dX, dY: SmallInt;
+ {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
+ w, h: Integer;
b: Integer;
s: ShortInt;
+ {$ELSE}
+ pan: TPanel;
+ ex, ey: Integer;
+ {$ENDIF}
begin
+ {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
w := gMapInfo.Width;
h := gMapInfo.Height;
+ {$ENDIF}
+ //TODO: trace wall end when water becomes stick
if (State = STATE_STICK) and (Random(30) = 15) then
begin // Ñòåêàåò/îòëèïàåò
VelY := 0.5;
AccelY := 0.15;
+ {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
if (not isBlockedAt(X-1, Y) {ByteBool(gCollideMap[Y, X-1] and MARK_BLOCKED)}) and
(not isBlockedAt(X+1, Y) {ByteBool(gCollideMap[Y, X+1] and MARK_BLOCKED)}) then
State := STATE_NORMAL;
+ {$ELSE}
+ if (stickDX = 0) then
+ begin
+ // no walls around, drop
+ State := STATE_NORMAL;
+ end
+ else
+ begin
+ if (g_Map_PanelAtPoint(X+stickDX, Y, (GridTagWall or GridTagDoor or GridTagStep)) = nil) then State := STATE_NORMAL;
+ end;
+ {$ENDIF}
exit;
end;
+ {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
if not isBlockedAt(X, Y) {ByteBool(gCollideMap[Y, X] and MARK_BLOCKED)} then
begin
if isLiftUpAt(X, Y) {ByteBool(gCollideMap[Y, X] and MARK_LIFTUP)} then
AccelY := 0.15;
end;
end;
+ {$ELSE}
+ pan := g_Map_PanelAtPoint(X, Y, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagLift));
+ if (pan <> nil) then
+ begin
+ if ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
+ if ((pan.PanelType and PANEL_LIFTUP) <> 0) then
+ begin
+ if (VelY > -4-Random(3)) then VelY -= 0.8;
+ if (Abs(VelX) > 0.1) then VelX -= VelX/10.0;
+ VelX += (Random-Random)*0.2;
+ AccelY := 0.15;
+ end;
+ if ((pan.PanelType and PANEL_LIFTLEFT) <> 0) then
+ begin
+ if (VelX > -8-Random(3)) then VelX -= 0.8;
+ AccelY := 0.15;
+ end;
+ if ((pan.PanelType and PANEL_LIFTRIGHT) <> 0) then
+ begin
+ if (VelX < 8+Random(3)) then VelX += 0.8;
+ AccelY := 0.15;
+ end;
+ end;
+ {$ENDIF}
dX := Round(VelX);
dY := Round(VelY);
+ {$IF not DEFINED(D2F_NEW_SPARK_THINKER)}
if (Abs(VelX) < 0.1) and (Abs(VelY) < 0.1) then
+ begin
if (State <> STATE_STICK) and
(not isBlockedAt(X, Y-1) {ByteBool(gCollideMap[Y-1, X] and MARK_BLOCKED)}) and
(not isBlockedAt(X, Y) {ByteBool(gCollideMap[Y, X] and MARK_BLOCKED)}) and
AccelY := 0.5;
State := STATE_NORMAL;
end;
-
- if dX <> 0 then
+ end;
+ {$ELSE}
+ if (State <> STATE_STICK) and (Abs(VelX) < 0.1) and (Abs(VelY) < 0.1) then
begin
- if dX > 0 then
- s := 1
- else
- s := -1;
+ // Âèñèò â âîçäóõå - êàïàåò
+ if (nil = g_Map_traceToNearest(X, Y-1, X, Y+1, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey)) then
+ begin
+ VelY := 0.8;
+ AccelY := 0.5;
+ State := STATE_NORMAL;
+ end;
+ end;
+ {$ENDIF}
+ {$IF DEFINED(D2F_NEW_SPARK_THINKER)}
+ // horizontal
+ if (dX <> 0) then
+ begin
+ pan := g_Map_traceToNearest(X, Y, X+dX, Y, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
+ X := ex;
+ // free to ride?
+ if (pan <> nil) then
+ begin
+ // nope
+ if (dY > 0) and ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
+ // Ñòåíà/äâåðü?
+ if ((pan.tag and (GridTagWall or GridTagDoor or GridTagStep)) <> 0) then
+ begin
+ VelX := 0;
+ VelY := 0;
+ AccelX := 0;
+ AccelY := 0;
+ State := STATE_STICK;
+ if (dX > 0) then stickDX := 1 else stickDX := -1;
+ end;
+ end;
+ if (X < 0) or (X >= gMapInfo.Width) then begin die(); exit; end;
+ end;
+ // vertical
+ if (dY <> 0) then
+ begin
+ pan := g_Map_traceToNearest(X, Y, X, Y+dY, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey);
+ Y := ey;
+ // free to ride?
+ if (pan <> nil) then
+ begin
+ // nope
+ if (dY > 0) and ((pan.tag and (GridTagAcid1 or GridTagAcid2 or GridTagWater)) <> 0) then begin die(); exit; end;
+ // Ñòåíà/äâåðü?
+ if ((pan.tag and (GridTagWall or GridTagDoor or GridTagStep)) <> 0) then
+ begin
+ VelX := 0;
+ VelY := 0;
+ AccelX := 0;
+ AccelY := 0;
+ if (dY > 0) and (State <> STATE_STICK) then
+ begin
+ State := STATE_NORMAL;
+ end
+ else
+ begin
+ State := STATE_STICK;
+ if (g_Map_PanelAtPoint(X-1, Y, (GridTagWall or GridTagDoor or GridTagStep)) <> nil) then stickDX := -1
+ else if (g_Map_PanelAtPoint(X+1, Y, (GridTagWall or GridTagDoor or GridTagStep)) <> nil) then stickDX := 1
+ else stickDX := 0;
+ end;
+ end;
+ end;
+ if (Y < 0) or (Y >= gMapInfo.Height) then begin die(); exit; end;
+ end;
+ {$ELSE}
+ // horizontal
+ if (dX <> 0) then
+ begin
+ if (dX > 0) then s := 1 else s := -1;
for b := 1 to Abs(dX) do
begin
- // Ñáîêó ãðàíèöà?
+ // Ñáîêó ãðàíèöà?
if (X+s >= w) or (X+s <= 0) then begin die(); break;end;
-
//c := gCollideMap[Y, X+s];
-
// Ñáîêó æèäêîñòü, à ÷àñòèöà óæå ïàäàåò?
if isLiquidAt(X+s, Y) {ByteBool(c and MARK_LIQUID)} and (dY > 0) then begin die(); break; end;
-
if isBlockedAt(X+s, Y) {ByteBool(c and MARK_BLOCKED)} then
begin // Ñòåíà/äâåðü
VelX := 0;
State := STATE_STICK;
Break;
end;
-
X := X+s;
end;
end;
-
- if dY <> 0 then
+ // vertical
+ if (dY <> 0) then
begin
- if dY > 0 then
- s := 1
- else
- s := -1;
-
+ if (dY > 0) then s := 1 else s := -1;
for b := 1 to Abs(dY) do
begin
// Ñíèçó/ñâåðõó ãðàíèöà
if (Y+s >= h) or (Y+s <= 0) then begin die(); break; end;
-
//c := gCollideMap[Y+s, X];
-
// Ñíèçó æèäêîñòü, à ÷àñòèöà óæå ïàäàåò
if isLiquidAt(X, Y+s) {ByteBool(c and MARK_LIQUID)} and (dY > 0) then begin die(); break; end;
-
if isBlockedAt(X, Y+s) {ByteBool(c and MARK_BLOCKED)} then
begin // Ñòåíà/äâåðü
VelX := 0;
VelY := 0;
AccelX := 0;
AccelY := 0;
- if (s > 0) and (State <> STATE_STICK) then
- State := STATE_NORMAL
- else
- State := STATE_STICK;
+ if (s > 0) and (State <> STATE_STICK) then State := STATE_NORMAL else State := STATE_STICK;
+ break;
+ end;
+ Y := Y+s;
+ end;
+ end;
+ {$ENDIF}
+
+ VelX += AccelX;
+ VelY += AccelY;
+
+ Time += 1;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+procedure TParticle.thinkerBubble ();
+var
+ h: Integer;
+ dY: SmallInt;
+ b: Integer;
+ s: ShortInt;
+begin
+ h := gMapInfo.Height;
+
+ dY := Round(VelY);
+
+ if dY <> 0 then
+ begin
+ if dY > 0 then
+ s := 1
+ else
+ s := -1;
+
+ for b := 1 to Abs(dY) do
+ begin
+ if (Y+s >= h) or (Y+s <= 0) then begin die(); break; end;
+
+ (*
+ if not isLiquidAt(X, Y+s) {ByteBool(gCollideMap[Y+s, X] and MARK_LIQUID)} then
+ begin // Óæå íå æèäêîñòü
+ State := STATE_FREE;
Break;
end;
+ *)
+ // we traced liquid before, so don't bother checking
+ if (Y+s <= liquidTopY) then begin die(); break; end;
Y := Y+s;
end;
end;
- VelX := VelX + AccelX;
- VelY := VelY + AccelY;
+ if VelY > -4 then
+ VelY := VelY + AccelY;
Time := Time + 1;
end;
// trace liquid, so we'll know where it ends; do it in 8px steps for speed
// tracer will return `false` if we started outside of the liquid
- if not g_Map_TraceLiquid(X, Y, 0, -8, liquidx, liquidTopY) then continue;
+ if not g_Map_TraceLiquidNonPrecise(X, Y, 0, -8, liquidx, liquidTopY) then continue;
VelX := 0;
VelY := -1-Random;
diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas
index 3ff9230a3e1c27414a28fd4867ab6df0280bd759..2afca2f3c16c0db534a6ec68cb4bb665c200e186 100644 (file)
--- a/src/game/g_grid.pas
+++ b/src/game/g_grid.pas
// 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
// no callback: return object of the nearest hit or nil
+ // if `inverted` is true, trace will register bodies *exluding* tagmask
//WARNING: don't change tags in callbacks here!
function traceRay (const x0, y0, x1, y1: Integer; cb: TGridRayQueryCB; tagmask: Integer=-1): ITP; overload;
function traceRay (out ex, ey: Integer; const ax0, ay0, ax1, ay1: Integer; cb: TGridRayQueryCB; tagmask: Integer=-1): ITP;
+ //function traceRayWhileIn (const x0, y0, x1, y1: Integer; tagmask: Integer=-1): ITP; overload;
+ //function traceRayWhileIn (out ex, ey: Integer; const ax0, ay0, ax1, ay1: Integer; tagmask: Integer=-1): ITP;
+
//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
result := forEachAtPoint(ax0, ay0, nil, tagmask, @ptag);
if (result <> nil) then
begin
- if assigned(cb) then
- begin
- if cb(result, ptag, ax0, ay0, ax0, ay0) then
- begin
- ex := ax0;
- ey := ay0;
- end
- else
- begin
- result := nil;
- end;
- end
- else
- begin
- ex := ax0;
- ey := ay0;
- end;
+ if assigned(cb) and not cb(result, ptag, ax0, ay0, ax0, ay0) then result := Default(ITP);
end;
exit;
end;
end;
+// ////////////////////////////////////////////////////////////////////////// //
+(*
+function TBodyGridBase.traceRayWhileIn (const x0, y0, x1, y1: Integer; tagmask: Integer=-1): ITP; overload;
+var
+ ex, ey: Integer;
+begin
+ result := traceRayWhileIn(ex, ey, x0, y0, x1, y1, tagmask);
+end;
+
+
+// FUCKIN' PASTA!
+function TBodyGridBase.traceRayWhileIn (out ex, ey: Integer; const ax0, ay0, ax1, ay1: Integer; tagmask: Integer=-1): ITP;
+const
+ tsize = mTileSize;
+var
+ wx0, wy0, wx1, wy1: Integer; // window coordinates
+ stx, sty: Integer; // "steps" for x and y axes
+ dsx, dsy: Integer; // "lengthes" for x and y axes
+ dx2, dy2: Integer; // "double lengthes" for x and y axes
+ xd, yd: Integer; // current coord
+ e: Integer; // "error" (as in bresenham algo)
+ rem: Integer;
+ term: Integer;
+ xptr, yptr: PInteger;
+ xfixed: Boolean;
+ temp: Integer;
+ prevx, prevy: Integer;
+ lastDistSq: Integer;
+ ccidx, curci: Integer;
+ hasUntried: Boolean;
+ lastGA: Integer = -1;
+ ga, x, y: Integer;
+ lastObj: ITP;
+ wasHit: Boolean = false;
+ gw, gh, minx, miny, maxx, maxy: Integer;
+ cc: PGridCell;
+ px: PBodyProxyRec;
+ lq: LongWord;
+ f, ptag, distSq: Integer;
+ x0, y0, x1, y1: Integer;
+ inx, iny: Integer;
+begin
+ result := Default(ITP);
+ lastObj := Default(ITP);
+ tagmask := tagmask and TagFullMask;
+ ex := ax1; // why not?
+ ey := ay1; // why not?
+ if (tagmask = 0) then exit;
+
+ if (ax0 = ax1) and (ay0 = ay1) then exit; // doesn't matter
+
+ // we should start inside
+ if (forEachAtPoint(ax0, ay0, nil, tagmask, @ptag) = nil) then
+ begin
+ ex := ax0; // why not?
+ ey := ay0; // why not?
+ exit;
+ end;
+
+ lastDistSq := distanceSq(ax0, ay0, ax1, ay1)+1;
+
+ gw := mWidth;
+ gh := mHeight;
+ minx := mMinX;
+ miny := mMinY;
+ maxx := gw*tsize-1;
+ maxy := gh*tsize-1;
+
+ x0 := ax0;
+ y0 := ay0;
+ x1 := ax1;
+ y1 := ay1;
+
+ // offset query coords to (0,0)-based
+ Dec(x0, minx);
+ Dec(y0, miny);
+ Dec(x1, minx);
+ Dec(y1, miny);
+
+ // clip rectange
+ wx0 := 0;
+ wy0 := 0;
+ wx1 := maxx;
+ wy1 := maxy;
+
+ // horizontal setup
+ if (x0 < x1) then
+ begin
+ // from left to right
+ if (x0 > wx1) or (x1 < wx0) then exit; // out of screen
+ stx := 1; // going right
+ end
+ else
+ begin
+ // from right to left
+ if (x1 > wx1) or (x0 < wx0) then exit; // out of screen
+ stx := -1; // going left
+ x0 := -x0;
+ x1 := -x1;
+ wx0 := -wx0;
+ wx1 := -wx1;
+ swapInt(wx0, wx1);
+ end;
+
+ // vertical setup
+ if (y0 < y1) then
+ begin
+ // from top to bottom
+ if (y0 > wy1) or (y1 < wy0) then exit; // out of screen
+ sty := 1; // going down
+ end
+ else
+ begin
+ // from bottom to top
+ if (y1 > wy1) or (y0 < wy0) then exit; // out of screen
+ sty := -1; // going up
+ y0 := -y0;
+ y1 := -y1;
+ wy0 := -wy0;
+ wy1 := -wy1;
+ swapInt(wy0, wy1);
+ end;
+
+ dsx := x1-x0;
+ dsy := y1-y0;
+
+ if (dsx < dsy) then
+ begin
+ xptr := @yd;
+ yptr := @xd;
+ swapInt(x0, y0);
+ swapInt(x1, y1);
+ swapInt(dsx, dsy);
+ swapInt(wx0, wy0);
+ swapInt(wx1, wy1);
+ swapInt(stx, sty);
+ end
+ else
+ begin
+ xptr := @xd;
+ yptr := @yd;
+ end;
+
+ dx2 := 2*dsx;
+ dy2 := 2*dsy;
+ xd := x0;
+ yd := y0;
+ e := 2*dsy-dsx;
+ term := x1;
+
+ xfixed := false;
+ if (y0 < wy0) then
+ begin
+ // clip at top
+ temp := dx2*(wy0-y0)-dsx;
+ xd += temp div dy2;
+ rem := temp mod dy2;
+ if (xd > wx1) then exit; // x is moved out of clipping rect, nothing to do
+ if (xd+1 >= wx0) then
+ begin
+ yd := wy0;
+ e -= rem+dsx;
+ if (rem > 0) then begin Inc(xd); e += dy2; end;
+ xfixed := true;
+ end;
+ end;
+
+ if (not xfixed) and (x0 < wx0) then
+ begin
+ // clip at left
+ temp := dy2*(wx0-x0);
+ yd += temp div dx2;
+ rem := temp mod dx2;
+ if (yd > wy1) or (yd = wy1) and (rem >= dsx) then exit;
+ xd := wx0;
+ e += rem;
+ if (rem >= dsx) then begin Inc(yd); e -= dx2; end;
+ end;
+
+ if (y1 > wy1) then
+ begin
+ // clip at bottom
+ temp := dx2*(wy1-y0)+dsx;
+ term := x0+temp div dy2;
+ rem := temp mod dy2;
+ if (rem = 0) then Dec(term);
+ end;
+
+ if (term > wx1) then term := wx1; // clip at right
+
+ Inc(term); // draw last point
+ //if (term = xd) then exit; // this is the only point, get out of here
+
+ if (sty = -1) then yd := -yd;
+ if (stx = -1) then begin xd := -xd; term := -term; end;
+ dx2 -= dy2;
+
+ // first move, to skip starting point
+ // DON'T DO THIS! loop will take care of that
+ if (xd = term) then
+ begin
+ result := forEachAtPoint(ax0, ay0, nil, tagmask, @ptag);
+ if (result <> nil) and ((ptag and tagmask) <> 0) then result := nil;
+ exit;
+ end;
+
+ prevx := xptr^+minx;
+ prevy := yptr^+miny;
+
+ // increase query counter
+ Inc(mLastQuery);
+ if (mLastQuery = 0) then
+ begin
+ // just in case of overflow
+ mLastQuery := 1;
+ for f := 0 to High(mProxies) do mProxies[f].mQueryMark := 0;
+ end;
+ lq := mLastQuery;
+
+ ccidx := -1;
+ // draw it; can omit checks
+ while (xd <> term) do
+ begin
+ // check cell(s)
+ // new tile?
+ ga := (yptr^ div tsize)*gw+(xptr^ div tsize);
+ if (ga <> lastGA) then
+ begin
+ // yes
+ lastGA := ga;
+ ccidx := mGrid[lastGA];
+ // no objects in cell == exit
+ if (ccidx = -1) then exit;
+ end;
+ // has something to process in this tile?
+ if (ccidx <> -1) then
+ begin
+ // process cell
+ curci := ccidx;
+ // convert coords to map (to avoid ajdusting coords inside the loop)
+ x := xptr^+minx;
+ y := yptr^+miny;
+ wasHit := false;
+ // process cell list
+ while (curci <> -1) do
+ begin
+ cc := @mCells[curci];
+ for f := 0 to GridCellBucketSize-1 do
+ begin
+ if (cc.bodies[f] = -1) then break;
+ px := @mProxies[cc.bodies[f]];
+ ptag := px.mTag;
+ if ((ptag and TagDisabled) = 0) and (px.mQueryMark <> lq) then
+ begin
+function lineAABBIntersects (x0, y0, x1, y1: Integer; bx, by, bw, bh: Integer; out inx, iny: Integer): Boolean;
+ // can we process this proxy?
+ if (x >= px.mX) and (y >= px.mY) and (x < px.mX+px.mWidth) and (y < px.mY+px.mHeight) then
+ begin
+ px.mQueryMark := lq; // mark as processed
+ if ((ptag and tagmask) = 0) then
+ begin
+ result := px.mObj;
+ ex := x;
+ ey := y;
+ exit;
+ end;
+ // march out of the panel/cell
+ while (xd <> term) do
+ begin
+ if (e >= 0) then begin yd += sty; e -= dx2; end else e += dy2;
+ xd += stx;
+ // new cell?
+ ga := (yptr^ div tsize)*gw+(xptr^ div tsize);
+ if (ga <> lastGA) then break;
+ // out of panel?
+ if not ((x >= px.mX) and (y >= px.mY) and (x < px.mX+px.mWidth) and (y < px.mY+px.mHeight)) then break;
+ end;
+ end;
+ end;
+ end;
+ // next cell
+ curci := cc.next;
+ end;
+ // still has something interesting in this cell?
+ if not hasUntried then
+ begin
+ // nope, don't process this cell anymore; signal cell completion
+ ccidx := -1;
+ if assigned(cb) then
+ begin
+ if cb(nil, 0, x, y, prevx, prevy) then begin result := lastObj; exit; end;
+ end
+ else if wasHit then
+ begin
+ result := lastObj;
+ exit;
+ end;
+ end;
+ end;
+ //putPixel(xptr^, yptr^);
+ // move coords
+ prevx := xptr^+minx;
+ prevy := yptr^+miny;
+ if (e >= 0) then begin yd += sty; e -= dx2; end else e += dy2;
+ xd += stx;
+ end;
+ // we can travel less than one cell
+ if wasHit and not assigned(cb) then
+ begin
+ result := lastObj;
+ end
+ else
+ begin
+ ex := ax1; // why not?
+ ey := ay1; // why not?
+ end;
+end;
+*)
+
+
end.
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 2c2a6b5c1a18c16e16c35cd2f4210eb79c5b6662..f0419bf49cf4314ad47ee168b1eb3fd78c87ad8a 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
TForEachPanelCB = function (pan: TPanel): Boolean; // return `true` to stop
function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean;
+function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel;
// trace liquid, stepping by `dx` and `dy`
// return last seen liquid coords, and `false` if we're started outside of the liquid
-function g_Map_TraceLiquid (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean;
+function g_Map_TraceLiquidNonPrecise (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean;
procedure g_Map_ProfilersBegin ();
end;
+function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel;
+begin
+ result := nil;
+ if (tagmask = 0) then exit;
+ result := mapGrid.forEachAtPoint(x, y, nil, tagmask);
+end;
+
+
function g_Map_IsSpecialTexture(Texture: String): Boolean;
begin
Result := (Texture = TEXTURE_NAME_WATER) or
// trace liquid, stepping by `dx` and `dy`
// return last seen liquid coords, and `false` if we're started outside of the liquid
-function g_Map_TraceLiquid (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean;
+function g_Map_TraceLiquidNonPrecise (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean;
const
MaskLiquid = GridTagWater or GridTagAcid1 or GridTagAcid2;
begin