6ae077b111553f4193f959550e7ac90774e1b670
1 (* Copyright (C) DooM 2D:Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 {$DEFINE MAP_DEBUG_ENABLED_FLAG}
20 interface
22 uses
26 type
95 // returns panel or nil
96 // sets `ex` and `ey` to `x1` and `y1` when no hit was detected
97 function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel;
99 // returns panel or nil
100 // sets `ex` and `ey` to `x1` and `y1` when no hit was detected
101 function g_Map_traceToNearest (x0, y0, x1, y1: Integer; tag: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel;
103 type
109 // trace liquid, stepping by `dx` and `dy`
110 // return last seen liquid coords, and `false` if we're started outside of the liquid
120 const
129 const
152 const
155 (* draw order:
156 PANEL_BACK
157 PANEL_STEP
158 PANEL_WALL
159 PANEL_CLOSEDOOR
160 PANEL_ACID1
161 PANEL_ACID2
162 PANEL_WATER
163 PANEL_FORE
164 *)
165 // sorted by draw priority
174 // the following are invisible
178 GridDrawableMask = (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore);
181 var
190 //gDOMFlags: array of TFlag;
202 gDrawPanelList: TBinaryHeapObj = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()`
210 type
213 var
217 implementation
219 uses
228 const
234 var
238 var
242 begin
244 try
247 except
252 begin
255 begin
256 //raise Exception.Create('cannot load "game.wad"');
258 end
259 else
260 begin
266 begin
267 //raise Exception.Create('cannot open "mapdef.txt"');
270 end
271 else
272 begin
276 try
279 raise Exception.Create(Format('ERROR in "mapdef.txt" at (%s,%s): %s', [pr.line, pr.col, e.message]));
288 var
291 begin
299 if (PAnsiChar(data)[0] = 'M') and (PAnsiChar(data)[1] = 'A') and (PAnsiChar(data)[2] = 'P') and (PByte(data)[3] = 1) then
300 begin
301 // binary map
302 try
305 begin
309 exit;
313 end
314 else
315 begin
316 // text map
318 try
321 begin
326 exit;
334 var
341 var
344 begin
352 begin
355 Exit;
356 end
357 else
358 begin
361 Break;
365 // Íå ïåðåâåñòè â ÷èñëî:
367 Exit;
376 begin
378 begin
381 Exit;
387 Result := NNF_NAME_BEFORE
388 else
390 Result := NNF_NAME_AFTER
391 else
399 begin
409 PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: result := GridTagLift; // gLifts -- this is for all lifts
417 var
419 begin
428 begin
429 if (gDrawPanelList = nil) then gDrawPanelList := TBinaryHeapObj.Create(@dplLess) else gDrawPanelList.clear();
433 type
439 var
444 //DOMFlagPoints: Array of TFlagPoint;
448 begin
449 if (profMapCollision = nil) then profMapCollision := TProfiler.Create('COLSOLID', g_profile_history_size);
451 // create sections
453 begin
462 begin
467 // wall index in `gWalls` or -1
468 function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel;
469 var
471 begin
474 begin
477 end
478 else
479 begin
485 // returns panel or nil
486 function g_Map_traceToNearest (x0, y0, x1, y1: Integer; tag: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel;
487 var
489 begin
492 begin
495 end
496 else
497 begin
507 begin
508 {
509 if ((tag and (GridTagWall or GridTagDoor)) <> 0) then
510 begin
511 result := pan.Enabled; // stop if wall is enabled
512 exit;
513 end;
514 }
517 begin
518 // stop if the lift of the right type
519 result :=
524 exit;
527 result := true; // otherwise, stop anyway, 'cause `forEachAtPoint()` is guaranteed to call this only for correct panels
530 var
532 begin
535 if WordBool(PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_OPENDOOR)) then tagmask := tagmask or (GridTagWall or GridTagDoor);
540 if WordBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) then tagmask := tagmask or GridTagLift;
545 begin
546 // slow
548 end
549 else
550 begin
551 // fast
558 begin
566 begin
573 var
582 begin
584 Exit;
592 begin
602 begin
608 // Íåò äâåðåé:
610 begin
612 Exit;
621 begin
630 begin
636 if {((gRenderWalls[PanelArray[b].RenderPanelID].TextureID = gRenderWalls[gDoorMap[m, c]].TextureID) or
637 gRenderWalls[PanelArray[b].RenderPanelID].Hide or gRenderWalls[gDoorMap[m, c]].Hide) and}
644 begin
650 Break;
661 var
669 begin
671 Exit;
677 begin
692 begin
700 begin
713 begin
723 Break;
740 var
743 begin
749 PANEL_BACK:
751 PANEL_FORE:
753 PANEL_WATER:
755 PANEL_ACID1:
757 PANEL_ACID2:
759 PANEL_STEP:
763 PANEL_BLOCKMON:
765 else
766 Exit;
788 begin
793 begin
803 var
808 begin
816 Exit;
819 // Òåêñòóðû ñî ñïåöèàëüíûìè èìåíàìè (âîäà, ëàâà, êèñëîòà):
823 begin
827 begin
832 else
835 else
843 Exit;
846 // Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à:
853 else
859 {
860 if (WADName = Map) and WAD.GetResource(g_ExtractFilePathName(RecName), TextureData, ResLength) then
861 begin
862 FreeMem(TextureData);
863 RecName := 'COMMON\ALIEN';
864 end;
865 }
868 begin
871 Exit;
880 end
882 begin
883 //e_WriteLog(Format('SHIT! Error loading texture %s : %s : %s', [RecName, txname, g_ExtractFilePathName(RecName)]), MSG_WARNING);
885 begin
887 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
895 var
906 //imgfmt: string;
909 begin
912 //e_WriteLog(Format('*** Loading animated texture "%s"', [RecName]), MSG_NOTIFY);
914 // ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü:
918 try
921 else
927 begin
929 begin
931 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
933 exit;
936 {TEST
937 if WADName = Map then
938 begin
939 //FreeMem(TextureWAD);
940 if not WAD.GetResource('COMMON/animation', TextureWAD, ResLength) then Halt(1);
941 end;
942 }
947 begin
949 exit;
952 // ýòî ïòèöà? ýòî ñàìîë¸ò?
955 begin
956 // íåò, ýòî ñóïåðìåí!
958 begin
960 exit;
963 // ×èòàåì INI-ðåñóðñ àíèì. òåêñòóðû è çàïîìèíàåì åãî óñòàíîâêè:
965 begin
967 exit;
974 begin
976 exit;
988 // ×èòàåì ðåñóðñ òåêñòóð (êàäðîâ) àíèì. òåêñòóðû â ïàìÿòü:
990 begin
991 e_WriteLog(Format('Animated texture WAD file "%s" has no texture "%s"', [RecName, 'TEXTURES/'+TextureResource]), MSG_WARNING);
992 exit;
1000 begin
1001 // Ñîçäàåì êàäðû àíèì. òåêñòóðû èç ïàìÿòè:
1002 if g_Frames_CreateMemory(@FramesID, '', TextureData, ResLength, _width, _height, _framecount, _backanimation) then
1003 begin
1011 end
1012 else
1013 begin
1017 end
1018 else
1019 begin
1020 // try animated image
1021 {
1022 imgfmt := DetermineMemoryFormat(TextureWAD, ResLength);
1023 if length(imgfmt) = 0 then
1024 begin
1025 e_WriteLog(Format('Animated texture file "%s" has unknown format', [RecName]), MSG_WARNING);
1026 exit;
1027 end;
1028 }
1032 begin
1034 exit;
1037 begin
1039 exit;
1053 begin
1054 //writeln(' frame delay: ', GlobalMetadata.MetaItems[SMetaFrameDelay]);
1055 try
1059 // rounding ;-)
1065 except
1069 begin
1070 //writeln(' frame loop : ', GlobalMetadata.MetaItems[SMetaAnimationLoops]);
1071 try
1075 except
1078 //writeln(' creating animated texture with ', length(ia), ' frames (delay:', _speed, '; backloop:', _backanimation, ') from "', RecName, '"...');
1079 //for f := 0 to high(ia) do writeln(' frame #', f, ': ', ia[f].width, 'x', ia[f].height);
1081 e_WriteLog(Format('Animated texture file "%s": %d frames (delay:%d; back:%d; frdelay:%d; frloop:%d), %dx%d', [RecName, length(ia), _speed, f, frdelay, frloop, _width, _height]), MSG_NOTIFY);
1084 // cîçäàåì êàäðû àíèì. òåêñòóðû èç êàðòèíîê
1086 begin
1094 //writeln(' CREATED!');
1095 end
1096 else
1097 begin
1098 if log then e_WriteLog(Format('Error loading animation texture "%s" images', [RecName]), MSG_WARNING);
1101 finally
1112 begin
1117 Exit;
1124 var
1127 begin
1131 begin
1134 begin
1150 begin
1158 begin
1165 begin
1178 AREA_DOMFLAG:
1179 begin
1180 {SetLength(DOMFlagPoints, Length(DOMFlagPoints)+1);
1181 with DOMFlagPoints[High(DOMFlagPoints)] do
1182 begin
1183 X := Area.X;
1184 Y := Area.Y;
1185 Direction := TDirection(Area.Direction);
1186 end;
1188 g_Map_CreateFlag(DOMFlagPoints[High(DOMFlagPoints)], FLAG_DOM, FLAG_STATE_NORMAL);}
1193 procedure CreateTrigger(Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word);
1194 var
1196 begin
1200 begin
1206 //TexturePanel := Trigger.TexturePanel;
1214 //trigShotPanelId := ashotpanid;
1215 //Data.Default := Trigger.DATA;
1223 var
1226 begin
1231 begin
1232 mon := g_Monsters_Create(monster.MonsterType, monster.X, monster.Y, TDirection(monster.Direction));
1235 begin
1237 begin
1239 begin
1240 //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a);
1253 var
1255 begin
1259 begin
1261 begin
1262 //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a);
1268 begin
1275 var
1277 begin
1281 else
1286 begin
1293 //var
1294 //textures: TTexturesRec1Array;
1295 //textures: TDynField;
1296 //trec: TDynRecord;
1297 //mapHeader: TMapHeaderRec_1;
1298 //i: integer;
1299 //resFile: String = '';
1300 begin
1306 (*
1307 {
1308 textures := GetTextures(map);
1309 for i := 0 to High(textures) do
1310 begin
1311 addResToExternalResList(resFile);
1312 end;
1313 }
1315 textures := map['texture'];
1316 if (textures <> nil) then
1317 begin
1318 for trec in textures do
1319 begin
1320 addResToExternalResList(resFile);
1321 end;
1322 end;
1324 textures := nil;
1325 *)
1327 //mapHeader := GetMapHeader(map);
1335 var
1342 var
1345 begin
1347 begin
1359 var
1363 begin
1364 //tag := panelTypeToTag(tag);
1366 begin
1370 begin
1371 {$IF DEFINED(D2F_DEBUG)}
1372 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);
1373 {$ENDIF}
1374 continue;
1392 // "enabled" flag has meaning only for doors and walls (engine assumes it); but meh...
1394 {$IFDEF MAP_DEBUG_ENABLED_FLAG}
1395 {
1396 if ((tag and (GridTagWall or GridTagDoor)) <> 0) then
1397 begin
1398 e_WriteLog(Format('INSERTED wall #%d(%d) enabled (%d)', [Integer(idx), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId])]), MSG_NOTIFY);
1399 end;
1400 }
1401 {$ENDIF}
1405 begin
1419 e_LogWritefln('map dimensions: (%d,%d)-(%d,%d); editor size:(0,0)-(%d,%d)', [mapX0, mapY0, mapX1, mapY1, gMapInfo.Width, gMapInfo.Height]);
1428 //mapGrid := TPanelGrid.Create(0, 0, gMapInfo.Width, gMapInfo.Height);
1447 const
1450 type
1453 //TexturePanel: Integer;
1464 var
1466 //MapReader: TMapReader_1;
1468 //Header: TMapHeaderRec_1;
1470 //_texnummap: array of Integer = nil; // `_textures` -> `Textures`
1479 //texture: TTextureRec_1;
1489 // key: panel index; value: `TriggersTable` index
1494 begin
1505 //FillChar(texture, SizeOf(texture), 0);
1508 try
1509 // Çàãðóçêà WAD:
1516 begin
1519 Exit;
1522 //k8: why loader ignores path here?
1525 begin
1528 Exit;
1534 begin
1537 exit;
1540 // Çàãðóçêà êàðòû:
1544 try
1546 except
1550 Exit;
1561 //_textures := GetTextures(mapReader);
1563 //_texnummap := nil;
1564 // get all other lists here too
1565 //panels := GetPanels(mapReader);
1567 //triggers := GetTriggers(mapReader);
1569 //items := GetItems(mapReader);
1571 //areas := GetAreas(mapReader);
1573 //monsters := GetMonsters(mapReader);
1576 // Çàãðóçêà îïèñàíèÿ êàðòû:
1579 //Header := GetMapHeader(mapReader);
1582 begin
1592 // Çàãðóçêà òåêñòóð:
1594 // Äîáàâëåíèå òåêñòóð â Textures[]:
1596 begin
1599 //SetLength(_texnummap, _textures.count);
1603 begin
1606 {$IF DEFINED(D2F_DEBUG_TXLOAD)}
1608 {$ENDIF}
1609 //if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY);
1611 begin
1612 // Àíèìèðîâàííàÿ òåêñòóðà
1615 end
1616 else
1617 begin
1618 // Îáû÷íàÿ òåêñòóðà
1624 //_texnummap[a] := ntn; // fix texture number
1629 // set panel tagInt to texture index
1631 begin
1633 begin
1640 // Çàãðóçêà òðèããåðîâ
1645 // Çàãðóçêà ïàíåëåé
1649 // check texture numbers for panels
1651 begin
1653 begin
1655 begin
1658 exit;
1663 // Ñîçäàíèå òàáëèöû òðèããåðîâ (ñîîòâåòñòâèå ïàíåëåé òðèããåðàì)
1665 begin
1667 //SetLength(TriggersTable, triggers.count);
1671 begin
1683 // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè)
1684 //if (rec.TexturePanel >= 0) and (pttit.texPan = nil) then e_WriteLog('error loading map: invalid texture panel index for trigger', MSG_WARNING);
1685 // Ëèôòû
1687 begin
1688 //pttit.LiftPanel := TTriggerData(rec.DATA).PanelID
1690 //if (rec.trigRec.trigPanelID >= 0) and (pttit.liftPan = nil) then e_WriteLog('error loading map: invalid lift panel index for trigger', MSG_WARNING);
1692 // Äâåðè
1693 if rec.TriggerType in [TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP] then
1694 begin
1695 //pttit.DoorPanel := TTriggerData(rec.DATA).PanelID
1698 // Òóðåëü
1700 begin
1701 //pttit.ShotPanel := TTriggerData(rec.DATA).ShotPanelID
1705 // update hashes
1709 if (pttit.shotPan <> nil) then hashShotPan.put(rec.trigRec.tgShotPanelID, High(TriggersTable));
1715 // Ñîçäàåì ïàíåëè
1717 begin
1723 begin
1732 begin
1738 begin
1739 // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû.
1740 // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð
1743 begin
1745 begin
1747 begin
1750 break;
1757 begin
1758 // Åñòü ññûëêè òðèããåðîâ íà ýòó ïàíåëü
1761 // Ñïåö-òåêñòóðû çàïðåùåíû
1763 begin
1765 end
1766 else
1767 begin
1768 // Îïðåäåëÿåì íàëè÷èå è ïîëîæåíèå öèôð â êîíöå ñòðîêè
1772 // Åñëè ok, çíà÷èò åñòü öèôðû â êîíöå.
1773 // Çàãðóæàåì òåêñòóðû ñ îñòàëüíûìè #
1775 begin
1777 // Öèêë ïî èçìåíåíèþ èìåíè òåêñòóðû
1779 begin
1783 begin
1784 // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó
1786 begin
1787 // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ
1791 begin
1792 // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ
1796 end
1797 else
1798 begin
1799 // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ
1803 begin
1804 // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ
1810 // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè
1812 begin
1814 begin
1816 begin
1820 break;
1824 end
1825 else
1826 begin
1828 begin
1829 // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî
1831 //AddTextures[High(AddTextures)].Texture := _texnummap[rec.TextureNum]; //panels[a].TextureNum;
1836 end
1838 begin
1849 begin
1850 // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó
1858 //e_WriteLog(Format('panel #%d: TextureNum=%d; ht=%d; ht1=%d; atl=%d', [a, panels[a].TextureNum, High(_textures), High(Textures), High(AddTextures)]), MSG_NOTIFY);
1860 // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð
1862 //e_LogWritefln('panel #%s of type %s got id #%s', [pannum, rec.PanelType, PanelID]);
1864 // Åñëè èñïîëüçóåòñÿ â òðèããåðàõ, òî ñòàâèì òî÷íûé ID
1870 (*
1871 if (TriggersTable <> nil) then
1872 begin
1873 for b := 0 to High(TriggersTable) do
1874 begin
1875 if (TriggersTable[b].texPan = rec) then TriggersTable[b].texPanIdx := PanelID;
1876 if (TriggersTable[b].liftPan = rec) then TriggersTable[b].LiftPanelIdx := PanelID;
1877 if (TriggersTable[b].doorPan = rec) then TriggersTable[b].DoorPanelIdx := PanelID;
1878 if (TriggersTable[b].shotPan = rec) then TriggersTable[b].ShotPanelIdx := PanelID;
1879 {
1880 // Òðèããåð äâåðè/ëèôòà
1881 if (TriggersTable[b].LiftPanel = pannum) or
1882 (TriggersTable[b].DoorPanel = pannum) then
1883 //TTriggerData(TriggersTable[b].trigrec.DATA).PanelID := PanelID;
1884 TriggersTable[b].trigrec.trigRec.trigPanelID := PanelID;
1885 // Òðèããåð ñìåíû òåêñòóðû
1886 if TriggersTable[b].texPanIdx = pannum then
1887 TriggersTable[b].trigrec.TexturePanel := PanelID;
1888 // Òðèããåð "Òóðåëü"
1889 if TriggersTable[b].ShotPanel = pannum then
1890 TriggersTable[b].trigrec.trigRec.trigShotPanelID := PanelID;
1891 }
1892 end;
1893 end;
1894 *)
1900 (*
1901 begin
1902 for b := 0 to High(TriggersTable) do
1903 begin
1904 // Òðèããåð äâåðè/ëèôòà
1905 if (TriggersTable[b].texPan <> nil) then e_LogWritefln('trigger #%s: textPan=%s; panidx=%s', [b, TriggersTable[b].texPanIdx, mapReader.panelIndex[TriggersTable[b].texPan]]);
1906 if (TriggersTable[b].liftPan <> nil) then e_LogWritefln('trigger #%s: liftPan=%s; panidx=%s', [b, TriggersTable[b].LiftPanelIdx, mapReader.panelIndex[TriggersTable[b].liftPan]]);
1907 if (TriggersTable[b].doorPan <> nil) then e_LogWritefln('trigger #%s: doorPan=%s; panidx=%s', [b, TriggersTable[b].DoorPanelIdx, mapReader.panelIndex[TriggersTable[b].doorPan]]);
1908 if (TriggersTable[b].shotPan <> nil) then e_LogWritefln('trigger #%s: shotPan=%s; panidx=%s', [b, TriggersTable[b].ShotPanelIdx, mapReader.panelIndex[TriggersTable[b].shotPan]]);
1909 end;
1910 end;
1911 *)
1913 // create map grid, init other grids (for monsters, for example)
1917 // Åñëè íå LoadState, òî ñîçäàåì òðèããåðû
1919 begin
1922 // Óêàçûâàåì òèï ïàíåëè, åñëè åñòü
1925 begin
1927 if (TriggersTable[trignum].texPan <> nil) then b := TriggersTable[trignum].texPan.PanelType else b := 0;
1928 if (TriggersTable[trignum].shotPan <> nil) then c := TriggersTable[trignum].shotPan.PanelType else c := 0;
1930 if (TriggersTable[trignum].LiftPanelIdx <> -1) then tgpid := TriggersTable[trignum].LiftPanelIdx
1931 else if (TriggersTable[trignum].DoorPanelIdx <> -1) then tgpid := TriggersTable[trignum].DoorPanelIdx
1932 else if (TriggersTable[trignum].ShotPanelIdx <> -1) then tgpid := TriggersTable[trignum].ShotPanelIdx
1934 (*
1935 if (rec.TexturePanel <> -1) then
1936 begin
1937 {
1938 if (TriggersTable[trignum].TexturePanel < 0) or (TriggersTable[trignum].TexturePanel >= panels.count) then
1939 begin
1940 e_WriteLog('error loading map: invalid panel index for trigger', MSG_FATALERROR);
1941 result := false;
1942 exit;
1943 end;
1944 }
1945 //b := panels[TriggersTable[a].TexturePanel].PanelType;
1946 //b := mapReader.panel[TriggersTable[trignum].texPanIdx].PanelType;
1947 assert(TriggersTable[trignum].texPanIdx >= 0);
1948 b := TriggersTable[trignum].texPanIdx;
1949 end
1950 else
1951 begin
1952 b := 0;
1953 end;
1954 e_LogWritefln('trigger #%s: type=%s; texPanIdx=%s; b=%s', [trignum, rec.TriggerType, TriggersTable[trignum].texPanIdx, b]);
1955 if (rec.TriggerType = TRIGGER_SHOT) then e_LogWritefln(' SHOT: shotpanidx=%s', [rec.trigRec.trigShotPanelID]);
1956 if (rec.TriggerType = TRIGGER_SHOT) and {(rec.trigRec.trigShotPanelID <> -1)} (TriggersTable[trignum].shotPan <> nil) then
1957 begin
1958 //c := panels[TriggersTable[a].ShotPanel].PanelType;
1959 //c := mapReader.panel[TriggersTable[trignum].ShotPanel].PanelType;
1960 assert(TriggersTable[trignum].ShotPanelIdx >= 0);
1961 c := TriggersTable[trignum].ShotPanelIdx;
1962 end
1963 else
1964 begin
1965 c := 0;
1966 end;
1967 *)
1968 //e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]);
1973 // Çàãðóçêà ïðåäìåòîâ
1977 // Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû
1979 begin
1985 // Çàãðóçêà îáëàñòåé
1989 // Åñëè íå LoadState, òî ñîçäàåì îáëàñòè
1991 begin
1997 // Çàãðóçêà ìîíñòðîâ
2003 // Åñëè íå LoadState, òî ñîçäàåì ìîíñòðîâ
2005 begin
2011 //MapReader.Free();
2015 // Çàãðóçêà íåáà
2017 begin
2024 else
2025 begin
2031 begin
2033 end
2034 else
2038 // Çàãðóçêà ìóçûêè
2041 begin
2048 else
2049 begin
2056 else
2060 // Îñòàëüíûå óñòàíâêè
2068 // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé:
2071 // Ñáðîñ ëîêàëüíûõ ìàññèâîâ:
2080 // Âêëþ÷àåì ìóçûêó, åñëè ýòî íå çàãðóçêà:
2082 begin
2085 end
2086 else
2087 begin
2090 finally
2104 var
2107 //Header: TMapHeaderRec_1;
2111 begin
2117 begin
2119 Exit;
2122 //k8: it ignores path again
2124 begin
2126 Exit;
2131 {
2132 MapReader := TMapReader_1.Create();
2133 if not MapReader.LoadMap(Data) then
2134 begin
2135 g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True);
2136 ZeroMemory(@Header, SizeOf(Header));
2137 Result.Name := _lc[I_GAME_ERROR_MAP_SELECT];
2138 Result.Description := _lc[I_GAME_ERROR_MAP_SELECT];
2139 end
2140 else
2141 begin
2142 Header := MapReader.GetMapHeader();
2143 Result.Name := Header.MapName;
2144 Result.Description := Header.MapDescription;
2145 end;
2146 }
2147 try
2149 except
2154 //MapReader.Free();
2156 //if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0);
2157 //MapReader.Free();
2160 begin
2167 end
2168 else
2169 begin
2171 //ZeroMemory(@Header, SizeOf(Header));
2184 var
2188 begin
2192 begin
2194 Exit;
2198 begin
2200 begin
2209 var
2214 begin
2221 begin
2223 Exit;
2232 begin
2234 Exit;
2239 var
2243 var
2246 begin
2248 begin
2255 begin
2264 begin
2269 begin
2273 //DOMFlagPoints := nil;
2275 //gDOMFlags := nil;
2278 begin
2283 else
2301 begin
2325 var
2331 var
2334 begin
2340 begin
2350 begin
2354 begin
2361 Continue;
2363 // Ñîïðîòèâëåíèå âîçäóõà:
2366 // Òàéìàóò ïîòåðÿííîãî ôëàãà, ëèáî îí âûïàë çà êàðòó:
2368 begin
2373 else
2379 Continue;
2385 // Èãðîê áåðåò ôëàã:
2387 begin
2391 begin
2399 begin
2401 Break;
2410 // old algo
2414 var
2416 begin
2418 begin
2419 // alas, no visible set
2421 begin
2427 begin
2441 // new algo
2445 begin
2451 begin
2453 //tagmask := panelTypeToTag(PanelType);
2455 // list will be rendered in `g_game.DrawPlayer()`
2462 begin
2467 begin
2468 mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker, (GridTagWall or GridTagDoor));
2473 begin
2476 else
2482 var
2484 begin
2489 begin
2497 begin
2499 Exit;
2505 begin
2512 begin
2514 Exit;
2520 begin
2527 begin
2529 Exit;
2535 begin
2542 begin
2544 Exit;
2550 begin
2557 begin
2559 Exit;
2563 if WordBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) then
2565 begin
2576 begin
2578 Exit;
2584 begin
2593 begin
2595 Exit;
2601 var
2605 var
2607 begin
2611 begin
2612 if g_Collide(X, Y, Width, Height, panels[a].X, panels[a].Y, panels[a].Width, panels[a].Height) then
2613 begin
2616 exit;
2621 begin
2631 function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean): Boolean;
2632 const
2635 begin
2636 {
2637 if ((tag and (GridTagWall or GridTagDoor)) <> 0) then
2638 begin
2639 result := pan.Enabled;
2640 exit;
2641 end;
2642 }
2645 begin
2646 result :=
2652 exit;
2656 begin
2657 result := ((not b1x3) or (pan.Width+pan.Height >= 64)); //and g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height);
2658 exit;
2661 // other shit
2662 //result := g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height);
2666 var
2668 begin
2669 if WordBool(PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_OPENDOOR)) then tagmask := tagmask or (GridTagWall or GridTagDoor);
2674 if WordBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) then tagmask := tagmask or GridTagLift;
2681 begin
2683 begin
2685 begin
2686 // slow
2688 end
2689 else
2690 begin
2691 // fast
2694 end
2695 else
2696 begin
2698 begin
2699 // slow
2701 end
2702 else
2703 begin
2704 // fast
2708 end
2709 else
2710 begin
2718 var
2719 cctype: Integer = 3; // priority: 0: water was hit, 1: acid1 was hit, 2: acid2 was hit; 3: nothing was hit
2722 // slightly different from the old code, but meh...
2724 begin
2726 //if ((tag and (GridTagWater or GridTagAcid1 or GridTagAcid2)) = 0) then exit;
2727 // check priorities
2731 //2: if ((tag and (GridTagWater or GridTagAcid1 or GridTagAcid2) = 0) then exit; // allowed: water, acid1, acid2
2733 // collision?
2734 //if not g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height) then exit;
2735 // yeah
2737 // water? water has the highest priority, so stop right here
2739 // acid2?
2741 // acid1?
2745 begin
2748 begin
2751 begin
2753 end
2754 else
2755 begin
2756 mapGrid.forEachInAABB(X, Y, Width, Height, checker, (GridTagWater or GridTagAcid1 or GridTagAcid2));
2759 end
2760 else
2761 begin
2769 var
2771 begin
2777 //if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := true
2778 //else pan.proxyId := mapGrid.insertBody(pan, pan.X, pan.Y, pan.Width, pan.Height, GridTagDoor);
2782 {$IFDEF MAP_DEBUG_ENABLED_FLAG}
2783 //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);
2784 {$ENDIF}
2788 var
2790 begin
2796 //if (pan.proxyId >= 0) then begin mapGrid.removeBody(pan.proxyId); pan.proxyId := -1; end;
2800 {$IFDEF MAP_DEBUG_ENABLED_FLAG}
2801 //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);
2802 {$ENDIF}
2806 var
2808 begin
2812 PANEL_FORE:
2814 PANEL_BACK:
2816 PANEL_WATER:
2818 PANEL_ACID1:
2820 PANEL_ACID2:
2822 PANEL_STEP:
2824 else
2825 Exit;
2834 begin
2836 Exit;
2839 begin
2843 //TODO: make separate lift tags, and change tag here
2859 var
2862 begin
2867 Exit;
2871 begin
2877 Exit;
2884 var
2886 begin
2890 Exit;
2898 begin
2903 begin
2905 begin
2913 begin
2924 var
2927 begin
2929 Exit;
2934 begin
2936 continue;
2939 begin
2942 end
2943 else
2944 begin
2952 begin
2963 var
2970 var
2973 begin
2974 // Ñîçäàåì íîâûé ñïèñîê ñîõðàíÿåìûõ ïàíåëåé:
2979 begin
2981 begin
2982 // ID ïàíåëè:
2984 // Ñîõðàíÿåì ïàíåëü:
2990 // Ñîõðàíÿåì ýòîò ñïèñîê ïàíåëåé:
2996 begin
2997 // Ñèãíàòóðà ôëàãà:
3000 // Âðåìÿ ïåðåïîÿâëåíèÿ ôëàãà:
3002 // Ñîñòîÿíèå ôëàãà:
3004 // Íàïðàâëåíèå ôëàãà:
3010 // Îáúåêò ôëàãà:
3014 begin
3017 ///// Ñîõðàíÿåì ñïèñêè ïàíåëåé: /////
3018 // Ñîõðàíÿåì ïàíåëè ñòåí è äâåðåé:
3020 // Ñîõðàíÿåì ïàíåëè ôîíà:
3022 // Ñîõðàíÿåì ïàíåëè ïåðåäíåãî ïëàíà:
3024 // Ñîõðàíÿåì ïàíåëè âîäû:
3026 // Ñîõðàíÿåì ïàíåëè êèñëîòû-1:
3028 // Ñîõðàíÿåì ïàíåëè êèñëîòû-2:
3030 // Ñîõðàíÿåì ïàíåëè ñòóïåíåé:
3032 // Ñîõðàíÿåì ïàíåëè ëèôòîâ:
3034 ///// /////
3036 ///// Ñîõðàíÿåì ìóçûêó: /////
3037 // Ñèãíàòóðà ìóçûêè:
3040 // Íàçâàíèå ìóçûêè:
3044 else
3047 // Ïîçèöèÿ ïðîèãðûâàíèÿ ìóçûêè:
3050 // Ñòîèò ëè ìóçûêà íà ñïåö-ïàóçå:
3053 ///// /////
3055 ///// Ñîõðàíÿåì êîëè÷åñòâî ìîíñòðîâ: /////
3057 ///// /////
3059 //// Ñîõðàíÿåì ôëàãè, åñëè ýòî CTF: /////
3061 begin
3062 // Ôëàã Êðàñíîé êîìàíäû:
3064 // Ôëàã Ñèíåé êîìàíäû:
3067 ///// /////
3069 ///// Ñîõðàíÿåì êîëè÷åñòâî ïîáåä, åñëè ýòî TDM/CTF: /////
3071 begin
3072 // Î÷êè Êðàñíîé êîìàíäû:
3074 // Î÷êè Ñèíåé êîìàíäû:
3077 ///// /////
3081 var
3088 var
3091 begin
3092 // Çàãðóæàåì òåêóùèé ñïèñîê ïàíåëåé:
3097 begin
3099 begin
3100 // ID ïàíåëè:
3103 begin
3106 // Çàãðóæàåì ïàíåëü:
3108 if (panels[i].arrIdx <> i) then raise Exception.Create('g_Map_LoadState: LoadPanelArray: Wrong Panel arrIdx');
3113 // Ýòîò ñïèñîê ïàíåëåé çàãðóæåí:
3118 begin
3119 // Ñèãíàòóðà ôëàãà:
3122 begin
3125 // Âðåìÿ ïåðåïîÿâëåíèÿ ôëàãà:
3127 // Ñîñòîÿíèå ôëàãà:
3129 // Íàïðàâëåíèå ôëàãà:
3135 // Îáúåêò ôëàãà:
3139 begin
3141 Exit;
3143 ///// Çàãðóæàåì ñïèñêè ïàíåëåé: /////
3144 // Çàãðóæàåì ïàíåëè ñòåí è äâåðåé:
3146 // Çàãðóæàåì ïàíåëè ôîíà:
3148 // Çàãðóæàåì ïàíåëè ïåðåäíåãî ïëàíà:
3150 // Çàãðóæàåì ïàíåëè âîäû:
3152 // Çàãðóæàåì ïàíåëè êèñëîòû-1:
3154 // Çàãðóæàåì ïàíåëè êèñëîòû-2:
3156 // Çàãðóæàåì ïàíåëè ñòóïåíåé:
3158 // Çàãðóæàåì ïàíåëè ëèôòîâ:
3160 ///// /////
3162 // Îáíîâëÿåì êàðòó ñòîëêíîâåíèé è ñåòêó:
3164 //mapCreateGrid();
3166 ///// Çàãðóæàåì ìóçûêó: /////
3167 // Ñèãíàòóðà ìóçûêè:
3170 begin
3173 // Íàçâàíèå ìóçûêè:
3176 // Ïîçèöèÿ ïðîèãðûâàíèÿ ìóçûêè:
3178 // Ñòîèò ëè ìóçûêà íà ñïåö-ïàóçå:
3180 // Çàïóñêàåì ýòó ìóçûêó:
3186 ///// /////
3188 ///// Çàãðóæàåì êîëè÷åñòâî ìîíñòðîâ: /////
3190 ///// /////
3192 //// Çàãðóæàåì ôëàãè, åñëè ýòî CTF: /////
3194 begin
3195 // Ôëàã Êðàñíîé êîìàíäû:
3197 // Ôëàã Ñèíåé êîìàíäû:
3200 ///// /////
3202 ///// Çàãðóæàåì êîëè÷åñòâî ïîáåä, åñëè ýòî TDM/CTF: /////
3204 begin
3205 // Î÷êè Êðàñíîé êîìàíäû:
3207 // Î÷êè Ñèíåé êîìàíäû:
3210 ///// /////
3214 var
3216 begin
3225 // trace liquid, stepping by `dx` and `dy`
3226 // return last seen liquid coords, and `false` if we're started outside of the liquid
3227 function g_Map_TraceLiquidNonPrecise (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean;
3228 const
3230 begin
3233 // started outside of the liquid?
3234 if (mapGrid.forEachAtPoint(x, y, nil, MaskLiquid) = nil) then begin result := false; exit; end;
3238 begin
3241 if (mapGrid.forEachAtPoint(x, y, nil, MaskLiquid) = nil) then exit; // out of the water, just exit