DEADSOFTWARE

migrating from PanelIDs to panel GUIDs; part one
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Fri, 1 Sep 2017 23:57:34 +0000 (02:57 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Sat, 2 Sep 2017 00:40:11 +0000 (03:40 +0300)
src/game/g_holmes.pas
src/game/g_map.pas
src/game/g_net.pas
src/game/g_netmsg.pas
src/game/g_panel.pas
src/game/g_triggers.pas
src/mapdef/mapdef.txt
src/shared/MAPDEF.pas
src/shared/hashtable.pas
src/shared/mapdef.inc

index 23c4b13d16ee07817d48508006086f0d16661c82..27fd1691c8ee62058d15c0c97c00ab664fbb265a 100644 (file)
@@ -1041,12 +1041,12 @@ procedure plrDebugDraw ();
 
   procedure drawTrigger (var trig: TTrigger);
 
-    procedure drawPanelDest (var parr: TPanelArray; idx: Integer);
+    procedure drawPanelDest (pguid: Integer);
     var
       pan: TPanel;
     begin
-      if (idx < 0) or (idx >= Length(parr)) then exit;
-      pan := parr[idx];
+      pan := g_Map_PanelByGUID(pguid);
+      if (pan = nil) then exit;
       drawLine(
         trig.trigCenter.x, trig.trigCenter.y,
         pan.x+pan.width div 2, pan.y+pan.height div 2,
@@ -1065,20 +1065,21 @@ procedure plrDebugDraw ();
     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);
+    drawPanelDest(trig.trigPanelGUID);
     case trig.TriggerType of
       TRIGGER_NONE: begin end;
       TRIGGER_EXIT: begin end;
       TRIGGER_TELEPORT: begin end;
-      TRIGGER_OPENDOOR: begin drawPanelDest(gWalls, trig.trigPanelId); end;
-      TRIGGER_CLOSEDOOR: begin drawPanelDest(gWalls, trig.trigPanelId); end;
-      TRIGGER_DOOR: begin drawPanelDest(gWalls, trig.trigPanelId); end;
-      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_OPENDOOR: begin end;
+      TRIGGER_CLOSEDOOR: begin end;
+      TRIGGER_DOOR: begin end;
+      TRIGGER_DOOR5: begin end;
+      TRIGGER_CLOSETRAP: begin end;
+      TRIGGER_TRAP: 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_LIFTUP: begin end;
+      TRIGGER_LIFTDOWN: begin end;
+      TRIGGER_LIFT: begin end;
       TRIGGER_TEXTURE: begin end;
       TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF, TRIGGER_PRESS:
         begin
@@ -1374,7 +1375,7 @@ procedure cbAtcurToggleWalls ();
   begin
     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);
-    if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
+    if pan.Enabled then g_Map_DisableWallGUID(pan.guid) else g_Map_EnableWallGUID(pan.guid);
   end;
 begin
   //e_WriteLog('=== TOGGLE WALL ===', MSG_NOTIFY);
index ff6e7570c3b35863ce5ad0dd26127907ed12d8ce..00f39a188463600e838906f1726e382dbf102801 100644 (file)
@@ -63,6 +63,8 @@ function  g_Map_Exist(Res: String): Boolean;
 procedure g_Map_Free(freeTextures: Boolean=true);
 procedure g_Map_Update();
 
+function g_Map_PanelByGUID (aguid: Integer): TPanel; inline;
+
 procedure g_Map_DrawPanels (PanelType: Word); // unaccelerated
 procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
 
@@ -70,10 +72,18 @@ procedure g_Map_DrawBack(dx, dy: Integer);
 function  g_Map_CollidePanel(X, Y: Integer; Width, Height: Word;
                              PanelType: Word; b1x3: Boolean=false): Boolean;
 function  g_Map_CollideLiquid_Texture(X, Y: Integer; Width, Height: Word): DWORD;
-procedure g_Map_EnableWall(ID: DWORD);
-procedure g_Map_DisableWall(ID: DWORD);
-procedure g_Map_SwitchTexture(PanelType: Word; ID: DWORD; AnimLoop: Byte = 0);
-procedure g_Map_SetLift(ID: DWORD; t: Integer);
+
+procedure g_Map_EnableWallGUID (pguid: Integer);
+procedure g_Map_DisableWallGUID (pguid: Integer);
+procedure g_Map_SetLiftGUID (pguid: Integer; t: Integer);
+
+// HACK!!!
+procedure g_Map_EnableWall_XXX (ID: DWORD);
+procedure g_Map_DisableWall_XXX (ID: DWORD);
+procedure g_Map_SetLift_XXX (ID: DWORD; t: Integer);
+
+procedure g_Map_SwitchTextureGUID (PanelType: Word; pguid: Integer; AnimLoop: Byte = 0);
+
 procedure g_Map_ReAdd_DieTriggers();
 function  g_Map_IsSpecialTexture(Texture: String): Boolean;
 
@@ -161,17 +171,17 @@ const
       PANEL_FORE
    *)
   // sorted by draw priority
-  GridTagBack = 1 shl 0;
-  GridTagStep = 1 shl 1;
-  GridTagWall = 1 shl 2;
-  GridTagDoor = 1 shl 3;
-  GridTagAcid1 = 1 shl 4;
-  GridTagAcid2 = 1 shl 5;
-  GridTagWater = 1 shl 6;
-  GridTagFore = 1 shl 7;
+  GridTagBack = 1 shl 0; // gRenderBackgrounds
+  GridTagStep = 1 shl 1; // gSteps
+  GridTagWall = 1 shl 2; // gWalls
+  GridTagDoor = 1 shl 3; // gWalls
+  GridTagAcid1 = 1 shl 4; // gAcid1
+  GridTagAcid2 = 1 shl 5; // gAcid2
+  GridTagWater = 1 shl 6; // gWater
+  GridTagFore = 1 shl 7; // gRenderForegrounds
   // the following are invisible
-  GridTagLift = 1 shl 8;
-  GridTagBlockMon = 1 shl 9;
+  GridTagLift = 1 shl 8; // gLifts
+  GridTagBlockMon = 1 shl 9; // gBlockMon
 
   GridDrawableMask = (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore);
 
@@ -231,6 +241,32 @@ const
   FLAG_SIGNATURE = $47414C46; // 'FLAG'
 
 
+{
+type
+  THashIntPanel = specialize THashBase<Integer, TPanel>;
+
+function hashNewIntPanel (): THashIntPanel;
+begin
+  result := THashIntPanel.Create(hiihash, hiiequ);
+end;
+}
+
+
+var
+  //panByGUID: THashIntPanel = nil;
+  panByGUID: array of TPanel = nil;
+  //panLastGUID: Integer = 0;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+function g_Map_PanelByGUID (aguid: Integer): TPanel; inline;
+begin
+  //if (panByGUID = nil) or (not panByGUID.get(aguid, result)) then result := nil;
+  if (aguid >= 0) and (aguid < Length(panByGUID)) then result := panByGUID[aguid] else result := nil;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
 var
   dfmapdef: TDynMapDef = nil;
 
@@ -284,6 +320,7 @@ begin
 end;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
 function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord;
 var
   wst: TSFSMemoryChunkStream = nil;
@@ -331,6 +368,7 @@ begin
 end;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
 var
   NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
   NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
@@ -395,6 +433,7 @@ begin
 end;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
 function panelTypeToTag (panelType: Word): Integer;
 begin
   case panelType of
@@ -430,19 +469,12 @@ begin
 end;
 
 
-type
-  TPanelID = record
-    PWhere: ^TPanelArray;
-    PArrID: Integer;
-  end;
-
 var
-  PanelById:     array of TPanelID;
-  Textures:      TLevelTextureArray = nil;
+  Textures: TLevelTextureArray = nil;
   TextNameHash: THashStrInt = nil; // key: texture name; value: index in `Textures`
   BadTextNameHash: THashStrInt = nil; // set; so we won't spam with non-existing texture messages
-  RespawnPoints: Array of TRespawnPoint;
-  FlagPoints:    Array [FLAG_RED..FLAG_BLUE] of PFlagPoint;
+  RespawnPoints: array of TRespawnPoint;
+  FlagPoints: array[FLAG_RED..FLAG_BLUE] of PFlagPoint;
   //DOMFlagPoints: Array of TFlagPoint;
 
 
