X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=b84bf3aaca6170f165147659879aa9e2971c8f28;hb=7869ee331ead2e3f765af47eeca1566ed97faa19;hp=b2e35c0eb0b3044abc5308cd98354f286651a9c8;hpb=422b1bad780adc75cee9edc8ef16092f29181951;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index b2e35c0..b84bf3a 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -13,15 +13,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *) -{$MODE DELPHI} -{$modeswitch nestedprocvars} +{$INCLUDE ../shared/a_modes.inc} unit g_map; interface uses e_graphics, g_basic, MAPSTRUCT, g_textures, Classes, - g_phys, wadreader, BinEditor, g_panel, g_grid, md5; + g_phys, wadreader, BinEditor, g_panel, g_grid, md5, xprofiler; type TMapInfo = record @@ -91,6 +90,9 @@ procedure g_Map_LoadState(Var Mem: TBinMemoryReader); procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: Integer); +procedure g_Map_ProfilersBegin (); +procedure g_Map_ProfilersEnd (); + const RESPAWNPOINT_PLAYER1 = 1; RESPAWNPOINT_PLAYER2 = 2; @@ -131,7 +133,10 @@ var gWADHash: TMD5Digest; BackID: DWORD = DWORD(-1); gExternalResources: TStringList; - gMapGrid: TBodyGrid = nil; + + gdbg_map_use_grid_render: Boolean = true; + gdbg_map_use_grid_coldet: Boolean = true; + profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY! implementation @@ -149,6 +154,35 @@ const MUSIC_SIGNATURE = $4953554D; // 'MUSI' FLAG_SIGNATURE = $47414C46; // 'FLAG' + GridTagInvalid = -1; + GridTagWallDoor = 0; + GridTagBack = 1; + GridTagFore = 2; + GridTagWater = 3; + GridTagAcid1 = 4; + GridTagAcid2 = 5; + GridTagStep = 6; + GridTagLift = 7; + GridTagBlockMon = 8; + + +function panelTypeToTag (panelType: Word): Integer; +begin + case panelType of + PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: result := GridTagWallDoor; // gWalls + PANEL_BACK: result := GridTagBack; // gRenderBackgrounds + PANEL_FORE: result := GridTagFore; // gRenderForegrounds + PANEL_WATER: result := GridTagWater; // gWater + PANEL_ACID1: result := GridTagAcid1; // gAcid1 + PANEL_ACID2: result := GridTagAcid2; // gAcid2 + PANEL_STEP: result := GridTagStep; // gSteps + PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: result := GridTagLift; // gLifts -- this is for all lifts + PANEL_BLOCKMON: result := GridTagBlockMon; // gBlockMon -- this is for all blockmons + else result := GridTagInvalid; + end; +end; + + type TPanelID = record PWhere: ^TPanelArray; @@ -161,6 +195,27 @@ var RespawnPoints: Array of TRespawnPoint; FlagPoints: Array [FLAG_RED..FLAG_BLUE] of PFlagPoint; //DOMFlagPoints: Array of TFlagPoint; + gMapGrid: TBodyGrid = nil; + + +procedure g_Map_ProfilersBegin (); +begin + if (profMapCollision = nil) then profMapCollision := TProfiler.Create('MAP COLLISION'); + profMapCollision.mainBegin(g_profile_collision); + // create sections + if g_profile_collision then + begin + profMapCollision.sectionBeginAccum('wall coldet'); + profMapCollision.sectionEnd(); + profMapCollision.sectionBeginAccum('liquid coldet'); + profMapCollision.sectionEnd(); + end; +end; + +procedure g_Map_ProfilersEnd (); +begin + if (profMapCollision <> nil) then profMapCollision.mainEnd(); +end; function g_Map_IsSpecialTexture(Texture: String): Boolean; @@ -900,6 +955,73 @@ begin addResToExternalResList(mapHeader.SkyName); end; +procedure mapCreateGrid (); +var + mapX0: Integer = $3fffffff; + mapY0: Integer = $3fffffff; + mapX1: Integer = -$3fffffff; + mapY1: Integer = -$3fffffff; + + procedure fixMinMax (var panels: TPanelArray); + var + idx: Integer; + begin + for idx := 0 to High(panels) do + begin + if (panels[idx].Width < 1) or (panels[idx].Height < 1) then continue; + if mapX0 > panels[idx].X then mapX0 := panels[idx].X; + if mapY0 > panels[idx].Y then mapY0 := panels[idx].Y; + if mapX1 < panels[idx].X+panels[idx].Width-1 then mapX1 := panels[idx].X+panels[idx].Width-1; + if mapY1 < panels[idx].Y+panels[idx].Height-1 then mapY1 := panels[idx].Y+panels[idx].Height-1; + end; + end; + + procedure addPanelsToGrid (var panels: TPanelArray; tag: Integer); + var + idx: Integer; + begin + tag := panelTypeToTag(tag); + for idx := High(panels) downto 0 do + begin + gMapGrid.insertBody(panels[idx], panels[idx].X, panels[idx].Y, panels[idx].Width, panels[idx].Height, tag); + end; + end; + +begin + gMapGrid.Free(); + gMapGrid := nil; + + fixMinMax(gWalls); + fixMinMax(gRenderBackgrounds); + fixMinMax(gRenderForegrounds); + fixMinMax(gWater); + fixMinMax(gAcid1); + fixMinMax(gAcid2); + fixMinMax(gSteps); + fixMinMax(gLifts); + fixMinMax(gBlockMon); + + if (mapX0 < 0) or (mapY0 < 0) then + begin + e_WriteLog(Format('funny map dimensions: (%d,%d)-(%d,%d)', [mapX0, mapY0, mapX1, mapY1]), MSG_WARNING); + //raise Exception.Create('we are fucked'); + end; + + gMapGrid := TBodyGrid.Create(mapX0, mapY0, mapX1-mapX0+1, mapY1-mapY0+1); + + addPanelsToGrid(gWalls, PANEL_WALL); // and PANEL_CLOSEDOOR + 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); + + gMapGrid.dumpStats(); +end; + function g_Map_Load(Res: String): Boolean; const DefaultMusRes = 'Standart.wad:STDMUS\MUS1'; @@ -931,35 +1053,6 @@ var ok, isAnim, trigRef: Boolean; CurTex, ntn: Integer; - mapX0: Integer = $3fffffff; - mapY0: Integer = $3fffffff; - mapX1: Integer = -$3fffffff; - mapY1: Integer = -$3fffffff; - - procedure fixMinMax (var panels: TPanelArray); - var - idx: Integer; - begin - for idx := 0 to High(panels) do - begin - if (panels[idx].Width < 1) or (panels[idx].Height < 1) then continue; - if mapX0 > panels[idx].X then mapX0 := panels[idx].X; - if mapY0 > panels[idx].Y then mapY0 := panels[idx].Y; - if mapX1 < panels[idx].X+panels[idx].Width-1 then mapX1 := panels[idx].X+panels[idx].Width-1; - if mapY1 < panels[idx].Y+panels[idx].Height-1 then mapY1 := panels[idx].Y+panels[idx].Height-1; - end; - end; - - procedure addPanelsToGrid (var panels: TPanelArray; tag: Integer); - var - idx: Integer; - begin - for idx := High(panels) downto 0 do - begin - gMapGrid.insertBody(panels[idx], panels[idx].X, panels[idx].Y, panels[idx].Width, panels[idx].Height, tag); - end; - end; - begin gMapGrid.Free(); gMapGrid := nil; @@ -1431,26 +1524,7 @@ begin end; e_WriteLog('Creating map grid', MSG_NOTIFY); - - fixMinMax(gWalls); - fixMinMax(gRenderBackgrounds); - fixMinMax(gRenderForegrounds); - fixMinMax(gWater); - fixMinMax(gAcid1); - fixMinMax(gAcid2); - fixMinMax(gSteps); - - gMapGrid := TBodyGrid.Create(mapX1+1, mapY1+1); - - addPanelsToGrid(gWalls, PANEL_WALL); // and PANEL_CLOSEDOOR - addPanelsToGrid(gRenderBackgrounds, PANEL_BACK); - addPanelsToGrid(gRenderForegrounds, PANEL_FORE); - addPanelsToGrid(gWater, PANEL_WATER); - addPanelsToGrid(gAcid1, PANEL_ACID1); - addPanelsToGrid(gAcid2, PANEL_ACID2); - addPanelsToGrid(gSteps, PANEL_STEP); - - gMapGrid.dumpStats(); + mapCreateGrid(); e_WriteLog('Done loading map.', MSG_NOTIFY); Result := True; @@ -1736,23 +1810,6 @@ begin end; -{ -function pvpType (panelType: Word): Integer; -begin - case panelType of - PANEL_WALL, PANEL_CLOSEDOOR: result := 0; // gWalls - PANEL_BACK: result := 1; // gRenderBackgrounds - PANEL_FORE: result := 2; // gRenderForegrounds - PANEL_WATER: result := 3; // gWater - PANEL_ACID1: result := 4; // gAcid1 - PANEL_ACID2: result := 5; // gAcid2 - PANEL_STEP: result := 6; // gSteps - else result := -1; - end; -end; -} - - procedure g_Map_DrawPanelsOld(PanelType: Word); procedure DrawPanels (stp: Integer; var panels: TPanelArray; drawDoors: Boolean=False); @@ -1804,57 +1861,26 @@ end; procedure g_Map_DrawPanels(x0, y0, wdt, hgt: Integer; PanelType: Word); +var + ptag: Integer; - function qq (obj: TObject; tag: Integer): Boolean; + function checker (obj: TObject; tag: Integer): Boolean; var pan: TPanel; begin result := false; // don't stop, ever - + if (tag <> ptag) then exit; //e_WriteLog(Format(' *body: tag:%d; qtag:%d', [tag, PanelType]), MSG_NOTIFY); - if obj = nil then - begin - e_WriteLog(Format(' !bodyFUUUUU0: tag:%d; qtag:%d', [tag, PanelType]), MSG_NOTIFY); - end; - if not (obj is TPanel) then - begin - e_WriteLog(Format(' !bodyFUUUUU1: tag:%d; qtag:%d', [tag, PanelType]), MSG_NOTIFY); - exit; - end; - //pan := (obj as TPanel); - //e_WriteLog(Format(' !body: (%d,%d)-(%dx%d) tag:%d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); + if obj = nil then begin e_WriteLog(Format(' !bodyFUUUUU0: tag:%d; qtag:%d', [tag, PanelType]), MSG_NOTIFY); exit; end; + if not (obj is TPanel) then begin e_WriteLog(Format(' !bodyFUUUUU1: tag:%d; qtag:%d', [tag, PanelType]), MSG_NOTIFY); exit; end; + //pan := (obj as TPanel); + //e_WriteLog(Format(' !body: (%d,%d)-(%dx%d) tag:%d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); - if (tag = PANEL_WALL) then - begin - if (PanelType = PANEL_WALL) then - begin - pan := (obj as TPanel); - if not pan.Door then - begin - //e_WriteLog(Format(' body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); - dplAddPanel(pan); - end; - end - else if (PanelType = PANEL_CLOSEDOOR) then - begin - pan := (obj as TPanel); - if pan.Door then - begin - //e_WriteLog(Format(' body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); - dplAddPanel(pan); - end; - end - end - else if (PanelType = tag) then - begin - pan := (obj as TPanel); - if not pan.Door then - begin - //e_WriteLog(Format(' body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); - dplAddPanel(pan); - end; - end; + pan := (obj as TPanel); + if (PanelType = PANEL_CLOSEDOOR) then begin if not pan.Door then exit; end else begin if pan.Door then exit; end; + //e_WriteLog(Format(' body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, tag, PanelType]), MSG_NOTIFY); + dplAddPanel(pan); end; procedure DrawPanels (stp: Integer; var panels: TPanelArray; drawDoors: Boolean=False); @@ -1870,10 +1896,13 @@ procedure g_Map_DrawPanels(x0, y0, wdt, hgt: Integer; PanelType: Word); if not (drawDoors xor panels[idx].Door) then begin pan := panels[idx]; + { if (pan.Width < 1) or (pan.Height < 1) then continue; if (pan.X+pan.Width <= x0) or (pan.Y+pan.Height <= y0) then continue; if (pan.X >= x0+wdt) or (pan.Y >= y0+hgt) then continue; - e_WriteLog(Format(' *body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, PanelType, PanelType]), MSG_NOTIFY); + } + pan.Draw(); + //e_WriteLog(Format(' *body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, PanelType, PanelType]), MSG_NOTIFY); end; end; end; @@ -1884,46 +1913,50 @@ begin //e_WriteLog('==================', MSG_NOTIFY); //e_WriteLog(Format('***QQQ: qtag:%d', [PanelType]), MSG_NOTIFY); dplClear(); - gMapGrid.forEachInAABB(x0, y0, wdt, hgt, qq); - - // debug - { - e_WriteLog(Format('+++QQQ: qtag:%d', [PanelType]), MSG_NOTIFY); - case PanelType of - PANEL_WALL: DrawPanels(0, gWalls); - PANEL_CLOSEDOOR: DrawPanels(0, gWalls, True); - PANEL_BACK: DrawPanels(1, gRenderBackgrounds); - PANEL_FORE: DrawPanels(2, gRenderForegrounds); - PANEL_WATER: DrawPanels(3, gWater); - PANEL_ACID1: DrawPanels(4, gAcid1); - PANEL_ACID2: DrawPanels(5, gAcid2); - PANEL_STEP: DrawPanels(6, gSteps); - end; - e_WriteLog('==================', MSG_NOTIFY); - } + ptag := panelTypeToTag(PanelType); - // sort and draw the list (we need to sort it, or rendering is fucked) - while gDrawPanelList.count > 0 do + if gdbg_map_use_grid_render then + begin + gMapGrid.forEachInAABB(x0, y0, wdt, hgt, checker); + // sort and draw the list (we need to sort it, or rendering is fucked) + while gDrawPanelList.count > 0 do + begin + (gDrawPanelList.front() as TPanel).Draw(); + gDrawPanelList.popFront(); + end; + end + else begin - (gDrawPanelList.front() as TPanel).Draw(); - gDrawPanelList.popFront(); + //e_WriteLog(Format('+++QQQ: qtag:%d', [PanelType]), MSG_NOTIFY); + case PanelType of + PANEL_WALL: DrawPanels(0, gWalls); + PANEL_CLOSEDOOR: DrawPanels(0, gWalls, True); + PANEL_BACK: DrawPanels(1, gRenderBackgrounds); + PANEL_FORE: DrawPanels(2, gRenderForegrounds); + PANEL_WATER: DrawPanels(3, gWater); + PANEL_ACID1: DrawPanels(4, gAcid1); + PANEL_ACID2: DrawPanels(5, gAcid2); + PANEL_STEP: DrawPanels(6, gSteps); + end; end; + + //e_WriteLog('==================', MSG_NOTIFY); end; procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: Integer); - function qq (obj: TObject; tag: Integer): Boolean; + function checker (obj: TObject; tag: Integer): Boolean; var pan: TPanel; begin result := false; // don't stop, ever - if (tag <> PANEL_WALL) then exit; // only walls + if (tag <> GridTagWallDoor) then exit; // only walls pan := (obj as TPanel); pan.DrawShadowVolume(lightX, lightY, radius); end; begin - gMapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, qq); + gMapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker); end; @@ -2055,9 +2088,40 @@ begin end; end; +function g_Map_CollideLiquid_TextureOld(X, Y: Integer; Width, Height: Word): DWORD; +var + texid: DWORD; + + function checkPanels (var panels: TPanelArray): Boolean; + var + a: Integer; + begin + result := false; + if panels = nil then exit; + for a := 0 to High(panels) do + begin + if g_Collide(X, Y, Width, Height, panels[a].X, panels[a].Y, panels[a].Width, panels[a].Height) then + begin + result := true; + texid := panels[a].GetTextureID(); + exit; + end; + end; + end; + +begin + texid := TEXTURE_NONE; + result := texid; + if not checkPanels(gWater) then + if not checkPanels(gAcid1) then + if not checkPanels(gAcid2) then exit; + result := texid; +end; + + function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean): Boolean; - function qq (obj: TObject; tag: Integer): Boolean; + function checker (obj: TObject; tag: Integer): Boolean; var pan: TPanel; a: Integer; @@ -2079,7 +2143,7 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; pan := (obj as TPanel); a := pan.ArrIdx; - if WordBool(PanelType and PANEL_WALL) and WordBool(tag and PANEL_WALL) then + if WordBool(PanelType and PANEL_WALL) and (tag = GridTagWallDoor) then begin if gWalls[a].Enabled and g_Collide(X, Y, Width, Height, gWalls[a].X, gWalls[a].Y, gWalls[a].Width, gWalls[a].Height) then begin @@ -2088,7 +2152,7 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; end; - if WordBool(PanelType and PANEL_WATER) and WordBool(tag and PANEL_WATER) then + if WordBool(PanelType and PANEL_WATER) and (tag = GridTagWater) then begin if g_Collide(X, Y, Width, Height, gWater[a].X, gWater[a].Y, gWater[a].Width, gWater[a].Height) then begin @@ -2097,7 +2161,7 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; end; - if WordBool(PanelType and PANEL_ACID1) and WordBool(tag and PANEL_ACID1) then + if WordBool(PanelType and PANEL_ACID1) and (tag = GridTagAcid1) then begin if g_Collide(X, Y, Width, Height, gAcid1[a].X, gAcid1[a].Y, gAcid1[a].Width, gAcid1[a].Height) then begin @@ -2106,7 +2170,7 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; end; - if WordBool(PanelType and PANEL_ACID2) and WordBool(tag and PANEL_ACID2) then + if WordBool(PanelType and PANEL_ACID2) and (tag = GridTagAcid2) then begin if g_Collide(X, Y, Width, Height, gAcid2[a].X, gAcid2[a].Y, gAcid2[a].Width, gAcid2[a].Height) then begin @@ -2115,7 +2179,7 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; end; - if WordBool(PanelType and PANEL_STEP) and WordBool(tag and PANEL_STEP) then + if WordBool(PanelType and PANEL_STEP) and (tag = GridTagStep) then begin if g_Collide(X, Y, Width, Height, gSteps[a].X, gSteps[a].Y, gSteps[a].Width, gSteps[a].Height) then begin @@ -2123,99 +2187,111 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; exit; end; end; - end; -var - a, h: Integer; -begin - result := gMapGrid.forEachInAABB(X, Y, Width, Height, qq); - if not result then - begin - if WordBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) and (gLifts <> nil) then + if WordBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) and (tag = GridTagLift) then begin - h := High(gLifts); - for a := 0 to h do + if ((WordBool(PanelType and (PANEL_LIFTUP)) and (gLifts[a].LiftType = 0)) or + (WordBool(PanelType and (PANEL_LIFTDOWN)) and (gLifts[a].LiftType = 1)) or + (WordBool(PanelType and (PANEL_LIFTLEFT)) and (gLifts[a].LiftType = 2)) or + (WordBool(PanelType and (PANEL_LIFTRIGHT)) and (gLifts[a].LiftType = 3))) and + g_Collide(X, Y, Width, Height, gLifts[a].X, gLifts[a].Y, gLifts[a].Width, gLifts[a].Height) then begin - if ((WordBool(PanelType and (PANEL_LIFTUP)) and (gLifts[a].LiftType = 0)) or - (WordBool(PanelType and (PANEL_LIFTDOWN)) and (gLifts[a].LiftType = 1)) or - (WordBool(PanelType and (PANEL_LIFTLEFT)) and (gLifts[a].LiftType = 2)) or - (WordBool(PanelType and (PANEL_LIFTRIGHT)) and (gLifts[a].LiftType = 3))) and - g_Collide(X, Y, Width, Height, - gLifts[a].X, gLifts[a].Y, - gLifts[a].Width, gLifts[a].Height) then - begin - Result := True; - Exit; - end; + result := true; + exit; end; end; - if WordBool(PanelType and PANEL_BLOCKMON) and (gBlockMon <> nil) then + if WordBool(PanelType and PANEL_BLOCKMON) and (tag = GridTagBlockMon) then begin - h := High(gBlockMon); - for a := 0 to h do + if ((not b1x3) or ((gBlockMon[a].Width + gBlockMon[a].Height) >= 64)) and + g_Collide(X, Y, Width, Height, gBlockMon[a].X, gBlockMon[a].Y, gBlockMon[a].Width, gBlockMon[a].Height) then begin - if ( (not b1x3) or - ((gBlockMon[a].Width + gBlockMon[a].Height) >= 64) ) and - g_Collide(X, Y, Width, Height, - gBlockMon[a].X, gBlockMon[a].Y, - gBlockMon[a].Width, gBlockMon[a].Height) then - begin - Result := True; - Exit; - end; + result := True; + exit; end; end; end; + +begin + //TODO: detailed profile + if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('wall coldet'); + try + if gdbg_map_use_grid_coldet then + begin + result := gMapGrid.forEachInAABB(X, Y, Width, Height, checker); + end + else + begin + result := g_Map_CollidePanelOld(X, Y, Width, Height, PanelType, b1x3); + end; + finally + if (profMapCollision <> nil) then profMapCollision.sectionEnd(); + end; end; function g_Map_CollideLiquid_Texture(X, Y: Integer; Width, Height: Word): DWORD; var - a, h: Integer; -begin - Result := TEXTURE_NONE; + cctype: Integer = 3; // priority: 0: water, 1: acid1, 2: acid2; 3: others (nothing) + texid: DWORD; - if gWater <> nil then + // slightly different from the old code, but meh... + function checker (obj: TObject; tag: Integer): Boolean; + var + pan: TPanel; + a: Integer; begin - h := High(gWater); - - for a := 0 to h do - if g_Collide(X, Y, Width, Height, - gWater[a].X, gWater[a].Y, - gWater[a].Width, gWater[a].Height) then + result := false; // don't stop, ever + pan := (obj as TPanel); + a := pan.ArrIdx; + // water + if (tag = GridTagWater) then + begin + if g_Collide(X, Y, Width, Height, gWater[a].X, gWater[a].Y, gWater[a].Width, gWater[a].Height) then begin - Result := gWater[a].GetTextureID(); - Exit; + result := true; // water has highest priority, so stop right here + texid := gWater[a].GetTextureID(); + exit; end; - end; - - if gAcid1 <> nil then - begin - h := High(gAcid1); - - for a := 0 to h do - if g_Collide(X, Y, Width, Height, - gAcid1[a].X, gAcid1[a].Y, - gAcid1[a].Width, gAcid1[a].Height) then + end; + // acid1 + if (cctype > 1) and (tag = GridTagAcid1) then + begin + if g_Collide(X, Y, Width, Height, gAcid1[a].X, gAcid1[a].Y, gAcid1[a].Width, gAcid1[a].Height) then begin - Result := gAcid1[a].GetTextureID(); - Exit; + cctype := 1; + texid := gAcid1[a].GetTextureID(); + exit; end; - end; - - if gAcid2 <> nil then - begin - h := High(gAcid2); - - for a := 0 to h do - if g_Collide(X, Y, Width, Height, - gAcid2[a].X, gAcid2[a].Y, - gAcid2[a].Width, gAcid2[a].Height) then + end; + // acid2 + if (cctype > 2) and (tag = GridTagAcid2) then + begin + if g_Collide(X, Y, Width, Height, gAcid2[a].X, gAcid2[a].Y, gAcid2[a].Width, gAcid2[a].Height) then begin - Result := gAcid2[a].GetTextureID(); - Exit; + cctype := 2; + texid := gAcid2[a].GetTextureID(); + exit; end; + end; + end; + +begin + //TODO: detailed profile? + if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquid coldet'); + try + if not gdbg_map_use_grid_coldet then + begin + result := g_Map_CollideLiquid_TextureOld(X, Y, Width, Height); + end + else + begin + texid := TEXTURE_NONE; + gMapGrid.forEachInAABB(X, Y, Width, Height, checker); + result := texid; + end; + finally + if (profMapCollision <> nil) then profMapCollision.sectionEnd(); end; end; @@ -2593,8 +2669,9 @@ begin LoadPanelArray(gLifts); ///// ///// -// Îáíîâëÿåì êàðòó ñòîëêíîâåíèé: +// Îáíîâëÿåì êàðòó ñòîëêíîâåíèé è ñåòêó: g_GFX_Init(); + mapCreateGrid(); ///// Çàãðóæàåì ìóçûêó: ///// // Ñèãíàòóðà ìóçûêè: