DEADSOFTWARE

Map: Add rect alpha settings for monsters and areas
[d2df-editor.git] / src / editor / g_map.pas
index 237c247b58e1c6ca14acaf0307c28803eae5e736..10b8c47ce0142e11dc148650f6d2c7d0c1ad0944 100644 (file)
@@ -5,7 +5,7 @@ Unit g_map;
 Interface
 
 Uses
-  LCLIntf, LCLType, LMessages, g_basic, e_graphics, MAPREADER, MAPSTRUCT,
+  LCLIntf, LCLType, g_basic, e_graphics, MAPREADER, MAPSTRUCT,
   MAPWRITER, e_log, MAPDEF, utils;
 
 Type
@@ -194,6 +194,8 @@ var
   gAlphaEdge: Byte;
   gAlphaTriggerLine: Byte;
   gAlphaTriggerArea: Byte;
+  gAlphaMonsterRect: Byte;
+  gAlphaAreaRect: Byte;
   drEdge: Array[0..3] of Byte;
   gPanels: Array of TPanel;
   gItems: Array of TItem;
@@ -240,12 +242,11 @@ procedure FreeData();
 
 procedure ShiftMapObjects(dx, dy: Integer);
 
-Implementation
+implementation
 
-Uses
+uses
   BinEditor, g_textures, Dialogs, SysUtils, CONFIG, f_main,
-  Forms, Math, f_addresource_texture, WADEDITOR,
-  Masks, g_Language;
+  Forms, Math, f_addresource_texture, WADEDITOR, g_language;
 
 const
   OLD_ITEM_MEDKIT_SMALL          = 1;
@@ -701,6 +702,7 @@ var
 
 begin
   Result := False;
+  PanelID := DWORD(-1);
 
   case ObjectType of
     OBJECT_PANEL:
@@ -1065,6 +1067,16 @@ var
 
 begin
   WAD := nil;
+  textures := nil;
+  panels := nil;
+  items := nil;
+  areas := nil;
+  monsters := nil;
+  triggers := nil;
+  PanelTable := nil;
+  MonsterTable := nil;
+  Data := nil;
+  Len := 0;
 
 // Открываем WAD, если надо:
   if Res <> '' then
@@ -1084,20 +1096,25 @@ begin
   begin
     ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
 
-    if gMapInfo.Name <> '' then
-      CopyMemory(@MapName[0], @gMapInfo.Name[1], Min(32, Length(gMapInfo.Name)));
+    s := utf2win(gMapInfo.Name);
+    if s <> '' then
+      CopyMemory(@MapName[0], @s[1], Min(32, Length(s)));
 
-    if gMapInfo.Description <> '' then
-      CopyMemory(@MapDescription[0], @gMapInfo.Description[1], Min(256, Length(gMapInfo.Description)));
+    s := utf2win(gMapInfo.Description);
+    if s <> '' then
+      CopyMemory(@MapDescription[0], @s[1], Min(256, Length(s)));
 
-    if gMapInfo.Author <> '' then
-      CopyMemory(@MapAuthor[0], @gMapInfo.Author[1], Min(32, Length(gMapInfo.Author)));
+    s := utf2win(gMapInfo.Author);
+    if s <> '' then
+      CopyMemory(@MapAuthor[0], @s[1], Min(32, Length(s)));
 
-    if gMapInfo.MusicName <> '' then
-      CopyMemory(@MusicName[0], @gMapInfo.MusicName[1], Min(64, Length(gMapInfo.MusicName)));
+    s := utf2win(gMapInfo.MusicName);
+    if s <> '' then
+      CopyMemory(@MusicName[0], @s[1], Min(64, Length(s)));
 
-    if gMapInfo.SkyName <> '' then
-      CopyMemory(@SkyName[0], @gMapInfo.SkyName[1], Min(64, Length(gMapInfo.SkyName)));
+    s := utf2win(gMapInfo.SkyName);
+    if s <> '' then
+      CopyMemory(@SkyName[0], @s[1], Min(64, Length(s)));
 
     Width := gMapInfo.Width;
     Height := gMapInfo.Height;