@@ -742,48 +774,41 @@ function CreatePanel(PanelRec: TDynRecord; AddTextures: TAddTextureArray;
 var
   len: Integer;
   panels: ^TPanelArray;
+  pan: TPanel;
+  pguid: Integer;
 begin
   Result := -1;
 
   case PanelRec.PanelType of
-    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
-      panels := @gWalls;
-    PANEL_BACK:
-      panels := @gRenderBackgrounds;
-    PANEL_FORE:
-      panels := @gRenderForegrounds;
-    PANEL_WATER:
-      panels := @gWater;
-    PANEL_ACID1:
-      panels := @gAcid1;
-    PANEL_ACID2:
-      panels := @gAcid2;
-    PANEL_STEP:
-      panels := @gSteps;
-    PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT:
-      panels := @gLifts;
-    PANEL_BLOCKMON:
-      panels := @gBlockMon;
-    else
-      Exit;
+    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: panels := @gWalls;
+    PANEL_BACK: panels := @gRenderBackgrounds;
+    PANEL_FORE: panels := @gRenderForegrounds;
+    PANEL_WATER: panels := @gWater;
+    PANEL_ACID1: panels := @gAcid1;
+    PANEL_ACID2: panels := @gAcid2;
+    PANEL_STEP: panels := @gSteps;
+    PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: panels := @gLifts;
+    PANEL_BLOCKMON: panels := @gBlockMon;
+    else exit;
   end;
 
   len := Length(panels^);
-  SetLength(panels^, len + 1);
-
-  panels^[len] := TPanel.Create(PanelRec, AddTextures, CurTex, Textures);
-  panels^[len].arrIdx := len;
-  panels^[len].proxyId := -1;
-  panels^[len].tag := panelTypeToTag(PanelRec.PanelType);
-  if sav then
-    panels^[len].SaveIt := True;
-
-  Result := len;
-
-  len := Length(PanelByID);
-  SetLength(PanelByID, len + 1);
-  PanelByID[len].PWhere := panels;
-  PanelByID[len].PArrID := Result;
+  SetLength(panels^, len+1);
+
+  //Inc(panLastGUID);
+  pguid := Length(panByGUID);
+  SetLength(panByGUID, pguid+1); //FIXME!
+  pan := TPanel.Create(PanelRec, AddTextures, CurTex, Textures, pguid);
+  panels^[len] := pan;
+  pan.arrIdx := len;
+  pan.proxyId := -1;
+  pan.tag := panelTypeToTag(PanelRec.PanelType);
+  if sav then pan.SaveIt := True;
+
+  PanelRec.user['panel_guid'] := pan.guid;
+  //panByGUID.put(pan.guid, pan);
+
+  result := len;
 end;
 
 
@@ -1265,13 +1290,13 @@ begin
     Height := Trigger.Height;
     Enabled := Trigger.Enabled;
     //TexturePanel := Trigger.TexturePanel;
-    TexturePanel := atpanid;
+    TexturePanelGUID := atpanid;
     TexturePanelType := fTexturePanel1Type;
     ShotPanelType := fTexturePanel2Type;
     TriggerType := Trigger.TriggerType;
     ActivateType := Trigger.ActivateType;
     Keys := Trigger.Keys;
-    trigPanelId := atrigpanid;
+    trigPanelGUID := atrigpanid;
     //trigShotPanelId := ashotpanid;
     //Data.Default := Trigger.DATA;
     if (Trigger.trigRec = nil) then
@@ -1537,11 +1562,13 @@ type
     LiftPanelIdx: Integer;
     DoorPanelIdx: Integer;
     ShotPanelIdx: Integer;
+    MPlatPanelIdx: Integer;
     trigrec: TDynRecord;
     texPan: TDynRecord;
     liftPan: TDynRecord;
     doorPan: TDynRecord;
     shotPan: TDynRecord;
+    mplatPan: TDynRecord;
   end;
 var
   WAD: TWADFile;
@@ -1574,6 +1601,11 @@ begin
   gCurrentMap.Free();
   gCurrentMap := nil;
 
+  //panByGUID.Free();
+  //panByGUID := hashNewIntPanel();
+  //panLastGUID := 0;
+  panByGUID := nil;
+
   Result := False;
   gMapInfo.Map := Res;
   TriggersTable := nil;
@@ -1739,10 +1771,12 @@ begin
         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
@@ -1758,11 +1792,17 @@ begin
         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;
 
         g_Game_StepLoading();
       end;
@@ -1970,6 +2010,7 @@ begin
       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;
     end;
 
     // create map grid, init other grids (for monsters, for example)
@@ -1992,6 +2033,7 @@ begin
              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;
         //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));
@@ -2321,6 +2363,11 @@ begin
     BadTextNameHash := nil;
   end;
 
+  //panByGUID.Free();
+  //panByGUID := nil;
+  //panLastGUID := 0;
+  panByGUID := nil;
+
   FreePanelArray(gWalls);
   FreePanelArray(gRenderBackgrounds);
   FreePanelArray(gRenderForegrounds);
@@ -2352,8 +2399,6 @@ begin
 
   gDoorMap := nil;
   gLiftMap := nil;
-
-  PanelByID := nil;
 end;
 
 procedure g_Map_Update();
@@ -2798,11 +2843,18 @@ begin
 end;
 
 
-procedure g_Map_EnableWall(ID: DWORD);
+procedure g_Map_EnableWall_XXX (ID: DWORD); begin if (ID < Length(gWalls)) then g_Map_EnableWallGUID(gWalls[ID].guid); end;
+procedure g_Map_DisableWall_XXX (ID: DWORD); begin if (ID < Length(gWalls)) then g_Map_DisableWallGUID(gWalls[ID].guid); end;
+procedure g_Map_SetLift_XXX (ID: DWORD; t: Integer); begin if (ID < Length(gLifts)) then g_Map_SetLiftGUID(gLifts[ID].guid, t); end;
+
+
+procedure g_Map_EnableWallGUID (pguid: Integer);
 var
   pan: TPanel;
 begin
-  pan := gWalls[ID];
+  //pan := gWalls[ID];
+  pan := g_Map_PanelByGUID(pguid);
+  if (pan = nil) then exit;
   pan.Enabled := True;
   g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true);
 
@@ -2810,65 +2862,71 @@ 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].PanelType, ID);
+  if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState({gWalls[ID]}pan.PanelType, pguid);
 
   {$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);
   {$ENDIF}
 end;
 
-procedure g_Map_DisableWall(ID: DWORD);
+
+procedure g_Map_DisableWallGUID (pguid: Integer);
 var
   pan: TPanel;
 begin
-  pan := gWalls[ID];
+  //pan := gWalls[ID];
+  pan := g_Map_PanelByGUID(pguid);
+  if (pan = nil) 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, ID);
+  if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pan.PanelType, pguid);
 
   {$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);
   {$ENDIF}
 end;
 
-procedure g_Map_SwitchTexture(PanelType: Word; ID: DWORD; AnimLoop: Byte = 0);
+
+procedure g_Map_SwitchTextureGUID (PanelType: Word; pguid: Integer; AnimLoop: Byte = 0);
 var
   tp: TPanel;
 begin
+  tp := g_Map_PanelByGUID(pguid);
+  if (tp = nil) then exit;
+  {
   case PanelType of
-    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
-      tp := gWalls[ID];
-    PANEL_FORE:
-      tp := gRenderForegrounds[ID];
-    PANEL_BACK:
-      tp := gRenderBackgrounds[ID];
-    PANEL_WATER:
-      tp := gWater[ID];
-    PANEL_ACID1:
-      tp := gAcid1[ID];
-    PANEL_ACID2:
-      tp := gAcid2[ID];
-    PANEL_STEP:
-      tp := gSteps[ID];
-    else
-      Exit;
+    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: tp := gWalls[ID];
+    PANEL_FORE: tp := gRenderForegrounds[ID];
+    PANEL_BACK: tp := gRenderBackgrounds[ID];
+    PANEL_WATER: tp := gWater[ID];
+    PANEL_ACID1: tp := gAcid1[ID];
+    PANEL_ACID2: tp := gAcid2[ID];
+    PANEL_STEP: tp := gSteps[ID];
+    else exit;
   end;
+  }
 
   tp.NextTexture(AnimLoop);
-  if g_Game_IsServer and g_Game_IsNet then
-    MH_SEND_PanelTexture(PanelType, ID, AnimLoop);
+  if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(PanelType, pguid, AnimLoop);
 end;
 
-procedure g_Map_SetLift(ID: DWORD; t: Integer);
+
+procedure g_Map_SetLiftGUID (pguid: Integer; t: Integer);
+var
+  pan: TPanel;
 begin
-  if gLifts[ID].LiftType = t then
-    Exit;
+  //pan := gLifts[ID];
+  pan := g_Map_PanelByGUID(pguid);
+  if (pan = nil) then exit;
+  if not pan.isGLift then exit;
 
-  with gLifts[ID] do
+  if ({gLifts[ID]}pan.LiftType = t) then exit; //!FIXME!TRIGANY!
+
+  with {gLifts[ID]} pan do
   begin
     LiftType := t;
 
@@ -2882,11 +2940,12 @@ begin
       3: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT);
     end;
 
-    if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(PanelType, ID);
+    if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(PanelType, pguid);
   end;
 end;
 
-function g_Map_GetPoint(PointType: Byte; var RespawnPoint: TRespawnPoint): Boolean;
+
+function g_Map_GetPoint (PointType: Byte; var RespawnPoint: TRespawnPoint): Boolean;
 var
   a: Integer;
   PointsArray: Array of TRespawnPoint;
index b6a60c0fae409bd9fcbca2100547d4fbd3e4f8dc..16e6bb511d3c2437e8d0bd76da86a26fec99343b 100644 (file)
@@ -22,7 +22,7 @@ uses
   e_log, e_msg, ENet, Classes;
 
 const
-  NET_PROTOCOL_VER = 171;
+  NET_PROTOCOL_VER = 172;
 
   NET_MAXCLIENTS = 24;
   NET_CHANS = 11;
index f77bdcadd97dbafa8ea20c15c44e4f473ce80806..53ab6a501b063c2cae51a19a9edcf326df2840a4 100644 (file)
@@ -52,8 +52,8 @@ const
   NET_MSG_MSHOT  = 134;
   NET_MSG_MDEL   = 135;
 
-  NET_MSG_PSTATE = 141;
-  NET_MSG_PTEX   = 142;
+  NET_MSG_PSTATE   = 141;
+  NET_MSG_PTEX     = 142;
 
   NET_MSG_TSOUND = 151;
   NET_MSG_TMUSIC = 152;
@@ -168,8 +168,8 @@ procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_
 procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
 // PANEL
