From a17222535319cb4089e3f9a92711731c015819b3 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Wed, 23 Aug 2017 23:30:15 +0300 Subject: [PATCH] fixed passing thru disabled walls 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 | 98 ++++++++++++++++++++++++++++++------------- src/game/g_holmes.pas | 9 +++- src/game/g_map.pas | 54 ++++++++++++++++-------- src/game/g_window.pas | 3 +- 4 files changed, 116 insertions(+), 48 deletions(-) diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas index b1b157f..19c4d0d 100644 --- a/src/game/g_grid.pas +++ b/src/game/g_grid.pas @@ -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; diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas index 37ade09..d7ab6bf 100644 --- a/src/game/g_holmes.pas +++ b/src/game/g_holmes.pas @@ -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; diff --git a/src/game/g_map.pas b/src/game/g_map.pas index d41d677..bbe1d6c 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -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; diff --git a/src/game/g_window.pas b/src/game/g_window.pas index f5249cc..8578b70 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -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 -- 2.29.2