DEADSOFTWARE

fixed passing thru disabled walls
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Wed, 23 Aug 2017 20:30:15 +0000 (23:30 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Wed, 23 Aug 2017 20:31:26 +0000 (23:31 +0300)
  i completely fucked up map grid creation by inserting walls and
  doors twice (or even thrice). what a moron i am!

src/game/g_grid.pas
src/game/g_holmes.pas
src/game/g_map.pas
src/game/g_window.pas

index b1b157f8d3c685b3b65d457ed5620051d2bbb4dc..19c4d0d2ca8f31fc39170217693375c3d8cc5de2 100644 (file)
@@ -17,6 +17,7 @@
 {$INCLUDE ../shared/a_modes.inc}
 {$IF DEFINED(D2F_DEBUG)}
   {.$DEFINE D2F_DEBUG_RAYTRACE}
+  {.$DEFINE D2F_DEBUG_XXQ}
 {$ENDIF}
 unit g_grid;
 
@@ -142,12 +143,14 @@ type
     //         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 `true` on the nearest hit
+    //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;
 
     //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
+    //WARNING: don't change tags in callbacks here!
     function forEachAlongLine (const x0, y0, x1, y1: Integer; cb: TGridAlongQueryCB; tagmask: Integer=-1; log: Boolean=false): ITP;
 
     // debug
@@ -675,22 +678,42 @@ begin
   pc := mGrid[grida];
   if (pc <> -1) then
   begin
-    pi := @mCells[pc];
-    // check "has room" flag
-    if (pi.bodies[GridCellBucketSize-1] = -1) then
+    {$IF DEFINED(D2F_DEBUG)}
+    cidx := pc;
+    while (cidx <> -1) do
     begin
-      // can add here
+      pi := @mCells[cidx];
       for f := 0 to GridCellBucketSize-1 do
       begin
-        if (pi.bodies[f] = -1) then
+        if (pi.bodies[f] = -1) then break;
+        if (pi.bodies[f] = bodyId) then raise Exception.Create('trying to insert already inserted proxy');
+      end;
+      cidx := pi.next;
+    end;
+    {$ENDIF}
+    cidx := pc;
+    while (cidx <> -1) do
+    begin
+      pi := @mCells[cidx];
+      // check "has room" flag
+      if (pi.bodies[GridCellBucketSize-1] = -1) then
+      begin
+        // can add here
+        for f := 0 to GridCellBucketSize-1 do
         begin
-          pi.bodies[f] := bodyId;
-          if (f+1 < GridCellBucketSize) then pi.bodies[f+1] := -1;
-          exit;
+          if (pi.bodies[f] = -1) then
+          begin
+            pi.bodies[f] := bodyId;
+            if (f+1 < GridCellBucketSize) then pi.bodies[f+1] := -1;
+            exit;
+          end;
         end;
+        raise Exception.Create('internal error in grid inserter');
       end;
-      raise Exception.Create('internal error in grid inserter');
+      // no room, go to next cell in list (if there is any)
+      cidx := pi.next;
     end;
+    // no room in cells, add new cell to list
   end;
   // either no room, or no cell at all
   cidx := allocCell();
@@ -975,12 +998,21 @@ begin
   tagmask := tagmask and TagFullMask;
   if (tagmask = 0) then exit;
 
+  {$IF DEFINED(D2F_DEBUG_XXQ)}
+  if (assigned(cb)) then e_WriteLog(Format('0: grid pointquery: (%d,%d)', [x, y]), MSG_NOTIFY);
+  {$ENDIF}
+
   // make coords (0,0)-based
   Dec(x, mMinX);
   Dec(y, mMinY);
   if (x < 0) or (y < 0) or (x >= mWidth*mTileSize) or (y >= mHeight*mTileSize) then exit;
 
   curci := mGrid[(y div mTileSize)*mWidth+(x div mTileSize)];
+
+  {$IF DEFINED(D2F_DEBUG_XXQ)}
+  if (assigned(cb)) then e_WriteLog(Format('1: grid pointquery: (%d,%d) (%d,%d) %d', [x, y, (x div mTileSize), (y div mTileSize), curci]), MSG_NOTIFY);
+  {$ENDIF}
+
   // restore coords
   Inc(x, mMinX);
   Inc(y, mMinY);
@@ -995,19 +1027,31 @@ begin
   end;
   lq := mLastQuery;
 
+  {$IF DEFINED(D2F_DEBUG_XXQ)}
+  if (assigned(cb)) then e_WriteLog(Format('2: grid pointquery: (%d,%d); lq=%u', [x, y, lq]), MSG_NOTIFY);
+  {$ENDIF}
+
   while (curci <> -1) do
   begin
+    {$IF DEFINED(D2F_DEBUG_XXQ)}
+    if (assigned(cb)) then e_WriteLog(Format(' cell #%d', [curci]), MSG_NOTIFY);
+    {$ENDIF}
     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 ((ptag and tagmask) <> 0) and (px.mQueryMark <> lq) then
+      {$IF DEFINED(D2F_DEBUG_XXQ)}
+      if (assigned(cb)) then e_WriteLog(Format('  proxy #%d; qm:%u; tag:%08x; tagflag:%d  %u', [cc.bodies[f], px.mQueryMark, px.mTag, (px.mTag and tagmask), LongWord(px.mObj)]), MSG_NOTIFY);
+      {$ENDIF}
+      // shit. has to do it this way, so i can change tag in callback
+      if (px.mQueryMark <> lq) then
       begin
-        if (x >= px.mX) and (y >= px.mY) and (x < px.mX+px.mWidth) and (y < px.mY+px.mHeight) then
+        px.mQueryMark := lq;
+        ptag := px.mTag;
+        if ((ptag and TagDisabled) = 0) and ((ptag and tagmask) <> 0) and
+           (x >= px.mX) and (y >= px.mY) and (x < px.mX+px.mWidth) and (y < px.mY+px.mHeight) then
         begin
-          px.mQueryMark := lq;
           if assigned(cb) then
           begin
             if cb(px.mObj, ptag) then begin result := px.mObj; exit; end;
@@ -1089,24 +1133,22 @@ begin
         begin
           if (cc.bodies[f] = -1) then break;
           px := @mProxies[cc.bodies[f]];
+          // shit. has to do it this way, so i can change tag in callback
+          if (px.mQueryMark = lq) then continue;
+          px.mQueryMark := lq;
           ptag := px.mTag;
           if (not allowDisabled) and ((ptag and TagDisabled) <> 0) then continue;
-          if ((ptag and tagmask) <> 0) and (px.mQueryMark <> lq) then
-          //if ((ptag and TagDisabled) = 0) and ((ptag and tagmask) <> 0) and (px.mQueryMark <> lq) then
-          //if ( ((ptag and TagDisabled) = 0) = ignoreDisabled) and ((ptag and tagmask) <> 0) and (px.mQueryMark <> lq) then
+          if ((ptag and tagmask) = 0) then continue;
+          if (x0 >= px.mX+px.mWidth) or (y0 >= px.mY+px.mHeight) then continue;
+          if (x0+w <= px.mX) or (y0+h <= px.mY) then continue;
+          if assigned(cb) then
           begin
-            if (x0 >= px.mX+px.mWidth) or (y0 >= px.mY+px.mHeight) then continue;
-            if (x0+w <= px.mX) or (y0+h <= px.mY) then continue;
-            px.mQueryMark := lq;
-            if assigned(cb) then
-            begin
-              if cb(px.mObj, ptag) then begin result := px.mObj; exit; end;
-            end
-            else
-            begin
-              result := px.mObj;
-              exit;
-            end;
+            if cb(px.mObj, ptag) then begin result := px.mObj; exit; end;
+          end
+          else
+          begin
+            result := px.mObj;
+            exit;
           end;
         end;
         curci := cc.next;
index 37ade0969ba649690bfaecbb95c1821fa85842c3..d7ab6bfec15ac5484115a67a40a23b0f22d30b24 100644 (file)
@@ -159,6 +159,7 @@ begin
   laserY0 := ay0;
   laserX1 := ax1;
   laserY1 := ay1;
+  laserSet := laserSet; // shut up, fpc!
 end;
 
 
@@ -171,6 +172,7 @@ procedure plrDebugMouse (var ev: THMouseEvent);
   function wallToggle (pan: TPanel; tag: Integer): Boolean;
   begin
     result := false; // don't stop
+    e_WriteLog(Format('wall #%d(%d); enabled=%d (%d)', [pan.arrIdx, pan.proxyId, Integer(pan.Enabled), Integer(mapGrid.proxyEnabled[pan.proxyId])]), MSG_NOTIFY);
     if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
   end;
 
@@ -190,9 +192,11 @@ procedure plrDebugMouse (var ev: THMouseEvent);
 
 begin
   //e_WriteLog(Format('mouse: x=%d; y=%d; but=%d; bstate=%d', [msx, msy, but, bstate]), MSG_NOTIFY);
-  if (gPlayer1 = nil) then exit;
+  if (gPlayer1 = nil) or not vpSet then exit;
   if (ev.kind <> THMouseEvent.Press) then exit;
 
+  e_WriteLog(Format('mev: %d', [Integer(ev.kind)]), MSG_NOTIFY);
+
   if (ev.but = THMouseEvent.Left) then
   begin
     if ((kbS and THKeyEvent.ModShift) <> 0) then
@@ -205,7 +209,9 @@ begin
     else
     begin
       // toggle wall
+      e_WriteLog('=== TOGGLE WALL ===', MSG_NOTIFY);
       mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor));