-procedure MH_SEND_PanelTexture(PType: Word; PID: LongWord; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
-procedure MH_SEND_PanelState(PType: Word; PID: LongWord; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelTexture(PType: Word; PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelState(PType: Word; PGUID: Integer; ID: Integer = NET_EVERYONE);
 // MONSTER
 procedure MH_SEND_MonsterSpawn(UID: Word; ID: Integer = NET_EVERYONE);
 procedure MH_SEND_MonsterPos(UID: Word; ID: Integer = NET_EVERYONE);
@@ -1217,10 +1217,13 @@ end;
 
 // PANEL
 
-procedure MH_SEND_PanelTexture(PType: Word; PID: LongWord; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelTexture(PType: Word; PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
 var
   TP: TPanel;
 begin
+  TP := g_Map_PanelByGUID(PGUID);
+  if (TP = nil) then exit;
+  {
   case PType of
     PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
       TP := gWalls[PID];
@@ -1239,12 +1242,13 @@ begin
     else
       Exit;
   end;
+  }
 
   with TP do
   begin
     NetOut.Write(Byte(NET_MSG_PTEX));
     NetOut.Write(PType);
-    NetOut.Write(PID);
+    NetOut.Write(LongWord(PGUID));
     NetOut.Write(FCurTexture);
     NetOut.Write(FCurFrame);
     NetOut.Write(FCurFrameCount);
@@ -1254,32 +1258,36 @@ begin
   g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
 end;
 
-procedure MH_SEND_PanelState(PType: Word; PID: LongWord; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelState(PType: Word; PGUID: Integer; ID: Integer = NET_EVERYONE);
 var
   TP: TPanel;
 begin
+  TP := g_Map_PanelByGUID(PGUID);
+  if (TP = nil) then exit;
   case PType of
-    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
-      TP := gWalls[PID];
-    PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT:
-      TP := gLifts[PID];
+    {
+    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: TP := gWalls[PID];
+    PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: TP := gLifts[PID];
+    }
     PANEL_BACK:
     begin
-      TP := gRenderBackgrounds[PID];
+      //TP := gRenderBackgrounds[PID];
       TP.Moved := True;
     end;
     PANEL_FORE:
     begin
-      TP := gRenderForegrounds[PID];
+      //TP := gRenderForegrounds[PID];
       TP.Moved := True;
     end;
+    {
     else
       Exit;
+    }
   end;
 
   NetOut.Write(Byte(NET_MSG_PSTATE));
   NetOut.Write(PType);
-  NetOut.Write(PID);
+  NetOut.Write(LongWord(PGUID));
   NetOut.Write(Byte(TP.Enabled));
   NetOut.Write(TP.LiftType);
   NetOut.Write(TP.X);
@@ -2403,67 +2411,62 @@ end;
 procedure MC_RECV_PanelTexture(var M: TMsg);
 var
   TP: TPanel;
-  PType: Word;
-  ID: LongWord;
+  //PType: Word;
+  PGUID: Integer;
   Tex, Fr: Integer;
   Loop, Cnt: Byte;
 begin
   if not gGameOn then Exit;
-  PType := M.ReadWord();
-  ID := M.ReadLongWord();
+  {PType :=} M.ReadWord();
+  PGUID := Integer(M.ReadLongWord());
   Tex := M.ReadLongInt();
   Fr := M.ReadLongInt();
   Cnt := M.ReadByte();
   Loop := M.ReadByte();
 
-  TP := nil;
+  TP := g_Map_PanelByGUID(PGUID);
 
+  {
   case PType of
-    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
-     if gWalls <> nil then
-      TP := gWalls[ID];
-    PANEL_FORE:
-     if gRenderForegrounds <> nil then
-      TP := gRenderForegrounds[ID];
-    PANEL_BACK:
-     if gRenderBackgrounds <> nil then
-      TP := gRenderBackgrounds[ID];
-    PANEL_WATER:
-     if gWater <> nil then
-      TP := gWater[ID];
-    PANEL_ACID1:
-     if gAcid1 <> nil then
-      TP := gAcid1[ID];
-    PANEL_ACID2:
-     if gAcid2 <> nil then
-      TP := gAcid2[ID];
-    PANEL_STEP:
-     if gSteps <> nil then
-      TP := gSteps[ID];
-    else
-      Exit;
+    PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: if gWalls <> nil then TP := gWalls[ID];
+    PANEL_FORE: if gRenderForegrounds <> nil then TP := gRenderForegrounds[ID];
+    PANEL_BACK: if gRenderBackgrounds <> nil then TP := gRenderBackgrounds[ID];
+    PANEL_WATER: if gWater <> nil then TP := gWater[ID];
+    PANEL_ACID1: if gAcid1 <> nil then TP := gAcid1[ID];
+    PANEL_ACID2: if gAcid2 <> nil then TP := gAcid2[ID];
+    PANEL_STEP: if gSteps <> nil then TP := gSteps[ID];
+    else Exit;
   end;
+  }
 
   if TP <> nil then
+  begin
     if Loop = 0 then
-    begin    // switch texture
+    begin
+      // switch texture
       TP.SetTexture(Tex, Loop);
       TP.SetFrame(Fr, Cnt);
-    end else // looped or non-looped animation
+    end
+    else
+    begin
+      // looped or non-looped animation
       TP.NextTexture(Loop);
+    end;
+  end;
 end;
 
 procedure MC_RECV_PanelState(var M: TMsg);
 var
-  ID: LongWord;
+  PGUID: Integer;
   E: Boolean;
   Lift: Byte;
   PType: Word;
   X, Y: Integer;
+  TP: TPanel;
 begin
   if not gGameOn then Exit;
   PType := M.ReadWord();
-  ID := M.ReadLongWord();
+  PGUID := Integer(M.ReadLongWord());
   E := (M.ReadByte() <> 0);
   Lift := M.ReadByte();
   X := M.ReadLongInt();
@@ -2471,25 +2474,33 @@ begin
 
   case PType of
     PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
-      if E then
-        g_Map_EnableWall(ID)
-      else
-        g_Map_DisableWall(ID);
+      if E then g_Map_EnableWallGUID(PGUID) else g_Map_DisableWallGUID(PGUID);
 
     PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT:
-      g_Map_SetLift(ID, Lift);
+      g_Map_SetLiftGUID(PGUID, Lift);
 
-    PANEL_BACK:
+    {PANEL_BACK,
+    PANEL_FORE:}
+    else
     begin
-      gRenderBackgrounds[ID].X := X;
-      gRenderBackgrounds[ID].Y := Y;
+      TP := g_Map_PanelByGUID(PGUID);
+      if (TP <> nil) then
+      begin
+        TP.X := X;
+        TP.Y := Y;
+        TP.positionChanged();
+      end;
+      //gRenderBackgrounds[ID].X := X;
+      //gRenderBackgrounds[ID].Y := Y;
     end;
 
+    {
     PANEL_FORE:
     begin
       gRenderForegrounds[ID].X := X;
       gRenderForegrounds[ID].Y := Y;
-    end;      
+    end;
+    }
   end;
 end;
 
index f1aa0078ede8d0e6d64e1ff1a680348d859f1409..3c95a56ffe7f3b07724ad060b99a995f7fad3c26 100644 (file)
@@ -31,6 +31,9 @@ type
 
   TPanel = Class (TObject)
   private
+    const
+  private
+    mGUID: Integer; // will be assigned in "g_map.pas"
     FTextureWidth:    Word;
     FTextureHeight:   Word;
     FAlpha:           Byte;
@@ -65,14 +68,17 @@ type
     FMoved:           Boolean;
     FLiftType:        Byte;
     FLastAnimLoop:    Byte;
+    // sorry, there fields are public to allow setting 'em in g_map; this should be fixed later
+    // for now, PLEASE, don't modify 'em, or all hell will break loose
     arrIdx:           Integer; // index in one of internal arrays; sorry
-    tag:              Integer; // used in coldets and such; sorry
+    tag:              Integer; // used in coldets and such; sorry; see g_map.GridTagXXX
     proxyId:          Integer; // proxy id in map grid (DO NOT USE!)
+    mapId:            AnsiString; // taken directly from map file; dunno why it is here
 
     constructor Create(PanelRec: TDynRecord;
                        AddTextures: TAddTextureArray;
                        CurTex: Integer;
-                       var Textures: TLevelTextureArray);
+                       var Textures: TLevelTextureArray; aguid: Integer);
     destructor  Destroy(); override;
 
     procedure   Draw();
@@ -87,10 +93,24 @@ type
     procedure   SaveState(var Mem: TBinMemoryWriter);
     procedure   LoadState(var Mem: TBinMemoryReader);
 
+    procedure positionChanged ();
+
+    function isGBack (): Boolean; inline; // gRenderBackgrounds
+    function isGStep (): Boolean; inline; // gSteps
+    function isGWall (): Boolean; inline; // gWalls
+    function isGAcid1 (): Boolean; inline; // gAcid1
+    function isGAcid2 (): Boolean; inline; // gAcid2
+    function isGWater (): Boolean; inline; // gWater
+    function isGFore (): Boolean; inline; // gRenderForegrounds
+    function isGLift (): Boolean; inline; // gLifts
+    function isGBlockMon (): Boolean; inline; // gBlockMon
+
+
   public
     property visvalid: Boolean read getvisvalid; // panel is "visvalid" when it's width and height are positive
 
   published
+    property guid: Integer read mGUID; // will be assigned in "g_map.pas"
     property x0: Integer read FX;
     property y0: Integer read FY;
     property x1: Integer read getx1; // inclusive!
@@ -131,7 +151,7 @@ const
 constructor TPanel.Create(PanelRec: TDynRecord;
                           AddTextures: TAddTextureArray;
                           CurTex: Integer;
-                          var Textures: TLevelTextureArray);
+                          var Textures: TLevelTextureArray; aguid: Integer);
 var
   i: Integer;
 begin
@@ -146,6 +166,9 @@ begin
   LastAnimLoop := 0;
   Moved := False;
 
+  mapId := PanelRec.id;
+  mGUID := aguid;
+
   mMovingSpeed := PanelRec.moveSpeed;
   mMovingStart := PanelRec.moveStart;
   mMovingEnd := PanelRec.moveEnd;
@@ -295,6 +318,16 @@ function TPanel.getx1 (): Integer; inline; begin result := X+Width-1; end;
 function TPanel.gety1 (): Integer; inline; begin result := Y+Height-1; end;
 function TPanel.getvisvalid (): Boolean; inline; begin result := (Width > 0) and (Height > 0); end;
 
+function TPanel.isGBack (): Boolean; inline; begin result := ((tag and GridTagBack) <> 0); end;
+function TPanel.isGStep (): Boolean; inline; begin result := ((tag and GridTagStep) <> 0); end;
+function TPanel.isGWall (): Boolean; inline; begin result := ((tag and (GridTagWall or GridTagDoor)) <> 0); end;
+function TPanel.isGAcid1 (): Boolean; inline; begin result := ((tag and GridTagAcid1) <> 0); end;
+function TPanel.isGAcid2 (): Boolean; inline; begin result := ((tag and GridTagAcid2) <> 0); end;
+function TPanel.isGWater (): Boolean; inline; begin result := ((tag and GridTagWater) <> 0); end;
+function TPanel.isGFore (): Boolean; inline; begin result := ((tag and GridTagFore) <> 0); end;
+function TPanel.isGLift (): Boolean; inline; begin result := ((tag and GridTagLift) <> 0); end;
+function TPanel.isGBlockMon (): Boolean; inline; begin result := ((tag and GridTagBlockMon) <> 0); end;
+
 procedure TPanel.Draw();
 var
   xx, yy: Integer;
@@ -406,6 +439,12 @@ begin
 end;
 
 
+procedure TPanel.positionChanged ();
+begin
+  if (proxyId >= 0) then mapGrid.moveBody(proxyId, X, Y);
+end;
+
+
 var
   monMoveList: array of TMonster = nil;
   monMoveListUsed: Integer = 0;
@@ -518,7 +557,7 @@ begin
     Y := ny;
     g_Mark(nx, ny, Width, Height, MARK_WALL);
     // fix grid
-    if (proxyId >= 0) then mapGrid.moveBody(proxyId, nx, ny);
+    positionChanged();
     // notify moved monsters about their movement
     for f := 0 to monMoveListUsed-1 do monMoveList[f].positionChanged();
   end;
index 6698288c33cda673ec4fe9129256171494b1fc1c..437d1f6462c98f8c1c9973dfd3c099c5a4d906cf 100644 (file)
@@ -38,7 +38,7 @@ type
     Enabled:          Boolean;
     ActivateType:     Byte;
     Keys:             Byte;
-    TexturePanel:     Integer;
+    TexturePanelGUID: Integer;
     TexturePanelType: Word;
 
     TimeOut:          Word;
@@ -64,8 +64,7 @@ type
 
     mapId: AnsiString; // trigger id, from map
     mapIndex: Integer; // index in fields['trigger'], used in save/load
-    //trigShotPanelId: Integer;
-    trigPanelId: Integer;
+    trigPanelGUID: Integer;
 
     //TrigData:             TTriggerData;
     trigData: TDynRecord; // triggerdata; owned by trigger
@@ -74,7 +73,7 @@ type
     function trigCenter (): TDFPoint; inline;
 
   public
-    property trigShotPanelId: Integer read trigPanelId write trigPanelId;
+    property trigShotPanelGUID: Integer read trigPanelGUID write trigPanelGUID;
   end;
 
 function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD;
@@ -92,16 +91,18 @@ procedure g_Triggers_LoadState(var Mem: TBinMemoryReader);
 
 function tr_Message(MKind: Integer; MText: string; MSendTo: Integer; MTime: Integer; ActivateUID: Integer): Boolean;
 
-function tr_CloseDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
-function tr_OpenDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
-procedure tr_CloseTrap(PanelID: Integer; NoSound: Boolean; d2d: Boolean);
-function tr_SetLift(PanelID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
+{
+function tr_CloseDoor (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
+function tr_OpenDoor (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
+procedure tr_CloseTrap (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean);
+function tr_SetLift (PanelGUID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
 
-function tr_Teleport(ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean;
-function tr_Push(ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean;
+function tr_Teleport (ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean;
+function tr_Push (ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean;
 
-procedure tr_MakeEffect(X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean);
-function tr_SpawnShot(ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer;
+procedure tr_MakeEffect (X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean);
+function tr_SpawnShot (ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer;
+}
 
 var
   gTriggerClientID: Integer = 0;
@@ -112,7 +113,8 @@ var
 implementation
 
 uses
-  g_player, g_map, Math, g_gfx, g_game, g_textures,
+  Math,
+  g_player, g_map, g_panel, g_gfx, g_game, g_textures,
   g_console, g_monsters, g_items, g_phys, g_weapons,
   wadreader, g_main, SysUtils, e_log, g_language,
   g_options, g_net, g_netmsg, utils, xparser;
@@ -128,7 +130,7 @@ begin
 end;
 
 
-function FindTrigger(): DWORD;
+function FindTrigger (): DWORD;
 var
   i: Integer;
 begin
@@ -151,85 +153,95 @@ begin
 end;
 
 
-function tr_CloseDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
+function tr_CloseDoor (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
 var
   a, b, c: Integer;
+  pan: TPanel;
+  PanelID: Integer;
 begin
-  Result := False;
-
-  if PanelID = -1 then Exit;
+  result := false;
+  pan := g_Map_PanelByGUID(PanelGUID);
+  if (pan = nil) or not pan.isGWall then exit; //!FIXME!TRIGANY!
+  PanelID := pan.arrIdx;
 
   if not d2d then
   begin
     with gWalls[PanelID] do
     begin
-      if g_CollidePlayer(X, Y, Width, Height) or
-         g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit;
-
+      if g_CollidePlayer(X, Y, Width, Height) or g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit;
       if not Enabled then
       begin
         if not NoSound then
         begin
           g_Sound_PlayExAt('SOUND_GAME_DOORCLOSE', X, Y);
-          if g_Game_IsServer and g_Game_IsNet then
-            MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE');
+          if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE');
         end;
-        g_Map_EnableWall(PanelID);
-        Result := True;
+        g_Map_EnableWallGUID(PanelGUID);
+        result := true;
       end;
     end;
   end
   else
   begin
-    if gDoorMap = nil then Exit;
+    if (gDoorMap = nil) then exit;
 
     c := -1;
     for a := 0 to High(gDoorMap) do
     begin
       for b := 0 to High(gDoorMap[a]) do
+      begin
         if gDoorMap[a, b] = DWORD(PanelID) then
         begin
           c := a;
-          Break;
+          break;
         end;
-
-      if c <> -1 then Break;
+      end;
+      if (c <> -1) then break;
     end;
-    if c = -1 then Exit;
+    if (c = -1) then exit;
 
     for b := 0 to High(gDoorMap[c]) do
+    begin
       with gWalls[gDoorMap[c, b]] do
       begin
-        if g_CollidePlayer(X, Y, Width, Height) or
-          g_Mons_IsAnyAliveAt(X, Y, Width, Height) then Exit;
+        if g_CollidePlayer(X, Y, Width, Height) or g_Mons_IsAnyAliveAt(X, Y, Width, Height) then exit;
       end;
+    end;
 
     if not NoSound then
+    begin
       for b := 0 to High(gDoorMap[c]) do
+      begin
         if not gWalls[gDoorMap[c, b]].Enabled then
         begin
           with gWalls[PanelID] do
           begin
             g_Sound_PlayExAt('SOUND_GAME_DOORCLOSE', X, Y);
-            if g_Game_IsServer and g_Game_IsNet then
-              MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE');
+            if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOORCLOSE');
           end;
-          Break;
+          break;
         end;
+      end;
+    end;
 
     for b := 0 to High(gDoorMap[c]) do
+    begin
       if not gWalls[gDoorMap[c, b]].Enabled then
       begin
-        g_Map_EnableWall(gDoorMap[c, b]);
-        Result := True;
+        g_Map_EnableWall_XXX(gDoorMap[c, b]);
+        result := true;
       end;
+    end;
   end;
 end;
 
-procedure tr_CloseTrap(PanelID: Integer; NoSound: Boolean; d2d: Boolean);
+
+procedure tr_CloseTrap (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean);
 var
   a, b, c: Integer;
   wx, wy, wh, ww: Integer;
+  pan: TPanel;
+  PanelID: Integer;
 
   function monsDamage (mon: TMonster): Boolean;
   begin
@@ -238,7 +250,9 @@ var
   end;
 
 begin
-  if PanelID = -1 then Exit;
+  pan := g_Map_PanelByGUID(PanelGUID);
+  if (pan = nil) or not pan.isGWall then exit; //!FIXME!TRIGANY!
+  PanelID := pan.arrIdx;
 
   if not d2d then
   begin
@@ -247,8 +261,7 @@ begin
       if (not NoSound) and (not Enabled) then
       begin
         g_Sound_PlayExAt('SOUND_GAME_SWITCH1', X, Y);
-        if g_Game_IsServer and g_Game_IsNet then
-          MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1');
+        if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH1');
       end;
     end;
 
@@ -260,20 +273,25 @@ begin
     with gWalls[PanelID] do
     begin
       if gPlayers <> nil then
+      begin
         for a := 0 to High(gPlayers) do
-          if (gPlayers[a] <> nil) and gPlayers[a].Live and
-              gPlayers[a].Collide(X, Y, Width, Height) then
+        begin
+          if (gPlayers[a] <> nil) and gPlayers[a].Live and gPlayers[a].Collide(X, Y, Width, Height) then
+          begin
             gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
+          end;
+        end;
+      end;
 
       //g_Mons_ForEach(monsDamage);
       g_Mons_ForEachAliveAt(wx, wy, ww, wh, monsDamage);
 
-      if not Enabled then g_Map_EnableWall(PanelID);
+      if not Enabled then g_Map_EnableWallGUID(PanelGUID);
     end;
   end
   else
   begin
-    if gDoorMap = nil then Exit;
+    if (gDoorMap = nil) then exit;
 
     c := -1;
     for a := 0 to High(gDoorMap) do
@@ -283,13 +301,12 @@ begin
         if gDoorMap[a, b] = DWORD(PanelID) then
         begin
           c := a;
-          Break;
+          break;
         end;
       end;
-
-      if c <> -1 then Break;
+      if (c <> -1) then break;
     end;
-    if c = -1 then Exit;
+    if (c = -1) then exit;
 
     if not NoSound then
     begin
@@ -317,10 +334,15 @@ begin
       with gWalls[gDoorMap[c, b]] do
       begin
         if gPlayers <> nil then
+        begin
           for a := 0 to High(gPlayers) do
-            if (gPlayers[a] <> nil) and gPlayers[a].Live and
-            gPlayers[a].Collide(X, Y, Width, Height) then
+          begin
+            if (gPlayers[a] <> nil) and gPlayers[a].Live and gPlayers[a].Collide(X, Y, Width, Height) then
+            begin
               gPlayers[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
+            end;
+          end;
+        end;
 
         //g_Mons_ForEach(monsDamage);
         g_Mons_ForEachAliveAt(wx, wy, ww, wh, monsDamage);
@@ -332,128 +354,146 @@ begin
               gMonsters[a].Damage(TRAP_DAMAGE, 0, 0, 0, HIT_TRAP);
         *)
 
-        if not Enabled then g_Map_EnableWall(gDoorMap[c, b]);
+        if not Enabled then g_Map_EnableWall_XXX(gDoorMap[c, b]);
       end;
     end;
   end;
 end;
 
-function tr_OpenDoor(PanelID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
+
+function tr_OpenDoor (PanelGUID: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
 var
   a, b, c: Integer;
+  pan: TPanel;
+  PanelID: Integer;
 begin
-  Result := False;
-
-  if PanelID = -1 then Exit;
+  result := false;
+  pan := g_Map_PanelByGUID(PanelGUID);
+  if (pan = nil) or not pan.isGWall then exit; //!FIXME!TRIGANY!
+  PanelID := pan.arrIdx;
 
   if not d2d then
   begin
     with gWalls[PanelID] do
+    begin
       if Enabled then
       begin
         if not NoSound then
         begin
           g_Sound_PlayExAt('SOUND_GAME_DOOROPEN', X, Y);
-          if g_Game_IsServer and g_Game_IsNet then
-            MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN');
+          if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN');
         end;
-        g_Map_DisableWall(PanelID);
-        Result := True;
+        g_Map_DisableWallGUID(PanelGUID);
+        result := true;
       end;
+    end
   end
   else
   begin
-    if gDoorMap = nil then Exit;
+    if (gDoorMap = nil) then exit;
 
     c := -1;
     for a := 0 to High(gDoorMap) do
     begin
       for b := 0 to High(gDoorMap[a]) do
+      begin
         if gDoorMap[a, b] = DWORD(PanelID) then
         begin
           c := a;
-          Break;
+          break;
         end;
-
-      if c <> -1 then Break;
+      end;
+      if (c <> -1) then break;
     end;
-    if c = -1 then Exit;
+    if (c = -1) then exit;
 
     if not NoSound then
+    begin
       for b := 0 to High(gDoorMap[c]) do
+      begin
         if gWalls[gDoorMap[c, b]].Enabled then
         begin
           with gWalls[PanelID] do
           begin
             g_Sound_PlayExAt('SOUND_GAME_DOOROPEN', X, Y);
-            if g_Game_IsServer and g_Game_IsNet then
-              MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN');
+            if g_Game_IsServer and g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_DOOROPEN');
           end;
-          Break;
+          break;
         end;
+      end;
+    end;
 
     for b := 0 to High(gDoorMap[c]) do
+    begin
       if gWalls[gDoorMap[c, b]].Enabled then
       begin
-        g_Map_DisableWall(gDoorMap[c, b]);
-        Result := True;
+        g_Map_DisableWall_XXX(gDoorMap[c, b]);
+        result := true;
       end;
+    end;
   end;
 end;
 
-function tr_SetLift(PanelID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
+
+function tr_SetLift (PanelGUID: Integer; d: Integer; NoSound: Boolean; d2d: Boolean): Boolean;
 var
-  a, b, c, t: Integer;
+  a, b, c: Integer;
+  t: Integer = 0;
+  pan: TPanel;
+  PanelID: Integer;
 begin
-  t := 0;
-  Result := False;
-
-  if PanelID = -1 then Exit;
+  result := false;
+  pan := g_Map_PanelByGUID(PanelGUID);
+  if (pan = nil) or not pan.isGLift then exit; //!FIXME!TRIGANY!
+  PanelID := pan.arrIdx;
 
-  if (gLifts[PanelID].PanelType = PANEL_LIFTUP) or
-     (gLifts[PanelID].PanelType = PANEL_LIFTDOWN) then
+  if (gLifts[PanelID].PanelType = PANEL_LIFTUP) or (gLifts[PanelID].PanelType = PANEL_LIFTDOWN) then
+  begin
     case d of
       0: t := 0;
       1: t := 1;
       else t := IfThen(gLifts[PanelID].LiftType = 1, 0, 1);
     end
-  else if (gLifts[PanelID].PanelType = PANEL_LIFTLEFT) or
-          (gLifts[PanelID].PanelType = PANEL_LIFTRIGHT) then
+  end
+  else if (gLifts[PanelID].PanelType = PANEL_LIFTLEFT) or (gLifts[PanelID].PanelType = PANEL_LIFTRIGHT) then
+  begin
     case d of
       0: t := 2;
       1: t := 3;
       else t := IfThen(gLifts[PanelID].LiftType = 2, 3, 2);
     end;
+  end;
 
   if not d2d then
   begin
     with gLifts[PanelID] do
-      if LiftType <> t then
+    begin
+      if (LiftType <> t) then
       begin
-        g_Map_SetLift(PanelID, t);
-
-        {if not NoSound then
-          g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X, Y);}
-        Result := True;
+        g_Map_SetLiftGUID(PanelGUID, t); //???
+        //if not NoSound then g_Sound_PlayExAt('SOUND_GAME_SWITCH0', X, Y);
+        result := true;
       end;
+    end;
   end
   else // Êàê â D2d
   begin
-    if gLiftMap = nil then Exit;
+    if (gLiftMap = nil) then exit;
 
     c := -1;
     for a := 0 to High(gLiftMap) do
     begin
       for b := 0 to High(gLiftMap[a]) do
-        if gLiftMap[a, b] = DWORD(PanelID) then
+      begin
+        if (gLiftMap[a, b] = DWORD(PanelID)) then
         begin
           c := a;
-          Break;
+          break;
         end;
-
-      if c <> -1 then Break;
+      end;
+      if (c <> -1) then break;
     end;
-    if c = -1 then Exit;
+    if (c = -1) then exit;
 
     {if not NoSound then
       for b := 0 to High(gLiftMap[c]) do
@@ -465,27 +505,32 @@ begin
         end;}
 
     for b := 0 to High(gLiftMap[c]) do
+    begin
       with gLifts[gLiftMap[c, b]] do
-        if LiftType <> t then
+      begin
+        if (LiftType <> t) then
         begin
-          g_Map_SetLift(gLiftMap[c, b], t);
-
-          Result := True;
+          g_Map_SetLift_XXX(gLiftMap[c, b], t);
+          result := true;
         end;
+      end;
+    end;
   end;
 end;
 
-function tr_SpawnShot(ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer;
+
+function tr_SpawnShot (ShotType: Integer; wx, wy, dx, dy: Integer; ShotSound: Boolean; ShotTarget: Word): Integer;
 var
   snd: string;
   Projectile: Boolean;
   TextureID: DWORD;
   Anim: TAnimation;
 begin
-  Result := -1;
+  result := -1;
   TextureID := DWORD(-1);
   snd := 'SOUND_WEAPON_FIREROCKET';
-  Projectile := True;
+  Projectile := true;
+
   case ShotType of
     TRIGGER_SHOT_PISTOL:
       begin
@@ -495,8 +540,7 @@ begin
         if ShotSound then
         begin
           g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET);
-          if g_Game_IsNet then
-            MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1);
+          if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1);
         end;
       end;
 
@@ -509,8 +553,7 @@ begin
         if ShotSound then
         begin
           g_Player_CreateShell(wx, wy, 0, -2, SHELL_BULLET);
-          if g_Game_IsNet then
-            MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1);
+          if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL1);
         end;
       end;
 
@@ -522,8 +565,7 @@ begin
         if ShotSound then
         begin
           g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL);
-          if g_Game_IsNet then
-            MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL2);
+          if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL2);
         end;
       end;
 
@@ -536,8 +578,7 @@ begin
         begin
           g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL);
           g_Player_CreateShell(wx, wy, 0, -2, SHELL_SHELL);
-          if g_Game_IsNet then
-            MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL3);
+          if g_Game_IsNet then MH_SEND_Effect(wx, wy, 0, NET_GFX_SHELL3);
         end;
       end;
 
@@ -627,125 +668,118 @@ begin
   end;
 
   if g_Game_IsNet and g_Game_IsServer then
+  begin
     case ShotType of
-      TRIGGER_SHOT_EXPL:
-        MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_EXPLODE);
-      TRIGGER_SHOT_BFGEXPL:
-        MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_BFGEXPL);
+      TRIGGER_SHOT_EXPL: MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_EXPLODE);
+      TRIGGER_SHOT_BFGEXPL: MH_SEND_Effect(wx, wy, Byte(ShotSound), NET_GFX_BFGEXPL);
       else
       begin
-        if Projectile then
-          MH_SEND_CreateShot(LastShotID);
-        if ShotSound then
-          MH_SEND_Sound(wx, wy, snd);
+        if Projectile then MH_SEND_CreateShot(LastShotID);
+        if ShotSound then MH_SEND_Sound(wx, wy, snd);
       end;
     end;
+  end;
 
-  if ShotSound then
-    g_Sound_PlayExAt(snd, wx, wy);
+  if ShotSound then g_Sound_PlayExAt(snd, wx, wy);
 
-  if Projectile then
-    Result := LastShotID;
+  if Projectile then Result := LastShotID;
 end;
 
-procedure MakeShot(var Trigger: TTrigger; wx, wy, dx, dy: Integer; TargetUID: Word);
+
+procedure MakeShot (var Trigger: TTrigger; wx, wy, dx, dy: Integer; TargetUID: Word);
 begin
   with Trigger do
-    if (trigData.trigShotAmmo = 0) or
-       ((trigData.trigShotAmmo > 0) and (ShotAmmoCount > 0)) then
+  begin
+    if (trigData.trigShotAmmo = 0) or ((trigData.trigShotAmmo > 0) and (ShotAmmoCount > 0)) then
     begin
-      if (trigShotPanelID <> -1) and (ShotPanelTime = 0) then
+      if (trigShotPanelGUID <> -1) and (ShotPanelTime = 0) then
       begin
-        g_Map_SwitchTexture(ShotPanelType, trigShotPanelID);
+        g_Map_SwitchTextureGUID(ShotPanelType, trigShotPanelGUID);
         ShotPanelTime := 4; // òèêîâ íà âñïûøêó âûñòðåëà
       end;
 
-      if trigData.trigShotIntSight > 0 then
-        ShotSightTimeout := 180; // ~= 5 ñåêóíä
+      if (trigData.trigShotIntSight > 0) then ShotSightTimeout := 180; // ~= 5 ñåêóíä
 
-      if ShotAmmoCount > 0 then Dec(ShotAmmoCount);
+      if (ShotAmmoCount > 0) then Dec(ShotAmmoCount);
 
-      dx := dx + Random(trigData.trigShotAccuracy) - Random(trigData.trigShotAccuracy);
-      dy := dy + Random(trigData.trigShotAccuracy) - Random(trigData.trigShotAccuracy);
+      dx += Random(trigData.trigShotAccuracy)-Random(trigData.trigShotAccuracy);
+      dy += Random(trigData.trigShotAccuracy)-Random(trigData.trigShotAccuracy);
 
       tr_SpawnShot(trigData.trigShotType, wx, wy, dx, dy, trigData.trigShotSound, TargetUID);
     end
     else
+    begin
       if (trigData.trigShotIntReload > 0) and (ShotReloadTime = 0) then
+      begin
         ShotReloadTime := trigData.trigShotIntReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè
+      end;
+    end;
+  end;
 end;
 
-procedure tr_MakeEffect(X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean);
+
+procedure tr_MakeEffect (X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean);
 var
   FramesID: DWORD;
   Anim: TAnimation;
 begin
   if T = TRIGGER_EFFECT_PARTICLE then
+  begin
     case ST of
       TRIGGER_EFFECT_SLIQUID:
       begin
-        if (CR = 255) and (CG = 0) and (CB = 0) then
-          g_GFX_SimpleWater(X, Y, 1, VX, VY, 1, 0, 0, 0)
-        else if (CR = 0) and (CG = 255) and (CB = 0) then
-          g_GFX_SimpleWater(X, Y, 1, VX, VY, 2, 0, 0, 0)
-        else if (CR = 0) and (CG = 0) and (CB = 255) then
-          g_GFX_SimpleWater(X, Y, 1, VX, VY, 3, 0, 0, 0)
-        else
-          g_GFX_SimpleWater(X, Y, 1, VX, VY, 0, 0, 0, 0);
+             if (CR = 255) and (CG = 0) and (CB = 0) then g_GFX_SimpleWater(X, Y, 1, VX, VY, 1, 0, 0, 0)
+        else if (CR = 0) and (CG = 255) and (CB = 0) then g_GFX_SimpleWater(X, Y, 1, VX, VY, 2, 0, 0, 0)
+        else if (CR = 0) and (CG = 0) and (CB = 255) then g_GFX_SimpleWater(X, Y, 1, VX, VY, 3, 0, 0, 0)
+        else g_GFX_SimpleWater(X, Y, 1, VX, VY, 0, 0, 0, 0);
       end;
-      TRIGGER_EFFECT_LLIQUID:
-        g_GFX_SimpleWater(X, Y, 1, VX, VY, 4, CR, CG, CB);
-      TRIGGER_EFFECT_DLIQUID:
-        g_GFX_SimpleWater(X, Y, 1, VX, VY, 5, CR, CG, CB);
-      TRIGGER_EFFECT_BLOOD:
-        g_GFX_Blood(X, Y, 1, VX, VY, 0, 0, CR, CG, CB);
-      TRIGGER_EFFECT_SPARK:
-        g_GFX_Spark(X, Y, 1, GetAngle2(VX, VY), 0, 0);
-      TRIGGER_EFFECT_BUBBLE:
-        g_GFX_Bubbles(X, Y, 1, 0, 0);
+      TRIGGER_EFFECT_LLIQUID: g_GFX_SimpleWater(X, Y, 1, VX, VY, 4, CR, CG, CB);
+      TRIGGER_EFFECT_DLIQUID: g_GFX_SimpleWater(X, Y, 1, VX, VY, 5, CR, CG, CB);
+      TRIGGER_EFFECT_BLOOD: g_GFX_Blood(X, Y, 1, VX, VY, 0, 0, CR, CG, CB);
+      TRIGGER_EFFECT_SPARK: g_GFX_Spark(X, Y, 1, GetAngle2(VX, VY), 0, 0);
+      TRIGGER_EFFECT_BUBBLE: g_GFX_Bubbles(X, Y, 1, 0, 0);
     end;
+  end;
+
   if T = TRIGGER_EFFECT_ANIMATION then
+  begin
     case ST of
       EFFECT_TELEPORT: begin
         if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
         begin
           Anim := TAnimation.Create(FramesID, False, 3);
-          if not Silent then
-            g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y);
+          if not Silent then g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y);
           g_GFX_OnceAnim(X-32, Y-32, Anim);
           Anim.Free();
         end;
-        if Send and g_Game_IsServer and g_Game_IsNet then
-          MH_SEND_Effect(X, Y, Byte(not Silent), NET_GFX_TELE);
+        if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X, Y, Byte(not Silent), NET_GFX_TELE);
       end;
       EFFECT_RESPAWN: begin
         if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
         begin
           Anim := TAnimation.Create(FramesID, False, 4);
-          if not Silent then
-            g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y);
+          if not Silent then g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y);
           g_GFX_OnceAnim(X-16, Y-16, Anim);
           Anim.Free();
         end;
