X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Feditor%2Ff_main.pas;h=3f65bba33336ec96c8a80a4f7a8c0f0e268a3efa;hb=7bc7d5022ae82e37fee8b3003432f9294176a470;hp=d3193006eebd27184d3b0bc384de61a50d60962e;hpb=b72e164f0fb64e3301ae8ca217449daf6a9d301d;p=d2df-editor.git diff --git a/src/editor/f_main.pas b/src/editor/f_main.pas index d319300..3f65bba 100644 --- a/src/editor/f_main.pas +++ b/src/editor/f_main.pas @@ -1,17 +1,21 @@ unit f_main; -{$MODE Delphi} +{$INCLUDE ../shared/a_modes.inc} interface uses - LCLIntf, LCLType, LMessages, SysUtils, Variants, Classes, Graphics, - Controls, Forms, Dialogs, ImgList, StdCtrls, Buttons, - ComCtrls, ValEdit, Types, ToolWin, Menus, ExtCtrls, - CheckLst, Grids; + LCLIntf, LCLType, SysUtils, Variants, Classes, Graphics, + Controls, Forms, Dialogs, StdCtrls, Buttons, + ComCtrls, ValEdit, Types, Menus, ExtCtrls, + CheckLst, Grids, OpenGLContext, utils, UTF8Process; type + + { TMainForm } + TMainForm = class(TForm) + lLoad: TLabel; // Главное меню: MainMenu: TMainMenu; // "Файл": @@ -22,6 +26,7 @@ type miSaveMapAs: TMenuItem; miOpenWadMap: TMenuItem; miLine1: TMenuItem; + miReopenMap: TMenuItem; miSaveMiniMap: TMenuItem; miDeleteMap: TMenuItem; miPackMap: TMenuItem; @@ -77,6 +82,9 @@ type // Панель инструментов: MainToolBar: TToolBar; + pbLoad: TProgressBar; + pLoadProgress: TPanel; + RenderPanel: TOpenGLControl; tbNewMap: TToolButton; tbOpenMap: TToolButton; tbSaveMap: TToolButton; @@ -107,12 +115,6 @@ type // Панель карты: PanelMap: TPanel; - // Панель отображения карты: - RenderPanel: TPanel; - // Панель загрузки: - pLoadProgress: TPanel; - lLoad: TLabel; - pbLoad: TProgressBar; // Полосы прокрутки: sbHorizontal: TScrollBar; sbVertical: TScrollBar; @@ -203,14 +205,21 @@ type procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); + procedure FormDropFiles(Sender: TObject; const FileNames: array of String); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormResize(Sender: TObject); procedure lbTextureListClick(Sender: TObject); + procedure lbTextureListDrawItem(Control: TWinControl; Index: Integer; + ARect: TRect; State: TOwnerDrawState); + procedure miReopenMapClick(Sender: TObject); procedure RenderPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure RenderPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure RenderPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure RenderPanelPaint(Sender: TObject); procedure RenderPanelResize(Sender: TObject); + procedure Splitter1Moved(Sender: TObject); procedure vleObjectPropertyEditButtonClick(Sender: TObject); + procedure vleObjectPropertyApply(Sender: TObject); procedure vleObjectPropertyGetPickList(Sender: TObject; const KeyName: String; Values: TStrings); procedure vleObjectPropertyKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); @@ -256,8 +265,9 @@ type procedure OnIdle(Sender: TObject; var Done: Boolean); public procedure RefreshRecentMenu(); - { procedure lbTextureListDrawItem(Control: TWinControl; Index: Integer; - Rect: TRect; State: TOwnerDrawState); } + procedure OpenMapFile(FileName: String); + function RenderMousePos(): TPoint; + procedure RecountSelectedObjects(); end; const @@ -289,6 +299,7 @@ var DrawPanelSize: Boolean; BackColor: TColor; PreviewColor: TColor; + UseCheckerboard: Boolean; Scale: Byte; RecentCount: Integer; RecentFiles: TStringList; @@ -307,7 +318,7 @@ var LayerEnabled: Array [LAYER_BACK..LAYER_TRIGGERS] of Boolean = (True, True, True, True, True, True, True, True, True); - PreviewMode: Boolean = False; + PreviewMode: Byte = 0; gLanguage: String; FormCaption: String; @@ -321,14 +332,14 @@ procedure ChangeShownProperty(Name: String; NewValue: String); implementation uses - f_options, e_graphics, e_log, dglOpenGL, Math, + f_options, e_graphics, e_log, GL, Math, f_mapoptions, g_basic, f_about, f_mapoptimization, f_mapcheck, f_addresource_texture, g_textures, - f_activationtype, f_keys, MAPWRITER, MAPSTRUCT, - MAPREADER, f_selectmap, f_savemap, WADEDITOR, MAPDEF, + f_activationtype, f_keys, + MAPREADER, f_selectmap, f_savemap, WADEDITOR, WADSTRUCT, MAPDEF, g_map, f_saveminimap, f_addresource, CONFIG, f_packmap, f_addresource_sound, f_maptest, f_choosetype, - g_language, f_selectlang, ClipBrd, Windows; + g_language, f_selectlang, ClipBrd, g_resources; const UNDO_DELETE_PANEL = 1; @@ -378,7 +389,7 @@ const SELECTFLAG_SHOTPANEL = 7; SELECTFLAG_SELECTED = 8; - RECENT_FILES_MENU_START = 11; + RECENT_FILES_MENU_START = 12; CLIPBOARD_SIG = 'DF:ED'; @@ -419,9 +430,8 @@ type TCopyRecArray = Array of TCopyRec; var - hDC: THandle; - hRC: THandle; gEditorFont: DWORD; + gDataLoaded: Boolean = False; ShowMap: Boolean = False; DrawRect: PRect = nil; SnapToGrid: Boolean = True; @@ -432,6 +442,7 @@ var MouseRDown: Boolean; MouseLDownPos: Types.TPoint; MouseRDownPos: Types.TPoint; + WASDOffset: TPoint; SelectFlag: Byte = SELECTFLAG_NONE; MouseAction: Byte = MOUSEACTION_NONE; @@ -729,6 +740,7 @@ var str: String; begin MainForm.vleObjectProperty.Strings.Clear(); + MainForm.RecountSelectedObjects(); // Отображаем свойства если выделен только один объект: if SelectedObjectCount() <> 1 then @@ -950,7 +962,8 @@ begin case TriggerType of TRIGGER_EXIT: begin - with ItemProps[InsertRow(_lc[I_PROP_TR_NEXT_MAP], Data.MapName, True)] do + str := win2utf(Data.MapName); + with ItemProps[InsertRow(_lc[I_PROP_TR_NEXT_MAP], str, True)] do begin EditStyle := esEllipsis; ReadOnly := True; @@ -1104,7 +1117,8 @@ begin TRIGGER_SOUND: begin - with ItemProps[InsertRow(_lc[I_PROP_TR_SOUND_NAME], Data.SoundName, True)] do + str := win2utf(Data.SoundName); + with ItemProps[InsertRow(_lc[I_PROP_TR_SOUND_NAME], str, True)] do begin EditStyle := esEllipsis; ReadOnly := True; @@ -1267,7 +1281,8 @@ begin TRIGGER_MUSIC: begin - with ItemProps[InsertRow(_lc[I_PROP_TR_MUSIC_NAME], Data.MusicName, True)] do + str := win2utf(Data.MusicName); + with ItemProps[InsertRow(_lc[I_PROP_TR_MUSIC_NAME], str, True)] do begin EditStyle := esEllipsis; ReadOnly := True; @@ -1369,7 +1384,8 @@ begin EditStyle := esPickList; ReadOnly := True; end; - with ItemProps[InsertRow(_lc[I_PROP_TR_MESSAGE_TEXT], Data.MessageText, True)] do + str := win2utf(Data.MessageText); + with ItemProps[InsertRow(_lc[I_PROP_TR_MESSAGE_TEXT], str, True)] do begin EditStyle := esSimple; MaxLength := 100; @@ -1460,7 +1476,13 @@ begin MaxLength := 3; end; - with ItemProps[InsertRow(_lc[I_PROP_TR_SHOT_ALLMAP], BoolNames[Data.ShotAllMap], True)] do + case Data.ShotAim of + 1: str := _lc[I_PROP_TR_SHOT_AIM_1]; + 2: str := _lc[I_PROP_TR_SHOT_AIM_2]; + 3: str := _lc[I_PROP_TR_SHOT_AIM_3]; + else str := _lc[I_PROP_TR_SHOT_AIM_0]; + end; + with ItemProps[InsertRow(_lc[I_PROP_TR_SHOT_AIM], str, True)] do begin EditStyle := esPickList; ReadOnly := True; @@ -1754,6 +1776,7 @@ begin RemoveSelectFromObjects(); MainForm.miUndo.Enabled := UndoBuffer <> nil; + MainForm.RecountSelectedObjects(); end; procedure Undo_Add(ObjectType: Byte; ID: DWORD; Group: Boolean = False); @@ -1788,6 +1811,7 @@ procedure FullClear(); begin RemoveSelectFromObjects(); ClearMap(); + LoadSky(gMapInfo.SkyName); UndoBuffer := nil; slInvalidTextures.Clear(); MapCheckForm.lbErrorList.Clear(); @@ -1869,7 +1893,7 @@ end; function AddTexture(aWAD, aSection, aTex: String; silent: Boolean): Boolean; var - a: Integer; + a, FrameLen: Integer; ok: Boolean; FileName: String; ResourceName: String; @@ -1879,11 +1903,19 @@ var Width, Height: Word; fn: String; begin + Data := nil; + FrameLen := 0; + Width := 0; + Height := 0; + if aSection = '..' then SectionName := '' else SectionName := aSection; + if aWAD = '' then + aWAD := _lc[I_WAD_SPECIAL_MAP]; + if aWAD = _lc[I_WAD_SPECIAL_MAP] then begin // Файл карты g_ProcessResourceStr(OpenedMap, @fn, nil, nil); @@ -1899,7 +1931,7 @@ begin end else begin // Внешний WAD - FileName := EditorDir+'wads\'+aWAD; + FileName := EditorDir+'wads/'+aWAD; ResourceName := aWAD+':'+SectionName+'\'+aTex; end; @@ -1940,16 +1972,23 @@ begin if IsAnim(FullResourceName) then begin // Аним. текстура - GetFrame(FullResourceName, Data, Width, Height); + GetFrame(FullResourceName, Data, FrameLen, Width, Height); - if g_CreateTextureMemorySize(Data, ResourceName, 0, 0, Width, Height, 1) then - a := MainForm.lbTextureList.Items.Add(ResourceName); + if not g_CreateTextureMemorySize(Data, FrameLen, ResourceName, 0, 0, Width, Height, 1) then + ok := False; + a := MainForm.lbTextureList.Items.Add(ResourceName); end else // Обычная текстура begin - if g_CreateTextureWAD(ResourceName, FullResourceName) then - a := MainForm.lbTextureList.Items.Add(ResourceName); + if not g_CreateTextureWAD(ResourceName, FullResourceName) then + ok := False; + a := MainForm.lbTextureList.Items.Add(ResourceName); end; + if (not ok) and (slInvalidTextures.IndexOf(ResourceName) = -1) then + begin + slInvalidTextures.Add(ResourceName); + ok := True; + end; if (a > -1) and (not silent) then SelectTexture(a); end; @@ -1977,6 +2016,7 @@ var MapName: String; idx: Integer; begin + SelectMapForm.Caption := _lc[I_CAP_OPEN]; SelectMapForm.GetMaps(FileName); if (FileName = OpenedWAD) and @@ -2307,7 +2347,8 @@ begin Result := Res; end; -procedure StringToCopyBuffer(Str: String; var CopyBuf: TCopyRecArray); +procedure StringToCopyBuffer(Str: String; var CopyBuf: TCopyRecArray; + var pmin: TPoint); var i, j, t: Integer; @@ -2389,6 +2430,8 @@ begin PanelType := StrToIntDef(GetNext(), PANEL_WALL); X := StrToIntDef(GetNext(), 0); Y := StrToIntDef(GetNext(), 0); + pmin.X := Min(X, pmin.X); + pmin.Y := Min(Y, pmin.Y); Width := StrToIntDef(GetNext(), 16); Height := StrToIntDef(GetNext(), 16); TextureName := GetNext(); @@ -2403,6 +2446,8 @@ begin ItemType := StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL); X := StrToIntDef(GetNext(), 0); Y := StrToIntDef(GetNext(), 0); + pmin.X := Min(X, pmin.X); + pmin.Y := Min(Y, pmin.Y); OnlyDM := (GetNext() = '1'); Fall := (GetNext() = '1'); end; @@ -2413,6 +2458,8 @@ begin MonsterType := StrToIntDef(GetNext(), MONSTER_DEMON); X := StrToIntDef(GetNext(), 0); Y := StrToIntDef(GetNext(), 0); + pmin.X := Min(X, pmin.X); + pmin.Y := Min(Y, pmin.Y); if GetNext() = '1' then Direction := D_LEFT @@ -2426,6 +2473,8 @@ begin AreaType := StrToIntDef(GetNext(), AREA_PLAYERPOINT1); X := StrToIntDef(GetNext(), 0); Y := StrToIntDef(GetNext(), 0); + pmin.X := Min(X, pmin.X); + pmin.Y := Min(Y, pmin.Y); if GetNext() = '1' then Direction := D_LEFT else @@ -2438,6 +2487,8 @@ begin TriggerType := StrToIntDef(GetNext(), TRIGGER_EXIT); X := StrToIntDef(GetNext(), 0); Y := StrToIntDef(GetNext(), 0); + pmin.X := Min(X, pmin.X); + pmin.Y := Min(Y, pmin.Y); Width := StrToIntDef(GetNext(), 16); Height := StrToIntDef(GetNext(), 16); ActivateType := StrToIntDef(GetNext(), 0); @@ -2447,6 +2498,34 @@ begin for j := 0 to 127 do Data.Default[j] := StrToIntDef(GetNext(), 0); + + case TriggerType of + TRIGGER_TELEPORT: + begin + pmin.X := Min(Data.TargetPoint.X, pmin.X); + pmin.Y := Min(Data.TargetPoint.Y, pmin.Y); + end; + TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF: + begin + pmin.X := Min(Data.tX, pmin.X); + pmin.Y := Min(Data.tY, pmin.Y); + end; + TRIGGER_SPAWNMONSTER: + begin + pmin.X := Min(Data.MonPos.X, pmin.X); + pmin.Y := Min(Data.MonPos.Y, pmin.Y); + end; + TRIGGER_SPAWNITEM: + begin + pmin.X := Min(Data.ItemPos.X, pmin.X); + pmin.Y := Min(Data.ItemPos.Y, pmin.Y); + end; + TRIGGER_SHOT: + begin + pmin.X := Min(Data.ShotPos.X, pmin.X); + pmin.Y := Min(Data.ShotPos.Y, pmin.Y); + end; + end; end; end; end; @@ -2491,6 +2570,7 @@ procedure TMainForm.aRecentFileExecute(Sender: TObject); var n, pw: Integer; s, fn: String; + b: Boolean; begin s := LowerCase((Sender as TMenuItem).Caption); Delete(s, Pos('&', s), 1); @@ -2502,17 +2582,31 @@ begin s := RecentFiles[n]; pw := Pos('.wad:\', LowerCase(s)); + b := False; if pw > 0 then begin // Map name included fn := Copy(s, 1, pw + 3); Delete(s, 1, pw + 5); if (FileExists(fn)) then + begin OpenMap(fn, s); + b := True; + end; end else // Only wad name if (FileExists(s)) then + begin OpenMap(s, ''); + b := True; + end; + + if (not b) and (MessageBox(0, PChar(_lc[I_MSG_DEL_RECENT_PROMT]), + PChar(_lc[I_MSG_DEL_RECENT]), MB_ICONQUESTION or MB_YESNO) = idYes) then + begin + RecentFiles.Delete(n); + RefreshRecentMenu(); + end; end; procedure TMainForm.aEditorOptionsExecute(Sender: TObject); @@ -2520,10 +2614,41 @@ begin OptionsForm.ShowModal(); end; +procedure LoadStdFont(cfgres, texture: string; var FontID: DWORD); +var + cwdt, chgt: Byte; + spc: ShortInt; + ID: DWORD; + cfgdata: Pointer; + cfglen: Integer; + config: TConfig; +begin + ID := 0; + g_ReadResource(EditorDir + 'data/Game.wad', 'FONTS', cfgres, cfgdata, cfglen); + if cfgdata <> nil then + begin + if not g_CreateTextureWAD('FONT_STD', EditorDir + 'data/Game.wad:FONTS\' + texture) then + e_WriteLog('ERROR ERROR ERROR', MSG_WARNING); + + config := TConfig.CreateMem(cfgdata, cfglen); + cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255); + chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255); + spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127); + + if g_GetTexture('FONT_STD', ID) then + e_TextureFontBuild(ID, FontID, cwdt, chgt, spc - 2); + + config.Free(); + FreeMem(cfgdata) + end + else + begin + e_WriteLog('Could not load FONT_STD', MSG_WARNING) + end +end; + procedure TMainForm.FormCreate(Sender: TObject); var - PixelFormat: GLuint; - pfd: TPIXELFORMATDESCRIPTOR; config: TConfig; i: Integer; s: String; @@ -2534,38 +2659,8 @@ begin e_InitLog(EditorDir+'Editor.log', WM_NEWFILE); - e_WriteLog('Init OpenGL', MSG_NOTIFY); - - InitOpenGL(); - hDC := GetDC(RenderPanel.Handle); - - FillChar(pfd, SizeOf(pfd), 0); - with pfd do - begin - nSize := SizeOf(pfd); - nVersion := 1; - dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; - dwLayerMask := PFD_MAIN_PLANE; - iPixelType := PFD_TYPE_RGBA; - cColorBits := 24; - cDepthBits := 32; - iLayerType := PFD_MAIN_PLANE; - end; - PixelFormat := ChoosePixelFormat (hDC, @pfd); - SetPixelFormat(hDC, PixelFormat, @pfd); - - hRC := wglCreateContext(hDC); - ActivateRenderingContext(hDC, hRC); - - e_InitGL(False); - - gEditorFont := e_SimpleFontCreate('Arial Cyr', 12, FW_BOLD, hDC); - slInvalidTextures := TStringList.Create; - e_WriteLog('Loading data', MSG_NOTIFY); - LoadData(); - ShowLayer(LAYER_BACK, True); ShowLayer(LAYER_WALLS, True); ShowLayer(LAYER_FOREGROUND, True); @@ -2582,8 +2677,16 @@ begin OpenedMap := ''; OpenedWAD := ''; - config := TConfig.CreateFile(EditorDir+'\Editor.cfg'); + config := TConfig.CreateFile(EditorDir+'Editor.cfg'); + if config.ReadInt('Editor', 'XPos', -1) = -1 then + Position := poDesktopCenter + else begin + Left := config.ReadInt('Editor', 'XPos', Left); + Top := config.ReadInt('Editor', 'YPos', Top); + Width := config.ReadInt('Editor', 'Width', Width); + Height := config.ReadInt('Editor', 'Height', Height); + end; if config.ReadBool('Editor', 'Maximize', False) then WindowState := wsMaximized; ShowMap := config.ReadBool('Editor', 'Minimap', False); @@ -2601,6 +2704,7 @@ begin DrawPanelSize := config.ReadBool('Editor', 'DrawPanelSize', True); BackColor := config.ReadInt('Editor', 'BackColor', $7F6040); PreviewColor := config.ReadInt('Editor', 'PreviewColor', $00FF00); + UseCheckerboard := config.ReadBool('Editor', 'UseCheckerboard', True); gColorEdge := config.ReadInt('Editor', 'EdgeColor', COLOR_EDGE); gAlphaEdge := config.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE); if gAlphaEdge = 255 then @@ -2618,6 +2722,8 @@ begin gAlphaTriggerArea := config.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA); if gAlphaTriggerArea = 255 then gAlphaTriggerArea := ALPHA_AREA; + gAlphaMonsterRect := config.ReadInt('Editor', 'MonsterRectAlpha', 0); + gAlphaAreaRect := config.ReadInt('Editor', 'AreaRectAlpha', 0); if config.ReadInt('Editor', 'Scale', 0) = 1 then Scale := 2 else @@ -2657,18 +2763,27 @@ begin Application.OnIdle := OnIdle; end; +procedure PrintBlack(X, Y: Integer; Text: string; FontID: DWORD); +begin + // NOTE: all the font printing routines assume CP1251 + e_TextureFontPrintEx(X, Y, Text, FontID, 0, 0, 0, 1.0); +end; + procedure TMainForm.Draw(); var - ps: TPaintStruct; x, y: Integer; a, b: Integer; - ID: DWORD; + ID, PID: DWORD; Width, Height: Word; Rect: TRectWH; ObjCount: Word; aX, aY, aX2, aY2, XX, ScaleSz: Integer; begin - BeginPaint(Handle, ps); + ID := 0; + PID := 0; + Width := 0; + Height := 0; + e_BeginRender(); e_Clear(GL_COLOR_BUFFER_BIT, @@ -2713,7 +2828,7 @@ begin end; // Рисуем сетку: - if DotEnable and (not PreviewMode) then + if DotEnable and (PreviewMode = 0) then begin if DotSize = 2 then a := -1 @@ -2730,15 +2845,20 @@ begin // Превью текстуры: if (lbTextureList.ItemIndex <> -1) and (cbPreview.Checked) and - (not IsSpecialTextureSel()) and (not PreviewMode) then + (not IsSpecialTextureSel()) and (PreviewMode = 0) then begin if not g_GetTexture(SelectedTexture(), ID) then g_GetTexture('NOTEXTURE', ID); g_GetTextureSizeByID(ID, Width, Height); - e_DrawFillQuad(RenderPanel.Width-Width-2, RenderPanel.Height-Height-2, - RenderPanel.Width-1, RenderPanel.Height-1, - GetRValue(PreviewColor), GetGValue(PreviewColor), GetBValue(PreviewColor), 0); - e_Draw(ID, RenderPanel.Width-Width-1, RenderPanel.Height-Height-1, 0, True, False); + if UseCheckerboard then + begin + if g_GetTexture('PREVIEW', PID) then + e_DrawFill(PID, RenderPanel.Width-Width, RenderPanel.Height-Height, Width div 16 + 1, Height div 16 + 1, 0, True, False); + end else + e_DrawFillQuad(RenderPanel.Width-Width-2, RenderPanel.Height-Height-2, + RenderPanel.Width-1, RenderPanel.Height-1, + GetRValue(PreviewColor), GetGValue(PreviewColor), GetBValue(PreviewColor), 0); + e_Draw(ID, RenderPanel.Width-Width, RenderPanel.Height-Height, 0, True, False); end; // Подсказка при выборе точки Телепорта: @@ -2755,7 +2875,7 @@ begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_TELEPORT]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_TELEPORT], gEditorFont); end; // Подсказка при выборе точки появления: @@ -2766,7 +2886,7 @@ begin 0, 0, 255); e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_SPAWN]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_SPAWN], gEditorFont); end; // Подсказка при выборе панели двери: @@ -2774,7 +2894,7 @@ begin begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_DOOR]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_DOOR], gEditorFont); end; // Подсказка при выборе панели с текстурой: @@ -2782,7 +2902,7 @@ begin begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_TEXTURE]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_TEXTURE], gEditorFont); end; // Подсказка при выборе панели индикации выстрела: @@ -2790,7 +2910,7 @@ begin begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_SHOT]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_SHOT], gEditorFont); end; // Подсказка при выборе панели лифта: @@ -2798,7 +2918,7 @@ begin begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_LIFT]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_LIFT], gEditorFont); end; // Подсказка при выборе монстра: @@ -2806,7 +2926,7 @@ begin begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_MONSTER]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_MONSTER], gEditorFont); end; // Подсказка при выборе области воздействия: @@ -2814,7 +2934,7 @@ begin begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 192, 192, 192, 127); e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 255, 255, 255); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_EXT_AREA]), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_EXT_AREA], gEditorFont); end; // Рисуем текстуры, если чертим панель: @@ -2826,8 +2946,9 @@ begin g_GetTexture('NOTEXTURE', ID); g_GetTextureSizeByID(ID, Width, Height); with DrawRect^ do - e_DrawFill(ID, Min(Left, Right), Min(Top, Bottom), Abs(Right-Left) div Width, - Abs(Bottom-Top) div Height, 0, True, False); + if (Abs(Right-Left) >= Width) and (Abs(Bottom-Top) >= Height) then + e_DrawFill(ID, Min(Left, Right), Min(Top, Bottom), Abs(Right-Left) div Width, + Abs(Bottom-Top) div Height, 64, True, False); end; // Прямоугольник выделения: @@ -2836,7 +2957,8 @@ begin e_DrawQuad(Left, Top, Right-1, Bottom-1, 255, 255, 255); // Чертим мышью панель/триггер или меняем мышью их размер: - if (MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER, MOUSEACTION_RESIZE]) and + if (((MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER]) and + not(ssCtrl in GetKeyShiftState())) or (MouseAction = MOUSEACTION_RESIZE)) and (DrawPanelSize) then begin e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+88, MousePos.Y+33, 192, 192, 192, 127); @@ -2844,10 +2966,10 @@ begin if MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER] then begin // Чертим новый - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(Format(_lc[I_HINT_WIDTH], - [Abs(MousePos.X-MouseLDownPos.X)])), gEditorFont, 0, 0, 0); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+28, PChar(Format(_lc[I_HINT_HEIGHT], - [Abs(MousePos.Y-MouseLDownPos.Y)])), gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH], + [Abs(MousePos.X-MouseLDownPos.X)]), gEditorFont); + PrintBlack(MousePos.X+2, MousePos.Y+16, Format(_glc[I_HINT_HEIGHT], + [Abs(MousePos.Y-MouseLDownPos.Y)]), gEditorFont); end else // Растягиваем существующий if SelectedObjects[GetFirstSelected].ObjectType in [OBJECT_PANEL, OBJECT_TRIGGER] then @@ -2863,10 +2985,10 @@ begin Height := gTriggers[SelectedObjects[GetFirstSelected].ID].Height; end; - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(Format(_lc[I_HINT_WIDTH], [Width])), - gEditorFont, 0, 0, 0); - e_SimpleFontPrint(MousePos.X+8, MousePos.Y+28, PChar(Format(_lc[I_HINT_HEIGHT], [Height])), - gEditorFont, 0, 0, 0); + PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH], [Width]), + gEditorFont); + PrintBlack(MousePos.X+2, MousePos.Y+16, Format(_glc[I_HINT_HEIGHT], [Height]), + gEditorFont); end; end; @@ -2962,8 +3084,7 @@ begin end; // Мини-карта e_EndRender(); - SwapBuffers(hDC); - EndPaint(Handle, ps); + RenderPanel.SwapBuffers(); end; procedure TMainForm.FormResize(Sender: TObject); @@ -3486,10 +3607,24 @@ procedure TMainForm.RenderPanelMouseUp(Sender: TObject; var panel: TPanel; trigger: TTrigger; - i: Integer; - IDArray: DWArray; rRect: TRectWH; rSelectRect: Boolean; + wWidth, wHeight: Word; + TextureID: DWORD; + + procedure SelectObjects(ObjectType: Byte); + var + i: Integer; + IDArray: DWArray; + begin + IDArray := ObjectInRect(rRect.X, rRect.Y, + rRect.Width, rRect.Height, + ObjectType, rSelectRect); + + if IDArray <> nil then + for i := 0 to High(IDArray) do + SelectObject(ObjectType, IDArray[i], (ssCtrl in Shift) or rSelectRect); + end; begin if Button = mbLeft then MouseLDown := False; @@ -3498,14 +3633,18 @@ begin DrawRect := nil; ResizeType := RESIZETYPE_NONE; + TextureID := 0; if Button = mbLeft then // Left Mouse Button begin if MouseAction <> MOUSEACTION_NONE then begin // Было действие мышью - // Мышь сдвинулась во время удержания клавиши: - if (MousePos.X <> MouseLDownPos.X) and - (MousePos.Y <> MouseLDownPos.Y) then + // Мышь сдвинулась во время удержания клавиши, + // либо активирован режим быстрого рисования: + if ((MousePos.X <> MouseLDownPos.X) and + (MousePos.Y <> MouseLDownPos.Y)) or + ((MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER]) and + (ssCtrl in Shift)) then case MouseAction of // Рисовали панель: MOUSEACTION_DRAWPANEL: @@ -3535,8 +3674,25 @@ begin Panel.X := Min(MousePos.X-MapOffset.X, MouseLDownPos.X-MapOffset.X); Panel.Y := Min(MousePos.Y-MapOffset.Y, MouseLDownPos.Y-MapOffset.Y); - Panel.Width := Abs(MousePos.X-MouseLDownPos.X); - Panel.Height := Abs(MousePos.Y-MouseLDownPos.Y); + if ssCtrl in Shift then + begin + wWidth := DotStep; + wHeight := DotStep; + if (lbTextureList.ItemIndex <> -1) and + (not IsSpecialTextureSel()) then + begin + if not g_GetTexture(SelectedTexture(), TextureID) then + g_GetTexture('NOTEXTURE', TextureID); + g_GetTextureSizeByID(TextureID, wWidth, wHeight); + end; + Panel.Width := wWidth; + Panel.Height := wHeight; + end + else + begin + Panel.Width := Abs(MousePos.X-MouseLDownPos.X); + Panel.Height := Abs(MousePos.Y-MouseLDownPos.Y); + end; // Лифты, блокМон или отсутствие текстуры - пустая текстура: if (lbPanelType.ItemIndex in [9, 10, 11, 12, 13]) or @@ -3578,8 +3734,18 @@ begin begin trigger.X := Min(MousePos.X-MapOffset.X, MouseLDownPos.X-MapOffset.X); trigger.Y := Min(MousePos.Y-MapOffset.Y, MouseLDownPos.Y-MapOffset.Y); - trigger.Width := Abs(MousePos.X-MouseLDownPos.X); - trigger.Height := Abs(MousePos.Y-MouseLDownPos.Y); + if ssCtrl in Shift then + begin + wWidth := DotStep; + wHeight := DotStep; + trigger.Width := wWidth; + trigger.Height := wHeight; + end + else + begin + trigger.Width := Abs(MousePos.X-MouseLDownPos.X); + trigger.Height := Abs(MousePos.Y-MouseLDownPos.Y); + end; trigger.Enabled := True; trigger.TriggerType := lbTriggersList.ItemIndex+1; @@ -3616,7 +3782,7 @@ begin trigger.Key := Trigger.Key or KEY_BLUETEAM; // Параметры триггера: - ZeroMemory(@trigger.Data.Default[0], 128); + FillByte(trigger.Data.Default[0], 128, 0); case trigger.TriggerType of // Переключаемая панель: @@ -3725,7 +3891,7 @@ begin trigger.Data.ShotPanelID := -1; trigger.Data.ShotTarget := 0; trigger.Data.ShotIntSight := 0; - trigger.Data.ShotAllMap := False; + trigger.Data.ShotAim := TRIGGER_SHOT_AIM_DEFAULT; trigger.Data.ShotPos.X := trigger.X-64; trigger.Data.ShotPos.Y := trigger.Y-64; trigger.Data.ShotAngle := 0; @@ -3824,27 +3990,50 @@ begin RemoveSelectFromObjects(); // Выделяем всё в выбранном прямоугольнике: - IDArray := ObjectInRect(rRect.X, rRect.Y, - rRect.Width, rRect.Height, - pcObjects.ActivePageIndex+1, rSelectRect); - - if IDArray <> nil then - for i := 0 to High(IDArray) do - SelectObject(pcObjects.ActivePageIndex+1, IDArray[i], - (ssCtrl in Shift) or rSelectRect); + if (ssCtrl in Shift) and (ssAlt in Shift) then + begin + SelectObjects(OBJECT_PANEL); + SelectObjects(OBJECT_ITEM); + SelectObjects(OBJECT_MONSTER); + SelectObjects(OBJECT_AREA); + SelectObjects(OBJECT_TRIGGER); + end + else + SelectObjects(pcObjects.ActivePageIndex+1); FillProperty(); end; end; +procedure TMainForm.RenderPanelPaint(Sender: TObject); +begin + Draw(); +end; + +function TMainForm.RenderMousePos(): Types.TPoint; +begin + Result := RenderPanel.ScreenToClient(Mouse.CursorPos); +end; + +procedure TMainForm.RecountSelectedObjects(); +begin + if SelectedObjectCount() = 0 then + StatusBar.Panels[0].Text := '' + else + StatusBar.Panels[0].Text := Format(_lc[I_CAP_STAT_SELECTED], [SelectedObjectCount()]); +end; + procedure TMainForm.RenderPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var sX, sY: Integer; dWidth, dHeight: Integer; _id: Integer; + TextureID: DWORD; + wWidth, wHeight: Word; begin _id := GetFirstSelected(); + TextureID := 0; // Рисуем панель с текстурой, сетка - размеры текстуры: if (MouseAction = MOUSEACTION_DRAWPANEL) and @@ -3909,16 +4098,20 @@ begin begin if DrawRect = nil then New(DrawRect); - DrawRect.TopLeft := MouseRDownPos; - DrawRect.BottomRight := MousePos; + DrawRect.Top := MouseRDownPos.y; + DrawRect.Left := MouseRDownPos.x; + DrawRect.Bottom := MousePos.y; + DrawRect.Right := MousePos.x; end else // Двигаем выделенные объекты: if MouseAction = MOUSEACTION_MOVEOBJ then begin MoveSelectedObjects(ssShift in Shift, ssCtrl in Shift, - MousePos.X-LastMovePoint.X, - MousePos.Y-LastMovePoint.Y); + MousePos.X-LastMovePoint.X+WASDOffset.X, + MousePos.Y-LastMovePoint.Y+WASDOffset.Y); + WASDOffset.X := 0; + WASDOffset.Y := 0; end else // Меняем размер выделенного объекта: @@ -3927,8 +4120,10 @@ begin if (SelectedObjectCount = 1) and (SelectedObjects[GetFirstSelected].Live) then begin - dWidth := MousePos.X-LastMovePoint.X; - dHeight := MousePos.Y-LastMovePoint.Y; + dWidth := MousePos.X-LastMovePoint.X+WASDOffset.X; + dHeight := MousePos.Y-LastMovePoint.Y+WASDOffset.Y; + WASDOffset.X := 0; + WASDOffset.Y := 0; case ResizeType of RESIZETYPE_VERTICAL: dWidth := 0; @@ -3959,8 +4154,29 @@ begin begin if DrawRect = nil then New(DrawRect); - DrawRect.TopLeft := MouseLDownPos; - DrawRect.BottomRight := MousePos; + if ssCtrl in Shift then + begin + wWidth := DotStep; + wHeight := DotStep; + if (lbTextureList.ItemIndex <> -1) and (not IsSpecialTextureSel()) and + (MouseAction = MOUSEACTION_DRAWPANEL) then + begin + if not g_GetTexture(SelectedTexture(), TextureID) then + g_GetTexture('NOTEXTURE', TextureID); + g_GetTextureSizeByID(TextureID, wWidth, wHeight); + end; + DrawRect.Top := MouseLDownPos.y; + DrawRect.Left := MouseLDownPos.x; + DrawRect.Bottom := DrawRect.Top + wHeight; + DrawRect.Right := DrawRect.Left + wWidth; + end + else + begin + DrawRect.Top := MouseLDownPos.y; + DrawRect.Left := MouseLDownPos.x; + DrawRect.Bottom := MousePos.y; + DrawRect.Right := MousePos.x; + end; end else // Двигаем карту: if MouseAction = MOUSEACTION_MOVEMAP then @@ -3983,7 +4199,7 @@ begin CanClose := MessageBox(0, PChar(_lc[I_MSG_EXIT_PROMT]), PChar(_lc[I_MSG_EXIT]), MB_ICONQUESTION or MB_YESNO or - MB_TASKMODAL or MB_DEFBUTTON1) = idYes; + MB_DEFBUTTON1) = idYes; end; procedure TMainForm.aExitExecute(Sender: TObject); @@ -3996,8 +4212,22 @@ var config: TConfig; i: Integer; begin - config := TConfig.CreateFile(EditorDir+'\Editor.cfg'); + config := TConfig.CreateFile(EditorDir+'Editor.cfg'); + if WindowState <> wsMaximized then + begin + config.WriteInt('Editor', 'XPos', Left); + config.WriteInt('Editor', 'YPos', Top); + config.WriteInt('Editor', 'Width', Width); + config.WriteInt('Editor', 'Height', Height); + end + else + begin + config.WriteInt('Editor', 'XPos', RestoredLeft); + config.WriteInt('Editor', 'YPos', RestoredTop); + config.WriteInt('Editor', 'Width', RestoredWidth); + config.WriteInt('Editor', 'Height', RestoredHeight); + end; config.WriteBool('Editor', 'Maximize', WindowState = wsMaximized); config.WriteBool('Editor', 'Minimap', ShowMap); config.WriteInt('Editor', 'PanelProps', PanelProps.ClientWidth); @@ -4011,6 +4241,8 @@ begin config.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge); config.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine); config.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea); + config.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect); + config.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect); for i := 0 to RecentCount-1 do if i < RecentFiles.Count then @@ -4019,12 +4251,19 @@ begin config.WriteStr('RecentFiles', IntToStr(i+1), ''); RecentFiles.Free(); - config.SaveFile(EditorDir+'\Editor.cfg'); + config.SaveFile(EditorDir+'Editor.cfg'); config.Free(); slInvalidTextures.Free; +end; + +procedure TMainForm.FormDropFiles(Sender: TObject; + const FileNames: array of String); +begin + if Length(FileNames) <> 1 then + Exit; - wglDeleteContext(hRC); + OpenMapFile(FileNames[0]); end; procedure TMainForm.RenderPanelResize(Sender: TObject); @@ -4033,6 +4272,11 @@ begin MainForm.Resize(); end; +procedure TMainForm.Splitter1Moved(Sender: TObject); +begin + FormResize(Sender); +end; + procedure TMainForm.aMapOptionsExecute(Sender: TObject); var ResName: String; @@ -4119,17 +4363,34 @@ begin if not (ssCtrl in Shift) then begin + // Быстрое превью карты: + if Key = Ord('E') then + begin + if PreviewMode = 0 then + PreviewMode := 2; + end; + // Вертикальный скролл карты: with sbVertical do begin if Key = Ord('W') then begin + if (MouseLDown or MouseRDown) and (Position >= DotStep) then + begin + Dec(WASDOffset.Y, DotStep); + RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y); + end; Position := IfThen(Position > DotStep, Position-DotStep, 0); MapOffset.Y := -Round(Position/16) * 16; end; if Key = Ord('S') then begin + if (MouseLDown or MouseRDown) and (Position+DotStep <= Max) then + begin + Inc(WASDOffset.Y, DotStep); + RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y); + end; Position := IfThen(Position+DotStep < Max, Position+DotStep, Max); MapOffset.Y := -Round(Position/16) * 16; end; @@ -4140,16 +4401,36 @@ begin begin if Key = Ord('A') then begin + if (MouseLDown or MouseRDown) and (Position >= DotStep) then + begin + Dec(WASDOffset.X, DotStep); + RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y); + end; Position := IfThen(Position > DotStep, Position-DotStep, 0); MapOffset.X := -Round(Position/16) * 16; end; if Key = Ord('D') then begin + if (MouseLDown or MouseRDown) and (Position+DotStep <= Max) then + begin + Inc(WASDOffset.X, DotStep); + RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y); + end; Position := IfThen(Position+DotStep < Max, Position+DotStep, Max); MapOffset.X := -Round(Position/16) * 16; end; end; + end + else // ssCtrl in Shift + begin + if ssShift in Shift then + begin + // Вставка по абсолютному смещению: + if Key = Ord('V') then + aPasteObjectExecute(Sender); + end; + RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y); end; end; @@ -4208,6 +4489,7 @@ begin DrawPressRect := False; Exit; end; + i := -1; // Выбор области воздействия, в зависимости от типа триггера vleObjectProperty.FindRow(_lc[I_PROP_TR_EX_AREA], i); @@ -4248,6 +4530,7 @@ begin if i > 0 then begin g_ProcessResourceStr(OpenedMap, @FileName, nil, nil); + SelectMapForm.Caption := _lc[I_CAP_SELECT]; SelectMapForm.GetMaps(FileName); if SelectMapForm.ShowModal() = mrOK then @@ -4308,6 +4591,9 @@ var TextureID: DWORD; TextureWidth, TextureHeight: Word; begin + TextureID := 0; + TextureWidth := 0; + TextureHeight := 0; if (lbTextureList.ItemIndex <> -1) and (not IsSpecialTextureSel()) then begin @@ -4330,6 +4616,42 @@ begin end; end; +procedure TMainForm.lbTextureListDrawItem(Control: TWinControl; Index: Integer; + ARect: TRect; State: TOwnerDrawState); +begin + with Control as TListBox do + begin + if LCLType.odSelected in State then + begin + Canvas.Brush.Color := clHighlight; + Canvas.Font.Color := clHighlightText; + end else + if (Items <> nil) and (Index >= 0) then + if slInvalidTextures.IndexOf(Items[Index]) > -1 then + begin + Canvas.Brush.Color := clRed; + Canvas.Font.Color := clWhite; + end; + Canvas.FillRect(ARect); + Canvas.TextRect(ARect, ARect.Left, ARect.Top, Items[Index]); + end; +end; + +procedure TMainForm.miReopenMapClick(Sender: TObject); +var + FileName, Resource: String; +begin + if OpenedMap = '' then + Exit; + + if MessageBox(0, PChar(_lc[I_MSG_REOPEN_MAP_PROMT]), + PChar(_lc[I_MENU_FILE_REOPEN]), MB_ICONQUESTION or MB_YESNO) <> idYes then + Exit; + + g_ProcessResourceStr(OpenedMap, @FileName, nil, @Resource); + OpenMap(FileName, Resource); +end; + procedure TMainForm.vleObjectPropertyGetPickList(Sender: TObject; const KeyName: String; Values: TStrings); begin @@ -4399,6 +4721,13 @@ begin Values.Add(_lc[I_PROP_TR_SHOT_TO_5]); Values.Add(_lc[I_PROP_TR_SHOT_TO_6]); end + else if KeyName = _lc[I_PROP_TR_SHOT_AIM] then + begin + Values.Add(_lc[I_PROP_TR_SHOT_AIM_0]); + Values.Add(_lc[I_PROP_TR_SHOT_AIM_1]); + Values.Add(_lc[I_PROP_TR_SHOT_AIM_2]); + Values.Add(_lc[I_PROP_TR_SHOT_AIM_3]); + end else if (KeyName = _lc[I_PROP_PANEL_BLEND]) or (KeyName = _lc[I_PROP_DM_ONLY]) or (KeyName = _lc[I_PROP_ITEM_FALLS]) or @@ -4416,7 +4745,6 @@ begin (KeyName = _lc[I_PROP_TR_SCORE_CON]) or (KeyName = _lc[I_PROP_TR_SCORE_MSG]) or (KeyName = _lc[I_PROP_TR_HEALTH_MAX]) or - (KeyName = _lc[I_PROP_TR_SHOT_ALLMAP]) or (KeyName = _lc[I_PROP_TR_SHOT_SOUND]) or (KeyName = _lc[I_PROP_TR_EFFECT_CENTER]) then begin @@ -4434,6 +4762,10 @@ var NoTextureID: DWORD; NW, NH: Word; begin + NoTextureID := 0; + NW := 0; + NH := 0; + if SelectedObjectCount() <> 1 then Exit; if not SelectedObjects[GetFirstSelected()].Live then @@ -4631,10 +4963,10 @@ begin case TriggerType of TRIGGER_EXIT: begin - s := vleObjectProperty.Values[_lc[I_PROP_TR_NEXT_MAP]]; - ZeroMemory(@Data.MapName[0], 16); + s := utf2win(vleObjectProperty.Values[_lc[I_PROP_TR_NEXT_MAP]]); + FillByte(Data.MapName[0], 16, 0); if s <> '' then - CopyMemory(@Data.MapName[0], @s[1], Min(Length(s), 16)); + Move(s[1], Data.MapName[0], Min(Length(s), 16)); end; TRIGGER_TEXTURE: @@ -4670,10 +5002,10 @@ begin TRIGGER_SOUND: begin - s := vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_NAME]]; - ZeroMemory(@Data.SoundName[0], 64); + s := utf2win(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_NAME]]); + FillByte(Data.SoundName[0], 64, 0); if s <> '' then - CopyMemory(@Data.SoundName[0], @s[1], Min(Length(s), 64)); + Move(s[1], Data.SoundName[0], Min(Length(s), 64)); Data.Volume := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_VOLUME]], 0), 255); Data.Pan := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_PAN]], 0), 255); @@ -4724,10 +5056,10 @@ begin TRIGGER_MUSIC: begin - s := vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_NAME]]; - ZeroMemory(@Data.MusicName[0], 64); + s := utf2win(vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_NAME]]); + FillByte(Data.MusicName[0], 64, 0); if s <> '' then - CopyMemory(@Data.MusicName[0], @s[1], Min(Length(s), 64)); + Move(s[1], Data.MusicName[0], Min(Length(s), 64)); if vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_ACT]] = _lc[I_PROP_TR_MUSIC_ON] then Data.MusicAction := 1 @@ -4784,10 +5116,10 @@ begin else if vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TO]] = _lc[I_PROP_TR_MESSAGE_TO_5] then Data.MessageSendTo := 5; - s := vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TEXT]]; - ZeroMemory(@Data.MessageText[0], 100); + s := utf2win(vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TEXT]]); + FillByte(Data.MessageText[0], 100, 0); if s <> '' then - CopyMemory(@Data.MessageText[0], @s[1], Min(Length(s), 100)); + Move(s[1], Data.MessageText[0], Min(Length(s), 100)); Data.MessageTime := Min(Max( StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TIME]], 0), 0), 65535); @@ -4830,7 +5162,13 @@ begin Data.ShotTarget := 6; Data.ShotIntSight := Min(Max( StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_SIGHT]], 0), 0), 65535); - Data.ShotAllMap := NameToBool(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_ALLMAP]]); + Data.ShotAim := 0; + if vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_AIM]] = _lc[I_PROP_TR_SHOT_AIM_1] then + Data.ShotAim := 1 + else if vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_AIM]] = _lc[I_PROP_TR_SHOT_AIM_2] then + Data.ShotAim := 2 + else if vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_AIM]] = _lc[I_PROP_TR_SHOT_AIM_3] then + Data.ShotAim := 3; Data.ShotAngle := Min( StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_ANGLE]], 0), 360); Data.ShotWait := Min(Max( @@ -4915,7 +5253,7 @@ begin [SelectedTexture()])), PChar(_lc[I_MSG_DEL_TEXTURE]), MB_ICONQUESTION or MB_YESNO or - MB_TASKMODAL or MB_DEFBUTTON1) <> idYes then + MB_DEFBUTTON1) <> idYes then Exit; if gPanels <> nil then @@ -4940,7 +5278,7 @@ begin if (MessageBox(0, PChar(_lc[I_MSG_CLEAR_MAP_PROMT]), PChar(_lc[I_MSG_CLEAR_MAP]), MB_ICONQUESTION or MB_YESNO or - MB_TASKMODAL or MB_DEFBUTTON1) = mrYes) then + MB_DEFBUTTON1) = mrYes) then FullClear(); end; @@ -5188,12 +5526,18 @@ procedure TMainForm.aPasteObjectExecute(Sender: TObject); var a, h: Integer; CopyBuffer: TCopyRecArray; - res: Boolean; + res, rel: Boolean; swad, ssec, sres: String; + NoTextureID: DWORD; + pmin: TPoint; begin CopyBuffer := nil; + NoTextureID := 0; + pmin.X := High(pmin.X); + pmin.Y := High(pmin.Y); - StringToCopyBuffer(ClipBoard.AsText, CopyBuffer); + StringToCopyBuffer(ClipBoard.AsText, CopyBuffer, pmin); + rel := not(ssShift in GetKeyShiftState()); if CopyBuffer = nil then Exit; @@ -5208,8 +5552,11 @@ begin OBJECT_PANEL: if Panel <> nil then begin - Panel^.X := Panel^.X + 16; - Panel^.Y := Panel^.Y + 16; + if rel then + begin + Panel^.X := Panel^.X - pmin.X - MapOffset.X + 32; + Panel^.Y := Panel^.Y - pmin.Y - MapOffset.Y + 32; + end; Panel^.TextureID := TEXTURE_SPECIAL_NONE; Panel^.TextureWidth := 1; @@ -5241,7 +5588,11 @@ begin g_GetTextureSizeByName(Panel^.TextureName, Panel^.TextureWidth, Panel^.TextureHeight) else - Panel^.TextureName := ''; + if g_GetTexture('NOTEXTURE', NoTextureID) then + begin + Panel^.TextureID := TEXTURE_SPECIAL_NOTEXTURE; + g_GetTextureSizeByID(NoTextureID, Panel^.TextureWidth, Panel^.TextureHeight); + end; end else // Спец.текстура: begin @@ -5260,8 +5611,11 @@ begin OBJECT_ITEM: begin - Item.X := Item.X + 16; - Item.Y := Item.Y + 16; + if rel then + begin + Item.X := Item.X - pmin.X - MapOffset.X + 32; + Item.Y := Item.Y - pmin.Y - MapOffset.Y + 32; + end; ID := AddItem(Item); Undo_Add(OBJECT_ITEM, ID, a > 0); @@ -5270,8 +5624,11 @@ begin OBJECT_MONSTER: begin - Monster.X := Monster.X + 16; - Monster.Y := Monster.Y + 16; + if rel then + begin + Monster.X := Monster.X - pmin.X - MapOffset.X + 32; + Monster.Y := Monster.Y - pmin.Y - MapOffset.Y + 32; + end; ID := AddMonster(Monster); Undo_Add(OBJECT_MONSTER, ID, a > 0); @@ -5280,8 +5637,11 @@ begin OBJECT_AREA: begin - Area.X := Area.X + 16; - Area.Y := Area.Y + 16; + if rel then + begin + Area.X := Area.X - pmin.X - MapOffset.X + 32; + Area.Y := Area.Y - pmin.Y - MapOffset.Y + 32; + end; ID := AddArea(Area); Undo_Add(OBJECT_AREA, ID, a > 0); @@ -5290,8 +5650,48 @@ begin OBJECT_TRIGGER: begin - Trigger.X := Trigger.X + 16; - Trigger.Y := Trigger.Y + 16; + if rel then + with Trigger do + begin + X := X - pmin.X - MapOffset.X + 32; + Y := Y - pmin.Y - MapOffset.Y + 32; + + case TriggerType of + TRIGGER_TELEPORT: + begin + Data.TargetPoint.X := + Data.TargetPoint.X - pmin.X - MapOffset.X + 32; + Data.TargetPoint.Y := + Data.TargetPoint.Y - pmin.Y - MapOffset.Y + 32; + end; + TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF: + begin + Data.tX := Data.tX - pmin.X - MapOffset.X + 32; + Data.tY := Data.tY - pmin.Y - MapOffset.Y + 32; + end; + TRIGGER_SPAWNMONSTER: + begin + Data.MonPos.X := + Data.MonPos.X - pmin.X - MapOffset.X + 32; + Data.MonPos.Y := + Data.MonPos.Y - pmin.Y - MapOffset.Y + 32; + end; + TRIGGER_SPAWNITEM: + begin + Data.ItemPos.X := + Data.ItemPos.X - pmin.X - MapOffset.X + 32; + Data.ItemPos.Y := + Data.ItemPos.Y - pmin.Y - MapOffset.Y + 32; + end; + TRIGGER_SHOT: + begin + Data.ShotPos.X := + Data.ShotPos.X - pmin.X - MapOffset.X + 32; + Data.ShotPos.Y := + Data.ShotPos.Y - pmin.Y - MapOffset.Y + 32; + end; + end; + end; ID := AddTrigger(Trigger); Undo_Add(OBJECT_TRIGGER, ID, a > 0); @@ -5366,7 +5766,7 @@ begin begin b := lbTypeSelect.ItemIndex; Values[Key] := PANELNAMES[b]; - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end end @@ -5396,12 +5796,13 @@ begin else if Key = _lc[I_PROP_TR_NEXT_MAP] then begin // Выбор следующей карты: g_ProcessResourceStr(OpenedMap, @FileName, nil, nil); + SelectMapForm.Caption := _lc[I_CAP_SELECT]; SelectMapForm.GetMaps(FileName); if SelectMapForm.ShowModal() = mrOK then begin vleObjectProperty.Values[Key] := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex]; - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if (Key = _lc[I_PROP_TR_SOUND_NAME]) or @@ -5414,7 +5815,7 @@ begin if (AddSoundForm.ShowModal() = mrOk) then begin vleObjectProperty.Values[Key] := AddSoundForm.ResourceName; - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_ACTIVATION] then @@ -5444,7 +5845,7 @@ begin b := b or ACTIVATE_NOMONSTER; Values[Key] := ActivateToStr(b); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_KEYS] then @@ -5471,7 +5872,7 @@ begin b := b or KEY_BLUETEAM; Values[Key] := KeyToStr(b); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_FX_TYPE] then @@ -5489,7 +5890,7 @@ begin begin b := lbTypeSelect.ItemIndex; Values[Key] := EffectToStr(b); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_MONSTER_TYPE] then @@ -5507,7 +5908,7 @@ begin begin b := lbTypeSelect.ItemIndex + MONSTER_DEMON; Values[Key] := MonsterToStr(b); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_ITEM_TYPE] then @@ -5522,6 +5923,8 @@ begin lbTypeSelect.Items.Add(ItemToStr(ITEM_HELMET)); lbTypeSelect.Items.Add(ItemToStr(ITEM_JETPACK)); lbTypeSelect.Items.Add(ItemToStr(ITEM_INVIS)); + lbTypeSelect.Items.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER)); + lbTypeSelect.Items.Add(ItemToStr(ITEM_AMMO_FUELCAN)); b := StrToItem(Values[Key]); if b >= ITEM_BOTTLE then @@ -5534,7 +5937,7 @@ begin if b >= ITEM_WEAPON_KASTET then b := b + 2; Values[Key] := ItemToStr(b); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_SHOT_TYPE] then @@ -5552,7 +5955,7 @@ begin begin b := lbTypeSelect.ItemIndex; Values[Key] := ShotToStr(b); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_EFFECT_TYPE] then @@ -5575,7 +5978,7 @@ begin Values[Key] := _lc[I_PROP_TR_EFFECT_PARTICLE] else Values[Key] := _lc[I_PROP_TR_EFFECT_ANIMATION]; - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_EFFECT_SUBTYPE] then @@ -5631,7 +6034,7 @@ begin Values[Key] := _lc[I_PROP_TR_EFFECT_BUBBLE]; end; - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_TR_EFFECT_COLOR] then @@ -5641,16 +6044,24 @@ begin if ColorDialog.Execute then begin Values[Key] := IntToStr(ColorDialog.Color); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end else if Key = _lc[I_PROP_PANEL_TEX] then begin // Смена текстуры: vleObjectProperty.Values[Key] := SelectedTexture(); - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; end; +procedure TMainForm.vleObjectPropertyApply(Sender: TObject); +begin + // hack to prevent empty ID in list + RenderPanel.SetFocus(); + bApplyProperty.Click(); + vleObjectProperty.SetFocus(); +end; + procedure TMainForm.aSaveMapExecute(Sender: TObject); var FileName, Section, Res: String; @@ -5672,31 +6083,35 @@ begin if OpenDialog.Execute() then begin - if (Pos('.ini', LowerCase(ExtractFileName(OpenDialog.FileName))) > 0) then - begin // INI карты: - FullClear(); + OpenMapFile(OpenDialog.FileName); + OpenDialog.InitialDir := ExtractFileDir(OpenDialog.FileName); + end; +end; - pLoadProgress.Left := (RenderPanel.Width div 2)-(pLoadProgress.Width div 2); - pLoadProgress.Top := (RenderPanel.Height div 2)-(pLoadProgress.Height div 2); - pLoadProgress.Show(); +procedure TMainForm.OpenMapFile(FileName: String); +begin + if (Pos('.ini', LowerCase(ExtractFileName(FileName))) > 0) then + begin // INI карты: + FullClear(); - OpenedMap := ''; - OpenedWAD := ''; + pLoadProgress.Left := (RenderPanel.Width div 2)-(pLoadProgress.Width div 2); + pLoadProgress.Top := (RenderPanel.Height div 2)-(pLoadProgress.Height div 2); + pLoadProgress.Show(); - LoadMapOld(OpenDialog.FileName); + OpenedMap := ''; + OpenedWAD := ''; - MainForm.Caption := Format('%s - %s', [FormCaption, ExtractFileName(OpenDialog.FileName)]); + LoadMapOld(FileName); - pLoadProgress.Hide(); - MainForm.FormResize(Self); - end - else // Карты из WAD: - begin - OpenMap(OpenDialog.FileName, ''); - end; + MainForm.Caption := Format('%s - %s', [FormCaption, ExtractFileName(FileName)]); - OpenDialog.InitialDir := ExtractFileDir(OpenDialog.FileName); - end; + pLoadProgress.Hide(); + MainForm.FormResize(Self); + end + else // Карты из WAD: + begin + OpenMap(FileName, ''); + end; end; procedure TMainForm.FormActivate(Sender: TObject); @@ -5715,9 +6130,9 @@ begin else gLanguage := LANGUAGE_RUSSIAN; end; - config := TConfig.CreateFile(EditorDir+'\Editor.cfg'); + config := TConfig.CreateFile(EditorDir+'Editor.cfg'); config.WriteStr('Editor', 'Language', gLanguage); - config.SaveFile(EditorDir+'\Editor.cfg'); + config.SaveFile(EditorDir+'Editor.cfg'); config.Free(); end; @@ -5751,32 +6166,33 @@ begin MapList := WAD.GetResourcesList(''); + SelectMapForm.Caption := _lc[I_CAP_REMOVE]; SelectMapForm.lbMapList.Items.Clear(); if MapList <> nil then for a := 0 to High(MapList) do - SelectMapForm.lbMapList.Items.Add(MapList[a]); + SelectMapForm.lbMapList.Items.Add(win2utf(MapList[a])); if (SelectMapForm.ShowModal() = mrOK) then begin str := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex]; MapName := ''; - CopyMemory(@MapName[0], @str[1], Min(16, Length(str))); + Move(str[1], MapName[0], Min(16, Length(str))); if MessageBox(0, PChar(Format(_lc[I_MSG_DELETE_MAP_PROMT], [MapName, OpenDialog.FileName])), PChar(_lc[I_MSG_DELETE_MAP]), MB_ICONQUESTION or MB_YESNO or - MB_TASKMODAL or MB_DEFBUTTON2) <> mrYes then + MB_DEFBUTTON2) <> mrYes then Exit; - WAD.RemoveResource('', MapName); + WAD.RemoveResource('', utf2win(MapName)); MessageBox(0, PChar(Format(_lc[I_MSG_MAP_DELETED_PROMT], [MapName])), PChar(_lc[I_MSG_MAP_DELETED]), MB_ICONINFORMATION or MB_OK or - MB_TASKMODAL or MB_DEFBUTTON1); + MB_DEFBUTTON1); WAD.SaveTo(OpenDialog.FileName); @@ -5796,7 +6212,7 @@ procedure TMainForm.vleObjectPropertyKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_RETURN then - bApplyProperty.Click(); + vleObjectPropertyApply(Sender); end; procedure MovePanel(var ID: DWORD; MoveType: Byte); @@ -6004,6 +6420,8 @@ begin if gTriggers[a].TriggerType <> TRIGGER_NONE then SelectObject(OBJECT_TRIGGER, a, True); end; + + RecountSelectedObjects(); end; procedure TMainForm.tbGridOnClick(Sender: TObject); @@ -6014,12 +6432,28 @@ end; procedure TMainForm.OnIdle(Sender: TObject; var Done: Boolean); begin + // FIXME: this is a shitty hack + if not gDataLoaded then + begin + e_WriteLog('Init OpenGL', MSG_NOTIFY); + e_InitGL(); + e_WriteLog('Loading data', MSG_NOTIFY); + LoadStdFont('STDTXT', 'STDFONT', gEditorFont); + e_WriteLog('Loading more data', MSG_NOTIFY); + LoadData(); + e_WriteLog('Loading even more data', MSG_NOTIFY); + gDataLoaded := True; + MainForm.FormResize(nil); + end; Draw(); end; procedure TMainForm.miMapPreviewClick(Sender: TObject); begin - if not PreviewMode then + if PreviewMode = 2 then + Exit; + + if PreviewMode = 0 then begin Splitter2.Visible := False; Splitter1.Visible := False; @@ -6042,8 +6476,10 @@ begin sbVertical.Visible := True; end; - PreviewMode := not PreviewMode; - (Sender as TMenuItem).Checked := PreviewMode; + PreviewMode := PreviewMode xor 1; + (Sender as TMenuItem).Checked := PreviewMode > 0; + + FormResize(Self); end; procedure TMainForm.miLayer1Click(Sender: TObject); @@ -6176,21 +6612,33 @@ end; procedure TMainForm.miTestMapClick(Sender: TObject); var - cmd, mapWAD, mapToRun: String; + cmd, mapWAD, mapToRun, tempWAD: String; opt: LongWord; time: Integer; - lpMsgBuf: PChar; + proc: TProcessUTF8; + res: Boolean; begin + mapToRun := ''; + if OpenedMap <> '' then + begin + // Указываем текущую карту для теста: + g_ProcessResourceStr(OpenedMap, @mapWAD, nil, @mapToRun); + mapToRun := mapWAD + ':\' + mapToRun; + mapToRun := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps/', mapToRun); + end; // Сохраняем временную карту: time := 0; repeat - mapWAD := ExtractFilePath(TestD2dExe) + Format('maps\temp%.4d.wad', [time]); + mapWAD := ExtractFilePath(TestD2dExe) + Format('maps/temp%.4d.wad', [time]); Inc(time); until not FileExists(mapWAD); - mapToRun := mapWAD + ':\' + TEST_MAP_NAME; - SaveMap(mapToRun); + tempWAD := mapWAD + ':\' + TEST_MAP_NAME; + SaveMap(tempWAD); - mapToRun := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps\', mapToRun); + tempWAD := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps/', tempWAD); +// Если карта не была открыта, указываем временную в качестве текущей: + if mapToRun = '' then + mapToRun := tempWAD; // Опции игры: opt := 32 + 64; @@ -6206,7 +6654,8 @@ begin opt := opt + 16; // Составляем командную строку: - cmd := ' -map "' + mapToRun + '"'; + cmd := '-map "' + mapToRun + '"'; + cmd := cmd + ' -testmap "' + tempWAD + '"'; cmd := cmd + ' -gm ' + TestGameMode; cmd := cmd + ' -limt ' + TestLimTime; cmd := cmd + ' -lims ' + TestLimScore; @@ -6216,19 +6665,29 @@ begin cmd := cmd + ' --close'; cmd := cmd + ' --debug'; - cmd := cmd + ' --tempdelete'; // Запускаем: - Application.Minimize(); - if ExecuteProcess(TestD2dExe, cmd) < 0 then + proc := TProcessUTF8.Create(nil); + proc.Executable := TestD2dExe; + proc.Parameters.Add(cmd); + res := True; + try + proc.Execute(); + except + res := False; + end; + if res then + begin + Application.Minimize(); + proc.WaitOnExit(); + end; + if (not res) or (proc.ExitCode < 0) then begin - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, - nil, GetLastError(), LANG_SYSTEM_DEFAULT, - @lpMsgBuf, 0, nil); - MessageBox(0, lpMsgBuf, + MessageBox(0, 'FIXME', PChar(_lc[I_MSG_EXEC_ERROR]), MB_OK or MB_ICONERROR); end; + proc.Free(); SysUtils.DeleteFile(mapWAD); Application.Restore(); @@ -6284,6 +6743,8 @@ begin for a := 0 to High(gTriggers) do if gTriggers[a].TriggerType <> TRIGGER_NONE then SelectObject(OBJECT_TRIGGER, a, True); + + RecountSelectedObjects(); end; procedure TMainForm.Splitter1CanResize(Sender: TObject; @@ -6321,28 +6782,13 @@ begin (Key = Ord('V')) then FillProperty(); end; -end; - -{ -procedure TMainForm.lbTextureListDrawItem(Control: TWinControl; Index: Integer; - Rect: TRect; State: LCLType.TOwnerDrawState); -begin - with Control as TListBox do +// Быстрое превью карты: + if Key = Ord('E') then begin - if LCLType.odSelected in State then - begin - Canvas.Brush.Color := clHighlight; - Canvas.Font.Color := clHighlightText; - end else - if (Items <> nil) and (Index >= 0) then - if slInvalidTextures.IndexOf(Items[Index]) > -1 then - begin - Canvas.Brush.Color := clRed; - Canvas.Font.Color := clWhite; - end; - Canvas.FillRect(Rect); - Canvas.TextRect(Rect, Rect.Left, Rect.Top, Items[Index]); + if PreviewMode = 2 then + PreviewMode := 0; end; + RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y); end; -} + end.