diff --git a/src/editor/f_main.pas b/src/editor/f_main.pas
index 63f31f4a83d7edc3aaa77513e34b171e75e1f2e1..4498ee9efd55146bcab5e8b00205ed86bb668d16 100644 (file)
--- a/src/editor/f_main.pas
+++ b/src/editor/f_main.pas
LCLIntf, LCLType, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Buttons,
ComCtrls, ValEdit, Types, Menus, ExtCtrls,
- CheckLst, Grids, OpenGLContext, utils, UTF8Process;
+ CheckLst, Grids, OpenGLContext, Utils, UTF8Process;
type
miSaveMapAs: TMenuItem;
miOpenWadMap: TMenuItem;
miLine1: TMenuItem;
+ miReopenMap: TMenuItem;
miSaveMiniMap: TMenuItem;
miDeleteMap: TMenuItem;
miPackMap: TMenuItem;
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 OnIdle(Sender: TObject; var Done: Boolean);
public
procedure RefreshRecentMenu();
+ procedure OpenMapFile(FileName: String);
+ function RenderMousePos(): TPoint;
+ procedure RecountSelectedObjects();
end;
const
DotColor: TColor;
DotEnable: Boolean;
- DotStep: Byte;
- DotStepOne, DotStepTwo: Byte;
+ DotStep: Word;
+ DotStepOne, DotStepTwo: Word;
DotSize: Byte;
DrawTexturePanel: Boolean;
DrawPanelSize: Boolean;
BackColor: TColor;
PreviewColor: TColor;
+ UseCheckerboard: Boolean;
Scale: Byte;
RecentCount: Integer;
RecentFiles: TStringList;
TestOptionsAllowExit: Boolean;
TestOptionsWeaponStay: Boolean;
TestOptionsMonstersDM: Boolean;
- TestD2dExe: String;
+ TestD2dExe, TestD2DArgs: String;
TestMapOnce: Boolean;
LayerEnabled: Array [LAYER_BACK..LAYER_TRIGGERS] of Boolean =
(True, True, True, True, True, True, True, True, True);
+ ContourEnabled: Array [LAYER_BACK..LAYER_TRIGGERS] of Boolean =
+ (False, False, False, False, False, False, False, False, False);
PreviewMode: Byte = 0;
gLanguage: String;
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,
- MAPREADER, f_selectmap, f_savemap, WADEDITOR, WADSTRUCT, MAPDEF,
+ f_activationtype, f_keys, wadreader,
+ MAPREADER, f_selectmap, f_savemap, WADEDITOR, MAPDEF,
g_map, f_saveminimap, f_addresource, CONFIG, f_packmap,
f_addresource_sound, f_maptest, f_choosetype,
- g_language, f_selectlang, ClipBrd;
+ g_language, f_selectlang, ClipBrd, g_resources;
const
UNDO_DELETE_PANEL = 1;
SELECTFLAG_SHOTPANEL = 7;
SELECTFLAG_SELECTED = 8;
- RECENT_FILES_MENU_START = 11;
+ RECENT_FILES_MENU_START = 12;
CLIPBOARD_SIG = 'DF:ED';
LastMovePoint: Types.TPoint;
MouseLDown: Boolean;
MouseRDown: Boolean;
+ MouseMDown: Boolean;
MouseLDownPos: Types.TPoint;
MouseRDownPos: Types.TPoint;
- WASDOffset: TPoint;
+ MouseMDownPos: Types.TPoint;
SelectFlag: Byte = SELECTFLAG_NONE;
MouseAction: Byte = MOUSEACTION_NONE;
begin
ScaleSz := 16 div Scale;
// Размер видимой части карты:
- rx := min(Normalize16(Width), Normalize16(gMapInfo.Width)) div 2;
- ry := min(Normalize16(Height), Normalize16(gMapInfo.Height)) div 2;
+ rx := Min(Normalize16(Width), Normalize16(gMapInfo.Width)) div 2;
+ ry := Min(Normalize16(Height), Normalize16(gMapInfo.Height)) div 2;
// Место клика на мини-карте:
- MapOffset.X := X - (Width-max(gMapInfo.Width div ScaleSz, 1)-1);
+ MapOffset.X := X - (Width - Max(gMapInfo.Width div ScaleSz, 1) - 1);
MapOffset.Y := Y - 1;
// Это же место на "большой" карте:
MapOffset.X := MapOffset.X * ScaleSz;
MapOffset.X := MapOffset.X - rx;
MapOffset.Y := MapOffset.Y - ry;
// Выход за границы:
- if MapOffset.X < 0 then
- MapOffset.X := 0;
- if MapOffset.Y < 0 then
- MapOffset.Y := 0;
- if MapOffset.X > MainForm.sbHorizontal.Max then
- MapOffset.X := MainForm.sbHorizontal.Max;
- if MapOffset.Y > MainForm.sbVertical.Max then
- MapOffset.Y := MainForm.sbVertical.Max;
+ MapOffset.X := EnsureRange(MapOffset.X, MainForm.sbHorizontal.Min, MainForm.sbHorizontal.Max);
+ MapOffset.Y := EnsureRange(MapOffset.Y, MainForm.sbVertical.Min, MainForm.sbVertical.Max);
// Кратно 16:
- MapOffset.X := Normalize16(MapOffset.X);
- MapOffset.Y := Normalize16(MapOffset.Y);
+ // MapOffset.X := Normalize16(MapOffset.X);
+ // MapOffset.Y := Normalize16(MapOffset.Y);
end;
MainForm.sbHorizontal.Position := MapOffset.X;
str: String;
begin
MainForm.vleObjectProperty.Strings.Clear();
+ MainForm.RecountSelectedObjects();
// Отображаем свойства если выделен только один объект:
if SelectedObjectCount() <> 1 then
EditStyle := esSimple;
MaxLength := 5;
end;
+ case Data.DamageKind of
+ 3: str := _lc[I_PROP_TR_DAMAGE_KIND_3];
+ 4: str := _lc[I_PROP_TR_DAMAGE_KIND_4];
+ 5: str := _lc[I_PROP_TR_DAMAGE_KIND_5];
+ 6: str := _lc[I_PROP_TR_DAMAGE_KIND_6];
+ 7: str := _lc[I_PROP_TR_DAMAGE_KIND_7];
+ 8: str := _lc[I_PROP_TR_DAMAGE_KIND_8];
+ else str := _lc[I_PROP_TR_DAMAGE_KIND_0];
+ end;
+ with ItemProps[InsertRow(_lc[I_PROP_TR_DAMAGE_KIND], str, True)] do
+ begin
+ EditStyle := esPickList;
+ ReadOnly := True;
+ end;
end;
TRIGGER_HEALTH:
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)-1] do
+ with ItemProps[InsertRow(_lc[I_PROP_TR_SHOT_AIM], str, True)] do
begin
EditStyle := esPickList;
ReadOnly := True;
RemoveSelectFromObjects();
MainForm.miUndo.Enabled := UndoBuffer <> nil;
+ MainForm.RecountSelectedObjects();
end;
procedure Undo_Add(ObjectType: Byte; ID: DWORD; Group: Boolean = False);
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;
procedure TMainForm.aRecentFileExecute(Sender: TObject);
var
- n, pw: Integer;
- s, fn: String;
- b: Boolean;
+ n: Integer;
+ fn, s: String;
begin
s := LowerCase((Sender as TMenuItem).Caption);
Delete(s, Pos('&', s), 1);
s := Trim(Copy(s, 1, 2));
n := StrToIntDef(s, 0) - 1;
-
- if (n < 0) or (n >= RecentFiles.Count) then
- Exit;
-
- 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;
+ if (n >= 0) and (n <= RecentFiles.Count) then
+ begin
+ fn := g_ExtractWadName(RecentFiles[n]);
+ if FileExists(fn) then
+ begin
+ s := g_ExtractFilePathName(RecentFiles[n]);
+ OpenMap(fn, s)
end
- else // Only wad name
- if (FileExists(s)) then
+ else if MessageBox(0, PChar(_lc[I_MSG_DEL_RECENT_PROMT]), PChar(_lc[I_MSG_DEL_RECENT]), MB_ICONQUESTION or MB_YESNO) = idYes 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;
+ RecentFiles.Delete(n);
+ RefreshRecentMenu();
+ end
+ end
end;
procedure TMainForm.aEditorOptionsExecute(Sender: TObject);
cwdt, chgt: Byte;
spc: ShortInt;
ID: DWORD;
- wad: TWADEditor_1;
cfgdata: Pointer;
cfglen: Integer;
config: TConfig;
begin
- cfgdata := nil;
- cfglen := 0;
ID := 0;
-
- wad := TWADEditor_1.Create;
- if wad.ReadFile(EditorDir+'data/Game.wad') then
- wad.GetResource('FONTS', cfgres, cfgdata, cfglen);
- wad.Free();
-
- if cfglen <> 0 then
+ 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
+ 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);
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);
+ e_TextureFontBuild(ID, FontID, cwdt, chgt, spc - 2);
config.Free();
+ FreeMem(cfgdata)
end
else
- e_WriteLog('Could not load FONT_STD', MSG_WARNING);
-
- if cfglen <> 0 then FreeMem(cfgdata);
+ begin
+ e_WriteLog('Could not load FONT_STD', MSG_WARNING)
+ end
end;
procedure TMainForm.FormCreate(Sender: TObject);
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
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
s := config.ReadStr('Editor', 'Language', '');
gLanguage := s;
+ Compress := config.ReadBool('Editor', 'Compress', True);
+ Backup := config.ReadBool('Editor', 'Backup', True);
+
RecentCount := config.ReadInt('Editor', 'RecentCount', 5);
if RecentCount > 10 then
RecentCount := 10;
else
a := 0;
- for x := 0 to (RenderPanel.Width div DotStep) do
- for y := 0 to (RenderPanel.Height div DotStep) do
- e_DrawPoint(DotSize, x*DotStep + a, y*DotStep + a,
+ x := MapOffset.X mod DotStep;
+ y := MapOffset.Y mod DotStep;
+
+ while x < RenderPanel.Width do
+ begin
+ while y < RenderPanel.Height do
+ begin
+ e_DrawPoint(DotSize, x + a, y + a,
GetRValue(DotColor),
GetGValue(DotColor),
GetBValue(DotColor));
+ y += DotStep;
+ end;
+ x += DotStep;
+ y := MapOffset.Y mod DotStep;
+ end;
end;
// Превью текстуры:
if not g_GetTexture(SelectedTexture(), ID) then
g_GetTexture('NOTEXTURE', ID);
g_GetTextureSizeByID(ID, Width, Height);
- 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);
+ 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;
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;
begin
e_SetViewPort(0, 0, RenderPanel.Width, RenderPanel.Height);
- if gMapInfo.Width >= RenderPanel.Width then
- sbHorizontal.Max := Normalize16(gMapInfo.Width-RenderPanel.Width+16)
- else
- sbHorizontal.Max := 0;
-
- if gMapInfo.Height >= RenderPanel.Height then
- sbVertical.Max := Normalize16(gMapInfo.Height-RenderPanel.Height+16)
- else
- sbVertical.Max := 0;
+ sbHorizontal.Min := Min(gMapInfo.Width - RenderPanel.Width, -RenderPanel.Width div 2);
+ sbHorizontal.Max := Max(0, gMapInfo.Width - RenderPanel.Width div 2);
+ sbVertical.Min := Min(gMapInfo.Height - RenderPanel.Height, -RenderPanel.Height div 2);
+ sbVertical.Max := Max(0, gMapInfo.Height - RenderPanel.Height div 2);
- MapOffset.X := -Normalize16(sbHorizontal.Position);
- MapOffset.Y := -Normalize16(sbVertical.Position);
+ MapOffset.X := -sbHorizontal.Position;
+ MapOffset.Y := -sbVertical.Position;
end;
procedure SelectNextObject(X, Y: Integer; ObjectType: Byte; ID: DWORD);
end;
end; // if Button = mbRight
+ if Button = mbMiddle then // Middle Mouse Button
+ begin
+ SetCapture(RenderPanel.Handle);
+ RenderPanel.Cursor := crSize;
+ end;
+
+ MouseMDown := Button = mbMiddle;
+ if MouseMDown then
+ MouseMDownPos := Mouse.CursorPos;
+
MouseRDown := Button = mbRight;
if MouseRDown then
MouseRDownPos := MousePos;
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;
if Button = mbRight then
MouseRDown := False;
+ if Button = mbMiddle then
+ MouseMDown := 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;
MouseAction := MOUSEACTION_NONE;
end;
end // if Button = mbLeft...
- else // Right Mouse Button:
+ else if Button = mbRight then // Right Mouse Button:
begin
if MouseAction = MOUSEACTION_NOACTION then
begin
// Объект передвинут или изменен в размере:
if MouseAction in [MOUSEACTION_MOVEOBJ, MOUSEACTION_RESIZE] then
begin
+ RenderPanel.Cursor := crDefault;
MouseAction := MOUSEACTION_NONE;
FillProperty();
Exit;
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
+
+ else // Middle Mouse Button
+ begin
+ RenderPanel.Cursor := crDefault;
+ ReleaseCapture();
end;
end;
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
end
else
begin // Кнопки мыши не зажаты
- MousePos.X := (Round(X/sX)*sX);
- MousePos.Y := (Round(Y/sY)*sY);
+ MousePos.X := Round((-MapOffset.X + X) / sX) * sX + MapOffset.X;
+ MousePos.Y := Round((-MapOffset.Y + Y) / sY) * sY + MapOffset.Y;
end;
-// Изменение размера закончилось - ставим обычный курсор:
- if ResizeType = RESIZETYPE_NONE then
- RenderPanel.Cursor := crDefault;
-
// Зажата только правая кнопка мыши:
- if (not MouseLDown) and (MouseRDown) then
+ if (not MouseLDown) and (MouseRDown) and (not MouseMDown) then
begin
// Рисуем прямоугольник выделения:
if MouseAction = MOUSEACTION_NONE then
if MouseAction = MOUSEACTION_MOVEOBJ then
begin
MoveSelectedObjects(ssShift in Shift, ssCtrl in Shift,
- MousePos.X-LastMovePoint.X+WASDOffset.X,
- MousePos.Y-LastMovePoint.Y+WASDOffset.Y);
- WASDOffset.X := 0;
- WASDOffset.Y := 0;
+ MousePos.X-LastMovePoint.X,
+ MousePos.Y-LastMovePoint.Y);
end
else
// Меняем размер выделенного объекта:
if (SelectedObjectCount = 1) and
(SelectedObjects[GetFirstSelected].Live) then
begin
- dWidth := MousePos.X-LastMovePoint.X+WASDOffset.X;
- dHeight := MousePos.Y-LastMovePoint.Y+WASDOffset.Y;
- WASDOffset.X := 0;
- WASDOffset.Y := 0;
+ dWidth := MousePos.X-LastMovePoint.X;
+ dHeight := MousePos.Y-LastMovePoint.Y;
case ResizeType of
RESIZETYPE_VERTICAL: dWidth := 0;
RESIZEDIR_LEFT: dWidth := -dWidth;
end;
- ResizeObject(SelectedObjects[GetFirstSelected].ObjectType,
- SelectedObjects[GetFirstSelected].ID,
- dWidth, dHeight, ResizeDirection);
-
- LastMovePoint := MousePos;
+ if ResizeObject(SelectedObjects[GetFirstSelected].ObjectType,
+ SelectedObjects[GetFirstSelected].ID,
+ dWidth, dHeight, ResizeDirection) then
+ LastMovePoint := MousePos;
end;
end;
end;
// Зажата только левая кнопка мыши:
- if (not MouseRDown) and (MouseLDown) then
+ if (not MouseRDown) and (MouseLDown) and (not MouseMDown) then
begin
// Рисуем прямоугольник планирования панели:
if MouseAction in [MOUSEACTION_DRAWPANEL,
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
end;
end;
+// Only Middle Mouse Button is pressed
+ if (not MouseLDown) and (not MouseRDown) and (MouseMDown) then
+ begin
+ MapOffset.X := -EnsureRange(-MapOffset.X + MouseMDownPos.X - Mouse.CursorPos.X,
+ sbHorizontal.Min, sbHorizontal.Max);
+ sbHorizontal.Position := -MapOffset.X;
+ MapOffset.Y := -EnsureRange(-MapOffset.Y + MouseMDownPos.Y - Mouse.CursorPos.Y,
+ sbVertical.Min, sbVertical.Max);
+ sbVertical.Position := -MapOffset.Y;
+ MouseMDownPos := Mouse.CursorPos;
+ end;
+
// Клавиши мыши не зажаты:
if (not MouseRDown) and (not MouseLDown) then
DrawRect := nil;
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
slInvalidTextures.Free;
end;
+procedure TMainForm.FormDropFiles(Sender: TObject;
+ const FileNames: array of String);
+begin
+ if Length(FileNames) <> 1 then
+ Exit;
+
+ OpenMapFile(FileNames[0]);
+end;
+
procedure TMainForm.RenderPanelResize(Sender: TObject);
begin
if MainForm.Visible then
AboutForm.ShowModal();
end;
-procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
- Shift: TShiftState);
+procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
dx, dy, i: Integer;
FileName: String;
+ ok: Boolean;
begin
if (not EditingProperties) then
begin
- if Key = Ord('1') then
- SwitchLayer(LAYER_BACK);
- if Key = Ord('2') then
- SwitchLayer(LAYER_WALLS);
- if Key = Ord('3') then
- SwitchLayer(LAYER_FOREGROUND);
- if Key = Ord('4') then
- SwitchLayer(LAYER_STEPS);
- if Key = Ord('5') then
- SwitchLayer(LAYER_WATER);
- if Key = Ord('6') then
- SwitchLayer(LAYER_ITEMS);
- if Key = Ord('7') then
- SwitchLayer(LAYER_MONSTERS);
- if Key = Ord('8') then
- SwitchLayer(LAYER_AREAS);
- if Key = Ord('9') then
- SwitchLayer(LAYER_TRIGGERS);
- if Key = Ord('0') then
- tbShowClick(tbShow);
+ if ssCtrl in Shift then
+ begin
+ case Chr(Key) of
+ '1': ContourEnabled[LAYER_BACK] := not ContourEnabled[LAYER_BACK];
+ '2': ContourEnabled[LAYER_WALLS] := not ContourEnabled[LAYER_WALLS];
+ '3': ContourEnabled[LAYER_FOREGROUND] := not ContourEnabled[LAYER_FOREGROUND];
+ '4': ContourEnabled[LAYER_STEPS] := not ContourEnabled[LAYER_STEPS];
+ '5': ContourEnabled[LAYER_WATER] := not ContourEnabled[LAYER_WATER];
+ '6': ContourEnabled[LAYER_ITEMS] := not ContourEnabled[LAYER_ITEMS];
+ '7': ContourEnabled[LAYER_MONSTERS] := not ContourEnabled[LAYER_MONSTERS];
+ '8': ContourEnabled[LAYER_AREAS] := not ContourEnabled[LAYER_AREAS];
+ '9': ContourEnabled[LAYER_TRIGGERS] := not ContourEnabled[LAYER_TRIGGERS];
+ '0':
+ begin
+ ok := False;
+ for i := Low(ContourEnabled) to High(ContourEnabled) do
+ if ContourEnabled[i] then
+ ok := True;
+ for i := Low(ContourEnabled) to High(ContourEnabled) do
+ ContourEnabled[i] := not ok
+ end
+ end
+ end
+ else
+ begin
+ case Chr(key) of
+ '1': SwitchLayer(LAYER_BACK);
+ '2': SwitchLayer(LAYER_WALLS);
+ '3': SwitchLayer(LAYER_FOREGROUND);
+ '4': SwitchLayer(LAYER_STEPS);
+ '5': SwitchLayer(LAYER_WATER);
+ '6': SwitchLayer(LAYER_ITEMS);
+ '7': SwitchLayer(LAYER_MONSTERS);
+ '8': SwitchLayer(LAYER_AREAS);
+ '9': SwitchLayer(LAYER_TRIGGERS);
+ '0': tbShowClick(tbShow);
+ end
+ end;
if Key = Ord('V') then
begin // Поворот монстров и областей:
begin
if Key = Ord('W') then
begin
- if (MouseLDown or MouseRDown) and (Position >= DotStep) then
+ dy := Position;
+ if ssShift in Shift then Position := EnsureRange(Position - DotStep * 4, Min, Max)
+ else Position := EnsureRange(Position - DotStep, Min, Max);
+ MapOffset.Y := -Position;
+ dy -= Position;
+
+ if (MouseLDown or MouseRDown) then
begin
- Dec(WASDOffset.Y, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ if DrawRect <> nil then
+ begin
+ Inc(MouseLDownPos.y, dy);
+ Inc(MouseRDownPos.y, dy);
+ end;
+ Inc(LastMovePoint.Y, dy);
+ 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
+ dy := Position;
+ if ssShift in Shift then Position := EnsureRange(Position + DotStep * 4, Min, Max)
+ else Position := EnsureRange(Position + DotStep, Min, Max);
+ MapOffset.Y := -Position;
+ dy -= Position;
+
+ if (MouseLDown or MouseRDown) then
begin
- Inc(WASDOffset.Y, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ if DrawRect <> nil then
+ begin
+ Inc(MouseLDownPos.y, dy);
+ Inc(MouseRDownPos.y, dy);
+ end;
+ Inc(LastMovePoint.Y, dy);
+ RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y);
end;
- Position := IfThen(Position+DotStep < Max, Position+DotStep, Max);
- MapOffset.Y := -Round(Position/16) * 16;
end;
end;
begin
if Key = Ord('A') then
begin
- if (MouseLDown or MouseRDown) and (Position >= DotStep) then
+ dx := Position;
+ if ssShift in Shift then Position := EnsureRange(Position - DotStep * 4, Min, Max)
+ else Position := EnsureRange(Position - DotStep, Min, Max);
+ MapOffset.X := -Position;
+ dx -= Position;
+
+ if (MouseLDown or MouseRDown) then
begin
- Dec(WASDOffset.X, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ if DrawRect <> nil then
+ begin
+ Inc(MouseLDownPos.x, dx);
+ Inc(MouseRDownPos.x, dx);
+ end;
+ Inc(LastMovePoint.X, dx);
+ 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
+ dx := Position;
+ if ssShift in Shift then Position := EnsureRange(Position + DotStep * 4, Min, Max)
+ else Position := EnsureRange(Position + DotStep, Min, Max);
+ MapOffset.X := -Position;
+ dx -= Position;
+
+ if (MouseLDown or MouseRDown) then
begin
- Inc(WASDOffset.X, DotStep);
- RenderPanelMouseMove(Sender, Shift, LastMovePoint.X, LastMovePoint.Y);
+ if DrawRect <> nil then
+ begin
+ Inc(MouseLDownPos.x, dx);
+ Inc(MouseRDownPos.x, dx);
+ end;
+ Inc(LastMovePoint.X, dx);
+ 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
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_TR_DAMAGE_KIND] then
+ begin
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_0]);
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_3]);
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_4]);
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_5]);
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_6]);
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_7]);
+ Values.Add(_lc[I_PROP_TR_DAMAGE_KIND_8]);
+ end
else if (KeyName = _lc[I_PROP_PANEL_BLEND]) or
(KeyName = _lc[I_PROP_DM_ONLY]) or
(KeyName = _lc[I_PROP_ITEM_FALLS]) or
StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_DAMAGE_VALUE]], 0), 0), 65535);
Data.DamageInterval := Min(Max(
StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_INTERVAL]], 0), 0), 65535);
+ s := vleObjectProperty.Values[_lc[I_PROP_TR_DAMAGE_KIND]];
+ if s = _lc[I_PROP_TR_DAMAGE_KIND_3] then
+ Data.DamageKind := 3
+ else if s = _lc[I_PROP_TR_DAMAGE_KIND_4] then
+ Data.DamageKind := 4
+ else if s = _lc[I_PROP_TR_DAMAGE_KIND_5] then
+ Data.DamageKind := 5
+ else if s = _lc[I_PROP_TR_DAMAGE_KIND_6] then
+ Data.DamageKind := 6
+ else if s = _lc[I_PROP_TR_DAMAGE_KIND_7] then
+ Data.DamageKind := 7
+ else if s = _lc[I_PROP_TR_DAMAGE_KIND_8] then
+ Data.DamageKind := 8
+ else
+ Data.DamageKind := 0;
end;
TRIGGER_HEALTH:
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 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);
procedure TMainForm.aDeleteMap(Sender: TObject);
var
- WAD: TWADEditor_1;
- MapList: SArray;
- MapName: Char16;
- a: Integer;
- str: String;
+ res: Integer;
+ FileName: String;
+ MapName: String;
begin
OpenDialog.Filter := _lc[I_FILE_FILTER_WAD];
if not OpenDialog.Execute() then
Exit;
- WAD := TWADEditor_1.Create();
-
- if not WAD.ReadFile(OpenDialog.FileName) then
- begin
- WAD.Free();
- Exit;
- end;
-
- WAD.CreateImage();
-
- MapList := WAD.GetResourcesList('');
-
+ FileName := OpenDialog.FileName;
SelectMapForm.Caption := _lc[I_CAP_REMOVE];
SelectMapForm.lbMapList.Items.Clear();
+ SelectMapForm.GetMaps(FileName);
- if MapList <> nil then
- for a := 0 to High(MapList) do
- SelectMapForm.lbMapList.Items.Add(win2utf(MapList[a]));
+ if SelectMapForm.ShowModal() <> mrOK then
+ Exit;
- if (SelectMapForm.ShowModal() = mrOK) then
- begin
- str := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex];
- MapName := '';
- 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_DEFBUTTON2) <> mrYes then
- Exit;
+ MapName := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex];
+ 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_DEFBUTTON2) <> mrYes then
+ Exit;
- 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_DEFBUTTON1);
+ g_DeleteResource(FileName, '', MapName, res);
+ if res <> 0 then
+ begin
+ MessageBox(0, PChar('Cant delete map res=' + IntToStr(res)), PChar('Map not deleted!'), MB_ICONINFORMATION or MB_OK or MB_DEFBUTTON1);
+ Exit
+ end;
- WAD.SaveTo(OpenDialog.FileName);
+ MessageBox(
+ 0,
+ PChar(Format(_lc[I_MSG_MAP_DELETED_PROMT], [MapName])),
+ PChar(_lc[I_MSG_MAP_DELETED]),
+ MB_ICONINFORMATION or MB_OK or MB_DEFBUTTON1
+ );
// Удалили текущую карту - сохранять по старому ее нельзя:
- if OpenedMap = (OpenDialog.FileName+':\'+MapName) then
- begin
- OpenedMap := '';
- OpenedWAD := '';
- MainForm.Caption := FormCaption;
- end;
- end;
-
- WAD.Free();
+ if OpenedMap = (FileName + ':\' + MapName) then
+ begin
+ OpenedMap := '';
+ OpenedWAD := '';
+ MainForm.Caption := FormCaption
+ end
end;
procedure TMainForm.vleObjectPropertyKeyDown(Sender: TObject;
if gTriggers[a].TriggerType <> TRIGGER_NONE then
SelectObject(OBJECT_TRIGGER, a, True);
end;
+
+ RecountSelectedObjects();
end;
procedure TMainForm.tbGridOnClick(Sender: TObject);
MapTestForm.ShowModal();
end;
+type SSArray = array of String;
+
+function ParseString (Str: AnsiString): SSArray;
+ function GetStr (var Str: AnsiString): AnsiString;
+ var a, b: Integer;
+ begin
+ Result := '';
+ if Str[1] = '"' then
+ for b := 1 to Length(Str) do
+ if (b = Length(Str)) or (Str[b + 1] = '"') then
+ begin
+ Result := Copy(Str, 2, b - 1);
+ Delete(Str, 1, b + 1);
+ Str := Trim(Str);
+ Exit;
+ end;
+ for a := 1 to Length(Str) do
+ if (a = Length(Str)) or (Str[a + 1] = ' ') then
+ begin
+ Result := Copy(Str, 1, a);
+ Delete(Str, 1, a + 1);
+ Str := Trim(Str);
+ Exit;
+ end;
+ end;
+begin
+ Result := nil;
+ Str := Trim(Str);
+ while Str <> '' do
+ begin
+ SetLength(Result, Length(Result)+1);
+ Result[High(Result)] := GetStr(Str);
+ end;
+end;
+
procedure TMainForm.miTestMapClick(Sender: TObject);
var
- cmd, mapWAD, mapToRun, tempWAD: String;
+ mapWAD, tempWAD: String;
+ args: SSArray;
opt: LongWord;
- time: Integer;
+ time, i: Integer;
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
until not FileExists(mapWAD);
tempWAD := mapWAD + ':\' + TEST_MAP_NAME;
SaveMap(tempWAD);
-
tempWAD := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps/', tempWAD);
-// Если карта не была открыта, указываем временную в качестве текущей:
- if mapToRun = '' then
- mapToRun := tempWAD;
// Опции игры:
opt := 32 + 64;
if TestOptionsMonstersDM then
opt := opt + 16;
-// Составляем командную строку:
- cmd := '-map "' + mapToRun + '"';
- cmd := cmd + ' -testmap "' + tempWAD + '"';
- cmd := cmd + ' -gm ' + TestGameMode;
- cmd := cmd + ' -limt ' + TestLimTime;
- cmd := cmd + ' -lims ' + TestLimScore;
- cmd := cmd + ' -opt ' + IntToStr(opt);
-
- if TestMapOnce then
- cmd := cmd + ' --close';
-
- cmd := cmd + ' --debug';
-
// Запускаем:
proc := TProcessUTF8.Create(nil);
proc.Executable := TestD2dExe;
- proc.Parameters.Add(cmd);
+ proc.Parameters.Add('-map');
+ proc.Parameters.Add(tempWAD);
+ proc.Parameters.Add('-testmap');
+ proc.Parameters.Add(tempWAD);
+ proc.Parameters.Add('-gm');
+ proc.Parameters.Add(TestGameMode);
+ proc.Parameters.Add('-limt');
+ proc.Parameters.Add(TestLimTime);
+ proc.Parameters.Add('-lims');
+ proc.Parameters.Add(TestLimScore);
+ proc.Parameters.Add('-opt');
+ proc.Parameters.Add(IntToStr(opt));
+ proc.Parameters.Add('--debug');
+ if TestMapOnce then
+ proc.Parameters.Add('--close');
+
+ args := ParseString(TestD2DArgs);
+ for i := 0 to High(args) do
+ proc.Parameters.Add(args[i]);
+
res := True;
try
proc.Execute();
procedure TMainForm.sbVerticalScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
- MapOffset.Y := -Normalize16(sbVertical.Position);
+ MapOffset.Y := -sbVertical.Position;
end;
procedure TMainForm.sbHorizontalScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
- MapOffset.X := -Normalize16(sbHorizontal.Position);
+ MapOffset.X := -sbHorizontal.Position;
end;
procedure TMainForm.miOpenWadMapClick(Sender: TObject);
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;
EditingProperties := False;
end;
-procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
+procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
// Объекты передвигались:
if MainForm.ActiveControl = RenderPanel then
if PreviewMode = 2 then
PreviewMode := 0;
end;
+ RenderPanelMouseMove(Sender, Shift, RenderMousePos().X, RenderMousePos().Y);
end;
end.