-        if Send and g_Game_IsServer and g_Game_IsNet then
-          MH_SEND_Effect(X-16, Y-16, Byte(not Silent), NET_GFX_RESPAWN);
+        if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X-16, Y-16, Byte(not Silent), NET_GFX_RESPAWN);
       end;
       EFFECT_FIRE: begin
         if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
         begin
           Anim := TAnimation.Create(FramesID, False, 4);
-          if not Silent then
-            g_Sound_PlayExAt('SOUND_FIRE', X, Y);
+          if not Silent then g_Sound_PlayExAt('SOUND_FIRE', X, Y);
           g_GFX_OnceAnim(X-32, Y-128, Anim);
           Anim.Free();
         end;
-        if Send and g_Game_IsServer and g_Game_IsNet then
-          MH_SEND_Effect(X-32, Y-128, Byte(not Silent), NET_GFX_FIRE);
+        if Send and g_Game_IsServer and g_Game_IsNet then MH_SEND_Effect(X-32, Y-128, Byte(not Silent), NET_GFX_FIRE);
       end;
     end;
+  end;
 end;
 
-function tr_Teleport(ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean;
+
+function tr_Teleport (ActivateUID: Integer; TX, TY: Integer; TDir: Integer; Silent: Boolean; D2D: Boolean): Boolean;
 var
   p: TPlayer;
   m: TMonster;
@@ -756,56 +790,45 @@ begin
     UID_PLAYER:
       begin
         p := g_Player_Get(ActivateUID);
-        if p = nil then
-          Exit;
-
+        if p = nil then Exit;
         if D2D then
-          begin
-            if p.TeleportTo(TX-(p.Obj.Rect.Width div 2),
-                            TY-p.Obj.Rect.Height,
-                            Silent,
-                            TDir) then
-              Result := True;
-          end
+        begin
+          if p.TeleportTo(TX-(p.Obj.Rect.Width div 2), TY-p.Obj.Rect.Height, Silent, TDir) then result := true;
+        end
         else
-          if p.TeleportTo(TX, TY, Silent, TDir) then
-            Result := True;
+        begin
+          if p.TeleportTo(TX, TY, Silent, TDir) then result := true;
+        end;
       end;
-
     UID_MONSTER:
       begin
         m := g_Monsters_ByUID(ActivateUID);
-        if m = nil then
-          Exit;
-
+        if m = nil then Exit;
         if D2D then
-          begin
-            if m.TeleportTo(TX-(m.Obj.Rect.Width div 2),
-                            TY-m.Obj.Rect.Height,
-                            Silent,
-                            TDir) then
-              Result := True;
-          end
+        begin
+          if m.TeleportTo(TX-(m.Obj.Rect.Width div 2), TY-m.Obj.Rect.Height, Silent, TDir) then result := true;
+        end
         else
-          if m.TeleportTo(TX, TY, Silent, TDir) then
-            Result := True;
+        begin
+          if m.TeleportTo(TX, TY, Silent, TDir) then result := true;
+        end;
       end;
   end;
 end;
 
-function tr_Push(ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean;
+
+function tr_Push (ActivateUID: Integer; VX, VY: Integer; ResetVel: Boolean): Boolean;
 var
   p: TPlayer;
   m: TMonster;
 begin
-  Result := True;
-  if (ActivateUID < 0) or (ActivateUID > $FFFF) then Exit;
+  result := true;
+  if (ActivateUID < 0) or (ActivateUID > $FFFF) then exit;
   case g_GetUIDType(ActivateUID) of
     UID_PLAYER:
       begin
         p := g_Player_Get(ActivateUID);
-        if p = nil then
-          Exit;
+        if p = nil then Exit;
 
         if ResetVel then
         begin
@@ -821,8 +844,7 @@ begin
     UID_MONSTER:
       begin
         m := g_Monsters_ByUID(ActivateUID);
-        if m = nil then
-          Exit;
+        if m = nil then Exit;
 
         if ResetVel then
         begin
@@ -837,7 +859,8 @@ begin
   end;
 end;
 
-function tr_Message(MKind: Integer; MText: string; MSendTo: Integer; MTime: Integer; ActivateUID: Integer): Boolean;
+
+function tr_Message (MKind: Integer; MText: string; MSendTo: Integer; MTime: Integer; ActivateUID: Integer): Boolean;
 var
   msg: string;
   p: TPlayer;
@@ -853,19 +876,17 @@ begin
         begin
           if g_Game_IsWatchedPlayer(ActivateUID) then
           begin
-            if MKind = 0 then
-              g_Console_Add(msg, True)
-            else if MKind = 1 then
-              g_Game_Message(msg, MTime);
+                 if MKind = 0 then g_Console_Add(msg, True)
+            else if MKind = 1 then g_Game_Message(msg, MTime);
           end
           else
           begin
             p := g_Player_Get(ActivateUID);
             if g_Game_IsNet and (p.FClientID >= 0) then
-              if MKind = 0 then
-                MH_SEND_Chat(msg, NET_CHAT_SYSTEM, p.FClientID)
-              else if MKind = 1 then
-                MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, p.FClientID);
+            begin
+                   if MKind = 0 then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, p.FClientID)
+              else if MKind = 1 then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, p.FClientID);
+            end;
           end;
         end;
       end;
