diff --git a/src/editor/f_main.pas b/src/editor/f_main.pas
index 070939d11262449427ddd618720d851addd242b1..d217b30d0864c21869dcc3981be725bf741ed740 100644 (file)
--- a/src/editor/f_main.pas
+++ b/src/editor/f_main.pas
miSaveMapAs: TMenuItem;
miOpenWadMap: TMenuItem;
miLine1: TMenuItem;
+ miReopenMap: TMenuItem;
miSaveMiniMap: TMenuItem;
miDeleteMap: TMenuItem;
miPackMap: TMenuItem;
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);
public
procedure RefreshRecentMenu();
procedure OpenMapFile(FileName: String);
+ function RenderMousePos(): TPoint;
end;
const
SELECTFLAG_SHOTPANEL = 7;
SELECTFLAG_SELECTED = 8;
- RECENT_FILES_MENU_START = 11;
+ RECENT_FILES_MENU_START = 12;
CLIPBOARD_SIG = 'DF:ED';
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);
begin // Аним. текстура
GetFrame(FullResourceName, Data, FrameLen, Width, Height);
- if g_CreateTextureMemorySize(Data, FrameLen, 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;
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;
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();
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;
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
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
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);
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;
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
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;
// Прямоугольник выделения:
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);
begin // Чертим новый
PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH],
[Abs(MousePos.X-MouseLDownPos.X)]), gEditorFont);
- PrintBlack(MousePos.X+2, MousePos.Y+14, Format(_glc[I_HINT_HEIGHT],
+ PrintBlack(MousePos.X+2, MousePos.Y+16, Format(_glc[I_HINT_HEIGHT],
[Abs(MousePos.Y-MouseLDownPos.Y)]), gEditorFont);
end
else // Растягиваем существующий
PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH], [Width]),
gEditorFont);
- PrintBlack(MousePos.X+2, MousePos.Y+14, Format(_glc[I_HINT_HEIGHT], [Height]),
+ PrintBlack(MousePos.X+2, MousePos.Y+16, Format(_glc[I_HINT_HEIGHT], [Height]),
gEditorFont);
end;
end;
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;
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:
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
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;
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;
Draw();
end;
+function TMainForm.RenderMousePos(): Types.TPoint;
+begin
+ Result := RenderPanel.ScreenToClient(Mouse.CursorPos);
+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
begin
if DrawRect = nil then
New(DrawRect);
- DrawRect.Top := MouseLDownPos.y;
- DrawRect.Left := MouseLDownPos.x;
- DrawRect.Bottom := MousePos.y;
- DrawRect.Right := MousePos.x;
+ 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
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
if (MouseLDown or MouseRDown) and (Position >= DotStep) then
begin
Dec(WASDOffset.Y, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y);
end;
Position := IfThen(Position > DotStep, Position-DotStep, 0);
MapOffset.Y := -Round(Position/16) * 16;
if (MouseLDown or MouseRDown) and (Position+DotStep <= Max) then
begin
Inc(WASDOffset.Y, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y);
end;
Position := IfThen(Position+DotStep < Max, Position+DotStep, Max);
MapOffset.Y := -Round(Position/16) * 16;
if (MouseLDown or MouseRDown) and (Position >= DotStep) then
begin
Dec(WASDOffset.X, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y);
end;
Position := IfThen(Position > DotStep, Position-DotStep, 0);
MapOffset.X := -Round(Position/16) * 16;
if (MouseLDown or MouseRDown) and (Position+DotStep <= Max) then
begin
Inc(WASDOffset.X, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ 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;
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
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;
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;
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
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);
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);
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);
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);
if PreviewMode = 2 then
PreviewMode := 0;
end;
+ RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y);
end;
end.