X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=1695460c162e06e3b8b36e9c0f3b6b629390cc4a;hb=923fa980434e55419f35422119af2faae2bf68d7;hp=4bb340d1026a97f86893f6843e0f0f3dfb93a61a;hpb=223356cbae3197afc861efa6241c4ae91bd92885;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 4bb340d..1695460 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -20,8 +20,8 @@ unit g_map; interface uses - e_graphics, g_basic, MAPSTRUCT, g_textures, Classes, - g_phys, wadreader, BinEditor, g_panel, g_grid, md5, binheap, xprofiler; + e_graphics, g_basic, MAPDEF, g_textures, Classes, + g_phys, wadreader, BinEditor, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec; type TMapInfo = record @@ -115,6 +115,17 @@ procedure g_Map_ProfilersBegin (); procedure g_Map_ProfilersEnd (); +function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord; + +const + NNF_NO_NAME = 0; + NNF_NAME_BEFORE = 1; + NNF_NAME_EQUALS = 2; + NNF_NAME_AFTER = 3; + +function g_Texture_NumNameFindStart(name: String): Boolean; +function g_Texture_NumNameFindNext(var newName: String): Byte; + const RESPAWNPOINT_PLAYER1 = 1; RESPAWNPOINT_PLAYER2 = 2; @@ -178,7 +189,7 @@ var gFlags: array [FLAG_RED..FLAG_BLUE] of TFlag; //gDOMFlags: array of TFlag; gMapInfo: TMapInfo; - gBackSize: TPoint; + gBackSize: TDFPoint; gDoorMap: array of array of DWORD; gLiftMap: array of array of DWORD; gWADHash: TMD5Digest; @@ -190,6 +201,8 @@ var profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY! gDrawPanelList: TBinaryHeapObj = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()` + gCurrentMap: TDynRecord = nil; + function panelTypeToTag (panelType: Word): Integer; // returns GridTagXXX @@ -206,9 +219,9 @@ implementation uses g_main, e_log, SysUtils, g_items, g_gfx, g_console, GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG, - g_options, MAPREADER, g_triggers, g_player, MAPDEF, + g_options, g_triggers, g_player, Math, g_monsters, g_saveload, g_language, g_netmsg, - utils, sfs, xparser, xdynrec, xstreams, + utils, sfs, xstreams, hashtable, ImagingTypes, Imaging, ImagingUtility, ImagingGif, ImagingNetworkGraphics; @@ -218,11 +231,9 @@ const FLAG_SIGNATURE = $47414C46; // 'FLAG' -{$IF DEFINED(D2D_NEW_MAP_READER)} var dfmapdef: TDynMapDef = nil; - procedure loadMapDefinition (); var pr: TTextParser = nil; @@ -240,12 +251,27 @@ begin if (st = nil) then begin WAD := TWADFile.Create(); - if not WAD.ReadFile(GameWAD) then raise Exception.Create('cannot load "game.wad"'); - st := WAD.openFileStream('mapdef.txt'); + if not WAD.ReadFile(GameWAD) then + begin + //raise Exception.Create('cannot load "game.wad"'); + st := nil; + end + else + begin + st := WAD.openFileStream('mapdef.txt'); + end; end; - if (st = nil) then raise Exception.Create('cannot open "mapdef.txt"'); - pr := TFileTextParser.Create(st); + if (st = nil) then + begin + //raise Exception.Create('cannot open "mapdef.txt"'); + e_LogWritefln('using default "mapdef.txt"...', [], MSG_WARNING); + pr := TStrTextParser.Create(defaultMapDef); + end + else + begin + pr := TFileTextParser.Create(st); + end; try dfmapdef := TDynMapDef.Create(pr); @@ -256,7 +282,117 @@ begin st.Free(); WAD.Free(); end; -{$ENDIF} + + +function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord; +var + wst: TSFSMemoryChunkStream = nil; + pr: TTextParser = nil; +begin + result := nil; + if (dataLen < 4) then exit; + loadMapDefinition(); + if (dfmapdef = nil) then raise Exception.Create('internal map loader error'); + + wst := TSFSMemoryChunkStream.Create(data, dataLen); + + if (PAnsiChar(data)[0] = 'M') and (PAnsiChar(data)[1] = 'A') and (PAnsiChar(data)[2] = 'P') and (PByte(data)[3] = 1) then + begin + // binary map + try + result := dfmapdef.parseBinMap(wst); + except on e: Exception do + begin + e_LogWritefln('ERROR: %s', [e.message]); + wst.Free(); + result := nil; + exit; + end; + end; + wst.Free(); + end + else + begin + // text map + pr := TFileTextParser.Create(wst); + try + result := dfmapdef.parseMap(pr); + except on e: Exception do + begin + if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message]) + else e_LogWritefln('ERROR: %s', [e.message]); + pr.Free(); // will free `wst` + result := nil; + exit; + end; + end; + pr.Free(); // will free `wst` + end; +end; + + +var + NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå + NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû + NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû + + +function g_Texture_NumNameFindStart(name: String): Boolean; +var + i: Integer; + +begin + Result := False; + NNF_PureName := ''; + NNF_FirstNum := -1; + NNF_CurrentNum := -1; + + for i := Length(name) downto 1 do + if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà + begin + if i = Length(name) then + begin // Íåò öèôð â êîíöå ñòðîêè + Exit; + end + else + begin + NNF_PureName := Copy(name, 1, i); + Delete(name, 1, i); + Break; + end; + end; + +// Íå ïåðåâåñòè â ÷èñëî: + if not TryStrToInt(name, NNF_FirstNum) then + Exit; + + NNF_CurrentNum := 0; + + Result := True; +end; + + +function g_Texture_NumNameFindNext(var newName: String): Byte; +begin + if (NNF_PureName = '') or (NNF_CurrentNum < 0) then + begin + newName := ''; + Result := NNF_NO_NAME; + Exit; + end; + + newName := NNF_PureName + IntToStr(NNF_CurrentNum); + + if NNF_CurrentNum < NNF_FirstNum then + Result := NNF_NAME_BEFORE + else + if NNF_CurrentNum > NNF_FirstNum then + Result := NNF_NAME_AFTER + else + Result := NNF_NAME_EQUALS; + + Inc(NNF_CurrentNum); +end; function panelTypeToTag (panelType: Word): Integer; @@ -599,7 +735,7 @@ begin PanelArray := nil; end; -function CreatePanel(PanelRec: TPanelRec_1; AddTextures: TAddTextureArray; +function CreatePanel(PanelRec: TDynRecord; AddTextures: TAddTextureArray; CurTex: Integer; sav: Boolean): Integer; var len: Integer; @@ -659,7 +795,7 @@ begin Width := 1; Height := 1; Anim := False; - TextureID := TEXTURE_NONE; + TextureID := LongWord(TEXTURE_NONE); end; end; @@ -692,13 +828,13 @@ begin TextureName := RecName; if TextureName = TEXTURE_NAME_WATER then - TextureID := TEXTURE_SPECIAL_WATER + TextureID := LongWord(TEXTURE_SPECIAL_WATER) else if TextureName = TEXTURE_NAME_ACID1 then - TextureID := TEXTURE_SPECIAL_ACID1 + TextureID := LongWord(TEXTURE_SPECIAL_ACID1) else if TextureName = TEXTURE_NAME_ACID2 then - TextureID := TEXTURE_SPECIAL_ACID2; + TextureID := LongWord(TEXTURE_SPECIAL_ACID2); Anim := False; end; @@ -972,7 +1108,7 @@ begin end; end; -procedure CreateItem(Item: TItemRec_1); +procedure CreateItem(Item: TDynRecord); begin if g_Game_IsClient then Exit; @@ -984,7 +1120,7 @@ begin gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF, GM_COOP]); end; -procedure CreateArea(Area: TAreaRec_1); +procedure CreateArea(Area: TDynRecord); var a: Integer; id: DWORD = 0; @@ -1054,7 +1190,7 @@ begin end; end; -procedure CreateTrigger(Trigger: TTriggerRec_1; fTexturePanel1Type, fTexturePanel2Type: Word); +procedure CreateTrigger(Trigger: TDynRecord; atpanid, ashotpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word); var _trigger: TTrigger; begin @@ -1073,13 +1209,16 @@ begin TriggerType := Trigger.TriggerType; ActivateType := Trigger.ActivateType; Keys := Trigger.Keys; - Data.Default := Trigger.DATA; + trigPanelId := atpanid; + trigShotPanelId := ashotpanid; + //Data.Default := Trigger.DATA; + trigData := Trigger.trigRec.clone(); end; g_Triggers_Create(_trigger); end; -procedure CreateMonster(monster: TMonsterRec_1); +procedure CreateMonster(monster: TDynRecord); var a: Integer; mon: TMonster; @@ -1097,7 +1236,8 @@ begin begin if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then begin - if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a); + //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a); + if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); end; end; end; @@ -1118,7 +1258,8 @@ procedure g_Map_ReAdd_DieTriggers(); begin if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then begin - if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a); + //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a); + if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); end; end; end; @@ -1147,29 +1288,45 @@ begin gExternalResources.Add(res); end; -procedure generateExternalResourcesList(mapReader: TMapReader_1); -var - textures: TTexturesRec1Array; - mapHeader: TMapHeaderRec_1; - i: integer; - resFile: String = ''; +procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord); +//var + //textures: TTexturesRec1Array; + //textures: TDynField; + //trec: TDynRecord; + //mapHeader: TMapHeaderRec_1; + //i: integer; + //resFile: String = ''; begin if gExternalResources = nil then gExternalResources := TStringList.Create; gExternalResources.Clear; - textures := mapReader.GetTextures(); + + (* + { + textures := GetTextures(map); for i := 0 to High(textures) do begin addResToExternalResList(resFile); end; + } + + textures := map['texture']; + if (textures <> nil) then + begin + for trec in textures do + begin + addResToExternalResList(resFile); + end; + end; textures := nil; + *) - mapHeader := mapReader.GetMapHeader; + //mapHeader := GetMapHeader(map); - addResToExternalResList(mapHeader.MusicName); - addResToExternalResList(mapHeader.SkyName); + addResToExternalResList(map.MusicName); + addResToExternalResList(map.SkyName); end; @@ -1289,50 +1446,66 @@ function g_Map_Load(Res: String): Boolean; const DefaultMusRes = 'Standart.wad:STDMUS\MUS1'; DefaultSkyRes = 'Standart.wad:STDSKY\SKY0'; +type + PTRec = ^TTRec; + TTRec = record + //TexturePanel: Integer; + texPanIdx: Integer; + LiftPanelIdx: Integer; + DoorPanelIdx: Integer; + ShotPanelIdx: Integer; + trigrec: TDynRecord; + texPan: TDynRecord; + liftPan: TDynRecord; + doorPan: TDynRecord; + shotPan: TDynRecord; + end; var WAD: TWADFile; - MapReader: TMapReader_1; - Header: TMapHeaderRec_1; - _textures: TTexturesRec1Array; - _texnummap: array of Integer; // `_textures` -> `Textures` - panels: TPanelsRec1Array; - items: TItemsRec1Array; - monsters: TMonsterRec1Array; - areas: TAreasRec1Array; - triggers: TTriggersRec1Array; - a, b, c, k: Integer; + //MapReader: TMapReader_1; + mapReader: TDynRecord = nil; + //Header: TMapHeaderRec_1; + _textures: TDynField = nil; //TTexturesRec1Array; tagInt: texture index + //_texnummap: array of Integer = nil; // `_textures` -> `Textures` + panels: TDynField = nil; //TPanelsRec1Array; + items: TDynField = nil; //TItemsRec1Array; + monsters: TDynField = nil; //TMonsterRec1Array; + areas: TDynField = nil; //TAreasRec1Array; + triggers: TDynField = nil; //TTriggersRec1Array; + b, c, k: Integer; PanelID: DWORD; AddTextures: TAddTextureArray; - texture: TTextureRec_1; - TriggersTable: Array of record - TexturePanel: Integer; - LiftPanel: Integer; - DoorPanel: Integer; - ShotPanel: Integer; - end; + //texture: TTextureRec_1; + TriggersTable: array of TTRec; FileName, mapResName, s, TexName: String; Data: Pointer; Len: Integer; ok, isAnim, trigRef: Boolean; CurTex, ntn: Integer; - {$IF DEFINED(D2D_NEW_MAP_READER)} - pr: TTextParser = nil; - st: TStream = nil; - wst: TSFSMemoryChunkStream = nil; - rec: TDynRecord; - {$ENDIF} + rec, texrec: TDynRecord; + pttit: PTRec; + pannum, trignum, cnt: Integer; + // key: panel index; value: `TriggersTable` index + hashTextPan: THashIntInt = nil; + hashLiftPan: THashIntInt = nil; + hashDoorPan: THashIntInt = nil; + hashShotPan: THashIntInt = nil; begin mapGrid.Free(); mapGrid := nil; + gCurrentMap.Free(); + gCurrentMap := nil; + Result := False; gMapInfo.Map := Res; TriggersTable := nil; - FillChar(texture, SizeOf(texture), 0); + mapReader := nil; + //FillChar(texture, SizeOf(texture), 0); sfsGCDisable(); // temporary disable removing of temporary volumes try - // Çàãðóçêà WAD: + // Çàãðóçêà WAD: FileName := g_ExtractWadName(Res); e_WriteLog('Loading map WAD: '+FileName, MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_WAD_FILE], 0, False); @@ -1367,420 +1540,473 @@ begin e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False); - {$IF DEFINED(D2D_NEW_MAP_READER)} - if (PChar(Data)[0] = 'M') and (PChar(Data)[1] = 'A') and (PChar(Data)[2] = 'P') and (PByte(Data)[3] = 1) then - begin - // nothing - end - else - begin - e_LogWritefln('Loading text map: %s', [mapResName]); - loadMapDefinition(); - if (dfmapdef = nil) then raise Exception.Create('internal map loader error'); - //e_LogWritefln('***'#10'%s'#10'***', [dfmapdef.headerType.definition]); - wst := TSFSMemoryChunkStream.Create(Data, Len); - try - pr := TFileTextParser.Create(wst); - e_LogWritefln('parsing text map: %s', [mapResName]); - rec := dfmapdef.parseMap(pr); - except on e: Exception do - begin - if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message]) - else e_LogWritefln('ERROR: %s', [e.message]); - pr.Free(); - wst.Free(); - FreeMem(Data); - exit; - end; - end; - pr.Free(); - //wst.Free(); // pr will do it - e_LogWritefln('writing text map to temporary bin storage...', []); - st := TMemoryStream.Create(); - try - rec.writeBinTo(st); - Len := Integer(st.position); - st.position := 0; - FreeMem(Data); - GetMem(Data, Len); - st.ReadBuffer(Data^, Len); - except on e: Exception do - begin - rec.Free(); - st.Free(); - e_LogWritefln('ERROR: %s', [e.message]); - FreeMem(Data); - exit; - end; - end; - st.Free(); - end; - {$ENDIF} - - MapReader := TMapReader_1.Create(); - - if not MapReader.LoadMap(Data) then - begin + try + mapReader := g_Map_ParseMap(Data, Len); + except + mapReader.Free(); g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res])); FreeMem(Data); - MapReader.Free(); Exit; end; FreeMem(Data); - generateExternalResourcesList(MapReader); - // Çàãðóçêà òåêñòóð: - g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False); - _textures := MapReader.GetTextures(); - _texnummap := nil; - // Çàãðóçêà îïèñàíèÿ êàðòû: + hashTextPan := hashNewIntInt(); + hashLiftPan := hashNewIntInt(); + hashDoorPan := hashNewIntInt(); + hashShotPan := hashNewIntInt(); + + generateExternalResourcesList(MapReader); + //_textures := GetTextures(mapReader); + _textures := mapReader['texture']; + //_texnummap := nil; + // get all other lists here too + //panels := GetPanels(mapReader); + panels := mapReader['panel']; + //triggers := GetTriggers(mapReader); + triggers := mapReader['trigger']; + //items := GetItems(mapReader); + items := mapReader['item']; + //areas := GetAreas(mapReader); + areas := mapReader['area']; + //monsters := GetMonsters(mapReader); + monsters := mapReader['monster']; + + // Çàãðóçêà îïèñàíèÿ êàðòû: e_WriteLog(' Reading map info...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MAP_HEADER], 0, False); - Header := MapReader.GetMapHeader(); + //Header := GetMapHeader(mapReader); with gMapInfo do begin - Name := Header.MapName; - Description := Header.MapDescription; - Author := Header.MapAuthor; - MusicName := Header.MusicName; - SkyName := Header.SkyName; - Height := Header.Height; - Width := Header.Width; + Name := mapReader.MapName; + Description := mapReader.MapDesc; + Author := mapReader.MapAuthor; + MusicName := mapReader.MusicName; + SkyName := mapReader.SkyName; + Height := mapReader.Height; + Width := mapReader.Width; end; - // Äîáàâëåíèå òåêñòóð â Textures[]: - if _textures <> nil then + // Çàãðóçêà òåêñòóð: + g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False); + // Äîáàâëåíèå òåêñòóð â Textures[]: + if (_textures <> nil) and (_textures.count > 0) then begin e_WriteLog(' Loading textures:', MSG_NOTIFY); - g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], High(_textures), False); - SetLength(_texnummap, length(_textures)); + g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], _textures.count-1, False); + //SetLength(_texnummap, _textures.count); - for a := 0 to High(_textures) do + cnt := -1; + for rec in _textures do begin - SetLength(s, 64); - CopyMemory(@s[1], @_textures[a].Resource[0], 64); - for b := 1 to Length(s) do - begin - if s[b] = #0 then - begin - SetLength(s, b-1); - Break; - end; - end; - {$IF DEFINED(D2F_DEBUG)} - e_WriteLog(Format(' Loading texture #%d: %s', [a, s]), MSG_NOTIFY); + Inc(cnt); + s := rec.Resource; + {$IF DEFINED(D2F_DEBUG_TXLOAD)} + e_WriteLog(Format(' Loading texture #%d: %s', [cnt, s]), MSG_NOTIFY); {$ENDIF} //if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY); - // Àíèìèðîâàííàÿ òåêñòóðà: - if ByteBool(_textures[a].Anim) then - begin - ntn := CreateAnimTexture(_textures[a].Resource, FileName, True); - if ntn < 0 then - begin - g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [s])); - ntn := CreateNullTexture(_textures[a].Resource); - end; - end - else // Îáû÷íàÿ òåêñòóðà: - ntn := CreateTexture(_textures[a].Resource, FileName, True); - if ntn < 0 then - begin - g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [s])); - ntn := CreateNullTexture(_textures[a].Resource); - end; + if rec.Anim then + begin + // Àíèìèðîâàííàÿ òåêñòóðà + ntn := CreateAnimTexture(rec.Resource, FileName, True); + if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [s])); + end + else + begin + // Îáû÷íàÿ òåêñòóðà + ntn := CreateTexture(rec.Resource, FileName, True); + if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [s])); + end; + if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); - _texnummap[a] := ntn; // fix texture number + //_texnummap[a] := ntn; // fix texture number + rec.tagInt := ntn; g_Game_StepLoading(); end; + + // set panel tagInt to texture index + if (panels <> nil) then + begin + for rec in panels do + begin + texrec := rec.TextureRec; + if (texrec = nil) then rec.tagInt := -1 else rec.tagInt := texrec.tagInt; + end; + end; end; - // Çàãðóçêà òðèããåðîâ: + // Çàãðóçêà òðèããåðîâ gTriggerClientID := 0; e_WriteLog(' Loading triggers...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS], 0, False); - triggers := MapReader.GetTriggers(); - // Çàãðóçêà ïàíåëåé: + // Çàãðóçêà ïàíåëåé e_WriteLog(' Loading panels...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_PANELS], 0, False); - panels := MapReader.GetPanels(); // check texture numbers for panels - for a := 0 to High(panels) do + if (panels <> nil) and (panels.count > 0) then begin - if panels[a].TextureNum > High(_textures) then + for rec in panels do begin - e_WriteLog('error loading map: invalid texture index for panel', MSG_FATALERROR); - result := false; - exit; + if (rec.tagInt < 0) then + begin + e_WriteLog('error loading map: invalid texture index for panel', MSG_FATALERROR); + result := false; + exit; + end; end; - panels[a].TextureNum := _texnummap[panels[a].TextureNum]; end; - // Ñîçäàíèå òàáëèöû òðèããåðîâ (ñîîòâåòñòâèå ïàíåëåé òðèããåðàì): - if triggers <> nil then + // Ñîçäàíèå òàáëèöû òðèããåðîâ (ñîîòâåòñòâèå ïàíåëåé òðèããåðàì) + if (triggers <> nil) and (triggers.count > 0) then begin e_WriteLog(' Setting up trigger table...', MSG_NOTIFY); - SetLength(TriggersTable, Length(triggers)); - g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS_TABLE], High(TriggersTable), False); + //SetLength(TriggersTable, triggers.count); + g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS_TABLE], triggers.count-1, False); - for a := 0 to High(TriggersTable) do + for rec in triggers do begin - // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè): - TriggersTable[a].TexturePanel := triggers[a].TexturePanel; - // Ëèôòû: - if triggers[a].TriggerType in [TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then - TriggersTable[a].LiftPanel := TTriggerData(triggers[a].DATA).PanelID - else - TriggersTable[a].LiftPanel := -1; - // Äâåðè: - if triggers[a].TriggerType in [TRIGGER_OPENDOOR, - TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, - TRIGGER_CLOSETRAP, TRIGGER_TRAP] then - TriggersTable[a].DoorPanel := TTriggerData(triggers[a].DATA).PanelID - else - TriggersTable[a].DoorPanel := -1; - // Òóðåëü: - if triggers[a].TriggerType = TRIGGER_SHOT then - TriggersTable[a].ShotPanel := TTriggerData(triggers[a].DATA).ShotPanelID - else - TriggersTable[a].ShotPanel := -1; + SetLength(TriggersTable, Length(TriggersTable)+1); + pttit := @TriggersTable[High(TriggersTable)]; + pttit.trigrec := rec; + pttit.texPan := mapReader.panel[rec.TexturePanel]; + pttit.liftPan := nil; + pttit.doorPan := nil; + pttit.shotPan := nil; + pttit.texPanIdx := -1; + pttit.LiftPanelIdx := -1; + pttit.DoorPanelIdx := -1; + pttit.ShotPanelIdx := -1; + // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè) + //if (rec.TexturePanel >= 0) and (pttit.texPan = nil) then e_WriteLog('error loading map: invalid texture panel index for trigger', MSG_WARNING); + // Ëèôòû + if rec.TriggerType in [TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then + begin + //pttit.LiftPanel := TTriggerData(rec.DATA).PanelID + pttit.liftPan := mapReader.panel[rec.trigRec.tgPanelID]; + //if (rec.trigRec.trigPanelID >= 0) and (pttit.liftPan = nil) then e_WriteLog('error loading map: invalid lift panel index for trigger', MSG_WARNING); + end; + // Äâåðè + if rec.TriggerType in [TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP] then + begin + //pttit.DoorPanel := TTriggerData(rec.DATA).PanelID + pttit.doorPan := mapReader.panel[rec.trigRec.tgPanelID]; + end; + // Òóðåëü + if (rec.TriggerType = TRIGGER_SHOT) then + begin + //pttit.ShotPanel := TTriggerData(rec.DATA).ShotPanelID + pttit.shotPan := mapReader.panel[rec.trigRec.tgShotPanelID]; + end; + + // update hashes + if (pttit.texPan <> nil) then hashTextPan.put(rec.TexturePanel, High(TriggersTable)); + if (pttit.liftPan <> nil) then hashLiftPan.put(rec.trigRec.tgPanelID, High(TriggersTable)); + if (pttit.doorPan <> nil) then hashDoorPan.put(rec.trigRec.tgPanelID, High(TriggersTable)); + if (pttit.shotPan <> nil) then hashShotPan.put(rec.trigRec.tgShotPanelID, High(TriggersTable)); g_Game_StepLoading(); end; end; - // Ñîçäàåì ïàíåëè: - if panels <> nil then + // Ñîçäàåì ïàíåëè + if (panels <> nil) and (panels.count > 0) then begin e_WriteLog(' Setting up trigger links...', MSG_NOTIFY); - g_Game_SetLoadingText(_lc[I_LOAD_LINK_TRIGGERS], High(panels), False); + g_Game_SetLoadingText(_lc[I_LOAD_LINK_TRIGGERS], panels.count-1, False); - for a := 0 to High(panels) do + pannum := -1; + for rec in panels do begin + Inc(pannum); + texrec := nil; SetLength(AddTextures, 0); trigRef := False; CurTex := -1; - if _textures <> nil then - begin - texture := _textures[panels[a].TextureNum]; - ok := True; - end - else - ok := False; + ok := false; + + if (_textures <> nil) then + begin + texrec := rec.TextureRec; + ok := (texrec <> nil); + end; if ok then begin - // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû. - // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð: - ok := False; + // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû. + // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð + ok := false; if (TriggersTable <> nil) and (_textures <> nil) then + begin for b := 0 to High(TriggersTable) do - if (TriggersTable[b].TexturePanel = a) - or (TriggersTable[b].ShotPanel = a) then + begin + if (TriggersTable[b].texPan = rec) or (TriggersTable[b].shotPan = rec) then begin trigRef := True; ok := True; - Break; + break; end; + end; + end; end; if ok then - begin // Åñòü ññûëêè òðèããåðîâ íà ýòó ïàíåëü - SetLength(s, 64); - CopyMemory(@s[1], @texture.Resource[0], 64); - // Èçìåðÿåì äëèíó: - Len := Length(s); - for c := Len downto 1 do - if s[c] <> #0 then - begin - Len := c; - Break; - end; - SetLength(s, Len); + begin + // Åñòü ññûëêè òðèããåðîâ íà ýòó ïàíåëü + s := texrec.Resource; - // Ñïåö-òåêñòóðû çàïðåùåíû: + // Ñïåö-òåêñòóðû çàïðåùåíû if g_Map_IsSpecialTexture(s) then - ok := False + begin + ok := false + end else - // Îïðåäåëÿåì íàëè÷èå è ïîëîæåíèå öèôð â êîíöå ñòðîêè: + begin + // Îïðåäåëÿåì íàëè÷èå è ïîëîæåíèå öèôð â êîíöå ñòðîêè ok := g_Texture_NumNameFindStart(s); + end; - // Åñëè ok, çíà÷èò åñòü öèôðû â êîíöå. - // Çàãðóæàåì òåêñòóðû ñ îñòàëüíûìè #: + // Åñëè ok, çíà÷èò åñòü öèôðû â êîíöå. + // Çàãðóæàåì òåêñòóðû ñ îñòàëüíûìè # if ok then begin k := NNF_NAME_BEFORE; - // Öèêë ïî èçìåíåíèþ èìåíè òåêñòóðû: - while ok or (k = NNF_NAME_BEFORE) or - (k = NNF_NAME_EQUALS) do + // Öèêë ïî èçìåíåíèþ èìåíè òåêñòóðû + while ok or (k = NNF_NAME_BEFORE) or (k = NNF_NAME_EQUALS) do begin k := g_Texture_NumNameFindNext(TexName); - if (k = NNF_NAME_BEFORE) or - (k = NNF_NAME_AFTER) then + if (k = NNF_NAME_BEFORE) or (k = NNF_NAME_AFTER) then + begin + // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó + if texrec.Anim then begin - // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó: - if ByteBool(texture.Anim) then - begin // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ - isAnim := True; - ok := CreateAnimTexture(TexName, FileName, False) >= 0; - if not ok then - begin // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ - isAnim := False; - ok := CreateTexture(TexName, FileName, False) >= 0; - end; - end - else - begin // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ - isAnim := False; - ok := CreateTexture(TexName, FileName, False) >= 0; - if not ok then - begin // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ - isAnim := True; - ok := CreateAnimTexture(TexName, FileName, False) >= 0; - end; - end; - - // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè: - if ok then + // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ + isAnim := True; + ok := CreateAnimTexture(TexName, FileName, False) >= 0; + if not ok then begin - for c := 0 to High(Textures) do - if Textures[c].TextureName = TexName then - begin - SetLength(AddTextures, Length(AddTextures)+1); - AddTextures[High(AddTextures)].Texture := c; - AddTextures[High(AddTextures)].Anim := isAnim; - Break; - end; + // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ + isAnim := False; + ok := CreateTexture(TexName, FileName, False) >= 0; end; end + else + begin + // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ + isAnim := False; + ok := CreateTexture(TexName, FileName, False) >= 0; + if not ok then + begin + // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ + isAnim := True; + ok := CreateAnimTexture(TexName, FileName, False) >= 0; + end; + end; + + // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè + if ok then + begin + for c := 0 to High(Textures) do + begin + if (Textures[c].TextureName = TexName) then + begin + SetLength(AddTextures, Length(AddTextures)+1); + AddTextures[High(AddTextures)].Texture := c; + AddTextures[High(AddTextures)].Anim := isAnim; + break; + end; + end; + end; + end else + begin if k = NNF_NAME_EQUALS then - begin - // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî: - SetLength(AddTextures, Length(AddTextures)+1); - AddTextures[High(AddTextures)].Texture := panels[a].TextureNum; - AddTextures[High(AddTextures)].Anim := ByteBool(texture.Anim); - CurTex := High(AddTextures); - ok := True; - end + begin + // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî + SetLength(AddTextures, Length(AddTextures)+1); + //AddTextures[High(AddTextures)].Texture := _texnummap[rec.TextureNum]; //panels[a].TextureNum; + AddTextures[High(AddTextures)].Texture := rec.tagInt; //panels[a].TextureNum; + AddTextures[High(AddTextures)].Anim := texrec.Anim; + CurTex := High(AddTextures); + ok := true; + end else // NNF_NO_NAME - ok := False; + begin + ok := false; + end; + end; end; // while ok... - ok := True; + ok := true; end; // if ok - åñòü ñìåæíûå òåêñòóðû end; // if ok - ññûëàþòñÿ òðèããåðû if not ok then begin - // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó: + // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó SetLength(AddTextures, 1); - AddTextures[0].Texture := panels[a].TextureNum; - AddTextures[0].Anim := ByteBool(texture.Anim); + AddTextures[0].Texture := rec.tagInt; //panels[a].TextureNum; + AddTextures[0].Anim := false; + if (texrec <> nil) then AddTextures[0].Anim := texrec.Anim; CurTex := 0; end; //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); - // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð: - PanelID := CreatePanel(panels[a], AddTextures, CurTex, trigRef); + // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð + PanelID := CreatePanel(rec, AddTextures, CurTex, trigRef); + //e_LogWritefln('panel #%s of type %s got id #%s', [pannum, rec.PanelType, PanelID]); + + // Åñëè èñïîëüçóåòñÿ â òðèããåðàõ, òî ñòàâèì òî÷íûé ID + if hashTextPan.get(pannum, b) then TriggersTable[b].texPanIdx := PanelID; + if hashLiftPan.get(pannum, b) then TriggersTable[b].LiftPanelIdx := PanelID; + if hashDoorPan.get(pannum, b) then TriggersTable[b].DoorPanelIdx := PanelID; + if hashShotPan.get(pannum, b) then TriggersTable[b].ShotPanelIdx := PanelID; - // Åñëè èñïîëüçóåòñÿ â òðèããåðàõ, òî ñòàâèì òî÷íûé ID: - if TriggersTable <> nil then + (* + if (TriggersTable <> nil) then + begin for b := 0 to High(TriggersTable) do begin - // Òðèããåð äâåðè/ëèôòà: - if (TriggersTable[b].LiftPanel = a) or - (TriggersTable[b].DoorPanel = a) then - TTriggerData(triggers[b].DATA).PanelID := PanelID; - // Òðèããåð ñìåíû òåêñòóðû: - if TriggersTable[b].TexturePanel = a then - triggers[b].TexturePanel := PanelID; - // Òðèããåð "Òóðåëü": - if TriggersTable[b].ShotPanel = a then - TTriggerData(triggers[b].DATA).ShotPanelID := PanelID; + if (TriggersTable[b].texPan = rec) then TriggersTable[b].texPanIdx := PanelID; + if (TriggersTable[b].liftPan = rec) then TriggersTable[b].LiftPanelIdx := PanelID; + if (TriggersTable[b].doorPan = rec) then TriggersTable[b].DoorPanelIdx := PanelID; + if (TriggersTable[b].shotPan = rec) then TriggersTable[b].ShotPanelIdx := PanelID; + { + // Òðèããåð äâåðè/ëèôòà + if (TriggersTable[b].LiftPanel = pannum) or + (TriggersTable[b].DoorPanel = pannum) then + //TTriggerData(TriggersTable[b].trigrec.DATA).PanelID := PanelID; + TriggersTable[b].trigrec.trigRec.trigPanelID := PanelID; + // Òðèããåð ñìåíû òåêñòóðû + if TriggersTable[b].texPanIdx = pannum then + TriggersTable[b].trigrec.TexturePanel := PanelID; + // Òðèããåð "Òóðåëü" + if TriggersTable[b].ShotPanel = pannum then + TriggersTable[b].trigrec.trigRec.trigShotPanelID := PanelID; + } end; + end; + *) g_Game_StepLoading(); end; end; + (* + begin + for b := 0 to High(TriggersTable) do + begin + // Òðèããåð äâåðè/ëèôòà + if (TriggersTable[b].texPan <> nil) then e_LogWritefln('trigger #%s: textPan=%s; panidx=%s', [b, TriggersTable[b].texPanIdx, mapReader.panelIndex[TriggersTable[b].texPan]]); + if (TriggersTable[b].liftPan <> nil) then e_LogWritefln('trigger #%s: liftPan=%s; panidx=%s', [b, TriggersTable[b].LiftPanelIdx, mapReader.panelIndex[TriggersTable[b].liftPan]]); + if (TriggersTable[b].doorPan <> nil) then e_LogWritefln('trigger #%s: doorPan=%s; panidx=%s', [b, TriggersTable[b].DoorPanelIdx, mapReader.panelIndex[TriggersTable[b].doorPan]]); + if (TriggersTable[b].shotPan <> nil) then e_LogWritefln('trigger #%s: shotPan=%s; panidx=%s', [b, TriggersTable[b].ShotPanelIdx, mapReader.panelIndex[TriggersTable[b].shotPan]]); + end; + end; + *) + // create map grid, init other grids (for monsters, for example) e_WriteLog('Creating map grid', MSG_NOTIFY); mapCreateGrid(); - // Åñëè íå LoadState, òî ñîçäàåì òðèããåðû: - if (triggers <> nil) and not gLoadGameMode then + // Åñëè íå LoadState, òî ñîçäàåì òðèããåðû + if (triggers <> nil) and (panels <> nil) and (not gLoadGameMode) then begin - e_WriteLog(' Creating triggers...', MSG_NOTIFY); + e_LogWritefln(' Creating triggers (%d)...', [triggers.count]); g_Game_SetLoadingText(_lc[I_LOAD_CREATE_TRIGGERS], 0, False); - // Óêàçûâàåì òèï ïàíåëè, åñëè åñòü: - for a := 0 to High(triggers) do + // Óêàçûâàåì òèï ïàíåëè, åñëè åñòü + trignum := -1; + for rec in triggers do begin - if triggers[a].TexturePanel <> -1 then - b := panels[TriggersTable[a].TexturePanel].PanelType + Inc(trignum); + if (TriggersTable[trignum].texPan <> nil) then b := TriggersTable[trignum].texPan.PanelType else b := 0; + if (TriggersTable[trignum].shotPan <> nil) then c := TriggersTable[trignum].shotPan.PanelType else c := 0; + (* + if (rec.TexturePanel <> -1) then + begin + { + if (TriggersTable[trignum].TexturePanel < 0) or (TriggersTable[trignum].TexturePanel >= panels.count) then + begin + e_WriteLog('error loading map: invalid panel index for trigger', MSG_FATALERROR); + result := false; + exit; + end; + } + //b := panels[TriggersTable[a].TexturePanel].PanelType; + //b := mapReader.panel[TriggersTable[trignum].texPanIdx].PanelType; + assert(TriggersTable[trignum].texPanIdx >= 0); + b := TriggersTable[trignum].texPanIdx; + end else + begin b := 0; - if (triggers[a].TriggerType = TRIGGER_SHOT) and - (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then - c := panels[TriggersTable[a].ShotPanel].PanelType + end; + e_LogWritefln('trigger #%s: type=%s; texPanIdx=%s; b=%s', [trignum, rec.TriggerType, TriggersTable[trignum].texPanIdx, b]); + if (rec.TriggerType = TRIGGER_SHOT) then e_LogWritefln(' SHOT: shotpanidx=%s', [rec.trigRec.trigShotPanelID]); + if (rec.TriggerType = TRIGGER_SHOT) and {(rec.trigRec.trigShotPanelID <> -1)} (TriggersTable[trignum].shotPan <> nil) then + begin + //c := panels[TriggersTable[a].ShotPanel].PanelType; + //c := mapReader.panel[TriggersTable[trignum].ShotPanel].PanelType; + assert(TriggersTable[trignum].ShotPanelIdx >= 0); + c := TriggersTable[trignum].ShotPanelIdx; + end else + begin c := 0; - CreateTrigger(triggers[a], b, c); + end; + *) + //e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]); + CreateTrigger(rec, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx, Word(b), Word(c)); end; end; - // Çàãðóçêà ïðåäìåòîâ: - e_WriteLog(' Loading triggers...', MSG_NOTIFY); + // Çàãðóçêà ïðåäìåòîâ + e_WriteLog(' Loading items...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_ITEMS], 0, False); - items := MapReader.GetItems(); - // Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû: + // Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû if (items <> nil) and not gLoadGameMode then begin e_WriteLog(' Spawning items...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_CREATE_ITEMS], 0, False); - for a := 0 to High(items) do - CreateItem(Items[a]); + for rec in items do CreateItem(rec); end; - // Çàãðóçêà îáëàñòåé: + // Çàãðóçêà îáëàñòåé e_WriteLog(' Loading areas...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_AREAS], 0, False); - areas := MapReader.GetAreas(); - // Åñëè íå LoadState, òî ñîçäàåì îáëàñòè: + // Åñëè íå LoadState, òî ñîçäàåì îáëàñòè if areas <> nil then begin e_WriteLog(' Creating areas...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_CREATE_AREAS], 0, False); - for a := 0 to High(areas) do - CreateArea(areas[a]); + for rec in areas do CreateArea(rec); end; - // Çàãðóçêà ìîíñòðîâ: + // Çàãðóçêà ìîíñòðîâ e_WriteLog(' Loading monsters...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MONSTERS], 0, False); - monsters := MapReader.GetMonsters(); gTotalMonsters := 0; - // Åñëè íå LoadState, òî ñîçäàåì ìîíñòðîâ: + // Åñëè íå LoadState, òî ñîçäàåì ìîíñòðîâ if (monsters <> nil) and not gLoadGameMode then begin e_WriteLog(' Spawning monsters...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_CREATE_MONSTERS], 0, False); - for a := 0 to High(monsters) do - CreateMonster(monsters[a]); + for rec in monsters do CreateMonster(rec); end; - MapReader.Free(); + //MapReader.Free(); + gCurrentMap := mapReader; + mapReader := nil; - // Çàãðóçêà íåáà: + // Çàãðóçêà íåáà if gMapInfo.SkyName <> '' then begin e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, MSG_NOTIFY); @@ -1803,7 +2029,7 @@ begin g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s])); end; - // Çàãðóçêà ìóçûêè: + // Çàãðóçêà ìóçûêè ok := False; if gMapInfo.MusicName <> '' then begin @@ -1825,7 +2051,7 @@ begin g_FatalError(Format(_lc[I_GAME_ERROR_MUSIC], [s])); end; - // Îñòàëüíûå óñòàíâêè: + // Îñòàëüíûå óñòàíâêè CreateDoorMap(); CreateLiftMap(); @@ -1833,11 +2059,10 @@ begin g_Weapon_Init(); g_Monsters_Init(); - // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé: - if not gLoadGameMode then - g_GFX_Init(); + // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé: + if not gLoadGameMode then g_GFX_Init(); - // Ñáðîñ ëîêàëüíûõ ìàññèâîâ: + // Ñáðîñ ëîêàëüíûõ ìàññèâîâ: _textures := nil; panels := nil; items := nil; @@ -1846,16 +2071,23 @@ begin TriggersTable := nil; AddTextures := nil; - // Âêëþ÷àåì ìóçûêó, åñëè ýòî íå çàãðóçêà: + // Âêëþ÷àåì ìóçûêó, åñëè ýòî íå çàãðóçêà: if ok and (not gLoadGameMode) then - begin - gMusic.SetByName(gMapInfo.MusicName); - gMusic.Play(); - end + begin + gMusic.SetByName(gMapInfo.MusicName); + gMusic.Play(); + end else + begin gMusic.SetByName(''); + end; finally sfsGCEnable(); // enable releasing unused volumes + mapReader.Free(); + hashTextPan.Free(); + hashLiftPan.Free(); + hashDoorPan.Free(); + hashShotPan.Free(); end; e_WriteLog('Done loading map.', MSG_NOTIFY); @@ -1865,8 +2097,8 @@ end; function g_Map_GetMapInfo(Res: String): TMapInfo; var WAD: TWADFile; - MapReader: TMapReader_1; - Header: TMapHeaderRec_1; + MapReader: TDynRecord; + //Header: TMapHeaderRec_1; FileName: String; Data: Pointer; Len: Integer; @@ -1890,8 +2122,8 @@ begin WAD.Free(); + { MapReader := TMapReader_1.Create(); - if not MapReader.LoadMap(Data) then begin g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True); @@ -1905,14 +2137,41 @@ begin Result.Name := Header.MapName; Result.Description := Header.MapDescription; end; + } + try + mapReader := g_Map_ParseMap(Data, Len); + except + mapReader := nil; + end; FreeMem(Data); - MapReader.Free(); + //MapReader.Free(); + + //if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0); + //MapReader.Free(); + + if (mapReader.Width > 0) and (mapReader.Height > 0) then + begin + Result.Name := mapReader.MapName; + Result.Description := mapReader.MapDesc; + Result.Map := Res; + Result.Author := mapReader.MapAuthor; + Result.Height := mapReader.Height; + Result.Width := mapReader.Width; + end + else + begin + g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True); + //ZeroMemory(@Header, SizeOf(Header)); + Result.Name := _lc[I_GAME_ERROR_MAP_SELECT]; + Result.Description := _lc[I_GAME_ERROR_MAP_SELECT]; + Result.Map := Res; + Result.Author := ''; + Result.Height := 0; + Result.Width := 0; + end; - Result.Map := Res; - Result.Author := Header.MapAuthor; - Result.Height := Header.Height; - Result.Width := Header.Width; + mapReader.Free(); end; function g_Map_GetMapsList(WADName: string): SArray; @@ -2016,7 +2275,7 @@ begin if Textures[a].Anim then g_Frames_DeleteByID(Textures[a].FramesID) else - if Textures[a].TextureID <> TEXTURE_NONE then + if Textures[a].TextureID <> LongWord(TEXTURE_NONE) then e_DeleteTexture(Textures[a].TextureID); Textures := nil; @@ -2354,7 +2613,7 @@ var end; begin - texid := TEXTURE_NONE; + texid := LongWord(TEXTURE_NONE); result := texid; if not checkPanels(gWater) then if not checkPanels(gAcid1) then @@ -2481,7 +2740,7 @@ begin if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquids'); if gdbg_map_use_accel_coldet then begin - texid := TEXTURE_NONE; + texid := LongWord(TEXTURE_NONE); if (Width = 1) and (Height = 1) then begin mapGrid.forEachAtPoint(X, Y, checker, (GridTagWater or GridTagAcid1 or GridTagAcid2));