@@ -1113,7 +1130,7 @@ begin
       SetLength(textures, Length(textures)+1);
       s := utf2win(MainForm.lbTextureList.Items[a]);
       CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
-      if g_GetTextureFlagByName(s) = 1 then
+      if g_GetTextureFlagByName(MainForm.lbTextureList.Items[a]) = 1 then
         textures[High(textures)].Anim := 1
       else
         textures[High(textures)].Anim := 0;
@@ -1165,7 +1182,7 @@ begin
           // Номер текстуры в списке текстур:
             if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
               for b := 0 to High(textures) do
-                if gPanels[a].TextureName = textures[b].Resource then
+                if utf2win(gPanels[a].TextureName) = textures[b].Resource then
                 begin
                   TextureNum := b;
                   Break;
@@ -1329,9 +1346,9 @@ begin
 // Записываем в WAD, если надо:
   if Res <> '' then
     begin
-      e_WriteLog('Fuck me (A) ' + ResName, MSG_NOTIFY);
-      WAD.RemoveResource('', ResName);
-      WAD.AddResource(Data, Len, ResName, '');
+      s := utf2win(ResName);
+      WAD.RemoveResource('', s);
+      WAD.AddResource(Data, Len, s, '');
       WAD.SaveTo(FileName);
 
       FreeMem(Data);
@@ -1346,18 +1363,16 @@ end;
 procedure AddTexture(res: String; Error: Boolean);
 var
   a: Integer;
-  ures: String;
 begin
-  ures := win2utf(res);
   with MainForm.lbTextureList do
   begin
     for a := 0 to Count-1 do
-      if Items[a] = ures then
+      if Items[a] = res then
         Exit;
 
-    if Error and (slInvalidTextures.IndexOf(ures) = -1) then
-      slInvalidTextures.Add(ures);
-    Items.Add(ures);
+    if Error and (slInvalidTextures.IndexOf(res) = -1) then
+      slInvalidTextures.Add(res);
+    Items.Add(res);
   end;
 end;
 
@@ -1381,7 +1396,7 @@ var
   Data: Pointer;
   Width, Height, m: Word;
   FileName, SectionName, ResName, _fn: String;
-  TextureRes: String;
+  TextureRes, ustr: String;
   pData: Pointer;
   Len, FrameLen: Integer;
   Error: Boolean;
@@ -1389,6 +1404,15 @@ var
   NW, NH: Word;
 begin
   Result := False;
+  pData := nil;
+  Len := 0;
+  Data := nil;
+  FrameLen := 0;
+  Width := 0;
+  Height := 0;
+  NoTextureID := 0;
+  NW := 0;
+  NH := 0;
 
   MainForm.pbLoad.Position := 0;
   MainForm.lLoad.Caption := _lc[I_LOAD_WAD];
@@ -1405,7 +1429,7 @@ begin
   end;
 
 // Читаем ресурс карты:
-  if not WAD.GetResource('', ResName, pData, Len) then
+  if not WAD.GetResource('', utf2win(ResName), pData, Len) then
   begin
     WAD.Free();
     Exit;
@@ -1433,50 +1457,51 @@ begin
     begin
       MainForm.pbLoad.StepIt();
       Application.ProcessMessages();
+      ustr := win2utf(textures[a].Resource);
 
-      if IsSpecialTexture(textures[a].Resource) then
+      if IsSpecialTexture(ustr) then
       begin
-        AddTexture(textures[a].Resource, False);
+        AddTexture(ustr, False);
         Continue;
       end;
 
-      g_ProcessResourceStr(textures[a].Resource, @_fn, nil, nil);
+      g_ProcessResourceStr(ustr, @_fn, nil, nil);
 
       if _fn = '' then
-        TextureRes := FileName + textures[a].Resource
+        TextureRes := FileName + ustr
       else
-        TextureRes := EditorDir+'wads/'+textures[a].Resource;
+        TextureRes := EditorDir+'wads/'+ustr;
 
       Error := False;
 
       if not ByteBool(textures[a].Anim) then
         begin // Обычная текстура