@@ -876,19 +897,21 @@ begin
         begin
           p := g_Player_Get(ActivateUID);
           if g_Game_IsWatchedTeam(p.Team) then
-            if MKind = 0 then
-              g_Console_Add(msg, True)
-            else if MKind = 1 then
-              g_Game_Message(msg, MTime);
+          begin
+                 if MKind = 0 then g_Console_Add(msg, True)
+            else if MKind = 1 then g_Game_Message(msg, MTime);
+          end;
 
           if g_Game_IsNet then
           begin
             for i := Low(gPlayers) to High(gPlayers) do
+            begin
               if (gPlayers[i].Team = p.Team) and (gPlayers[i].FClientID >= 0) then
-                if MKind = 0 then
-                  MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
-                else if MKind = 1 then
-                  MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+              begin
+                     if MKind = 0 then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
+                else if MKind = 1 then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+              end;
+            end;
           end;
         end;
       end;
@@ -899,19 +922,21 @@ begin
         begin
           p := g_Player_Get(ActivateUID);
           if g_Game_IsWatchedTeam(p.Team) then
-            if MKind = 0 then
-              g_Console_Add(msg, True)
-            else if MKind = 1 then
-              g_Game_Message(msg, MTime);
+          begin
+                 if MKind = 0 then g_Console_Add(msg, True)
+            else if MKind = 1 then g_Game_Message(msg, MTime);
+          end;
 
           if g_Game_IsNet then
           begin
             for i := Low(gPlayers) to High(gPlayers) do
