diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 8e1068263bf2267005b9ab8f3f8adca6e0398eb4..29ece6fafd845f590715a7502689b9fc1dc2630a 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
end;
+function xxPanAtPointChecker (pan: TPanel; panelType: Word): Boolean; inline;
+begin
+ if ((pan.tag and GridTagLift) <> 0) then
+ begin
+ // stop if the lift of the right type
+ result :=
+ ((WordBool(PanelType and PANEL_LIFTUP) and (pan.LiftType = 0)) or
+ (WordBool(PanelType and PANEL_LIFTDOWN) and (pan.LiftType = 1)) or
+ (WordBool(PanelType and PANEL_LIFTLEFT) and (pan.LiftType = 2)) or
+ (WordBool(PanelType and PANEL_LIFTRIGHT) and (pan.LiftType = 3)));
+ exit;
+ end;
+ result := true; // otherwise, stop anyway, 'cause `forEachAtPoint()` is guaranteed to call this only for correct panels
+end;
+
function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean;
function checker (pan: TPanel; tag: Integer): Boolean;
var
tagmask: Integer = 0;
+ pmark: PoolMark;
+ hitcount: Integer;
+ ppan: PPanel;
begin
result := false;
if WordBool(PanelType and PANEL_BLOCKMON) then tagmask := tagmask or GridTagBlockMon;
if (tagmask = 0) then exit;// just in case
+
+ pmark := framePool.mark();
if ((tagmask and GridTagLift) <> 0) then
begin
// slow
- result := (mapGrid.forEachAtPoint(x, y, checker, tagmask) <> nil);
+ hitcount := mapGrid.forEachAtPoint(x, y, tagmask);
+ ppan := PPanel(framePool.getPtr(pmark));
+ while (hitcount > 0) do
+ begin
+ if (xxPanAtPointChecker(ppan^, PanelType)) then begin result := true; break; end;
+ Inc(ppan);
+ Dec(hitcount);
+ end;
end
else
begin
// fast
- result := (mapGrid.forEachAtPoint(x, y, nil, tagmask) <> nil);
+ result := (mapGrid.forEachAtPoint(x, y, tagmask, false, true) <> 0); // firsthit
end;
+ framePool.release(pmark);
end;
function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel;
+var
+ pmark: PoolMark;
+ hitcount: Integer;
begin
result := nil;
if (tagmask = 0) then exit;
- result := mapGrid.forEachAtPoint(x, y, nil, tagmask);
+ //result := mapGrid.forEachAtPoint(x, y, nil, tagmask);
+ pmark := framePool.mark();
+ hitcount := mapGrid.forEachAtPoint(x, y, tagmask, false, true); // firsthit
+ if (hitcount <> 0) then result := PPanel(framePool.getPtr(pmark))^;
+ framePool.release(pmark);
end;
topx := x;
topy := y;
// started outside of the liquid?
- if (mapGrid.forEachAtPoint(x, y, nil, MaskLiquid) = nil) then begin result := false; exit; end;
+ //if (mapGrid.forEachAtPoint(x, y, nil, MaskLiquid) = nil) then begin result := false; exit; end;
+ if (g_Map_PanelAtPoint(x, y, MaskLiquid) = nil) then begin result := false; exit; end;
if (dx = 0) and (dy = 0) then begin result := false; exit; end; // sanity check
result := true;
while true do
begin
Inc(x, dx);
Inc(y, dy);
- if (mapGrid.forEachAtPoint(x, y, nil, MaskLiquid) = nil) then exit; // out of the water, just exit
+ //if (mapGrid.forEachAtPoint(x, y, nil, MaskLiquid) = nil) then exit; // out of the water, just exit
+ if (g_Map_PanelAtPoint(x, y, MaskLiquid) = nil) then exit; // out of the water, just exit
topx := x;
topy := y;
end;