-          if not g_CreateTextureWAD(textures[a].Resource, TextureRes) then
+          if not g_CreateTextureWAD(ustr, TextureRes) then
           begin
             e_WriteLog(Format('g_CreateTextureWAD() error, res=%s',
-                              [textures[a].Resource]), MSG_WARNING);
+                              [ustr]), MSG_WARNING);
             Error := True;
           end;
 
-          AddTexture(textures[a].Resource, Error);
+          AddTexture(ustr, Error);
         end
       else // Anim
         begin // Анимированная текстура
           if not GetFrame(TextureRes, Data, FrameLen, Width, Height) then
           begin // Кадры
             e_WriteLog(Format('GetFrame() error, res=%s',
-                              [textures[a].Resource]), MSG_WARNING);
+                              [ustr]), MSG_WARNING);
             Error := True;
           end;
 
-          if not g_CreateTextureMemorySize(Data, FrameLen, textures[a].Resource, 0, 0, Width, Height, 1) then
+          if not g_CreateTextureMemorySize(Data, FrameLen, ustr, 0, 0, Width, Height, 1) then
           begin // Сама текстура
             e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s',
-                              [textures[a].Resource]), MSG_WARNING);
+                              [ustr]), MSG_WARNING);
             Error := True;
           end;
 
-          AddTexture(textures[a].Resource, Error);
+          AddTexture(ustr, Error);
         end;
     end;
   end;
@@ -1519,9 +1544,10 @@ begin
       if WordBool(panel.PanelType and m) and
          (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
       begin
-        if not IsSpecialTexture(textures[panels[a].TextureNum].Resource) then
+        ustr := win2utf(textures[panels[a].TextureNum].Resource);
+        if not IsSpecialTexture(ustr) then
           begin // Текстура
-            if g_GetTexture(textures[panels[a].TextureNum].Resource, panel.TextureID) then
+            if g_GetTexture(ustr, panel.TextureID) then
               g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
             else begin
               panel.TextureWidth := 1;
@@ -1536,9 +1562,9 @@ begin
             end;
           end
         else // Спец. текстура
-          panel.TextureID := SpecialTextureID(textures[panels[a].TextureNum].Resource);
+          panel.TextureID := SpecialTextureID(ustr);
 
-        panel.TextureName := textures[panels[a].TextureNum].Resource;
+        panel.TextureName := ustr;
       end;
 
     // Жидкость без текстуры:
@@ -1667,11 +1693,11 @@ begin
   with gMapInfo do
   begin
     MapName := ResName;
-    Name := Header.MapName;
-    Description := Header.MapDescription;
-    Author := Header.MapAuthor;
-    MusicName := Header.MusicName;
-    SkyName := Header.SkyName;
+    Name := win2utf(Header.MapName);
+    Description := win2utf(Header.MapDescription);
+    Author := win2utf(Header.MapAuthor);
+    MusicName := win2utf(Header.MusicName);
+    SkyName := win2utf(Header.SkyName);
     Height := Header.Height;
     Width := Header.Width;
   end;
@@ -1699,7 +1725,7 @@ const
 var
   map: TConfig;
   i, a: Integer;
-  s, us, section: String;
+  s, section: String;
   panel: TPanel;
   item: TItem;
   area: TArea;
@@ -1738,13 +1764,13 @@ begin
     begin
       s := ExtractFileName(_FileName);
       Delete(s, Length(s)-3, 4);
-      s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
+      s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
 
       if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
         Continue;
     end;
 
-    MainForm.lbTextureList.Items.Add(win2utf(s));
+    MainForm.lbTextureList.Items.Add(s);
   end;
 
 // Чтение панелей:
@@ -1794,7 +1820,7 @@ begin
           begin
             s := ExtractFileName(_FileName);
             Delete(s, Length(s)-3, 4);
-            s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(map.ReadStr(section, 'TextureName', ''));
+            s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
 
             if g_GetTexture(s, panel.TextureID) then
               begin
@@ -1825,10 +1851,9 @@ begin
             end;
         end;
 
-        us := win2utf(s);
         with MainForm.lbTextureList.Items do
-          if IndexOf(us) = -1 then
-            Add(us);
+          if IndexOf(s) = -1 then
+            Add(s);
         panel.TextureName := s;
         panel.TextureWidth := 1;
         panel.TextureHeight := 1;
@@ -1954,8 +1979,8 @@ begin
   begin
     if Items.Count > 0 then
       for a := Items.Count-1 downto 0 do
-        if not IsSpecialTexture(utf2win(Items[a])) then
-          g_DeleteTexture(utf2win(Items[a]));
+        if not IsSpecialTexture(Items[a]) then
+          g_DeleteTexture(Items[a]);
 
     Clear();
   end;
@@ -1971,11 +1996,14 @@ procedure DrawPanels(fPanelType: Word);
     NoTextureID: DWORD;
     NW, NH: Word;
   begin
+    NoTextureID := 0;
+    NW := 0;
+    NH := 0;
     with gPanels[a] do
     begin
       case TextureID of
         TEXTURE_SPECIAL_NONE:
-          if not PreviewMode then
+          if PreviewMode = 0 then
             e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                            X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                            64, 64, 64, 127);