+      e_WriteLog('--- toggle wall ---', MSG_NOTIFY);
     end;
     exit;
   end;
@@ -422,6 +428,7 @@ begin
   msY := ev.y;
   msB := ev.bstate;
   kbS := ev.kstate;
+  msB := msB;
   plrDebugMouse(ev);
 end;
 
index d41d6775e28e69a574fde58c1559f77bf77bd070..bbe1d6c3c7dc535a53ed9b84e1ffd31d84e459c1 100644 (file)
@@ -1124,18 +1124,40 @@ var
     end;
   end;
 
-  procedure addPanelsToGrid (constref panels: TPanelArray; tag: Integer);
+  procedure addPanelsToGrid (constref panels: TPanelArray);
   var
     idx: Integer;
     pan: TPanel;
+    newtag: Integer;
   begin
-    tag := panelTypeToTag(tag);
+    //tag := panelTypeToTag(tag);
     for idx := 0 to High(panels) do
     begin
       pan := panels[idx];
-      pan.tag := tag;
       if not pan.visvalid then continue;
-      pan.proxyId := mapGrid.insertBody(pan, pan.X, pan.Y, pan.Width, pan.Height, tag);
+      if (pan.proxyId <> -1) then
+      begin
+        {$IF DEFINED(D2F_DEBUG)}
+        e_WriteLog(Format('DUPLICATE wall #%d(%d) enabled (%d); type:%08x', [Integer(idx), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.PanelType]), MSG_NOTIFY);
+        {$ENDIF}
+        continue;
+      end;
+      case pan.PanelType of
+        PANEL_WALL: newtag := GridTagWall;
+        PANEL_OPENDOOR, PANEL_CLOSEDOOR: newtag := GridTagDoor;
+        PANEL_BACK: newtag := GridTagBack;
+        PANEL_FORE: newtag := GridTagFore;
+        PANEL_WATER: newtag := GridTagWater;
+        PANEL_ACID1: newtag := GridTagAcid1;
+        PANEL_ACID2: newtag := GridTagAcid2;
+        PANEL_STEP: newtag := GridTagStep;
+        PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: newtag := GridTagLift;
+        PANEL_BLOCKMON: newtag := GridTagBlockMon;
+        else continue; // oops
+      end;
+      pan.tag := newtag;
+
+      pan.proxyId := mapGrid.insertBody(pan, pan.X, pan.Y, pan.Width, pan.Height, newtag);
       // "enabled" flag has meaning only for doors and walls (engine assumes it); but meh...
       mapGrid.proxyEnabled[pan.proxyId] := pan.Enabled;
       {$IFDEF MAP_DEBUG_ENABLED_FLAG}