+            begin
               if (gPlayers[i].Team <> p.Team) and (gPlayers[i].FClientID >= 0) then
-                if MKind = 0 then
-                  MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
-                else if MKind = 1 then
-                  MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+              begin
+                     if MKind = 0 then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
+                else if MKind = 1 then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+              end;
+            end;
           end;
         end;
       end;
@@ -919,81 +944,84 @@ begin
     3: // red team
       begin
         if g_Game_IsWatchedTeam(TEAM_RED) then
-          if MKind = 0 then
-            g_Console_Add(msg, True)
-          else if MKind = 1 then
-            g_Game_Message(msg, MTime);
+        begin
+               if MKind = 0 then g_Console_Add(msg, True)
+          else if MKind = 1 then g_Game_Message(msg, MTime);
+        end;
 
         if g_Game_IsNet then
         begin
           for i := Low(gPlayers) to High(gPlayers) do
+          begin
             if (gPlayers[i].Team = TEAM_RED) and (gPlayers[i].FClientID >= 0) then
-              if MKind = 0 then
-                MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
-              else if MKind = 1 then
-                MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+            begin
+                   if MKind = 0 then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
+              else if MKind = 1 then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+            end;
+          end;
         end;
       end;
 
     4: // blue team
       begin
         if g_Game_IsWatchedTeam(TEAM_BLUE) then
-          if MKind = 0 then
-            g_Console_Add(msg, True)
-          else if MKind = 1 then
-            g_Game_Message(msg, MTime);
+        begin
+               if MKind = 0 then g_Console_Add(msg, True)
+          else if MKind = 1 then g_Game_Message(msg, MTime);
+        end;
 
         if g_Game_IsNet then
         begin
           for i := Low(gPlayers) to High(gPlayers) do
+          begin
             if (gPlayers[i].Team = TEAM_BLUE) and (gPlayers[i].FClientID >= 0) then
-              if MKind = 0 then
-                MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
-              else if MKind = 1 then
-                MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+            begin
+                   if MKind = 0 then MH_SEND_Chat(msg, NET_CHAT_SYSTEM, gPlayers[i].FClientID)
+              else if MKind = 1 then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg, gPlayers[i].FClientID);
+            end;
+          end;
         end;
       end;
 
     5: // everyone
       begin
-        if MKind = 0 then
-          g_Console_Add(msg, True)
-        else if MKind = 1 then
-          g_Game_Message(msg, MTime);
+             if MKind = 0 then g_Console_Add(msg, True)
+        else if MKind = 1 then g_Game_Message(msg, MTime);
 
         if g_Game_IsNet then
         begin
-          if MKind = 0 then
-            MH_SEND_Chat(msg, NET_CHAT_SYSTEM)
-          else if MKind = 1 then
-            MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg);
+               if MKind = 0 then MH_SEND_Chat(msg, NET_CHAT_SYSTEM)
+          else if MKind = 1 then MH_SEND_GameEvent(NET_EV_BIGTEXT, MTime, msg);
         end;
       end;
   end;
 end;
 
