X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=1b92a967f0c31115b5101b3db1be3c003c1ae070;hb=3e4c594ed4894e6a69897d3c2ac19c878da13280;hp=395a2ccbc4320a256545a286de9b34bb5e8e3137;hpb=d25ad51560a2159ff524fa9ef4ca37a81dcb528f;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 395a2cc..1b92a96 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -65,7 +65,7 @@ procedure g_Map_Update(); function g_Map_PanelByGUID (aguid: Integer): TPanel; inline; -procedure g_Map_DrawPanels (PanelType: Word); // unaccelerated +procedure g_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); // unaccelerated procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer); procedure g_Map_DrawBack(dx, dy: Integer); @@ -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 (); @@ -236,7 +242,7 @@ var implementation uses - e_input, g_main, e_log, SysUtils, g_items, g_gfx, g_console, + e_input, g_main, e_log, e_texture, SysUtils, g_items, g_gfx, g_console, 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, @@ -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; @@ -273,6 +307,7 @@ function g_Map_MaxY (): Integer; inline; begin if (mapGrid <> nil) then result : var dfmapdef: TDynMapDef = nil; + procedure loadMapDefinition (); var pr: TTextParser = nil; @@ -280,13 +315,15 @@ var WAD: TWADFile = nil; begin if (dfmapdef <> nil) then exit; + try e_LogWritefln('parsing "mapdef.txt"...', []); st := openDiskFileRO(DataDir+'mapdef.txt'); + e_LogWritefln('found local "%smapdef.txt"', [DataDir]); except st := nil; - e_LogWritefln('local "%smapdef.txt" not found', [DataDir]); end; + if (st = nil) then begin WAD := TWADFile.Create(); @@ -301,21 +338,31 @@ begin end; end; - 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); + try + if (st = nil) then + begin + //raise Exception.Create('cannot open "mapdef.txt"'); + e_LogWriteln('using default "mapdef.txt"...'); + pr := TStrTextParser.Create(defaultMapDef); + end + else + begin + pr := TFileTextParser.Create(st); + end; + except on e: Exception do + begin + e_LogWritefln('something is VERY wrong here! -- ', [e.message]); + raise; + end; end; 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(); @@ -327,47 +374,35 @@ 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; + + if (dfmapdef = nil) then writeln('need to load mapdef'); 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 + 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 - 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.line, pr.col, 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; @@ -772,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; @@ -807,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; @@ -1278,10 +1312,11 @@ begin end; end; -procedure CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word); +function CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word): Integer; var _trigger: TTrigger; begin + result := -1; if g_Game_IsClient and not (Trigger.TriggerType in [TRIGGER_SOUND, TRIGGER_MUSIC]) then Exit; with _trigger do @@ -1303,21 +1338,9 @@ begin trigPanelGUID := 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); + result := Integer(g_Triggers_Create(_trigger, Trigger)); end; procedure CreateMonster(monster: TDynRecord); @@ -1339,7 +1362,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; @@ -1371,7 +1394,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; @@ -1562,17 +1585,15 @@ type PTRec = ^TTRec; TTRec = record //TexturePanel: Integer; - texPanIdx: Integer; - LiftPanelIdx: Integer; - DoorPanelIdx: Integer; - ShotPanelIdx: Integer; - MPlatPanelIdx: Integer; + tnum: Integer; + id: Integer; trigrec: TDynRecord; - texPan: TDynRecord; - liftPan: TDynRecord; - doorPan: TDynRecord; - shotPan: TDynRecord; - mplatPan: TDynRecord; + // texture pane; + texPanelIdx: Integer; + texPanel: TDynRecord; + // "action" panel + actPanelIdx: Integer; + actPanel: TDynRecord; end; var WAD: TWADFile; @@ -1590,7 +1611,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; @@ -1598,6 +1619,8 @@ var stt: UInt64; moveSpeed{, moveStart, moveEnd}: TDFPoint; //moveActive: Boolean; + pan: TPanel; + mapOk: Boolean = false; begin mapGrid.Free(); mapGrid := nil; @@ -1649,7 +1672,7 @@ begin e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False); - stt := curTimeMicro(); + stt := getTimeMicro(); try mapReader := g_Map_ParseMap(Data, Len); @@ -1662,6 +1685,14 @@ begin FreeMem(Data); + if (mapReader = nil) then + begin + e_LogWritefln('invalid map file: ''%s''', [mapResName]); + exit; + end; + + gCurrentMap := mapReader; + generateExternalResourcesList(mapReader); mapTextureList := mapReader['texture']; // get all other lists here too @@ -1750,6 +1781,8 @@ begin begin e_WriteLog('error loading map: invalid texture index for panel', MSG_FATALERROR); result := false; + gCurrentMap := nil; + gCurrentMapFileName := ''; exit; end; end; @@ -1762,49 +1795,23 @@ begin //SetLength(TriggersTable, triggers.count); g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS_TABLE], triggers.count-1, False); + SetLength(TriggersTable, triggers.count); + trignum := -1; for rec in triggers do begin - SetLength(TriggersTable, Length(TriggersTable)+1); - pttit := @TriggersTable[High(TriggersTable)]; + Inc(trignum); + pttit := @TriggersTable[trignum]; pttit.trigrec := rec; // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè) - pttit.texPan := mapReader.panel[rec.TexturePanel]; - pttit.liftPan := nil; - pttit.doorPan := nil; - pttit.shotPan := nil; - pttit.mplatPan := nil; - pttit.texPanIdx := -1; - pttit.LiftPanelIdx := -1; - pttit.DoorPanelIdx := -1; - pttit.ShotPanelIdx := -1; - pttit.MPlatPanelIdx := -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; - // - if rec.TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then - begin - pttit.mplatPan := mapReader.panel[rec.trigRec.tgPanelID]; - end; - - if (pttit.texPan <> nil) then pttit.texPan.userPanelTrigRef := true; - if (pttit.liftPan <> nil) then pttit.liftPan.userPanelTrigRef := true; - if (pttit.doorPan <> nil) then pttit.doorPan.userPanelTrigRef := true; - if (pttit.shotPan <> nil) then pttit.shotPan.userPanelTrigRef := true; - if (pttit.mplatPan <> nil) then pttit.mplatPan.userPanelTrigRef := true; - + pttit.texPanelIdx := -1; // will be fixed later + pttit.texPanel := rec.TexturePanelRec; + // action panel + pttit.actPanelIdx := -1; + if (rec.trigRec <> nil) then pttit.actPanel := rec.trigRec.tgPanelRec else pttit.actPanel := nil; + // set flag + if (pttit.texPanel <> nil) then pttit.texPanel.userPanelTrigRef := true; + if (pttit.actPanel <> nil) then pttit.actPanel.userPanelTrigRef := true; + // update progress g_Game_StepLoading(); end; end; @@ -1822,7 +1829,6 @@ begin //e_LogWritefln('PANSTART: pannum=%s', [pannum]); texrec := nil; SetLength(AddTextures, 0); - trigRef := False; CurTex := -1; ok := false; @@ -1839,21 +1845,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; @@ -1981,7 +1975,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 @@ -1989,7 +1983,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); @@ -2006,11 +2000,8 @@ begin // ×èíèì ID'û ïàíåëåé, êîòîðûå èñïîëüçóþòñÿ â òðèããåðàõ for b := 0 to High(TriggersTable) do begin - if (TriggersTable[b].texPan <> nil) then TriggersTable[b].texPanIdx := TriggersTable[b].texPan.userPanelId; - if (TriggersTable[b].liftPan <> nil) then TriggersTable[b].LiftPanelIdx := TriggersTable[b].liftPan.userPanelId; - if (TriggersTable[b].doorPan <> nil) then TriggersTable[b].DoorPanelIdx := TriggersTable[b].doorPan.userPanelId; - if (TriggersTable[b].shotPan <> nil) then TriggersTable[b].ShotPanelIdx := TriggersTable[b].shotPan.userPanelId; - if (TriggersTable[b].mplatPan <> nil) then TriggersTable[b].MPlatPanelIdx := TriggersTable[b].mplatPan.userPanelId; + if (TriggersTable[b].texPanel <> nil) then TriggersTable[b].texPanelIdx := TriggersTable[b].texPanel.userPanelId; + if (TriggersTable[b].actPanel <> nil) then TriggersTable[b].actPanelIdx := TriggersTable[b].actPanel.userPanelId; end; // create map grid, init other grids (for monsters, for example) @@ -2027,16 +2018,26 @@ begin for rec in triggers do 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; + if (TriggersTable[trignum].texPanel <> nil) then b := TriggersTable[trignum].texPanel.PanelType else b := 0; + if (TriggersTable[trignum].actPanel <> nil) then c := TriggersTable[trignum].actPanel.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 if (TriggersTable[trignum].MPlatPanelIdx <> -1) then tgpid := TriggersTable[trignum].MPlatPanelIdx - else tgpid := -1; + tgpid := TriggersTable[trignum].actPanelIdx; //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)); + TriggersTable[trignum].tnum := trignum; + TriggersTable[trignum].id := CreateTrigger(trignum, rec, TriggersTable[trignum].texPanelIdx, tgpid, Word(b), Word(c)); + end; + end; + + //FIXME: use hashtable! + for pan in panByGUID do + begin + if (pan.endPosTrigId >= 0) and (pan.endPosTrigId < Length(TriggersTable)) then + begin + pan.endPosTrigId := TriggersTable[pan.endPosTrigId].id; + end; + if (pan.endSizeTrigId >= 0) and (pan.endSizeTrigId < Length(TriggersTable)) then + begin + pan.endSizeTrigId := TriggersTable[pan.endSizeTrigId].id; end; end; @@ -2083,26 +2084,28 @@ begin mapReader := nil; // Çàãðóçêà íåáà - if gMapInfo.SkyName <> '' then + if (gMapInfo.SkyName <> '') then begin e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_SKY], 0, False); FileName := g_ExtractWadName(gMapInfo.SkyName); - if FileName <> '' then - FileName := GameDir+'/wads/'+FileName - else - begin - FileName := g_ExtractWadName(Res); - end; + if (FileName <> '') then FileName := GameDir+'/wads/'+FileName else FileName := g_ExtractWadName(Res); - s := FileName+':'+g_ExtractFilePathName(gMapInfo.SkyName); - if g_Texture_CreateWAD(BackID, s) then + if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST; + try + s := FileName+':'+g_ExtractFilePathName(gMapInfo.SkyName); + if g_Texture_CreateWAD(BackID, s) then begin g_Game_SetupScreenSize(); end - else - g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s])); + else + begin + g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s])); + end; + finally + TEXTUREFILTER := GL_NEAREST; + end; end; // Çàãðóçêà ìóçûêè @@ -2158,12 +2161,18 @@ begin gMusic.SetByName(''); end; - stt := curTimeMicro()-stt; + stt := getTimeMicro()-stt; e_LogWritefln('map loaded in %s.%s milliseconds', [Integer(stt div 1000), Integer(stt mod 1000)]); + mapOk := true; finally sfsGCEnable(); // enable releasing unused volumes mapReader.Free(); e_ClearInputBuffer(); // why not? + if not mapOk then + begin + gCurrentMap := nil; + gCurrentMapFileName := ''; + end; end; e_WriteLog('Done loading map.', MSG_NOTIFY); @@ -2203,10 +2212,14 @@ begin mapReader := g_Map_ParseMap(Data, Len); except mapReader := nil; + FreeMem(Data); + exit; end; FreeMem(Data); + if (mapReader = nil) then exit; + if (mapReader.Width > 0) and (mapReader.Height > 0) then begin Result.Name := mapReader.MapName; @@ -2413,6 +2426,8 @@ var end; begin + if g_dbgpan_mplat_step then g_dbgpan_mplat_active := true; + UpdatePanelArray(gWalls); UpdatePanelArray(gRenderBackgrounds); UpdatePanelArray(gRenderForegrounds); @@ -2421,6 +2436,8 @@ begin UpdatePanelArray(gAcid2); UpdatePanelArray(gSteps); + if g_dbgpan_mplat_step then begin g_dbgpan_mplat_step := false; g_dbgpan_mplat_active := false; end; + if gGameSettings.GameMode = GM_CTF then begin for a := FLAG_RED to FLAG_BLUE do @@ -2466,7 +2483,7 @@ begin if j > High(gPlayers) then j := 0; if gPlayers[j] <> nil then begin - if gPlayers[j].Live and g_Obj_Collide(@Obj, @gPlayers[j].Obj) then + if gPlayers[j].alive and g_Obj_Collide(@Obj, @gPlayers[j].Obj) then begin if gPlayers[j].GetFlag(a) then Break; end; @@ -2481,7 +2498,7 @@ end; // old algo -procedure g_Map_DrawPanels (PanelType: Word); +procedure g_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); procedure DrawPanels (constref panels: TPanelArray; drawDoors: Boolean=False); var @@ -2492,7 +2509,7 @@ procedure g_Map_DrawPanels (PanelType: Word); // alas, no visible set for idx := 0 to High(panels) do begin - if not (drawDoors xor panels[idx].Door) then panels[idx].Draw(); + if not (drawDoors xor panels[idx].Door) then panels[idx].Draw(hasAmbient, ambColor); end; end; end; @@ -2850,6 +2867,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); @@ -2857,7 +2876,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); @@ -2872,13 +2893,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); @@ -2906,7 +2931,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; @@ -2935,7 +2960,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; @@ -3060,16 +3087,9 @@ var // Ñîçäàåì íîâûé ñïèñîê ñîõðàíÿåìûõ ïàíåëåé 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; + // Ñîõðàíÿåì ïàíåëè + //Mem.WriteInt(Length(panByGUID)); + for pan in panByGUID do pan.SaveState(PAMem); // Ñîõðàíÿåì ýòîò ñïèñîê ïàíåëåé PAMem.SaveToMemory(Mem); @@ -3152,25 +3172,20 @@ 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'); + //if (count <> Length(panByGUID)) then raise EBinSizeError.Create(Format('g_Map_LoadState: LoadPanelArray: invalid number of panels (%d : %d)', [count, Length(panByGUID)])); 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; // Ýòîò ñïèñîê ïàíåëåé çàãðóæåí