From b0369ee9442a79c9ace3454e7e1709cd61ed6a8e Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Fri, 1 Sep 2017 00:57:20 +0300 Subject: [PATCH] trigger loading now works; map loading code cleanup --- src/game/g_holmes.pas | 38 +++++++-- src/game/g_map.pas | 177 +++++++++------------------------------- src/game/g_triggers.pas | 18 +++- src/shared/MAPDEF.pas | 23 ++++++ src/shared/utils.pas | 15 ++-- src/shared/xdynrec.pas | 64 ++++++++++++++- 6 files changed, 183 insertions(+), 152 deletions(-) diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas index 31417e6..566cd19 100644 --- a/src/game/g_holmes.pas +++ b/src/game/g_holmes.pas @@ -968,7 +968,7 @@ procedure plrDebugDraw (); if (idx < 0) or (idx >= Length(parr)) then exit; pan := parr[idx]; drawLine( - trig.x+trig.width div 2, trig.y+trig.height div 2, + trig.trigCenter.x, trig.trigCenter.y, pan.x+pan.width div 2, pan.y+pan.height div 2, 255, 0, 255, 220); end; @@ -982,6 +982,9 @@ procedure plrDebugDraw (); tx := trig.x+(trig.width-Length(tts)*6) div 2; darkenRect(tx-2, trig.y-10, Length(tts)*6+4, 10, 64); drawText6(tx, trig.y-9, tts, 255, 127, 0); + tx := trig.x+(trig.width-Length(trig.mapId)*6) div 2; + darkenRect(tx-2, trig.y-20, Length(trig.mapId)*6+4, 10, 64); + drawText6(tx, trig.y-19, trig.mapId, 255, 255, 0); case trig.TriggerType of TRIGGER_NONE: begin end; TRIGGER_EXIT: begin end; @@ -992,15 +995,23 @@ procedure plrDebugDraw (); TRIGGER_DOOR5: begin drawPanelDest(gWalls, trig.trigPanelId); end; TRIGGER_CLOSETRAP: begin drawPanelDest(gWalls, trig.trigPanelId); end; TRIGGER_TRAP: begin drawPanelDest(gWalls, trig.trigPanelId); end; - TRIGGER_PRESS: begin end; TRIGGER_SECRET: begin end; TRIGGER_LIFTUP: begin drawPanelDest(gLifts, trig.trigPanelId); end; TRIGGER_LIFTDOWN: begin drawPanelDest(gLifts, trig.trigPanelId); end; TRIGGER_LIFT: begin drawPanelDest(gLifts, trig.trigPanelId); end; TRIGGER_TEXTURE: begin end; - TRIGGER_ON: begin end; - TRIGGER_OFF: begin end; - TRIGGER_ONOFF: begin end; + TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF, TRIGGER_PRESS: + begin + fillRect( + trig.trigData.trigTX, trig.trigData.trigTY, + trig.trigData.trigTWidth, trig.trigData.trigTHeight, + 0, 255, 255, 42); + drawLine( + trig.trigCenter.x, trig.trigCenter.y, + trig.trigData.trigTX+trig.trigData.trigTWidth div 2, + trig.trigData.trigTY+trig.trigData.trigTHeight div 2, + 255, 0, 255, 220); + end; TRIGGER_SOUND: begin end; TRIGGER_SPAWNMONSTER: begin end; TRIGGER_SPAWNITEM: begin end; @@ -1238,10 +1249,27 @@ procedure cbAtcurDumpWalls (); result := false; // don't stop e_WriteLog(Format('wall #%d(%d); enabled=%d (%d); (%d,%d)-(%d,%d)', [pan.arrIdx, pan.proxyId, Integer(pan.Enabled), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.X, pan.Y, pan.Width, pan.Height]), MSG_NOTIFY); end; +var + hasTrigs: Boolean = false; + f: Integer; + trig: PTrigger; begin e_WriteLog('=== TOGGLE WALL ===', MSG_NOTIFY); mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor)); e_WriteLog('--- toggle wall ---', MSG_NOTIFY); + if showTriggers then + begin + for f := 0 to High(gTriggers) do + begin + trig := @gTriggers[f]; + if (pmsCurMapX >= trig.x) and (pmsCurMapY >= trig.y) and (pmsCurMapX < trig.x+trig.width) and (pmsCurMapY < trig.y+trig.height) then + begin + if not hasTrigs then begin writeln('=== TRIGGERS ==='); hasTrigs := true; end; + writeln('trigger ''', trig.mapId, ''' of type ''', trigType2Str(trig.TriggerType), ''''); + end; + end; + if hasTrigs then writeln('--- triggers ---'); + end; end; procedure cbAtcurToggleWalls (); diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 6ae077b..6b64d88 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -1198,11 +1198,12 @@ begin with _trigger do begin + mapId := Trigger.id; X := Trigger.X; Y := Trigger.Y; Width := Trigger.Width; Height := Trigger.Height; - Enabled := ByteBool(Trigger.Enabled); + Enabled := Trigger.Enabled; //TexturePanel := Trigger.TexturePanel; TexturePanel := atpanid; TexturePanelType := fTexturePanel1Type; @@ -1213,7 +1214,18 @@ begin trigPanelId := atrigpanid; //trigShotPanelId := ashotpanid; //Data.Default := Trigger.DATA; - trigData := Trigger.trigRec.clone(); + 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); @@ -1463,11 +1475,8 @@ type end; var WAD: TWADFile; - //MapReader: TMapReader_1; mapReader: TDynRecord = nil; - //Header: TMapHeaderRec_1; - _textures: TDynField = nil; //TTexturesRec1Array; tagInt: texture index - //_texnummap: array of Integer = nil; // `_textures` -> `Textures` + mapTextureList: TDynField = nil; //TTexturesRec1Array; tagInt: texture index panels: TDynField = nil; //TPanelsRec1Array; items: TDynField = nil; //TItemsRec1Array; monsters: TDynField = nil; //TMonsterRec1Array; @@ -1476,7 +1485,6 @@ var b, c, k: Integer; PanelID: DWORD; AddTextures: TAddTextureArray; - //texture: TTextureRec_1; TriggersTable: array of TTRec; FileName, mapResName, s, TexName: String; Data: Pointer; @@ -1486,11 +1494,6 @@ var rec, texrec: TDynRecord; pttit: PTRec; pannum, trignum, cnt, tgpid: Integer; - // key: panel index; value: `TriggersTable` index - hashTextPan: THashIntInt = nil; - hashLiftPan: THashIntInt = nil; - hashDoorPan: THashIntInt = nil; - hashShotPan: THashIntInt = nil; begin mapGrid.Free(); mapGrid := nil; @@ -1502,7 +1505,6 @@ begin gMapInfo.Map := Res; TriggersTable := nil; mapReader := nil; - //FillChar(texture, SizeOf(texture), 0); sfsGCDisable(); // temporary disable removing of temporary volumes try @@ -1552,31 +1554,18 @@ begin FreeMem(Data); - hashTextPan := hashNewIntInt(); - hashLiftPan := hashNewIntInt(); - hashDoorPan := hashNewIntInt(); - hashShotPan := hashNewIntInt(); - - generateExternalResourcesList(MapReader); - //_textures := GetTextures(mapReader); - _textures := mapReader['texture']; - //_texnummap := nil; + generateExternalResourcesList(mapReader); + mapTextureList := mapReader['texture']; // 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 := GetMapHeader(mapReader); with gMapInfo do begin @@ -1592,14 +1581,13 @@ begin // Çàãðóçêà òåêñòóð: g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False); // Äîáàâëåíèå òåêñòóð â Textures[]: - if (_textures <> nil) and (_textures.count > 0) then + if (mapTextureList <> nil) and (mapTextureList.count > 0) then begin e_WriteLog(' Loading textures:', MSG_NOTIFY); - g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], _textures.count-1, False); - //SetLength(_texnummap, _textures.count); + g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], mapTextureList.count-1, False); cnt := -1; - for rec in _textures do + for rec in mapTextureList do begin Inc(cnt); s := rec.Resource; @@ -1621,8 +1609,7 @@ begin end; if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); - //_texnummap[a] := ntn; // fix texture number - rec.tagInt := ntn; + rec.tagInt := ntn; // remember texture number g_Game_StepLoading(); end; @@ -1672,6 +1659,7 @@ begin SetLength(TriggersTable, Length(TriggersTable)+1); pttit := @TriggersTable[High(TriggersTable)]; pttit.trigrec := rec; + // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè) pttit.texPan := mapReader.panel[rec.TexturePanel]; pttit.liftPan := nil; pttit.doorPan := nil; @@ -1680,34 +1668,22 @@ begin 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; @@ -1728,7 +1704,7 @@ begin CurTex := -1; ok := false; - if (_textures <> nil) then + if (mapTextureList <> nil) then begin texrec := rec.TextureRec; ok := (texrec <> nil); @@ -1739,7 +1715,7 @@ begin // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû. // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð ok := false; - if (TriggersTable <> nil) and (_textures <> nil) then + if (TriggersTable <> nil) and (mapTextureList <> nil) then begin for b := 0 to High(TriggersTable) do begin @@ -1828,8 +1804,7 @@ begin 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)].Texture := rec.tagInt; // internal texture number, not map index AddTextures[High(AddTextures)].Anim := texrec.Anim; CurTex := High(AddTextures); ok := true; @@ -1849,66 +1824,32 @@ begin begin // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó SetLength(AddTextures, 1); - AddTextures[0].Texture := rec.tagInt; //panels[a].TextureNum; + 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(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; - - (* - if (TriggersTable <> nil) then - begin - for b := 0 to High(TriggersTable) do - begin - 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; - *) + // 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 - 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; + 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); @@ -1926,45 +1867,11 @@ begin 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; - tgpid := -1; + // 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; - (* - 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; - 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; - 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, tgpid, Word(b), Word(c)); end; @@ -2008,8 +1915,7 @@ begin for rec in monsters do CreateMonster(rec); end; - //MapReader.Free(); - gCurrentMap := mapReader; + gCurrentMap := mapReader; // this will be our current map now mapReader := nil; // Çàãðóçêà íåáà @@ -2069,7 +1975,7 @@ begin if not gLoadGameMode then g_GFX_Init(); // Ñáðîñ ëîêàëüíûõ ìàññèâîâ: - _textures := nil; + mapTextureList := nil; panels := nil; items := nil; areas := nil; @@ -2090,20 +1996,17 @@ begin finally sfsGCEnable(); // enable releasing unused volumes mapReader.Free(); - hashTextPan.Free(); - hashLiftPan.Free(); - hashDoorPan.Free(); - hashShotPan.Free(); end; e_WriteLog('Done loading map.', MSG_NOTIFY); Result := True; end; + function g_Map_GetMapInfo(Res: String): TMapInfo; var WAD: TWADFile; - MapReader: TDynRecord; + mapReader: TDynRecord; //Header: TMapHeaderRec_1; FileName: String; Data: Pointer; diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index edafecc..064b3b6 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -27,7 +27,9 @@ type UID: Word; TimeOut: Word; end; + PTrigger = ^TTrigger; TTrigger = record + public ID: DWORD; ClientID: DWORD; TriggerType: Byte; @@ -60,12 +62,17 @@ type ShotAmmoCount: Word; ShotReloadTime: Integer; + mapId: AnsiString; // trigger id, from map //trigShotPanelId: Integer; trigPanelId: Integer; //TrigData: TTriggerData; trigData: TDynRecord; // triggerdata; owned by trigger + public + function trigCenter (): TDFPoint; inline; + + public property trigShotPanelId: Integer read trigPanelId write trigPanelId; end; @@ -113,6 +120,13 @@ const TRIGGER_SIGNATURE = $52475254; // 'TRGR' TRAP_DAMAGE = 1000; + +function TTrigger.trigCenter (): TDFPoint; inline; +begin + result := TDFPoint.Create(x+width div 2, y+height div 2); +end; + + function FindTrigger(): DWORD; var i: Integer; @@ -2106,6 +2120,7 @@ begin find_id := FindTrigger(); gTriggers[find_id] := Trigger; + { writeln('trigger #', find_id, ': pos=(', Trigger.x, ',', Trigger.y, ')-(', Trigger.width, 'x', Trigger.height, ')', '; TexturePanel=', Trigger.TexturePanel, '; TexturePanelType=', Trigger.TexturePanelType, @@ -2116,6 +2131,7 @@ begin '; trigPanelId=', Trigger.trigPanelId, '; trigShotPanelId=', Trigger.trigShotPanelId ); + } with gTriggers[find_id] do begin @@ -2666,7 +2682,6 @@ var begin for a := 0 to High(gTriggers) do begin - gTriggers[a].trigData.Free(); if (gTriggers[a].TriggerType = TRIGGER_SOUND) then begin if g_Sound_Exists(gTriggers[a].trigData.trigSoundName) then @@ -2679,6 +2694,7 @@ begin begin SetLength(gTriggers[a].Activators, 0); end; + gTriggers[a].trigData.Free(); end; gTriggers := nil; diff --git a/src/shared/MAPDEF.pas b/src/shared/MAPDEF.pas index a713716..ededbdd 100644 --- a/src/shared/MAPDEF.pas +++ b/src/shared/MAPDEF.pas @@ -117,6 +117,11 @@ type {$INCLUDE mapdef_help.inc} function trigMonsterId (): Integer; inline; + private + // user fields + function getGamePanelId (): Integer; inline; + procedure setGamePanelId (v: Integer); inline; + public property panel[idx: Integer]: TDynRecord read getPanelByIdx; property panelIndex[pan: TDynRecord]: Integer read getPanelIndex; @@ -124,6 +129,8 @@ type property tgPanelID: Integer read getPanelId {write setPanelId}; property tgShotPanelID: Integer read getPanelId {write setPanelId}; property TexturePanel: Integer read getTexturePanel {write setTexturePanel}; // texturepanel, int + // user fields + property gamePanelId: Integer read getGamePanelId write setGamePanelId; end; implementation @@ -136,6 +143,22 @@ uses constructor TDFPoint.Create (ax, ay: LongInt); begin X := ax; Y := ay; end; +// ////////////////////////////////////////////////////////////////////////// // +function TDynRecordHelper.getGamePanelId (): Integer; inline; +var + fld: TDynField; +begin + fld := field['gamePanelId']; + if (fld = nil) or (fld.baseType <> TDynField.TType.TInt) then result := -1 else result := fld.ival; +end; + + +procedure TDynRecordHelper.setGamePanelId (v: Integer); inline; +begin + setUserField('gamePanelId', Integer(v)); +end; + + // ////////////////////////////////////////////////////////////////////////// // function TDynRecordHelper.getFieldWithType (const aname: AnsiString; atype: TDynField.TType): TDynField; inline; begin diff --git a/src/shared/utils.pas b/src/shared/utils.pas index 6bfe791..1caa1f3 100644 --- a/src/shared/utils.pas +++ b/src/shared/utils.pas @@ -1247,6 +1247,7 @@ var fmtblen: Integer; pclen: Integer; pc: PAnsiChar; + ccname: ShortString; procedure writer (constref buf; len: SizeUInt); var @@ -1646,15 +1647,17 @@ begin end; vtObject: // args[curarg].VObject.Classname (TObject) begin - if (sign <> '-') then indent(width-Length(args[curarg].VObject.Classname)); - xwrite(args[curarg].VObject.Classname); - if (sign = '-') then indent(width-Length(args[curarg].VObject.Classname)); + if (args[curarg].VObject <> nil) then ccname := args[curarg].VObject.Classname else ccname := ''; + if (sign <> '-') then indent(width-Length(ccname)); + xwrite(ccname); + if (sign = '-') then indent(width-Length(ccname)); end; vtClass: // args[curarg].VClass.Classname (TClass) begin - if (sign <> '-') then indent(width-Length(args[curarg].VClass.Classname)); - xwrite(args[curarg].VClass.Classname); - if (sign = '-') then indent(width-Length(args[curarg].VClass.Classname)); + if (args[curarg].VClass <> nil) then ccname := args[curarg].VClass.Classname else ccname := ''; + if (sign <> '-') then indent(width-Length(ccname)); + xwrite(ccname); + if (sign = '-') then indent(width-Length(ccname)); end; //vtPWideChar: begin end; // args[curarg].VPWideChar (PWideChar) vtAnsiString: // AnsiString(args[curarg].VAnsiString) (Pointer) diff --git a/src/shared/xdynrec.pas b/src/shared/xdynrec.pas index 8ebac36..ac55cf5 100644 --- a/src/shared/xdynrec.pas +++ b/src/shared/xdynrec.pas @@ -110,6 +110,7 @@ type function addListItem (rec: TDynRecord): Boolean; inline; public + { type TListEnumerator = record private @@ -121,6 +122,7 @@ type function getCurrent (): TDynRecord; inline; property Current: TDynRecord read getCurrent; end; + } public constructor Create (const aname: AnsiString; atype: TType); @@ -145,7 +147,7 @@ type procedure setValue (const s: AnsiString); - function GetEnumerator (): TListEnumerator; + function GetEnumerator (): TDynRecList.TEnumerator; inline; public property pasname: AnsiString read mPasName; @@ -245,6 +247,9 @@ type // number of records of the given instance function instanceCount (const typename: AnsiString): Integer; + procedure setUserField (const fldname: AnsiString; v: LongInt); + procedure setUserField (const fldname: AnsiString; v: AnsiString); + public property id: AnsiString read mId; // for map parser property pasname: AnsiString read mPasName; @@ -358,6 +363,7 @@ function StrEqu (const a, b: AnsiString): Boolean; inline; begin result := (a = // ////////////////////////////////////////////////////////////////////////// // +{ constructor TDynField.TListEnumerator.Create (alist: TDynRecList); begin mList := alist; @@ -376,11 +382,13 @@ function TDynField.TListEnumerator.getCurrent (): TDynRecord; inline; begin result := mList[mCurIdx]; end; +} -function TDynField.GetEnumerator (): TListEnumerator; +function TDynField.GetEnumerator (): TDynRecList.TEnumerator; inline; begin - result := TListEnumerator.Create(mRVal); + //result := TListEnumerator.Create(mRVal); + if (mRVal <> nil) then result := mRVal.GetEnumerator else result := TDynRecList.TEnumerator.Create(nil, 0); end; @@ -1927,6 +1935,56 @@ begin end; +procedure TDynRecord.setUserField (const fldname: AnsiString; v: LongInt); +var + fld: TDynField; +begin + if (Length(fldname) = 0) then exit; + fld := field[fldname]; + if (fld <> nil) then + begin + if (fld.mType <> fld.TType.TInt) or (fld.mEBS <> fld.TEBS.TNone) then + begin + raise Exception.Create(Format('invalid user field ''%s'' type', [fld.name])); + end; + end + else + begin + fld := TDynField.Create(fldname, fld.TType.TInt); + fld.mOwner := self; + fld.mIVal := v; + fld.mInternal := true; + fld.mDefined := true; + addField(fld); + end; +end; + + +procedure TDynRecord.setUserField (const fldname: AnsiString; v: AnsiString); +var + fld: TDynField; +begin + if (Length(fldname) = 0) then exit; + fld := field[fldname]; + if (fld <> nil) then + begin + if (fld.mType <> fld.TType.TString) or (fld.mEBS <> fld.TEBS.TNone) then + begin + raise Exception.Create(Format('invalid user field ''%s'' type', [fld.name])); + end; + end + else + begin + fld := TDynField.Create(fldname, fld.TType.TString); + fld.mOwner := self; + fld.mSVal := v; + fld.mInternal := true; + fld.mDefined := true; + addField(fld); + end; +end; + + procedure TDynRecord.parseDef (pr: TTextParser); var fld: TDynField; -- 2.29.2