@@ -1173,17 +1195,15 @@ begin
 
   mapGrid := TPanelGrid.Create(mapX0-128, mapY0-128, mapX1-mapX0+1+128*2, mapY1-mapY0+1+128*2);
 
-  addPanelsToGrid(gWalls, PANEL_WALL);
-  addPanelsToGrid(gWalls, PANEL_CLOSEDOOR);
-  addPanelsToGrid(gWalls, PANEL_OPENDOOR);
-  addPanelsToGrid(gRenderBackgrounds, PANEL_BACK);
-  addPanelsToGrid(gRenderForegrounds, PANEL_FORE);
-  addPanelsToGrid(gWater, PANEL_WATER);
-  addPanelsToGrid(gAcid1, PANEL_ACID1);
-  addPanelsToGrid(gAcid2, PANEL_ACID2);
-  addPanelsToGrid(gSteps, PANEL_STEP);
-  addPanelsToGrid(gLifts, PANEL_LIFTUP); // it doesn't matter which LIFT type is used here
-  addPanelsToGrid(gBlockMon, PANEL_BLOCKMON);
+  addPanelsToGrid(gWalls);
+  addPanelsToGrid(gRenderBackgrounds);
+  addPanelsToGrid(gRenderForegrounds);
+  addPanelsToGrid(gWater);
+  addPanelsToGrid(gAcid1);
+  addPanelsToGrid(gAcid2);
+  addPanelsToGrid(gSteps);
+  addPanelsToGrid(gLifts); // it doesn't matter which LIFT type is used here
+  addPanelsToGrid(gBlockMon);
 
   mapGrid.dumpStats();
 
@@ -2390,7 +2410,7 @@ begin
   if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(gWalls[ID].PanelType, ID);
 
   {$IFDEF MAP_DEBUG_ENABLED_FLAG}
-  //e_WriteLog(Format('wall #%d(%d) enabled (%d)  (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY);
+  //e_WriteLog(Format('ENABLE: wall #%d(%d) enabled (%d)  (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY);
   {$ENDIF}
 end;
 
@@ -2408,7 +2428,7 @@ begin
   if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pan.PanelType, ID);
 
   {$IFDEF MAP_DEBUG_ENABLED_FLAG}
-  //e_WriteLog(Format('wall #%d(%d) disabled (%d)  (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY);
+  //e_WriteLog(Format('DISABLE: wall #%d(%d) disabled (%d)  (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY);
   {$ENDIF}
 end;
 
index f5249cc0e810e168e58409423eae45e306f9dc58..8578b70eabec5e305e83931ea42578ffb0663e58 100644 (file)
@@ -440,8 +440,7 @@ begin
         Result := True;
       end;
 
-    SDL_KEYDOWN,
-    SDL_KEYUP:
+    SDL_KEYDOWN, SDL_KEYUP:
       begin
         key := ev.key.keysym.scancode;
         if (g_holmes_enabled) then