X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_holmes.pas;h=3a50ffaba189b0355483ab7aa86d5eb26f4a009a;hb=9ab8e0d74b399aad6fd4793f427503bb857a4236;hp=007ffbb0be37380b2a7087e8fe1929a08b6aefca;hpb=27bcb8324b72ba67b2f6a43660fc5eecbb119750;p=d2df-sdl.git diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas index 007ffbb..3a50ffa 100644 --- a/src/game/g_holmes.pas +++ b/src/game/g_holmes.pas @@ -37,15 +37,15 @@ type WheelDown = $0010; // event types - Motion = 0; + Release = 0; Press = 1; - Release = 2; + Motion = 2; public kind: Byte; // motion, press, release x, y: Integer; dx, dy: Integer; // for wheel this is wheel motion, otherwise this is relative mouse motion - but: Word; // current pressed button or 0 + but: Word; // current pressed/released button, or 0 for motion bstate: Word; // button state kstate: Word; // keyboard state (see THKeyEvent); end; @@ -53,9 +53,21 @@ type THKeyEvent = record public const + // modifiers ModCtrl = $0001; ModAlt = $0002; ModShift = $0004; + + // event types + Release = 0; + Press = 1; + + public + kind: Byte; + scan: Word; // SDL_SCANCODE_XXX + sym: Word; // SDLK_XXX + bstate: Word; // button state + kstate: Word; // keyboard state end; @@ -64,8 +76,9 @@ procedure g_Holmes_WindowFocused (); procedure g_Holmes_WindowBlured (); procedure g_Holmes_Draw (); +procedure g_Holmes_DrawUI (); -function g_Holmes_mouseEvent (var ev: THMouseEvent): Boolean; // returns `true` if event was eaten +function g_Holmes_MouseEvent (var ev: THMouseEvent): Boolean; // returns `true` if event was eaten function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean; // returns `true` if event was eaten // hooks for player @@ -73,11 +86,15 @@ procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer) procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer); +var + g_holmes_enabled: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}false{$ENDIF}; + + implementation uses - SysUtils, GL, - g_options; + SysUtils, GL, SDL2, + MAPDEF, g_options; var @@ -86,116 +103,91 @@ var msY: Integer = -666; msB: Word = 0; // button state kbS: Word = 0; // keyboard modifiers state + showGrid: Boolean = true; + showMonsInfo: Boolean = false; + showMonsLOS2Plr: Boolean = false; + showAllMonsCells: Boolean = false; + showMapCurPos: Boolean = false; // ////////////////////////////////////////////////////////////////////////// // -// cursor (hi, Death Track!) -const curWidth = 17; -const curHeight = 23; - -const cursorImg: array[0..curWidth*curHeight-1] of Byte = ( - 0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,3,3,2,2,0,0,0,0,0,0,0,0,0,0,0, - 1,1,3,3,4,2,2,0,0,0,0,0,0,0,0,0,0, - 1,1,3,3,4,4,2,2,0,0,0,0,0,0,0,0,0, - 1,1,3,3,4,4,4,2,2,0,0,0,0,0,0,0,0, - 1,1,3,3,4,4,4,4,2,2,0,0,0,0,0,0,0, - 1,1,3,3,4,4,4,5,6,2,2,0,0,0,0,0,0, - 1,1,3,3,4,4,5,6,7,5,2,2,0,0,0,0,0, - 1,1,3,3,4,5,6,7,5,4,5,2,2,0,0,0,0, - 1,1,3,3,5,6,7,5,4,5,6,7,2,2,0,0,0, - 1,1,3,3,6,7,5,4,5,6,7,7,7,2,2,0,0, - 1,1,3,3,7,5,4,5,6,7,7,7,7,7,2,2,0, - 1,1,3,3,5,4,5,6,8,8,8,8,8,8,8,8,2, - 1,1,3,3,4,5,6,3,8,8,8,8,8,8,8,8,8, - 1,1,3,3,5,6,3,3,1,1,1,1,1,1,1,0,0, - 1,1,3,3,6,3,3,1,1,1,1,1,1,1,1,0,0, - 1,1,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0, - 1,1,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -); -const cursorPal: array[0..9*4-1] of Byte = ( - 0, 0, 0, 0, - 0, 0, 0,163, - 85,255,255,255, - 85, 85,255,255, - 255, 85, 85,255, - 170, 0,170,255, - 85, 85, 85,255, - 0, 0, 0,255, - 0, 0,170,255 -); - +{$INCLUDE g_holmes.inc} +{$INCLUDE g_holmes_ui.inc} -var - curtexid: GLuint = 0; -procedure createCursorTexture (); +// ////////////////////////////////////////////////////////////////////////// // var - tex, tpp: PByte; - c: Integer; - x, y: Integer; -begin - if (curtexid <> 0) then exit; //begin glDeleteTextures(1, @curtexid); curtexid := 0; end; + g_ol_nice: Boolean = false; + g_ol_rlayer_back: Boolean = false; + g_ol_rlayer_step: Boolean = false; + g_ol_rlayer_wall: Boolean = false; + g_ol_rlayer_door: Boolean = false; + g_ol_rlayer_acid1: Boolean = false; + g_ol_rlayer_acid2: Boolean = false; + g_ol_rlayer_water: Boolean = false; + g_ol_rlayer_fore: Boolean = false; - GetMem(tex, curWidth*curHeight*4); - - tpp := tex; - for y := 0 to curHeight-1 do - begin - for x := 0 to curWidth-1 do - begin - c := cursorImg[y*curWidth+x]*4; - tpp^ := cursorPal[c+0]; Inc(tpp); - tpp^ := cursorPal[c+1]; Inc(tpp); - tpp^ := cursorPal[c+2]; Inc(tpp); - tpp^ := cursorPal[c+3]; Inc(tpp); - end; - end; - glGenTextures(1, @curtexid); - if (curtexid = 0) then raise Exception.Create('can''t create Holmes texture'); +// ////////////////////////////////////////////////////////////////////////// // +var + winOptions: THTopWindow = nil; + winLayers: THTopWindow = nil; + winOutlines: THTopWindow = nil; - glBindTexture(GL_TEXTURE_2D, curtexid); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //GLfloat[4] bclr = 0.0; - //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr); +procedure createOptionsWindow (); +var + llb: THCtlCBListBox; +begin + llb := THCtlCBListBox.Create(0, 0); + llb.appendItem('map grid', @showGrid); + llb.appendItem('cursor position on map', @showMapCurPos); + llb.appendItem('monster info', @showMonsInfo); + llb.appendItem('monster LOS to player', @showMonsLOS2Plr); + llb.appendItem('monster cells (SLOW!)', @showAllMonsCells); + winOptions := THTopWindow.Create('Holmes Options', 100, 100); + winOptions.escClose := true; + winOptions.appendChild(llb); +end; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, curWidth, curHeight, 0, GL_RGBA{gltt}, GL_UNSIGNED_BYTE, tex); - //FreeMem(tex); +procedure createLayersWindow (); +var + llb: THCtlCBListBox; +begin + llb := THCtlCBListBox.Create(0, 0); + llb.appendItem('background', @g_rlayer_back); + llb.appendItem('steps', @g_rlayer_step); + llb.appendItem('walls', @g_rlayer_wall); + llb.appendItem('doors', @g_rlayer_door); + llb.appendItem('acid1', @g_rlayer_acid1); + llb.appendItem('acid2', @g_rlayer_acid2); + llb.appendItem('water', @g_rlayer_water); + llb.appendItem('foreground', @g_rlayer_fore); + winLayers := THTopWindow.Create('visible', 10, 10); + winLayers.escClose := true; + winLayers.appendChild(llb); end; -procedure drawCursor (); +procedure createOutlinesWindow (); +var + llb: THCtlCBListBox; begin - if (curtexid = 0) then createCursorTexture() else glBindTexture(GL_TEXTURE_2D, curtexid); - // blend it - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); - // color and opacity - glColor4f(1, 1, 1, 0.9); - Dec(msX, 2); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); glVertex2i(msX, msY); // top-left - glTexCoord2f(1.0, 0.0); glVertex2i(msX+curWidth, msY); // top-right - glTexCoord2f(1.0, 1.0); glVertex2i(msX+curWidth, msY+curHeight); // bottom-right - glTexCoord2f(0.0, 1.0); glVertex2i(msX, msY+curHeight); // bottom-left - glEnd(); - Inc(msX, 2); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glColor4f(1, 1, 1, 1); - glBindTexture(GL_TEXTURE_2D, 0); + llb := THCtlCBListBox.Create(0, 0); + llb.appendItem('background', @g_ol_rlayer_back); + llb.appendItem('steps', @g_ol_rlayer_step); + llb.appendItem('walls', @g_ol_rlayer_wall); + llb.appendItem('doors', @g_ol_rlayer_door); + llb.appendItem('acid1', @g_ol_rlayer_acid1); + llb.appendItem('acid2', @g_ol_rlayer_acid2); + llb.appendItem('water', @g_ol_rlayer_water); + llb.appendItem('foreground', @g_ol_rlayer_fore); + llb.appendItem('', nil); + llb.appendItem('slow''n''nice', @g_ol_nice); + winOutlines := THTopWindow.Create('outlines', 100, 10); + winOutlines.escClose := true; + winOutlines.appendChild(llb); end; @@ -203,7 +195,12 @@ end; procedure g_Holmes_VidModeChanged (); begin e_WriteLog(Format('Inspector: videomode changed: %dx%d', [gScreenWidth, gScreenHeight]), MSG_NOTIFY); - curtexid := 0; // texture is possibly lost here, idc + // texture space is possibly lost here, idc + curtexid := 0; + font6texid := 0; + font8texid := 0; + prfont6texid := 0; + prfont8texid := 0; //createCursorTexture(); end; @@ -227,6 +224,7 @@ var laserX0, laserY0, laserX1, laserY1: Integer; monMarkedUID: Integer = -1; + procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer); begin vpSet := true; @@ -243,6 +241,7 @@ begin laserY0 := ay0; laserX1 := ax1; laserY1 := ay1; + laserSet := laserSet; // shut up, fpc! end; @@ -255,7 +254,11 @@ procedure plrDebugMouse (var ev: THMouseEvent); function wallToggle (pan: TPanel; tag: Integer): Boolean; begin result := false; // don't stop - if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx); + e_WriteLog(Format('wall #%d(%d); enabled=%d (%d); (%d,%d)-(%d,%d)', [pan.arrIdx, pan.proxyId, Integer(pan.Enabled), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.X, pan.Y, pan.Width, pan.Height]), MSG_NOTIFY); + if ((kbS and THKeyEvent.ModAlt) <> 0) then + begin + if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx); + end; end; function monsAtDump (mon: TMonster; tag: Integer): Boolean; @@ -266,14 +269,35 @@ procedure plrDebugMouse (var ev: THMouseEvent); //if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx); end; + function monsInCell (mon: TMonster; tag: Integer): Boolean; + begin + result := false; // don't stop + e_WriteLog(Format('monster #%d (UID:%u) (proxyid:%d)', [mon.arrIdx, mon.UID, mon.proxyId]), MSG_NOTIFY); + end; + 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 - mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor)); + if ((kbS and THKeyEvent.ModShift) <> 0) then + begin + // dump monsters in cell + e_WriteLog('===========================', MSG_NOTIFY); + monsGrid.forEachInCell(pmsCurMapX, pmsCurMapY, monsInCell); + e_WriteLog('---------------------------', MSG_NOTIFY); + end + 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; @@ -288,8 +312,53 @@ begin end; +var + olEdgeL: array of Boolean = nil; + olEdgeR: array of Boolean = nil; + olEdgeU: array of Boolean = nil; + olEdgeD: array of Boolean = nil; + +procedure drawOutlines (); +begin +end; + + procedure plrDebugDraw (); + procedure drawTileGrid (); + var + x, y: Integer; + begin + for y := 0 to (mapGrid.gridHeight div mapGrid.tileSize) do + begin + drawLine(mapGrid.gridX0, mapGrid.gridY0+y*mapGrid.tileSize, mapGrid.gridX0+mapGrid.gridWidth, mapGrid.gridY0+y*mapGrid.tileSize, 96, 96, 96, 255); + end; + + for x := 0 to (mapGrid.gridWidth div mapGrid.tileSize) do + begin + drawLine(mapGrid.gridX0+x*mapGrid.tileSize, mapGrid.gridY0, mapGrid.gridX0+x*mapGrid.tileSize, mapGrid.gridY0+y*mapGrid.gridHeight, 96, 96, 96, 255); + end; + end; + + procedure hilightCell (cx, cy: Integer); + begin + fillRect(cx, cy, monsGrid.tileSize, monsGrid.tileSize, 0, 128, 0, 64); + end; + + procedure hilightCell1 (cx, cy: Integer); + begin + //e_WriteLog(Format('h1: (%d,%d)', [cx, cy]), MSG_NOTIFY); + fillRect(cx, cy, monsGrid.tileSize, monsGrid.tileSize, 255, 255, 0, 92); + end; + + function hilightWallTrc (pan: TPanel; tag: Integer; x, y, prevx, prevy: Integer): Boolean; + begin + result := false; // don't stop + if (pan = nil) then exit; // cell completion, ignore + //e_WriteLog(Format('h1: (%d,%d)', [cx, cy]), MSG_NOTIFY); + fillRect(pan.X, pan.Y, pan.Width, pan.Height, 0, 128, 128, 64); + end; + function monsCollector (mon: TMonster; tag: Integer): Boolean; var ex, ey: Integer; @@ -304,19 +373,124 @@ procedure plrDebugDraw (); end; end; + procedure drawMonsterInfo (mon: TMonster); + var + mx, my, mw, mh: Integer; + + procedure drawMonsterTargetLine (); + var + emx, emy, emw, emh: Integer; + enemy: TMonster; + eplr: TPlayer; + ex, ey: Integer; + begin + if (g_GetUIDType(mon.MonsterTargetUID) = UID_PLAYER) then + begin + eplr := g_Player_Get(mon.MonsterTargetUID); + if (eplr <> nil) then eplr.getMapBox(emx, emy, emw, emh) else exit; + end + else if (g_GetUIDType(mon.MonsterTargetUID) = UID_MONSTER) then + begin + enemy := g_Monsters_ByUID(mon.MonsterTargetUID); + if (enemy <> nil) then enemy.getMapBox(emx, emy, emw, emh) else exit; + end + else + begin + exit; + end; + mon.getMapBox(mx, my, mw, mh); + drawLine(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, 255, 0, 0, 255); + if (g_Map_traceToNearestWall(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, @ex, @ey) <> nil) then + begin + drawLine(mx+mw div 2, my+mh div 2, ex, ey, 0, 255, 0, 255); + end; + end; + + procedure drawLOS2Plr (); + var + emx, emy, emw, emh: Integer; + eplr: TPlayer; + ex, ey: Integer; + begin + eplr := gPlayers[0]; + if (eplr = nil) then exit; + eplr.getMapBox(emx, emy, emw, emh); + mon.getMapBox(mx, my, mw, mh); + drawLine(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, 255, 0, 0, 255); + {$IF DEFINED(D2F_DEBUG)} + //mapGrid.dbgRayTraceTileHitCB := hilightCell1; + {$ENDIF} + if (g_Map_traceToNearestWall(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, @ex, @ey) <> nil) then + //if (mapGrid.traceRay(ex, ey, mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, hilightWallTrc, (GridTagWall or GridTagDoor)) <> nil) then + begin + drawLine(mx+mw div 2, my+mh div 2, ex, ey, 0, 255, 0, 255); + end; + {$IF DEFINED(D2F_DEBUG)} + //mapGrid.dbgRayTraceTileHitCB := nil; + {$ENDIF} + end; + + begin + if (mon = nil) then exit; + mon.getMapBox(mx, my, mw, mh); + //mx += mw div 2; + + monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + + if showMonsInfo then + begin + //fillRect(mx-4, my-7*8-6, 110, 7*8+6, 0, 0, 94, 250); + darkenRect(mx-4, my-7*8-6, 110, 7*8+6, 128); + my -= 8; + my -= 2; + + // type + drawText6(mx, my, Format('%s(U:%u)', [monsTypeToString(mon.MonsterType), mon.UID]), 255, 127, 0); my -= 8; + // beh + drawText6(mx, my, Format('Beh: %s', [monsBehToString(mon.MonsterBehaviour)]), 255, 127, 0); my -= 8; + // state + drawText6(mx, my, Format('State:%s (%d)', [monsStateToString(mon.MonsterState), mon.MonsterSleep]), 255, 127, 0); my -= 8; + // health + drawText6(mx, my, Format('Health:%d', [mon.MonsterHealth]), 255, 127, 0); my -= 8; + // ammo + drawText6(mx, my, Format('Ammo:%d', [mon.MonsterAmmo]), 255, 127, 0); my -= 8; + // target + drawText6(mx, my, Format('TgtUID:%u', [mon.MonsterTargetUID]), 255, 127, 0); my -= 8; + drawText6(mx, my, Format('TgtTime:%d', [mon.MonsterTargetTime]), 255, 127, 0); my -= 8; + end; + + drawMonsterTargetLine(); + if showMonsLOS2Plr then drawLOS2Plr(); + { + property MonsterRemoved: Boolean read FRemoved write FRemoved; + property MonsterPain: Integer read FPain write FPain; + property MonsterAnim: Byte read FCurAnim write FCurAnim; + } + end; + + function highlightAllMonsterCells (mon: TMonster): Boolean; + begin + result := false; // don't stop + monsGrid.forEachBodyCell(mon.proxyId, hilightCell); + end; + var mon: TMonster; mx, my, mw, mh: Integer; begin - //e_DrawPoint(4, plrMouseX, plrMouseY, 255, 0, 255); if (gPlayer1 = nil) then exit; - //e_WriteLog(Format('(%d,%d)-(%d,%d)', [laserX0, laserY0, laserX1, laserY1]), MSG_NOTIFY); + glEnable(GL_SCISSOR_TEST); + glScissor(0, gWinSizeY-gPlayerScreenSize.Y-1, vpw, vph); glPushMatrix(); glTranslatef(-vpx, -vpy, 0); - g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true); + drawOutlines(); + + if (showGrid) then drawTileGrid(); + + if (laserSet) then g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true); if (monMarkedUID <> -1) then begin @@ -325,54 +499,175 @@ begin begin mon.getMapBox(mx, my, mw, mh); e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 0, 0, 30); + drawMonsterInfo(mon); end; end; - //e_DrawPoint(16, laserX0, laserY0, 255, 255, 255); + if showAllMonsCells then g_Mons_ForEach(highlightAllMonsterCells); glPopMatrix(); -end; + glDisable(GL_SCISSOR_TEST); -{ - procedure drawTileGrid (); - var - x, y: Integer; - begin - y := mapGrid.gridY0; - while (y < mapGrid.gridY0+mapGrid.gridHeight) do - begin - x := mapGrid.gridX0; - while (x < mapGrid.gridX0+mapGrid.gridWidth) do - begin - if (x+mapGrid.tileSize > vpx) and (y+mapGrid.tileSize > vpy) and - (x < vpx+vpw) and (y < vpy+vph) then - begin - e_DrawQuad(x, y, x+mapGrid.tileSize-1, y+mapGrid.tileSize-1, 96, 96, 96, 96); - end; - Inc(x, mapGrid.tileSize); - end; - Inc(y, mapGrid.tileSize); - end; - end; -} + if showMapCurPos then drawText8(4, gWinSizeY-10, Format('mappos:(%d,%d)', [pmsCurMapX, pmsCurMapY]), 255, 255, 0); +end; // ////////////////////////////////////////////////////////////////////////// // -function g_Holmes_mouseEvent (var ev: THMouseEvent): Boolean; +function g_Holmes_MouseEvent (var ev: THMouseEvent): Boolean; begin result := true; msX := ev.x; msY := ev.y; msB := ev.bstate; kbS := ev.kstate; - plrDebugMouse(ev); + msB := msB; + if not uiMouseEvent(ev) then plrDebugMouse(ev); end; function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean; +var + mon: TMonster; + pan: TPanel; + x, y, w, h: Integer; + ex, ey: Integer; + dx, dy: Integer; + + procedure dummyWallTrc (cx, cy: Integer); + begin + end; + begin result := false; + msB := ev.bstate; + kbS := ev.kstate; + case ev.scan of + SDL_SCANCODE_LCTRL, SDL_SCANCODE_RCTRL, + SDL_SCANCODE_LALT, SDL_SCANCODE_RALT, + SDL_SCANCODE_LSHIFT, SDL_SCANCODE_RSHIFT: + result := true; + end; + if uiKeyEvent(ev) then begin result := true; exit; end; + // press + if (ev.kind = THKeyEvent.Press) then + begin + // M-M: one monster think step + if (ev.scan = SDL_SCANCODE_M) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + begin + result := true; + gmon_debug_think := false; + gmon_debug_one_think_step := true; // do one step + exit; + end; + // M-I: toggle monster info + if (ev.scan = SDL_SCANCODE_I) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + begin + result := true; + showMonsInfo := not showMonsInfo; + exit; + end; + // M-L: toggle monster LOS to player + if (ev.scan = SDL_SCANCODE_L) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + begin + result := true; + showMonsLOS2Plr := not showMonsLOS2Plr; + exit; + end; + // M-G: toggle "show all cells occupied by monsters" + if (ev.scan = SDL_SCANCODE_G) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + begin + result := true; + showAllMonsCells := not showAllMonsCells; + exit; + end; + // M-A: wake up monster + if (ev.scan = SDL_SCANCODE_A) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then + begin + result := true; + if (monMarkedUID <> -1) then + begin + mon := g_Monsters_ByUID(monMarkedUID); + if (mon <> nil) then mon.WakeUp(); + end; + exit; + end; + // C-T: teleport player + if (ev.scan = SDL_SCANCODE_T) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + begin + result := true; + //e_WriteLog(Format('TELEPORT: (%d,%d)', [pmsCurMapX, pmsCurMapY]), MSG_NOTIFY); + if (gPlayers[0] <> nil) then + begin + gPlayers[0].getMapBox(x, y, w, h); + gPlayers[0].TeleportTo(pmsCurMapX-w div 2, pmsCurMapY-h div 2, true, 69); // 69: don't change dir + end; + exit; + end; + // C-P: show cursor position on the map + if (ev.scan = SDL_SCANCODE_P) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + begin + result := true; + showMapCurPos := not showMapCurPos; + exit; + end; + // C-G: toggle grid + if (ev.scan = SDL_SCANCODE_G) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + begin + result := true; + showGrid := not showGrid; + exit; + end; + // C-L: toggle layers window + if (ev.scan = SDL_SCANCODE_L) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + begin + result := true; + if (winLayers = nil) then createLayersWindow(); + if not uiVisibleWindow(winLayers) then uiAddWindow(winLayers) else uiRemoveWindow(winLayers); + exit; + end; + // C-O: toggle outlines window + if (ev.scan = SDL_SCANCODE_O) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + begin + result := true; + if (winOutlines = nil) then createOutlinesWindow(); + if not uiVisibleWindow(winOutlines) then uiAddWindow(winOutlines) else uiRemoveWindow(winOutlines); + exit; + end; + // F1: toggle options window + if (ev.scan = SDL_SCANCODE_F1) and (ev.kstate = 0) then + begin + result := true; + if (winOptions = nil) then createOptionsWindow(); + if not uiVisibleWindow(winOptions) then uiAddWindow(winOptions) else uiRemoveWindow(winOptions); + exit; + end; + // C-UP, C-DOWN, C-LEFT, C-RIGHT: trace 10 pixels from cursor in the respective direction + if ((ev.scan = SDL_SCANCODE_UP) or (ev.scan = SDL_SCANCODE_DOWN) or (ev.scan = SDL_SCANCODE_LEFT) or (ev.scan = SDL_SCANCODE_RIGHT)) and + ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then + begin + result := true; + dx := pmsCurMapX; + dy := pmsCurMapY; + case ev.scan of + SDL_SCANCODE_UP: dy -= 120; + SDL_SCANCODE_DOWN: dy += 120; + SDL_SCANCODE_LEFT: dx -= 120; + SDL_SCANCODE_RIGHT: dx += 120; + end; + {$IF DEFINED(D2F_DEBUG)} + //mapGrid.dbgRayTraceTileHitCB := dummyWallTrc; + mapGrid.dbgShowTraceLog := true; + {$ENDIF} + pan := g_Map_traceToNearest(pmsCurMapX, pmsCurMapY, dx, dy, (GridTagWall or GridTagDoor or GridTagStep or GridTagAcid1 or GridTagAcid2 or GridTagWater), @ex, @ey); + {$IF DEFINED(D2F_DEBUG)} + //mapGrid.dbgRayTraceTileHitCB := nil; + mapGrid.dbgShowTraceLog := false; + {$ENDIF} + e_LogWritefln('v-trace: (%d,%d)-(%d,%d); end=(%d,%d); hit=%d', [pmsCurMapX, pmsCurMapY, dx, dy, ex, ey, (pan <> nil)]); + exit; + end; + end; end; @@ -385,8 +680,18 @@ begin glDisable(GL_SCISSOR_TEST); glDisable(GL_TEXTURE_2D); - plrDebugDraw(); + if gGameOn then + begin + plrDebugDraw(); + end; + laserSet := false; +end; + + +procedure g_Holmes_DrawUI (); +begin + uiDraw(); drawCursor(); end;