@@ -1989,7 +2017,7 @@ procedure DrawPanels(fPanelType: Word);
           end;
 
         TEXTURE_SPECIAL_WATER:
-          if PreviewMode then
+          if PreviewMode > 0 then
             e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                            X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                            0, 0, 255, 0, B_FILTER)
@@ -1999,7 +2027,7 @@ procedure DrawPanels(fPanelType: Word);
                            0, 0, 255, 127);
 
         TEXTURE_SPECIAL_ACID1:
-          if PreviewMode then
+          if PreviewMode > 0 then
             e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                            X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                            0, 127, 0, 0, B_FILTER)
@@ -2009,7 +2037,7 @@ procedure DrawPanels(fPanelType: Word);
                            0, 255, 0, 127);
 
         TEXTURE_SPECIAL_ACID2:
-          if PreviewMode then
+          if PreviewMode > 0 then
             e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                            X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                            127, 0, 0, 0, B_FILTER)
@@ -2044,27 +2072,27 @@ begin
               DrawTexture(a);
 
             PANEL_LIFTUP:
-              if not PreviewMode then
+              if PreviewMode = 0 then
                 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                                X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                                128, 64, 0, 0);
             PANEL_LIFTDOWN:
-              if not PreviewMode then
+              if PreviewMode = 0 then
                 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                                X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                                90, 154, 138, 0);
             PANEL_LIFTLEFT:
-              if not PreviewMode then
+              if PreviewMode = 0 then
                 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                                X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                                200, 80,  4, 0);
             PANEL_LIFTRIGHT:
-              if not PreviewMode then
+              if PreviewMode = 0 then
                 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                                X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                                252, 140, 56, 0);
             PANEL_BLOCKMON:
-              if not PreviewMode then
+              if PreviewMode = 0 then
                 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
                                X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
                                192, 0, 192, 0);
@@ -2082,8 +2110,9 @@ var
   r: TRectWH;
 
 begin
+  ID := 0;
 // В режиме Превью рисуем небо:
-  if PreviewMode then
+  if PreviewMode > 0 then
   begin
     w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
     if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
@@ -2097,21 +2126,21 @@ begin
   end;
 
 // Рисуем панели (если Превью или если включен слой):
-  if LayerEnabled[LAYER_BACK] or PreviewMode then
+  if LayerEnabled[LAYER_BACK] or (PreviewMode = 1) then
     DrawPanels(PANEL_BACK);
-  if PreviewMode then
+  if PreviewMode > 0 then
     DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
   else
     if LayerEnabled[LAYER_WATER] then
       DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
                  PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
-  if LayerEnabled[LAYER_WALLS] or PreviewMode then
+  if LayerEnabled[LAYER_WALLS] or (PreviewMode = 1) then
     DrawPanels(PANEL_WALL);