-function tr_ShotAimCheck(var Trigger: TTrigger; Obj: PObj): Boolean;
+
+function tr_ShotAimCheck (var Trigger: TTrigger; Obj: PObj): Boolean;
 begin
   result := false;
   with Trigger do
   begin
-    if TriggerType <> TRIGGER_SHOT then
-      Exit;
-    Result := (trigData.trigShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
+    if TriggerType <> TRIGGER_SHOT then Exit;
+    result := (trigData.trigShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
               or g_Obj_Collide(X, Y, Width, Height, Obj);
-    if Result and (trigData.trigShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then
-      Result := g_TraceVector(trigData.trigShotPos.X,
-                              trigData.trigShotPos.Y,
+    if result and (trigData.trigShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then
+    begin
+      result := g_TraceVector(trigData.trigShotPos.X, trigData.trigShotPos.Y,
                               Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2),
                               Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2));
+    end;
   end;
 end;
 
-function ActivateTrigger(var Trigger: TTrigger; actType: Byte): Boolean;
+
+function ActivateTrigger (var Trigger: TTrigger; actType: Byte): Boolean;
 var
   animonce: Boolean;
   p: TPlayer;
   m: TMonster;
+  pan: TPanel;
   idx, k, wx, wy, xd, yd: Integer;
   iid: LongWord;
   coolDown: Boolean;
@@ -1042,16 +1070,12 @@ var
   end;
 
 begin
-  Result := False;
-  if g_Game_IsClient then
-    Exit;
+  result := false;
+  if g_Game_IsClient then exit;
 
-  if not Trigger.Enabled then
-    Exit;
-  if (Trigger.TimeOut <> 0) and (actType <> ACTIVATE_CUSTOM) then
-    Exit;
-  if gLMSRespawn = LMS_RESPAWN_WARMUP then
-    Exit;
+  if not Trigger.Enabled then exit;
+  if (Trigger.TimeOut <> 0) and (actType <> ACTIVATE_CUSTOM) then exit;
+  if gLMSRespawn = LMS_RESPAWN_WARMUP then exit;
 
   animonce := False;
 
@@ -1083,38 +1107,38 @@ begin
 
       TRIGGER_OPENDOOR:
         begin
-          Result := tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
+          Result := tr_OpenDoor(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors);
           TimeOut := 0;
         end;
 
       TRIGGER_CLOSEDOOR:
         begin
-          Result := tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
+          Result := tr_CloseDoor(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors);
           TimeOut := 0;
         end;
 
       TRIGGER_DOOR, TRIGGER_DOOR5:
         begin
-          if trigPanelID <> -1 then
+          pan := g_Map_PanelByGUID(trigPanelGUID);
+          if (pan <> nil) and pan.isGWall then
           begin
-            if gWalls[trigPanelID].Enabled then
-              begin
-                Result := tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
-
-                if TriggerType = TRIGGER_DOOR5 then
-                  DoorTime := 180;
-              end
+            if gWalls[{trigPanelID}pan.arrIdx].Enabled then
+            begin
+              result := tr_OpenDoor(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors);
+              if (TriggerType = TRIGGER_DOOR5) then DoorTime := 180;
+            end
             else
-              Result := tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
+            begin
+              result := tr_CloseDoor(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors);
+            end;
 
-            if Result then
-              TimeOut := 18;
+            if result then TimeOut := 18;
           end;
         end;
 
       TRIGGER_CLOSETRAP, TRIGGER_TRAP:
         begin
-          tr_CloseTrap(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
+          tr_CloseTrap(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors);
 
           if TriggerType = TRIGGER_TRAP then
             begin
@@ -1132,15 +1156,9 @@ begin
 
       TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF:
         begin
-          PressCount := PressCount + 1;
-
-          if PressTime = -1 then
-            PressTime := trigData.trigWait;
-
-          if coolDown then
-            TimeOut := 18
-          else
-            TimeOut := 0;
+          PressCount += 1;
+          if PressTime = -1 then PressTime := trigData.trigWait;
+          if coolDown then TimeOut := 18 else TimeOut := 0;
           Result := True;
         end;
 
@@ -1159,7 +1177,7 @@ begin
 
       TRIGGER_LIFTUP:
         begin
-          Result := tr_SetLift(trigPanelID, 0, trigData.trigNoSound, trigData.trigd2d_doors);
+          Result := tr_SetLift(trigPanelGUID, 0, trigData.trigNoSound, trigData.trigd2d_doors);
           TimeOut := 0;
 
           if (not trigData.trigNoSound) and Result then begin
@@ -1175,7 +1193,7 @@ begin
 
       TRIGGER_LIFTDOWN:
         begin
-          Result := tr_SetLift(trigPanelID, 1, trigData.trigNoSound, trigData.trigd2d_doors);
+          Result := tr_SetLift(trigPanelGUID, 1, trigData.trigNoSound, trigData.trigd2d_doors);
           TimeOut := 0;
 
           if (not trigData.trigNoSound) and Result then begin
@@ -1191,7 +1209,7 @@ begin
 
       TRIGGER_LIFT:
         begin
-          Result := tr_SetLift(trigPanelID, 3, trigData.trigNoSound, trigData.trigd2d_doors);
+          Result := tr_SetLift(trigPanelGUID, 3, trigData.trigNoSound, trigData.trigd2d_doors);
 
           if Result then
           begin
@@ -2093,8 +2111,10 @@ begin
     end;
   end;
 
-  if Result and (Trigger.TexturePanel <> -1) then
-    g_Map_SwitchTexture(Trigger.TexturePanelType, Trigger.TexturePanel, IfThen(animonce, 2, 1));
+  if Result {and (Trigger.TexturePanel <> -1)} then
+  begin
+    g_Map_SwitchTextureGUID(Trigger.TexturePanelType, Trigger.TexturePanelGUID, IfThen(animonce, 2, 1));
+  end;
 end;
 
 
@@ -2294,6 +2314,7 @@ var
 
 var
   mon: TMonster;
+  pan: TPanel;
 begin
   if (tgMonsList = nil) then tgMonsList := TSimpleMonsterList.Create();
 
@@ -2306,120 +2327,135 @@ begin
     // Åñòü òðèããåð:
       if TriggerType <> TRIGGER_NONE then
       begin
-      // Óìåíüøàåì âðåìÿ äî çàêðûòèÿ äâåðè (îòêðûòèÿ ëîâóøêè):
-        if DoorTime > 0 then
-          DoorTime := DoorTime - 1;
-      // Óìåíüøàåì âðåìÿ îæèäàíèÿ ïîñëå íàæàòèÿ:
-        if PressTime > 0 then
-          PressTime := PressTime - 1;
-      // Ïðîâåðÿåì èãðîêîâ è ìîíñòðîâ, êîòîðûõ ðàíåå çàïîìíèëè:
+        // Óìåíüøàåì âðåìÿ äî çàêðûòèÿ äâåðè (îòêðûòèÿ ëîâóøêè)
+        if DoorTime > 0 then DoorTime := DoorTime - 1;
+        // Óìåíüøàåì âðåìÿ îæèäàíèÿ ïîñëå íàæàòèÿ
+        if PressTime > 0 then PressTime := PressTime - 1;
+        // Ïðîâåðÿåì èãðîêîâ è ìîíñòðîâ, êîòîðûõ ðàíåå çàïîìíèëè:
         if (TriggerType = TRIGGER_DAMAGE) or (TriggerType = TRIGGER_HEALTH) then
+        begin
           for b := 0 to High(Activators) do
           begin
             // Óìåíüøàåì âðåìÿ äî ïîâòîðíîãî âîçäåéñòâèÿ:
             if Activators[b].TimeOut > 0 then
-              Dec(Activators[b].TimeOut)
+            begin
+              Dec(Activators[b].TimeOut);
+            end
             else
-              Continue;
+            begin
+              continue;
+            end;
             // Ñ÷èòàåì, ÷òî îáúåêò ïîêèíóë çîíó äåéñòâèÿ òðèããåðà
-            if (trigData.trigDamageInterval = 0) and (Activators[b].TimeOut < 65530) then
-              Activators[b].TimeOut := 0;
+            if (trigData.trigDamageInterval = 0) and (Activators[b].TimeOut < 65530) then Activators[b].TimeOut := 0;
           end;
+        end;
 
-      // Îáðàáàòûâàåì ñïàâíåðû:
+        // Îáðàáàòûâàåì ñïàâíåðû
         if Enabled and AutoSpawn then
+        begin
           if SpawnCooldown = 0 then
           begin
-            // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà:
+            // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà
             if (TriggerType = TRIGGER_SPAWNMONSTER) and (trigData.trigMonDelay > 0)  then
             begin
               ActivateUID := 0;
               ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
             end;
-            // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò:
+            // Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò
             if (TriggerType = TRIGGER_SPAWNITEM) and (trigData.trigItemDelay > 0) then
             begin
               ActivateUID := 0;
               ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
             end;
-          end else // Óìåíüøàåì âðåìÿ îæèäàíèÿ:
+          end
+          else
+          begin
+            // Óìåíüøàåì âðåìÿ îæèäàíèÿ
             Dec(SpawnCooldown);
+          end;
+        end;
 
-      // Îáðàáàòûâàåì ñîáûòèÿ òðèããåðà "Òóðåëü":
+        // Îáðàáàòûâàåì ñîáûòèÿ òðèããåðà "Òóðåëü"
         if TriggerType = TRIGGER_SHOT then
         begin
           if ShotPanelTime > 0 then
           begin
             Dec(ShotPanelTime);
-            if ShotPanelTime = 0 then
-              g_Map_SwitchTexture(ShotPanelType, trigShotPanelID);
+            if ShotPanelTime = 0 then g_Map_SwitchTextureGUID(ShotPanelType, trigShotPanelGUID);
           end;
           if ShotSightTime > 0 then
           begin
             Dec(ShotSightTime);
-            if ShotSightTime = 0 then
-              ShotSightTarget := ShotSightTargetN;
+            if ShotSightTime = 0 then ShotSightTarget := ShotSightTargetN;
           end;
           if ShotSightTimeout > 0 then
           begin
             Dec(ShotSightTimeout);
-            if ShotSightTimeout = 0 then
-              ShotSightTarget := 0;
+            if ShotSightTimeout = 0 then ShotSightTarget := 0;
           end;
           if ShotReloadTime > 0 then
           begin
             Dec(ShotReloadTime);
-            if ShotReloadTime = 0 then
-              ShotAmmoCount := trigData.trigShotAmmo;
+            if ShotReloadTime = 0 then ShotAmmoCount := trigData.trigShotAmmo;
           end;
         end;
 
-      // Òðèããåð "Çâóê" óæå îòûãðàë, åñëè íóæíî åùå - ïåðåçàïóñêàåì:
+        // Òðèããåð "Çâóê" óæå îòûãðàë, åñëè íóæíî åùå - ïåðåçàïóñêàåì
         if Enabled and (TriggerType = TRIGGER_SOUND) and (Sound <> nil) then
+        begin
           if (SoundPlayCount > 0) and (not Sound.IsPlaying()) then
           begin
-            if trigData.trigPlayCount > 0 then // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî
-              SoundPlayCount := SoundPlayCount - 1;
+            if trigData.trigPlayCount > 0 then SoundPlayCount -= 1; // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî
             if trigData.trigLocal then
-              Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0)
+            begin
+              Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0);
+            end
             else
+            begin
               Sound.PlayPanVolume((trigData.trigPan-127.0)/128.0, trigData.trigVolume/255.0);
-            if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then
-              MH_SEND_TriggerSound(gTriggers[a]);
+            end;
+            if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then MH_SEND_TriggerSound(gTriggers[a]);
           end;
+        end;
 
-      // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü:
-        if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (trigPanelID <> -1) then
+        // Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü
+        if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (g_Map_PanelByGUID(trigPanelGUID) <> nil) then
         begin
-          tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
+          tr_OpenDoor(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors);
           DoorTime := -1;
         end;
 
-      // Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü:
-        if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (trigPanelID <> -1) then
+        // Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü
+        if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (g_Map_PanelByGUID(trigPanelGUID) <> nil) then
         begin
-        // Óæå çàêðûòà:
-          if gWalls[trigPanelID].Enabled then
-            DoorTime := -1
-          else // Ïîêà îòêðûòà - çàêðûâàåì
-            if tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors) then
+          pan := g_Map_PanelByGUID(trigPanelGUID);
+          if (pan <> nil) and pan.isGWall then
+          begin
+            // Óæå çàêðûòà
+            if {gWalls[trigPanelID].Enabled} pan.Enabled then
+            begin
               DoorTime := -1;
+            end
+            else
+            begin
+              // Ïîêà îòêðûòà - çàêðûâàåì
+              if tr_CloseDoor(trigPanelGUID, trigData.trigNoSound, trigData.trigd2d_doors) then DoorTime := -1;
+            end;
+          end;
         end;
 
       // Òðèããåð - ðàñøèðèòåëü èëè ïåðåêëþ÷àòåëü, è ïðîøëà çàäåðæêà, è íàæàëè íóæíîå ÷èñëî ðàç:
         if (TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF]) and
            (PressTime = 0) and (PressCount >= trigData.trigCount) then
         begin
