X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=e976be49c616045a92b12fd0b2c4844fd9227be2;hb=db4e988645273fe1c11611d84e03f0199cd181f7;hp=101c3c544d06658454afb94777d730c333832545;hpb=8cd6b5c965cd6cae75db5f554e61d0d150d08b46;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 101c3c5..e976be4 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -109,7 +109,7 @@ function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; function g_Map_traceToNearest (x0, y0, x1, y1: Integer; tag: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel; type - TForEachPanelCB = function (pan: TPanel): Boolean; // return `true` to stop + TForEachPanelCB = function (pan: TPanel): Boolean is nested; // return `true` to stop function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean; function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel; @@ -119,6 +119,12 @@ function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel; function g_Map_TraceLiquidNonPrecise (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean; +// return `true` from `cb` to stop +function g_Map_ForEachPanel (cb: TForEachPanelCB): TPanel; + +procedure g_Map_NetSendInterestingPanels (); // yay! + + procedure g_Map_ProfilersBegin (); procedure g_Map_ProfilersEnd (); @@ -262,6 +268,34 @@ begin end; +// return `true` from `cb` to stop +function g_Map_ForEachPanel (cb: TForEachPanelCB): TPanel; +var + pan: TPanel; +begin + result := nil; + if not assigned(cb) then exit; + for pan in panByGUID do + begin + if cb(pan) then begin result := pan; exit; end; + end; +end; + + +procedure g_Map_NetSendInterestingPanels (); +var + pan: TPanel; +begin + if g_Game_IsServer and g_Game_IsNet then + begin + for pan in panByGUID do + begin + if pan.gncNeedSend then MH_SEND_PanelState(pan.guid); + end; + end; +end; + + // ////////////////////////////////////////////////////////////////////////// // function g_Map_MinX (): Integer; inline; begin if (mapGrid <> nil) then result := mapGrid.gridX0 else result := 0; end; function g_Map_MinY (): Integer; inline; begin if (mapGrid <> nil) then result := mapGrid.gridY0 else result := 0; end; @@ -324,8 +358,11 @@ begin try dfmapdef := TDynMapDef.Create(pr); - except on e: Exception do - raise Exception.Create(Format('ERROR in "mapdef.txt" at (%s,%s): %s', [pr.line, pr.col, e.message])); + except + on e: TDynParseException do + raise Exception.CreateFmt('ERROR in "mapdef.txt" at (%s,%s): %s', [e.tokLine, e.tokCol, e.message]); + on e: Exception do + raise Exception.CreateFmt('ERROR in "mapdef.txt" at (%s,%s): %s', [pr.tokLine, pr.tokCol, e.message]); end; st.Free(); @@ -337,7 +374,6 @@ end; function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord; var wst: TSFSMemoryChunkStream = nil; - pr: TTextParser = nil; begin result := nil; if (dataLen < 4) then exit; @@ -347,41 +383,25 @@ begin 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 - //e_LogWriteln('parsing binary map...'); - result := dfmapdef.parseBinMap(wst); - except on e: Exception do + try + result := dfmapdef.parseMap(wst); + except + on e: TDynParseException do begin - e_LogWritefln('ERROR: %s', [e.message]); + e_LogWritefln('ERROR at (%s,%s): %s', [e.tokLine, e.tokCol, e.message]); wst.Free(); result := nil; exit; end; - end; - wst.Free(); - end - else - begin - // text map - pr := TFileTextParser.Create(wst); - try - //e_LogWriteln('parsing text map...'); - result := dfmapdef.parseMap(pr); - except on e: Exception do + on e: Exception do begin - if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.tokLine, pr.tokCol, e.message]) - else e_LogWritefln('ERROR: %s', [e.message]); - pr.Free(); // will free `wst` + e_LogWritefln('ERROR: %s', [e.message]); + wst.Free(); result := nil; exit; end; - end; - pr.Free(); // will free `wst` end; + //e_LogWriteln('map parsed.'); end; @@ -787,7 +807,7 @@ begin PanelArray := nil; end; -function CreatePanel (PanelRec: TDynRecord; AddTextures: TAddTextureArray; CurTex: Integer; sav: Boolean): Integer; +function CreatePanel (PanelRec: TDynRecord; AddTextures: TAddTextureArray; CurTex: Integer): Integer; var len: Integer; panels: ^TPanelArray; @@ -822,7 +842,6 @@ begin pan.arrIdx := len; pan.proxyId := -1; pan.tag := panelTypeToTag(PanelRec.PanelType); - if sav then pan.SaveIt := True; PanelRec.user['panel_guid'] := pguid; @@ -1321,7 +1340,8 @@ begin //Data.Default := Trigger.DATA; if (Trigger.trigRec = nil) then begin - trigData := nil; + trigDataRec := nil; + //HACK! if (TriggerType <> TRIGGER_SECRET) then begin e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [TriggerType], MSG_WARNING); @@ -1329,7 +1349,7 @@ begin end else begin - trigData := Trigger.trigRec.clone(nil); + trigDataRec := Trigger.trigRec.clone(nil); end; end; @@ -1355,7 +1375,7 @@ begin if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then begin //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); + if (gTriggers[a].trigDataRec.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); end; end; end; @@ -1387,7 +1407,7 @@ procedure g_Map_ReAdd_DieTriggers(); tw.Free(); end; } - if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); + if (gTriggers[a].trigDataRec.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); end; end; end; @@ -1608,7 +1628,7 @@ var FileName, mapResName, s, TexName: String; Data: Pointer; Len: Integer; - ok, isAnim, trigRef: Boolean; + ok, isAnim: Boolean; CurTex, ntn: Integer; rec, texrec: TDynRecord; pttit: PTRec; @@ -1847,7 +1867,6 @@ begin //e_LogWritefln('PANSTART: pannum=%s', [pannum]); texrec := nil; SetLength(AddTextures, 0); - trigRef := False; CurTex := -1; ok := false; @@ -1864,21 +1883,9 @@ begin ok := false; if (TriggersTable <> nil) and (mapTextureList <> nil) then begin - { - for b := 0 to High(TriggersTable) do - begin - if (TriggersTable[b].texPan = rec) or (TriggersTable[b].shotPan = rec) then - begin - trigRef := True; - ok := True; - break; - end; - end; - } if rec.userPanelTrigRef then begin // e_LogWritefln('trigref for panel %s', [pannum]); - trigRef := True; ok := True; end; end; @@ -2006,7 +2013,7 @@ begin //e_LogWritefln('PANADD: pannum=%s', [pannum]); // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå GUID - PanelID := CreatePanel(rec, AddTextures, CurTex, trigRef); + PanelID := CreatePanel(rec, AddTextures, CurTex); //e_LogWritefln('panel #%s of type %s got guid #%s', [pannum, rec.PanelType, PanelID]); rec.userPanelId := PanelID; // remember game panel id, we'll fix triggers later @@ -2014,7 +2021,7 @@ begin moveSpeed := rec.moveSpeed; //moveStart := rec.moveStart; //moveEnd := rec.moveEnd; - //moveActive := rec['move_active'].varvalue; + //moveActive := rec['move_active'].value; if not moveSpeed.isZero then begin SetLength(gMovingWallIds, Length(gMovingWallIds)+1); @@ -2897,6 +2904,8 @@ begin //pan := gWalls[ID]; pan := g_Map_PanelByGUID(pguid); if (pan = nil) then exit; + if pan.Enabled and mapGrid.proxyEnabled[pan.proxyId] then exit; + pan.Enabled := True; g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true); @@ -2904,7 +2913,9 @@ begin //if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := true //else pan.proxyId := mapGrid.insertBody(pan, pan.X, pan.Y, pan.Width, pan.Height, GridTagDoor); - if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState({gWalls[ID]}pan.PanelType, pguid); + //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid); + // mark platform as interesting + pan.setDirty(); {$IFDEF MAP_DEBUG_ENABLED_FLAG} //e_WriteLog(Format('ENABLE: wall #%d(%d) enabled (%d) (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY); @@ -2919,13 +2930,17 @@ begin //pan := gWalls[ID]; pan := g_Map_PanelByGUID(pguid); if (pan = nil) then exit; + if (not pan.Enabled) and (not mapGrid.proxyEnabled[pan.proxyId]) then exit; + pan.Enabled := False; g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, false); mapGrid.proxyEnabled[pan.proxyId] := false; //if (pan.proxyId >= 0) then begin mapGrid.removeBody(pan.proxyId); pan.proxyId := -1; end; - if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pan.PanelType, pguid); + //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid); + // mark platform as interesting + pan.setDirty(); {$IFDEF MAP_DEBUG_ENABLED_FLAG} //e_WriteLog(Format('DISABLE: wall #%d(%d) disabled (%d) (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY); @@ -2953,7 +2968,7 @@ begin } tp.NextTexture(AnimLoop); - if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(PanelType, pguid, AnimLoop); + if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(pguid, AnimLoop); end; @@ -2982,7 +2997,9 @@ begin 3: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT); end; - if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(PanelType, pguid); + //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid); + // mark platform as interesting + pan.setDirty(); end; end; @@ -3103,20 +3120,15 @@ var var PAMem: TBinMemoryWriter; pan: TPanel; + count: Integer; begin // Ñîçäàåì íîâûé ñïèñîê ñîõðàíÿåìûõ ïàíåëåé PAMem := TBinMemoryWriter.Create((Length(panByGUID)+1) * 40); - for pan in panByGUID do - begin - if true{pan.SaveIt} then - begin - // ID ïàíåëè - //PAMem.WriteInt(i); - // Ñîõðàíÿåì ïàíåëü - pan.SaveState(PAMem); - end; - end; + // Ñîõðàíÿåì ïàíåëè + count := Length(panByGUID); + Mem.WriteInt(count); + for pan in panByGUID do pan.SaveState(PAMem); // Ñîõðàíÿåì ýòîò ñïèñîê ïàíåëåé PAMem.SaveToMemory(Mem); @@ -3199,25 +3211,19 @@ var var PAMem: TBinMemoryReader; pan: TPanel; + count: LongInt; begin // Çàãðóæàåì òåêóùèé ñïèñîê ïàíåëåé PAMem := TBinMemoryReader.Create(); PAMem.LoadFromMemory(Mem); + // Çàãðóæàåì ïàíåëè + PAMem.ReadInt(count); + if (count <> Length(panByGUID)) then raise EBinSizeError.Create('g_Map_LoadState: LoadPanelArray: invalid number of panels'); for pan in panByGUID do begin - if true{pan.SaveIt} then - begin - // ID ïàíåëè: - //PAMem.ReadInt(id); - { - if id <> i then raise EBinSizeError.Create('g_Map_LoadState: LoadPanelArray: Wrong Panel ID'); - } - // Çàãðóæàåì ïàíåëü - pan.LoadState(PAMem); - //if (panels[i].arrIdx <> i) then raise Exception.Create('g_Map_LoadState: LoadPanelArray: Wrong Panel arrIdx'); - if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := pan.Enabled; - end; + pan.LoadState(PAMem); + if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := pan.Enabled; end; // Ýòîò ñïèñîê ïàíåëåé çàãðóæåí