-  if LayerEnabled[LAYER_STEPS] or PreviewMode then
+  if LayerEnabled[LAYER_STEPS] or (PreviewMode = 1) then
     DrawPanels(PANEL_STEP);
 
 // Рисуем предметы:
-  if (LayerEnabled[LAYER_ITEMS] or PreviewMode) and
+  if (LayerEnabled[LAYER_ITEMS] or (PreviewMode = 1)) and
      (gItems <> nil) then
     for a := 0 to High(gItems) do
       if gItems[a].ItemType <> ITEM_NONE then
@@ -2164,13 +2193,14 @@ begin
         end;
 
 // Рисуем монстров:
-  if (LayerEnabled[LAYER_MONSTERS] or PreviewMode) and
+  if (LayerEnabled[LAYER_MONSTERS] or (PreviewMode = 1)) and
      (gMonsters <> nil) then
     for a := 0 to High(gMonsters) do
       if gMonsters[a].MonsterType <> MONSTER_NONE then
         with MonsterSize[gMonsters[a].MonsterType] do
         begin
           ID := DWORD(-1);
+          sel := ObjectSelected(OBJECT_MONSTER, a);
 
           case gMonsters[a].MonsterType of
             0: Continue;
@@ -2225,26 +2255,28 @@ begin
               end;
 
         // Рамка:
-          if not PreviewMode then
+          if PreviewMode = 0 then
           begin
             e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
                        MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
-                       255, 255, 255);
+                       255, 255, 255, IfThen(sel, 0, gAlphaMonsterRect));
           end;
         end;
 
 // Рисуем закрытые двери после монстров:
-  if PreviewMode then
+  if ((PreviewMode = 2) and LayerEnabled[LAYER_WATER])
+  or (PreviewMode = 1) then
     DrawPanels(PANEL_CLOSEDOOR);
 
 // Рисуем области:
-  if (LayerEnabled[LAYER_AREAS] or PreviewMode) and
+  if (LayerEnabled[LAYER_AREAS] or (PreviewMode = 1)) and
      (gAreas <> nil) then
     for a := 0 to High(gAreas) do
       if gAreas[a].AreaType <> AREA_NONE then
         with AreaSize[gAreas[a].AreaType] do
         begin
           ID := DWORD(-1);
+          sel := ObjectSelected(OBJECT_AREA, a);
 
           case gAreas[a].AreaType of
             AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
@@ -2257,7 +2289,7 @@ begin
             AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
           end;
 
-          if (not PreviewMode) or
+          if (PreviewMode = 0) or
              (gAreas[a].AreaType = AREA_REDFLAG) or
              (gAreas[a].AreaType = AREA_BLUEFLAG) or
              (gAreas[a].AreaType = AREA_DOMFLAG) then
@@ -2270,25 +2302,25 @@ begin
                        0, True, False);
 
         // Рамка:
-          if not PreviewMode then
+          if PreviewMode = 0 then
           begin
             e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
                        MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
-                       255, 255, 255);
+                       255, 255, 255, IfThen(sel, 0, gAlphaAreaRect));
 
             e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
           end;
         end;
 
 // Рисуем жидкости и передний план после областей:
-  if LayerEnabled[LAYER_WATER] or PreviewMode then
+  if LayerEnabled[LAYER_WATER] or (PreviewMode = 1) then
     DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
-  if LayerEnabled[LAYER_FOREGROUND] or PreviewMode then
+  if LayerEnabled[LAYER_FOREGROUND] or (PreviewMode = 1) then
     DrawPanels(PANEL_FORE);
 
 // Рисуем триггеры:
   if LayerEnabled[LAYER_TRIGGERS] and
-     (not PreviewMode) and (gTriggers <> nil) then
+     (PreviewMode = 0) and (gTriggers <> nil) then
     for a := 0 to High(gTriggers) do
       with gTriggers[a] do
         if TriggerType <> TRIGGER_NONE then
@@ -2621,7 +2653,7 @@ begin
         end;
 
 // Границы карты:
-  if not PreviewMode then
+  if PreviewMode = 0 then
   begin
     e_DrawFillQuad(-32+MapOffset.X,
                    -32+MapOffset.Y,