-        // Ñáðàñûâàåì çàäåðæêó àêòèâàöèè:
+          // Ñáðàñûâàåì çàäåðæêó àêòèâàöèè:
           PressTime := -1;
-        // Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé:
-          if trigData.trigCount > 0 then
-            PressCount := PressCount - trigData.trigCount
-          else
-            PressCount := 0;
+          // Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé:
+          if trigData.trigCount > 0 then PressCount -= trigData.trigCount else PressCount := 0;
 
-        // Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû:
+          // Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû:
           for b := 0 to High(gTriggers) do
+          begin
             if g_Collide(trigData.trigtX, trigData.trigtY, trigData.trigtWidth, trigData.trigtHeight, gTriggers[b].X, gTriggers[b].Y,
                gTriggers[b].Width, gTriggers[b].Height) and
                ((b <> a) or (trigData.trigWait > 0)) then
@@ -2430,7 +2466,14 @@ begin
                 Affected[High(Affected)] := b;
               end;
             end;
-        // Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì:
+          end;
+
+          // if we have panelid, assume that it will switch the moving platform
+          if (trigPanelGUID >= 0) then
+          begin
+          end;
+
+          // Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì:
           if (TriggerType = TRIGGER_PRESS) and trigData.trigExtRandom then
           begin
             if (Length(Affected) > 0) then
@@ -2441,6 +2484,7 @@ begin
             end;
           end
           else // Â ïðîòèâíîì ñëó÷àå ðàáîòàåì êàê îáû÷íî:
+          begin
             for i := 0 to High(Affected) do
             begin
               b := Affected[i];
@@ -2479,6 +2523,7 @@ begin
                   end;
               end;
             end;
+          end;
           SetLength(Affected, 0);
         end;
 
@@ -2696,15 +2741,19 @@ begin
 
   b := False;
   for a := 0 to High(gTriggers) do
+  begin
     with gTriggers[a] do
+    begin
       if (TriggerType = TRIGGER_OPENDOOR) or
          (TriggerType = TRIGGER_DOOR5) or
          (TriggerType = TRIGGER_DOOR) then
       begin
-        tr_OpenDoor(trigPanelID, True, trigData.trigd2d_doors);
+        tr_OpenDoor(trigPanelGUID, True, trigData.trigd2d_doors);
         if TriggerType = TRIGGER_DOOR5 then DoorTime := 180;
         b := True;
       end;
+    end;
+  end;
 
   if b then g_Sound_PlayEx('SOUND_GAME_DOOROPEN');
 end;
@@ -2787,11 +2836,11 @@ begin
   // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè:
     Mem.WriteByte(gTriggers[i].Keys);
   // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ:
-    Mem.WriteInt(gTriggers[i].TexturePanel);
+    Mem.WriteInt(gTriggers[i].TexturePanelGUID);
   // Òèï ýòîé ïàíåëè:
     Mem.WriteWord(gTriggers[i].TexturePanelType);
   // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
-    Mem.WriteInt(gTriggers[i].trigPanelId);
+    Mem.WriteInt(gTriggers[i].trigPanelGUID);
   // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
     Mem.WriteWord(gTriggers[i].TimeOut);
   // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
@@ -2914,11 +2963,11 @@ begin
   // Êëþ÷è, íåîáõîäèìûå äëÿ àêòèâàöèè:
     Mem.ReadByte(gTriggers[i].Keys);
   // ID ïàíåëè, òåêñòóðà êîòîðîé èçìåíèòñÿ:
-    Mem.ReadInt(gTriggers[i].TexturePanel);
+    Mem.ReadInt(gTriggers[i].TexturePanelGUID);
   // Òèï ýòîé ïàíåëè:
     Mem.ReadWord(gTriggers[i].TexturePanelType);
   // Âíóòðåííèé íîìåð äðóãîé ïàíåëè (ïî ñ÷àñòëèâîé ñëó÷àéíîñòè îí áóäåò ñîâïàäàòü ñ òåì, ÷òî ñîçäàíî ïðè çàãðóçêå êàðòû)
-    Mem.ReadInt(gTriggers[i].trigPanelId);
+    Mem.ReadInt(gTriggers[i].trigPanelGUID);
   // Âðåìÿ äî âîçìîæíîñòè àêòèâàöèè:
     Mem.ReadWord(gTriggers[i].TimeOut);
   // UID òîãî, êòî àêòèâèðîâàë ýòîò òðèããåð:
index 9851afea060f24d772123b5230eddc14f4c7b752..f30c218136283c6dc09fabf852f1531a8dc53130 100644 (file)
@@ -404,8 +404,10 @@ TriggerData for (TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF) {
   Size is "size" type size offset 8 as twh;
   Wait is "wait" type ushort offset 12;
   Count is "count" type ushort offset 14;
-  MonsterID is "monsterid" type int offset 16 monster as monsterid;
+  MonsterID is "monsterid" type int offset 16 monster as monsterid default null;
   ExtRandom is "extrandom" type bool offset 20;
+  // this one is for moving platforms
+  PanelId is "panelid" type int panel default null omitdefault;
 }
 
 TriggerData for TRIGGER_SECRET {
index 8f6a3cefbc4a080e54a1dacc20b173b7ae1f7059..ad160252dcc5877460d99f413785999aa8df791f 100644 (file)
@@ -122,6 +122,7 @@ type
 
     {$INCLUDE mapdef_help.inc}
     function trigMonsterId (): Integer; inline;
+    function trigPanelId (): Integer; inline; // panel index in list
 
   private
     // user fields
@@ -279,6 +280,16 @@ begin
 end;
 
 
+// panel index in list
+function TDynRecordHelper.trigPanelId (): Integer; inline;
+var
+  fld: TDynField;
+begin
+  fld := getFieldWithType('panelid', TDynField.TType.TInt);
+  result := fld.recrefIndex;
+end;
+
+
 // ////////////////////////////////////////////////////////////////////////// //
 function TDynRecordHelper.mapName (): AnsiString; inline; begin result := utf2win(getFieldWithType('name', TDynField.TType.TChar).sval); end;
 function TDynRecordHelper.mapAuthor (): AnsiString; inline; begin result := utf2win(getFieldWithType('author', TDynField.TType.TChar).sval); end;
index 9f72e3ab2f5fb547da371473cc30e87e8b47887b..ea71555c68ff7a6d4c4fa2db980990e96f41d8e0 100644 (file)
@@ -173,6 +173,11 @@ function joaatHash (constref buf; len: LongWord): LongWord;
 function nextPOT (x: LongWord): LongWord; inline;
 
 
+// for integer keys
+function hiiequ (constref a, b: Integer): Boolean;
+function hiihash (constref k: Integer): LongWord;
+
+
 implementation
 
 uses
@@ -204,7 +209,7 @@ function hsiequ (constref a, b: AnsiString): Boolean; begin result := (a = b); e
 {$RANGECHECKS OFF}
 function hiihash (constref k: Integer): LongWord;
 begin
-  result := k;
+  result := LongWord(k);
   result -= (result shl 6);
   result := result xor (result shr 17);
   result -= (result shl 9);
index 6e3aa03bb288434133af05acf2e1067871bb337f..27888ed54b724cbb5db021594f171ad67c1694ff 100644 (file)
@@ -797,6 +797,11 @@ const defaultMapDef: AnsiString = ''+
   #32#97#115#32#109#111#110#115#116#101#114#105#100#59#10#32#32#69#120#116#82+
   #97#110#100#111#109#32#105#115#32#34#101#120#116#114#97#110#100#111#109#34+
   #32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#50#48#59+
+  #10#32#32#47#47#32#116#104#105#115#32#111#110#101#32#105#115#32#102#111#114+
+  #32#109#111#118#105#110#103#32#112#108#97#116#102#111#114#109#115#10#32#32+
+  #80#97#110#101#108#73#100#32#105#115#32#34#112#97#110#101#108#105#100#34#32+
+  #116#121#112#101#32#105#110#116#32#112#97#110#101#108#32#100#101#102#97#117+
+  #108#116#32#110#117#108#108#32#111#109#105#116#100#101#102#97#117#108#116#59+
   #10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84+
   #82#73#71#71#69#82#95#83#69#67#82#69#84#32#123#10#125#10#10#84#114#105#103+
   #103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#84#69#88+