X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=f2922d4a9622c4f47d342a973a4e58b79d8b4694;hb=2b647061c5ce08e02c046c3ef8e0a31917cc28f3;hp=924dc000ada380a2b1b7a9010bffa327148b06fa;hpb=6d6df4e3427cd01e03e172984c9d0d391ff38032;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 924dc00..f2922d4 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -201,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 @@ -219,7 +221,7 @@ uses GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG, g_options, g_triggers, g_player, Math, g_monsters, g_saveload, g_language, g_netmsg, - utils, sfs, xstreams, + utils, sfs, xstreams, hashtable, ImagingTypes, Imaging, ImagingUtility, ImagingGif, ImagingNetworkGraphics; @@ -232,7 +234,6 @@ const var dfmapdef: TDynMapDef = nil; - procedure loadMapDefinition (); var pr: TTextParser = nil; @@ -734,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; @@ -1107,7 +1108,7 @@ begin end; end; -procedure CreateItem(Item: TItemRec_1); +procedure CreateItem(Item: TDynRecord); begin if g_Game_IsClient then Exit; @@ -1119,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; @@ -1189,7 +1190,7 @@ begin end; end; -procedure CreateTrigger(Trigger: TTriggerRec_1; fTexturePanel1Type, fTexturePanel2Type: Word); +procedure CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word); var _trigger: TTrigger; begin @@ -1197,24 +1198,41 @@ begin with _trigger do begin + mapId := Trigger.id; + mapIndex := amapIdx; X := Trigger.X; Y := Trigger.Y; Width := Trigger.Width; Height := Trigger.Height; - Enabled := ByteBool(Trigger.Enabled); - TexturePanel := Trigger.TexturePanel; + Enabled := Trigger.Enabled; + //TexturePanel := Trigger.TexturePanel; + TexturePanel := atpanid; TexturePanelType := fTexturePanel1Type; ShotPanelType := fTexturePanel2Type; TriggerType := Trigger.TriggerType; ActivateType := Trigger.ActivateType; Keys := Trigger.Keys; - Data.Default := Trigger.DATA; + trigPanelId := atrigpanid; + //trigShotPanelId := ashotpanid; + //Data.Default := Trigger.DATA; + if (Trigger.trigRec = nil) then + begin + trigData := nil; + if (TriggerType <> TRIGGER_SECRET) then + begin + e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [TriggerType], MSG_WARNING); + end; + end + else + begin + trigData := Trigger.trigRec.clone(); + end; end; g_Triggers_Create(_trigger); end; -procedure CreateMonster(monster: TMonsterRec_1); +procedure CreateMonster(monster: TDynRecord); var a: Integer; mon: TMonster; @@ -1232,7 +1250,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; @@ -1246,6 +1265,7 @@ procedure g_Map_ReAdd_DieTriggers(); function monsDieTrig (mon: TMonster): Boolean; var a: Integer; + //tw: TStrTextWriter; begin result := false; // don't stop mon.ClearTriggers(); @@ -1253,7 +1273,17 @@ 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); + { + tw := TStrTextWriter.Create(); + try + gTriggers[a].trigData.writeTo(tw); + e_LogWritefln('=== trigger #%s ==='#10'%s'#10'---', [a, tw.str]); + finally + tw.Free(); + end; + } + if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); end; end; end; @@ -1283,28 +1313,44 @@ begin end; procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord); -var - textures: TTexturesRec1Array; - mapHeader: TMapHeaderRec_1; - i: integer; - resFile: String = ''; +//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 := 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 := GetMapHeader(map); + //mapHeader := GetMapHeader(map); - addResToExternalResList(mapHeader.MusicName); - addResToExternalResList(mapHeader.SkyName); + addResToExternalResList(map.MusicName); + addResToExternalResList(map.SkyName); end; @@ -1424,45 +1470,56 @@ 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; mapReader: TDynRecord = nil; - 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; + mapTextureList: TDynField = nil; //TTexturesRec1Array; tagInt: texture index + 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; + TriggersTable: array of TTRec; FileName, mapResName, s, TexName: String; Data: Pointer; Len: Integer; ok, isAnim, trigRef: Boolean; CurTex, ntn: Integer; + rec, texrec: TDynRecord; + pttit: PTRec; + pannum, trignum, cnt, tgpid: Integer; begin mapGrid.Free(); mapGrid := nil; + gCurrentMap.Free(); + gCurrentMap := nil; + Result := False; gMapInfo.Map := Res; TriggersTable := nil; - FillChar(texture, SizeOf(texture), 0); + mapReader := nil; 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); @@ -1497,443 +1554,382 @@ begin e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False); - { - 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; - } 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; - { - MapReader := TMapReader_1.Create(); - if not MapReader.LoadMap(Data) then - begin - 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 := GetTextures(mapReader); - _texnummap := nil; - // Çàãðóçêà îïèñàíèÿ êàðòû: + generateExternalResourcesList(mapReader); + mapTextureList := mapReader['texture']; + // get all other lists here too + panels := mapReader['panel']; + triggers := mapReader['trigger']; + items := mapReader['item']; + areas := mapReader['area']; + monsters := mapReader['monster']; + + // Çàãðóçêà îïèñàíèÿ êàðòû: e_WriteLog(' Reading map info...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MAP_HEADER], 0, False); - 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 (mapTextureList <> nil) and (mapTextureList.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], mapTextureList.count-1, False); - for a := 0 to High(_textures) do + cnt := -1; + for rec in mapTextureList 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 + rec.tagInt := ntn; // remember texture number 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 := GetTriggers(mapReader); - // Çàãðóçêà ïàíåëåé: + // Çàãðóçêà ïàíåëåé e_WriteLog(' Loading panels...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_PANELS], 0, False); - panels := GetPanels(mapReader); // 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.TriggerType in [TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then + begin + pttit.liftPan := mapReader.panel[rec.trigRec.tgPanelID]; + end; + // Äâåðè + if rec.TriggerType in [TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP] then + begin + pttit.doorPan := mapReader.panel[rec.trigRec.tgPanelID]; + end; + // Òóðåëü + if (rec.TriggerType = TRIGGER_SHOT) then + begin + pttit.shotPan := mapReader.panel[rec.trigRec.tgShotPanelID]; + end; 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 (mapTextureList <> nil) then + begin + texrec := rec.TextureRec; + ok := (texrec <> nil); + end; if ok then begin - // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû. - // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð: - ok := False; - if (TriggersTable <> nil) and (_textures <> nil) then + // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû. + // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð + ok := false; + if (TriggersTable <> nil) and (mapTextureList <> 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 := rec.tagInt; // internal texture number, not map index + 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; // internal texture number, not map index + 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); + //e_WriteLog(Format('panel #%d: TextureNum=%d; ht=%d; ht1=%d; atl=%d', [a, panels[a].TextureNum, High(mapTextureList), High(Textures), High(AddTextures)]), MSG_NOTIFY); - // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð: - PanelID := CreatePanel(panels[a], AddTextures, CurTex, trigRef); - - // Åñëè èñïîëüçóåòñÿ â òðèããåðàõ, òî ñòàâèì òî÷íûé ID: - if TriggersTable <> nil then - 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; - end; + // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð + PanelID := CreatePanel(rec, AddTextures, CurTex, trigRef); + //e_LogWritefln('panel #%s of type %s got id #%s', [pannum, rec.PanelType, PanelID]); + // set 'gamePanelId' field to panel id + rec.gamePanelId := PanelID; // remember game panel id, we'll fix triggers later g_Game_StepLoading(); end; end; + // ×èíèì ID'û ïàíåëåé, êîòîðûå èñïîëüçóþòñÿ â òðèããåðàõ + for b := 0 to High(TriggersTable) do + begin + if (TriggersTable[b].texPan <> nil) then TriggersTable[b].texPanIdx := TriggersTable[b].texPan.gamePanelId; + if (TriggersTable[b].liftPan <> nil) then TriggersTable[b].LiftPanelIdx := TriggersTable[b].liftPan.gamePanelId; + if (TriggersTable[b].doorPan <> nil) then TriggersTable[b].DoorPanelIdx := TriggersTable[b].doorPan.gamePanelId; + if (TriggersTable[b].shotPan <> nil) then TriggersTable[b].ShotPanelIdx := TriggersTable[b].shotPan.gamePanelId; + 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_LogWritefln(' Creating triggers (%d)...', [Length(triggers)]); + 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 - begin - if (TriggersTable[a].TexturePanel < 0) or (TriggersTable[a].TexturePanel > High(panels)) then - begin - e_WriteLog('error loading map: invalid panel index for trigger', MSG_FATALERROR); - result := false; - exit; - end; - b := panels[TriggersTable[a].TexturePanel].PanelType; - end - else - begin - b := 0; - end; - if (triggers[a].TriggerType = TRIGGER_SHOT) and (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then - begin - c := panels[TriggersTable[a].ShotPanel].PanelType - end - else - begin - c := 0; - end; - CreateTrigger(triggers[a], b, c); + 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; + // we can have only one of those + if (TriggersTable[trignum].LiftPanelIdx <> -1) then tgpid := TriggersTable[trignum].LiftPanelIdx + else if (TriggersTable[trignum].DoorPanelIdx <> -1) then tgpid := TriggersTable[trignum].DoorPanelIdx + else if (TriggersTable[trignum].ShotPanelIdx <> -1) then tgpid := TriggersTable[trignum].ShotPanelIdx + else tgpid := -1; + //e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]); + CreateTrigger(trignum, rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c)); end; end; - // Çàãðóçêà ïðåäìåòîâ: + // Çàãðóçêà ïðåäìåòîâ e_WriteLog(' Loading items...', MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_ITEMS], 0, False); - items := GetItems(mapReader); - // Åñëè íå 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 := GetAreas(mapReader); - // Åñëè íå 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 := GetMonsters(mapReader); 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(); + gCurrentMap := mapReader; // this will be our current map now + mapReader := nil; - // Çàãðóçêà íåáà: + // Çàãðóçêà íåáà if gMapInfo.SkyName <> '' then begin e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, MSG_NOTIFY); @@ -1956,7 +1952,7 @@ begin g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s])); end; - // Çàãðóçêà ìóçûêè: + // Çàãðóçêà ìóçûêè ok := False; if gMapInfo.MusicName <> '' then begin @@ -1978,7 +1974,7 @@ begin g_FatalError(Format(_lc[I_GAME_ERROR_MUSIC], [s])); end; - // Îñòàëüíûå óñòàíâêè: + // Îñòàëüíûå óñòàíâêè CreateDoorMap(); CreateLiftMap(); @@ -1986,12 +1982,11 @@ 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; + // Ñáðîñ ëîêàëüíûõ ìàññèâîâ: + mapTextureList := nil; panels := nil; items := nil; areas := nil; @@ -1999,27 +1994,31 @@ 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(); end; e_WriteLog('Done loading map.', MSG_NOTIFY); Result := True; end; + function g_Map_GetMapInfo(Res: String): TMapInfo; var WAD: TWADFile; - MapReader: TDynRecord; - Header: TMapHeaderRec_1; + mapReader: TDynRecord; + //Header: TMapHeaderRec_1; FileName: String; Data: Pointer; Len: Integer; @@ -2068,26 +2067,31 @@ begin FreeMem(Data); //MapReader.Free(); - if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0); - MapReader.Free(); + //if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0); + //MapReader.Free(); - if (Header.Width > 0) and (Header.Height > 0) then + if (mapReader.Width > 0) and (mapReader.Height > 0) then begin - Result.Name := Header.MapName; - Result.Description := Header.MapDescription; + 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)); + //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;