3 {$INCLUDE ../shared/a_modes.inc}
8 LCLIntf
, LCLType
, SysUtils
, Variants
, Classes
, Graphics
,
9 Controls
, Forms
, Dialogs
, StdCtrls
, Buttons
,
10 ComCtrls
, ValEdit
, Types
, Menus
, ExtCtrls
,
11 CheckLst
, Grids
, OpenGLContext
, Utils
, UTF8Process
;
17 TMainForm
= class(TForm
)
23 miAppleAbout
: TMenuItem
;
24 miAppleLine0
: TMenuItem
;
25 miApplePref
: TMenuItem
;
26 miAppleLine1
: TMenuItem
;
28 miMenuFile
: TMenuItem
;
32 miSaveMapAs
: TMenuItem
;
33 miMacRecentSubMenu
: TMenuItem
;
34 miMacRecentClear
: TMenuItem
;
35 miOpenWadMap
: TMenuItem
;
37 miReopenMap
: TMenuItem
;
38 miSaveMiniMap
: TMenuItem
;
39 miDeleteMap
: TMenuItem
;
41 miWinRecent
: TMenuItem
;
45 miMenuEdit
: TMenuItem
;
52 miSelectAll
: TMenuItem
;
57 miMenuView
: TMenuItem
;
58 miShowEdges
: TMenuItem
;
69 miViewLine1
: TMenuItem
;
71 miViewLine2
: TMenuItem
;
72 miMapPreview
: TMenuItem
;
73 miSnapToGrid
: TMenuItem
;
74 miSwitchGrid
: TMenuItem
;
77 miMapOptions
: TMenuItem
;
79 miMenuService
: TMenuItem
;
80 miCheckMap
: TMenuItem
;
81 miOptimmization
: TMenuItem
;
84 miMenuWindow
: TMenuItem
;
85 miMacMinimize
: TMenuItem
;
88 miMenuHelp
: TMenuItem
;
90 // Скрытый пункт меню для Ctrl+Tab:
91 miMenuHidden
: TMenuItem
;
94 // Панель инструментов:
95 MainToolBar
: TToolBar
;
97 pLoadProgress
: TPanel
;
98 RenderPanel
: TOpenGLControl
;
99 Separator1
: TMenuItem
;
100 miMacRecentEnd
: TMenuItem
;
101 miWinRecentStart
: TMenuItem
;
102 Separator2
: TMenuItem
;
103 tbNewMap
: TToolButton
;
104 tbOpenMap
: TToolButton
;
105 tbSaveMap
: TToolButton
;
106 tbOpenWadMap
: TToolButton
;
107 tbLine1
: TToolButton
;
108 tbShowMap
: TToolButton
;
109 tbLine2
: TToolButton
;
111 tbLine3
: TToolButton
;
112 tbGridOn
: TToolButton
;
114 tbLine4
: TToolButton
;
115 tbTestMap
: TToolButton
;
116 // Всплывающее меню для кнопки слоев:
118 miLayerP1
: TMenuItem
;
119 miLayerP2
: TMenuItem
;
120 miLayerP3
: TMenuItem
;
121 miLayerP4
: TMenuItem
;
122 miLayerP5
: TMenuItem
;
123 miLayerP6
: TMenuItem
;
124 miLayerP7
: TMenuItem
;
125 miLayerP8
: TMenuItem
;
126 miLayerP9
: TMenuItem
;
131 sbHorizontal
: TScrollBar
;
132 sbVertical
: TScrollBar
;
136 // Панель применения свойств:
137 PanelPropApply
: TPanel
;
138 bApplyProperty
: TButton
;
139 MapTestTimer
: TTimer
;
140 // Редактор свойств объектов:
141 vleObjectProperty
: TValueListEditor
;
143 // Панель объектов - вкладки:
145 pcObjects
: TPageControl
;
148 lbTextureList
: TListBox
;
149 // Панель настройки текстур:
150 PanelTextures
: TPanel
;
152 lTextureWidth
: TLabel
;
154 lTextureHeight
: TLabel
;
155 cbPreview
: TCheckBox
;
156 bbAddTexture
: TBitBtn
;
157 bbRemoveTexture
: TBitBtn
;
158 bClearTexture
: TButton
;
159 // Панель типов панелей:
160 PanelPanelType
: TPanel
;
161 lbPanelType
: TListBox
;
162 // Вкладка "Предметы":
164 lbItemList
: TListBox
;
167 // Вкладка "Монстры":
168 tsMonsters
: TTabSheet
;
169 lbMonsterList
: TListBox
;
170 rbMonsterLeft
: TRadioButton
;
171 rbMonsterRight
: TRadioButton
;
172 // Вкладка "Области":
174 lbAreasList
: TListBox
;
175 rbAreaLeft
: TRadioButton
;
176 rbAreaRight
: TRadioButton
;
177 // Вкладка "Триггеры":
178 tsTriggers
: TTabSheet
;
179 lbTriggersList
: TListBox
;
180 clbActivationType
: TCheckListBox
;
181 clbKeys
: TCheckListBox
;
184 Splitter1
: TSplitter
;
185 Splitter2
: TSplitter
;
186 StatusBar
: TStatusBar
;
188 // Специальные объекты:
189 ImageList
: TImageList
;
190 ilToolbar
: TImageList
;
191 OpenDialog
: TOpenDialog
;
192 SaveDialog
: TSaveDialog
;
193 selectall1
: TMenuItem
;
194 ColorDialog
: TColorDialog
;
196 procedure aAboutExecute(Sender
: TObject
);
197 procedure aCheckMapExecute(Sender
: TObject
);
198 procedure aMoveToFore(Sender
: TObject
);
199 procedure aMoveToBack(Sender
: TObject
);
200 procedure aCopyObjectExecute(Sender
: TObject
);
201 procedure aCutObjectExecute(Sender
: TObject
);
202 procedure aEditorOptionsExecute(Sender
: TObject
);
203 procedure aExitExecute(Sender
: TObject
);
204 procedure aMapOptionsExecute(Sender
: TObject
);
205 procedure aNewMapExecute(Sender
: TObject
);
206 procedure aOpenMapExecute(Sender
: TObject
);
207 procedure aOptimizeExecute(Sender
: TObject
);
208 procedure aPasteObjectExecute(Sender
: TObject
);
209 procedure aSelectAllExecute(Sender
: TObject
);
210 procedure aSaveMapExecute(Sender
: TObject
);
211 procedure aSaveMapAsExecute(Sender
: TObject
);
212 procedure aUndoExecute(Sender
: TObject
);
213 procedure aDeleteMap(Sender
: TObject
);
214 procedure bApplyPropertyClick(Sender
: TObject
);
215 procedure bbAddTextureClick(Sender
: TObject
);
216 procedure bbRemoveTextureClick(Sender
: TObject
);
217 procedure FormActivate(Sender
: TObject
);
218 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
219 procedure FormCreate(Sender
: TObject
);
220 procedure FormDestroy(Sender
: TObject
);
221 procedure FormDropFiles(Sender
: TObject
; const FileNames
: array of String);
222 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
223 procedure FormResize(Sender
: TObject
);
224 procedure FormWindowStateChange(Sender
: TObject
);
225 procedure miMacRecentClearClick(Sender
: TObject
);
226 procedure miMacZoomClick(Sender
: TObject
);
227 procedure lbTextureListClick(Sender
: TObject
);
228 procedure lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
229 ARect
: TRect
; State
: TOwnerDrawState
);
230 procedure miMacMinimizeClick(Sender
: TObject
);
231 procedure miReopenMapClick(Sender
: TObject
);
232 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
233 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
234 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
235 procedure RenderPanelPaint(Sender
: TObject
);
236 procedure RenderPanelResize(Sender
: TObject
);
237 procedure Splitter1Moved(Sender
: TObject
);
238 procedure MapTestCheck(Sender
: TObject
);
239 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
240 procedure vleObjectPropertyApply(Sender
: TObject
);
241 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
242 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
244 procedure tbGridOnClick(Sender
: TObject
);
245 procedure miMapPreviewClick(Sender
: TObject
);
246 procedure miLayer1Click(Sender
: TObject
);
247 procedure miLayer2Click(Sender
: TObject
);
248 procedure miLayer3Click(Sender
: TObject
);
249 procedure miLayer4Click(Sender
: TObject
);
250 procedure miLayer5Click(Sender
: TObject
);
251 procedure miLayer6Click(Sender
: TObject
);
252 procedure miLayer7Click(Sender
: TObject
);
253 procedure miLayer8Click(Sender
: TObject
);
254 procedure miLayer9Click(Sender
: TObject
);
255 procedure tbShowClick(Sender
: TObject
);
256 procedure miSnapToGridClick(Sender
: TObject
);
257 procedure miMiniMapClick(Sender
: TObject
);
258 procedure miSwitchGridClick(Sender
: TObject
);
259 procedure miShowEdgesClick(Sender
: TObject
);
260 procedure minexttabClick(Sender
: TObject
);
261 procedure miSaveMiniMapClick(Sender
: TObject
);
262 procedure bClearTextureClick(Sender
: TObject
);
263 procedure miPackMapClick(Sender
: TObject
);
264 procedure miTestMapClick(Sender
: TObject
);
265 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
266 var ScrollPos
: Integer);
267 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
268 var ScrollPos
: Integer);
269 procedure miOpenWadMapClick(Sender
: TObject
);
270 procedure selectall1Click(Sender
: TObject
);
271 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
272 var Accept
: Boolean);
273 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
274 var Accept
: Boolean);
275 procedure vleObjectPropertyEnter(Sender
: TObject
);
276 procedure vleObjectPropertyExit(Sender
: TObject
);
277 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
281 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
282 procedure RefillRecentMenu (menu
: TMenuItem
; start
: Integer; fmt
: AnsiString);
284 procedure RefreshRecentMenu();
285 procedure OpenMapFile(FileName
: String);
286 function RenderMousePos(): TPoint
;
287 procedure RecountSelectedObjects();
293 LAYER_FOREGROUND
= 2;
301 TEST_MAP_NAME
= '$$$_TEST_$$$';
302 LANGUAGE_FILE_NAME
= '_Editor.txt';
313 DotStepOne
, DotStepTwo
: Word;
315 DrawTexturePanel
: Boolean;
316 DrawPanelSize
: Boolean;
318 PreviewColor
: TColor
;
319 UseCheckerboard
: Boolean;
321 RecentCount
: Integer;
322 RecentFiles
: TStringList
;
323 slInvalidTextures
: TStringList
;
325 TestGameMode
: String;
327 TestLimScore
: String;
328 TestOptionsTwoPlayers
: Boolean;
329 TestOptionsTeamDamage
: Boolean;
330 TestOptionsAllowExit
: Boolean;
331 TestOptionsWeaponStay
: Boolean;
332 TestOptionsMonstersDM
: Boolean;
333 TestD2dExe
, TestD2DArgs
: String;
334 TestMapOnce
: Boolean;
336 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
337 (True, True, True, True, True, True, True, True, True);
338 ContourEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
339 (False, False, False, False, False, False, False, False, False);
340 PreviewMode
: Byte = 0;
346 procedure OpenMap(FileName
: String; mapN
: String);
347 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
348 procedure RemoveSelectFromObjects();
349 procedure ChangeShownProperty(Name
: String; NewValue
: String);
354 f_options
, e_graphics
, e_log
, GL
, Math
,
355 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
356 f_mapcheck
, f_addresource_texture
, g_textures
,
357 f_activationtype
, f_keys
, wadreader
, fileutil
,
358 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, MAPDEF
,
359 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
360 f_addresource_sound
, f_choosetype
,
361 g_language
, f_selectlang
, ClipBrd
, g_resources
, g_options
;
364 UNDO_DELETE_PANEL
= 1;
365 UNDO_DELETE_ITEM
= 2;
366 UNDO_DELETE_AREA
= 3;
367 UNDO_DELETE_MONSTER
= 4;
368 UNDO_DELETE_TRIGGER
= 5;
372 UNDO_ADD_MONSTER
= 9;
373 UNDO_ADD_TRIGGER
= 10;
374 UNDO_MOVE_PANEL
= 11;
377 UNDO_MOVE_MONSTER
= 14;
378 UNDO_MOVE_TRIGGER
= 15;
379 UNDO_RESIZE_PANEL
= 16;
380 UNDO_RESIZE_TRIGGER
= 17;
382 MOUSEACTION_NONE
= 0;
383 MOUSEACTION_DRAWPANEL
= 1;
384 MOUSEACTION_DRAWTRIGGER
= 2;
385 MOUSEACTION_MOVEOBJ
= 3;
386 MOUSEACTION_RESIZE
= 4;
387 MOUSEACTION_MOVEMAP
= 5;
388 MOUSEACTION_DRAWPRESS
= 6;
389 MOUSEACTION_NOACTION
= 7;
392 RESIZETYPE_VERTICAL
= 1;
393 RESIZETYPE_HORIZONTAL
= 2;
402 SELECTFLAG_TELEPORT
= 1;
404 SELECTFLAG_TEXTURE
= 3;
406 SELECTFLAG_MONSTER
= 5;
407 SELECTFLAG_SPAWNPOINT
= 6;
408 SELECTFLAG_SHOTPANEL
= 7;
409 SELECTFLAG_SELECTED
= 8;
411 RECENT_FILES_MENU_START
= 12;
413 CLIPBOARD_SIG
= 'DF:ED';
419 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
420 UNDO_DELETE_ITEM
: (Item
: TItem
);
421 UNDO_DELETE_AREA
: (Area
: TArea
);
422 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
423 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
428 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
433 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
435 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
442 OBJECT_PANEL
: (Panel
: ^TPanel
);
443 OBJECT_ITEM
: (Item
: TItem
);
444 OBJECT_AREA
: (Area
: TArea
);
445 OBJECT_MONSTER
: (Monster
: TMonster
);
446 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
449 TCopyRecArray
= Array of TCopyRec
;
453 gDataLoaded
: Boolean = False;
454 ShowMap
: Boolean = False;
455 DrawRect
: PRect
= nil;
456 SnapToGrid
: Boolean = True;
458 MousePos
: Types
.TPoint
;
459 LastMovePoint
: Types
.TPoint
;
463 MouseLDownPos
: Types
.TPoint
;
464 MouseRDownPos
: Types
.TPoint
;
465 MouseMDownPos
: Types
.TPoint
;
467 SelectFlag
: Byte = SELECTFLAG_NONE
;
468 MouseAction
: Byte = MOUSEACTION_NONE
;
469 ResizeType
: Byte = RESIZETYPE_NONE
;
470 ResizeDirection
: Byte = RESIZEDIR_NONE
;
472 DrawPressRect
: Boolean = False;
473 EditingProperties
: Boolean = False;
475 UndoBuffer
: Array of Array of TUndoRec
= nil;
477 MapTestProcess
: TProcessUTF8
;
482 //----------------------------------------
483 //Далее идут вспомогательные процедуры
484 //----------------------------------------
486 function NameToBool(Name
: String): Boolean;
488 if Name
= BoolNames
[True] then
494 function NameToDir(Name
: String): TDirection
;
496 if Name
= DirNames
[D_LEFT
] then
502 function NameToDirAdv(Name
: String): Byte;
504 if Name
= DirNamesAdv
[1] then
507 if Name
= DirNamesAdv
[2] then
510 if Name
= DirNamesAdv
[3] then
516 function ActivateToStr(ActivateType
: Byte): String;
520 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
521 Result
:= Result
+ '+PC';
522 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
523 Result
:= Result
+ '+MC';
524 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
525 Result
:= Result
+ '+PP';
526 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
527 Result
:= Result
+ '+MP';
528 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
529 Result
:= Result
+ '+SH';
530 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
531 Result
:= Result
+ '+NM';
533 if (Result
<> '') and (Result
[1] = '+') then
534 Delete(Result
, 1, 1);
537 function StrToActivate(Str
: String): Byte;
541 if Pos('PC', Str
) > 0 then
542 Result
:= ACTIVATE_PLAYERCOLLIDE
;
543 if Pos('MC', Str
) > 0 then
544 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
545 if Pos('PP', Str
) > 0 then
546 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
547 if Pos('MP', Str
) > 0 then
548 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
549 if Pos('SH', Str
) > 0 then
550 Result
:= Result
or ACTIVATE_SHOT
;
551 if Pos('NM', Str
) > 0 then
552 Result
:= Result
or ACTIVATE_NOMONSTER
;
555 function KeyToStr(Key
: Byte): String;
559 if ByteBool(KEY_RED
and Key
) then
560 Result
:= Result
+ '+RK';
561 if ByteBool(KEY_GREEN
and Key
) then
562 Result
:= Result
+ '+GK';
563 if ByteBool(KEY_BLUE
and Key
) then
564 Result
:= Result
+ '+BK';
565 if ByteBool(KEY_REDTEAM
and Key
) then
566 Result
:= Result
+ '+RT';
567 if ByteBool(KEY_BLUETEAM
and Key
) then
568 Result
:= Result
+ '+BT';
570 if (Result
<> '') and (Result
[1] = '+') then
571 Delete(Result
, 1, 1);
574 function StrToKey(Str
: String): Byte;
578 if Pos('RK', Str
) > 0 then
580 if Pos('GK', Str
) > 0 then
581 Result
:= Result
or KEY_GREEN
;
582 if Pos('BK', Str
) > 0 then
583 Result
:= Result
or KEY_BLUE
;
584 if Pos('RT', Str
) > 0 then
585 Result
:= Result
or KEY_REDTEAM
;
586 if Pos('BT', Str
) > 0 then
587 Result
:= Result
or KEY_BLUETEAM
;
590 function EffectToStr(Effect
: Byte): String;
592 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
593 Result
:= EffectNames
[Effect
]
595 Result
:= EffectNames
[EFFECT_NONE
];
598 function StrToEffect(Str
: String): Byte;
602 Result
:= EFFECT_NONE
;
603 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
604 if EffectNames
[i
] = Str
then
611 function MonsterToStr(MonType
: Byte): String;
613 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
614 Result
:= MonsterNames
[MonType
]
616 Result
:= MonsterNames
[MONSTER_ZOMBY
];
619 function StrToMonster(Str
: String): Byte;
623 Result
:= MONSTER_ZOMBY
;
624 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
625 if MonsterNames
[i
] = Str
then
632 function ItemToStr(ItemType
: Byte): String;
634 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
635 Result
:= ItemNames
[ItemType
]
637 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
640 function StrToItem(Str
: String): Byte;
644 Result
:= ITEM_AMMO_BULLETS
;
645 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
646 if ItemNames
[i
] = Str
then
653 function ShotToStr(ShotType
: Byte): String;
655 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
656 Result
:= ShotNames
[ShotType
]
658 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
661 function StrToShot(Str
: String): Byte;
665 Result
:= TRIGGER_SHOT_PISTOL
;
666 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
667 if ShotNames
[i
] = Str
then
674 function SelectedObjectCount(): Word;
680 if SelectedObjects
= nil then
683 for a
:= 0 to High(SelectedObjects
) do
684 if SelectedObjects
[a
].Live
then
685 Result
:= Result
+ 1;
688 function GetFirstSelected(): Integer;
694 if SelectedObjects
= nil then
697 for a
:= 0 to High(SelectedObjects
) do
698 if SelectedObjects
[a
].Live
then
705 function Normalize16(x
: Integer): Integer;
707 Result
:= (x
div 16) * 16;
710 procedure MoveMap(X
, Y
: Integer);
712 rx
, ry
, ScaleSz
: Integer;
714 with MainForm
.RenderPanel
do
716 ScaleSz
:= 16 div Scale
;
717 // Размер видимой части карты:
718 rx
:= Min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
719 ry
:= Min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
720 // Место клика на мини-карте:
721 MapOffset
.X
:= X
- (Width
- Max(gMapInfo
.Width
div ScaleSz
, 1) - 1);
722 MapOffset
.Y
:= Y
- 1;
723 // Это же место на "большой" карте:
724 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
725 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
726 // Левый верхний угол новой видимой части карты:
727 MapOffset
.X
:= MapOffset
.X
- rx
;
728 MapOffset
.Y
:= MapOffset
.Y
- ry
;
730 MapOffset
.X
:= EnsureRange(MapOffset
.X
, MainForm
.sbHorizontal
.Min
, MainForm
.sbHorizontal
.Max
);
731 MapOffset
.Y
:= EnsureRange(MapOffset
.Y
, MainForm
.sbVertical
.Min
, MainForm
.sbVertical
.Max
);
733 // MapOffset.X := Normalize16(MapOffset.X);
734 // MapOffset.Y := Normalize16(MapOffset.Y);
737 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
738 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
740 MapOffset
.X
:= -MapOffset
.X
;
741 MapOffset
.Y
:= -MapOffset
.Y
;
746 function IsTexturedPanel(PanelType
: Word): Boolean;
748 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
749 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
750 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
753 procedure FillProperty();
758 MainForm
.vleObjectProperty
.Strings
.Clear();
759 MainForm
.RecountSelectedObjects();
761 // Отображаем свойства если выделен только один объект:
762 if SelectedObjectCount() <> 1 then
765 _id
:= GetFirstSelected();
766 if not SelectedObjects
[_id
].Live
then
769 with MainForm
.vleObjectProperty
do
770 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
772 EditStyle
:= esSimple
;
776 case SelectedObjects
[0].ObjectType
of
779 with MainForm
.vleObjectProperty
,
780 gPanels
[SelectedObjects
[_id
].ID
] do
782 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
784 EditStyle
:= esSimple
;
788 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
790 EditStyle
:= esSimple
;
794 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
796 EditStyle
:= esSimple
;
800 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
802 EditStyle
:= esSimple
;
806 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
808 EditStyle
:= esEllipsis
;
812 if IsTexturedPanel(PanelType
) then
813 begin // Может быть текстура
814 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
816 EditStyle
:= esEllipsis
;
820 if TextureName
<> '' then
821 begin // Есть текстура
822 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
824 EditStyle
:= esSimple
;
828 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
830 EditStyle
:= esPickList
;
840 with MainForm
.vleObjectProperty
,
841 gItems
[SelectedObjects
[_id
].ID
] do
843 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
845 EditStyle
:= esSimple
;
849 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
851 EditStyle
:= esSimple
;
855 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
857 EditStyle
:= esPickList
;
861 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
863 EditStyle
:= esPickList
;
871 with MainForm
.vleObjectProperty
,
872 gMonsters
[SelectedObjects
[_id
].ID
] do
874 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
876 EditStyle
:= esSimple
;
880 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
882 EditStyle
:= esSimple
;
886 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
888 EditStyle
:= esPickList
;
896 with MainForm
.vleObjectProperty
,
897 gAreas
[SelectedObjects
[_id
].ID
] do
899 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
901 EditStyle
:= esSimple
;
905 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
907 EditStyle
:= esSimple
;
911 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
913 EditStyle
:= esPickList
;
921 with MainForm
.vleObjectProperty
,
922 gTriggers
[SelectedObjects
[_id
].ID
] do
924 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
926 EditStyle
:= esSimple
;
930 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
932 EditStyle
:= esSimple
;
936 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
938 EditStyle
:= esSimple
;
942 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
944 EditStyle
:= esSimple
;
948 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
950 EditStyle
:= esSimple
;
954 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
956 EditStyle
:= esPickList
;
960 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
962 EditStyle
:= esEllipsis
;
966 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
968 EditStyle
:= esEllipsis
;
972 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
974 EditStyle
:= esEllipsis
;
981 str
:= win2utf(Data
.MapName
);
982 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], str
, True)] do
984 EditStyle
:= esEllipsis
;
991 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
993 EditStyle
:= esEllipsis
;
997 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
999 EditStyle
:= esPickList
;
1003 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
1005 EditStyle
:= esPickList
;
1009 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
1011 EditStyle
:= esPickList
;
1016 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
1017 TRIGGER_DOOR
, TRIGGER_DOOR5
:
1019 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
1021 EditStyle
:= esEllipsis
;
1025 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1027 EditStyle
:= esPickList
;
1031 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1033 EditStyle
:= esPickList
;
1038 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1040 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1042 EditStyle
:= esEllipsis
;
1046 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1048 EditStyle
:= esPickList
;
1052 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1054 EditStyle
:= esPickList
;
1059 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1062 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1063 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1065 EditStyle
:= esEllipsis
;
1069 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1071 EditStyle
:= esSimple
;
1075 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1077 EditStyle
:= esSimple
;
1081 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1083 EditStyle
:= esEllipsis
;
1087 if TriggerType
= TRIGGER_PRESS
then
1088 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1090 EditStyle
:= esPickList
;
1098 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1100 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1102 EditStyle
:= esEllipsis
;
1106 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1108 EditStyle
:= esPickList
;
1112 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1114 EditStyle
:= esPickList
;
1121 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1123 EditStyle
:= esPickList
;
1127 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1129 EditStyle
:= esPickList
;
1136 str
:= win2utf(Data
.SoundName
);
1137 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], str
, True)] do
1139 EditStyle
:= esEllipsis
;
1143 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1145 EditStyle
:= esSimple
;
1149 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1151 EditStyle
:= esSimple
;
1155 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1157 EditStyle
:= esSimple
;
1161 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1163 EditStyle
:= esPickList
;
1167 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1169 EditStyle
:= esPickList
;
1174 TRIGGER_SPAWNMONSTER
:
1176 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1178 EditStyle
:= esEllipsis
;
1182 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1183 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1185 EditStyle
:= esEllipsis
;
1189 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1191 EditStyle
:= esPickList
;
1195 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1197 EditStyle
:= esSimple
;
1201 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1203 EditStyle
:= esPickList
;
1207 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1209 EditStyle
:= esSimple
;
1213 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1215 EditStyle
:= esEllipsis
;
1219 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1221 EditStyle
:= esSimple
;
1225 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1227 EditStyle
:= esSimple
;
1231 case Data
.MonBehav
of
1232 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1233 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1234 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1235 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1236 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1237 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1239 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1241 EditStyle
:= esPickList
;
1248 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1250 EditStyle
:= esEllipsis
;
1254 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1255 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1257 EditStyle
:= esEllipsis
;
1261 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1263 EditStyle
:= esPickList
;
1267 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1269 EditStyle
:= esPickList
;
1273 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1275 EditStyle
:= esSimple
;
1279 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1281 EditStyle
:= esEllipsis
;
1285 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1287 EditStyle
:= esSimple
;
1291 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1293 EditStyle
:= esSimple
;
1300 str
:= win2utf(Data
.MusicName
);
1301 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], str
, True)] do
1303 EditStyle
:= esEllipsis
;
1307 if Data
.MusicAction
= 1 then
1308 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1310 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1312 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1314 EditStyle
:= esPickList
;
1321 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1323 EditStyle
:= esSimple
;
1326 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1328 EditStyle
:= esSimple
;
1331 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1333 EditStyle
:= esPickList
;
1340 case Data
.ScoreAction
of
1341 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1342 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1343 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1344 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1346 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1348 EditStyle
:= esPickList
;
1351 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1353 EditStyle
:= esSimple
;
1356 case Data
.ScoreTeam
of
1357 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1358 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1359 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1360 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1362 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1364 EditStyle
:= esPickList
;
1367 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1369 EditStyle
:= esPickList
;
1372 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1374 EditStyle
:= esPickList
;
1381 case Data
.MessageKind
of
1382 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1383 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1385 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1387 EditStyle
:= esPickList
;
1390 case Data
.MessageSendTo
of
1391 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1392 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1393 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1394 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1395 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1396 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1398 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1400 EditStyle
:= esPickList
;
1403 str
:= win2utf(Data
.MessageText
);
1404 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], str
, True)] do
1406 EditStyle
:= esSimple
;
1409 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1411 EditStyle
:= esSimple
;
1418 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1420 EditStyle
:= esSimple
;
1423 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1425 EditStyle
:= esSimple
;
1428 case Data
.DamageKind
of
1429 3: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_3
];
1430 4: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_4
];
1431 5: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_5
];
1432 6: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_6
];
1433 7: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_7
];
1434 8: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_8
];
1435 else str
:= _lc
[I_PROP_TR_DAMAGE_KIND_0
];
1437 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_KIND
], str
, True)] do
1439 EditStyle
:= esPickList
;
1446 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1448 EditStyle
:= esSimple
;
1451 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1453 EditStyle
:= esSimple
;
1456 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1458 EditStyle
:= esPickList
;
1461 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1463 EditStyle
:= esPickList
;
1470 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1472 EditStyle
:= esEllipsis
;
1476 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1478 EditStyle
:= esPickList
;
1482 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1484 EditStyle
:= esEllipsis
;
1488 case Data
.ShotTarget
of
1489 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1490 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1491 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1492 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1493 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1494 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1495 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1497 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1499 EditStyle
:= esPickList
;
1503 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1505 EditStyle
:= esSimple
;
1509 case Data
.ShotAim
of
1510 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1511 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1512 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1513 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1515 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)] do
1517 EditStyle
:= esPickList
;
1521 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1522 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1524 EditStyle
:= esEllipsis
;
1528 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1530 EditStyle
:= esSimple
;
1534 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1536 EditStyle
:= esSimple
;
1540 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1542 EditStyle
:= esSimple
;
1546 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1548 EditStyle
:= esSimple
;
1552 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1554 EditStyle
:= esSimple
;
1561 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1563 EditStyle
:= esSimple
;
1567 if Data
.FXType
= 0 then
1568 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1570 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1571 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1573 EditStyle
:= esEllipsis
;
1578 if Data
.FXType
= 0 then
1579 case Data
.FXSubType
of
1580 TRIGGER_EFFECT_SLIQUID
:
1581 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1582 TRIGGER_EFFECT_LLIQUID
:
1583 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1584 TRIGGER_EFFECT_DLIQUID
:
1585 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1586 TRIGGER_EFFECT_BLOOD
:
1587 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1588 TRIGGER_EFFECT_SPARK
:
1589 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1590 TRIGGER_EFFECT_BUBBLE
:
1591 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1593 if Data
.FXType
= 1 then
1595 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1596 Data
.FXSubType
:= EFFECT_TELEPORT
;
1597 str
:= EffectToStr(Data
.FXSubType
);
1599 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1601 EditStyle
:= esEllipsis
;
1605 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1607 EditStyle
:= esEllipsis
;
1611 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1613 EditStyle
:= esPickList
;
1617 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1619 EditStyle
:= esSimple
;
1623 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1625 EditStyle
:= esSimple
;
1629 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1631 EditStyle
:= esSimple
;
1635 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1637 EditStyle
:= esSimple
;
1641 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1643 EditStyle
:= esSimple
;
1647 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1649 EditStyle
:= esSimple
;
1653 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1655 EditStyle
:= esSimple
;
1659 end; //case TriggerType
1661 end; // OBJECT_TRIGGER:
1665 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1669 if SelectedObjectCount() <> 1 then
1671 if not SelectedObjects
[GetFirstSelected()].Live
then
1674 // Есть ли такой ключ:
1675 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1677 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1681 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1690 // Уже выделен - убираем:
1691 if SelectedObjects
<> nil then
1692 for a
:= 0 to High(SelectedObjects
) do
1693 with SelectedObjects
[a
] do
1694 if Live
and (ID
= fID
) and
1695 (ObjectType
= fObjectType
) then
1704 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1706 with SelectedObjects
[High(SelectedObjects
)] do
1708 ObjectType
:= fObjectType
;
1715 SetLength(SelectedObjects
, 1);
1717 with SelectedObjects
[0] do
1719 ObjectType
:= fObjectType
;
1725 MainForm
.miCopy
.Enabled
:= True;
1726 MainForm
.miCut
.Enabled
:= True;
1728 if fObjectType
= OBJECT_PANEL
then
1730 MainForm
.miToFore
.Enabled
:= True;
1731 MainForm
.miToBack
.Enabled
:= True;
1735 procedure RemoveSelectFromObjects();
1737 SelectedObjects
:= nil;
1738 DrawPressRect
:= False;
1739 MouseLDown
:= False;
1740 MouseRDown
:= False;
1741 MouseAction
:= MOUSEACTION_NONE
;
1742 SelectFlag
:= SELECTFLAG_NONE
;
1743 ResizeType
:= RESIZETYPE_NONE
;
1744 ResizeDirection
:= RESIZEDIR_NONE
;
1746 MainForm
.vleObjectProperty
.Strings
.Clear();
1748 MainForm
.miCopy
.Enabled
:= False;
1749 MainForm
.miCut
.Enabled
:= False;
1750 MainForm
.miToFore
.Enabled
:= False;
1751 MainForm
.miToBack
.Enabled
:= False;
1754 procedure DeleteSelectedObjects();
1759 if SelectedObjects
= nil then
1765 for a
:= 0 to High(SelectedObjects
) do
1766 with SelectedObjects
[a
] do
1771 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1772 i
:= High(UndoBuffer
);
1776 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1777 ii
:= High(UndoBuffer
[i
]);
1782 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1783 New(UndoBuffer
[i
, ii
].Panel
);
1784 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1788 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1789 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1793 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1794 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1798 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1799 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1803 RemoveObject(ID
, ObjectType
);
1806 RemoveSelectFromObjects();
1808 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1809 MainForm
.RecountSelectedObjects();
1812 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1816 if (not Group
) or (Length(UndoBuffer
) = 0) then
1817 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1818 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1819 i
:= High(UndoBuffer
);
1820 ii
:= High(UndoBuffer
[i
]);
1824 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1826 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1828 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1830 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1832 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1835 UndoBuffer
[i
, ii
].AddID
:= ID
;
1837 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1840 procedure FullClear();
1842 RemoveSelectFromObjects();
1844 LoadSky(gMapInfo
.SkyName
);
1846 slInvalidTextures
.Clear();
1847 MapCheckForm
.lbErrorList
.Clear();
1848 MapCheckForm
.mErrorDescription
.Clear();
1850 MainForm
.miUndo
.Enabled
:= False;
1851 MainForm
.sbHorizontal
.Position
:= 0;
1852 MainForm
.sbVertical
.Position
:= 0;
1853 MainForm
.FormResize(nil);
1854 MainForm
.Caption
:= FormCaption
;
1859 procedure ErrorMessageBox(str
: String);
1861 Application
.MessageBox(PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1862 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1865 function CheckProperty(): Boolean;
1871 _id
:= GetFirstSelected();
1873 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1874 with gPanels
[SelectedObjects
[_id
].ID
] do
1876 if TextureWidth
<> 0 then
1877 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1879 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1884 if TextureHeight
<> 0 then
1885 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1887 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1892 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1893 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1895 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1900 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1901 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1902 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1904 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1908 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1909 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1911 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1918 procedure SelectTexture(ID
: Integer);
1920 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1921 MainForm
.lbTextureListClick(nil);
1924 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1926 a
, FrameLen
: Integer;
1929 ResourceName
: String;
1930 FullResourceName
: String;
1931 SectionName
: String;
1933 Width
, Height
: Word;
1941 if aSection
= '..' then
1944 SectionName
:= aSection
;
1947 aWAD
:= _lc
[I_WAD_SPECIAL_MAP
];
1949 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1951 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1953 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1956 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1957 begin // Спец. текстуры
1959 ResourceName
:= aTex
;
1962 begin // Внешний WAD
1963 FileName
:= WadsDir
+ DirectorySeparator
+ aWAD
;
1964 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1969 // Есть ли уже такая текстура:
1970 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1971 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1974 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1979 // Название ресурса <= 64 символов:
1980 if Length(ResourceName
) > 64 then
1983 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1991 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1993 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
2000 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
2002 if IsAnim(FullResourceName
) then
2003 begin // Аним. текстура
2004 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
2006 if not g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
2008 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
2010 else // Обычная текстура
2012 if not g_CreateTextureWAD(ResourceName
, FullResourceName
) then
2014 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
2016 if (not ok
) and (slInvalidTextures
.IndexOf(ResourceName
) = -1) then
2018 slInvalidTextures
.Add(ResourceName
);
2021 if (a
> -1) and (not silent
) then
2028 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
2031 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
2032 Caption
:= FormCaption
2035 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
2037 if (sFile
<> '') and (sRes
<> '') then
2038 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
2040 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
2043 procedure OpenMap(FileName
: String; mapN
: String);
2048 SelectMapForm
.Caption
:= _lc
[I_CAP_OPEN
];
2049 SelectMapForm
.GetMaps(FileName
);
2051 if (FileName
= OpenedWAD
) and
2052 (OpenedMap
<> '') then
2054 MapName
:= OpenedMap
;
2055 while (Pos(':\', MapName
) > 0) do
2056 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
2058 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2059 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2062 if SelectMapForm
.lbMapList
.Count
> 0 then
2063 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2065 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2070 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2074 if (SelectMapForm
.ShowModal() = mrOK
) and
2075 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2076 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2081 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2087 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2088 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2089 pLoadProgress
.Show();
2091 OpenedMap
:= FileName
+':\'+MapName
;
2092 OpenedWAD
:= FileName
;
2094 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2095 // Такая карта уже недавно открывалась:
2097 RecentFiles
.Delete(idx
);
2098 RecentFiles
.Insert(0, OpenedMap
);
2099 RefreshRecentMenu();
2103 pLoadProgress
.Hide();
2106 lbTextureList
.Sorted
:= True;
2107 lbTextureList
.Sorted
:= False;
2109 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2113 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2118 if SelectedObjects
= nil then
2125 for a
:= 0 to High(SelectedObjects
) do
2126 if SelectedObjects
[a
].Live
then
2128 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2131 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2134 if (not okX
) or (not okY
) then
2140 for a
:= 0 to High(SelectedObjects
) do
2141 if SelectedObjects
[a
].Live
then
2144 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2147 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2149 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2151 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2152 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2153 begin // Двигаем зону Расширителя
2155 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2157 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2160 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2161 begin // Двигаем точку назначения Телепорта
2163 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2165 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2168 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2169 begin // Двигаем точку создания монстра
2171 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2173 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2176 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2177 begin // Двигаем точку создания предмета
2179 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2181 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2184 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2185 begin // Двигаем точку создания выстрела
2187 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2189 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2194 LastMovePoint
:= MousePos
;
2198 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2200 LayerEnabled
[Layer
] := show
;
2205 MainForm
.miLayer1
.Checked
:= show
;
2206 MainForm
.miLayerP1
.Checked
:= show
;
2210 MainForm
.miLayer2
.Checked
:= show
;
2211 MainForm
.miLayerP2
.Checked
:= show
;
2215 MainForm
.miLayer3
.Checked
:= show
;
2216 MainForm
.miLayerP3
.Checked
:= show
;
2220 MainForm
.miLayer4
.Checked
:= show
;
2221 MainForm
.miLayerP4
.Checked
:= show
;
2225 MainForm
.miLayer5
.Checked
:= show
;
2226 MainForm
.miLayerP5
.Checked
:= show
;
2230 MainForm
.miLayer6
.Checked
:= show
;
2231 MainForm
.miLayerP6
.Checked
:= show
;
2235 MainForm
.miLayer7
.Checked
:= show
;
2236 MainForm
.miLayerP7
.Checked
:= show
;
2240 MainForm
.miLayer8
.Checked
:= show
;
2241 MainForm
.miLayerP8
.Checked
:= show
;
2245 MainForm
.miLayer9
.Checked
:= show
;
2246 MainForm
.miLayerP9
.Checked
:= show
;
2250 RemoveSelectFromObjects();
2253 procedure SwitchLayer(Layer
: Byte);
2255 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2258 procedure SwitchMap();
2260 ShowMap
:= not ShowMap
;
2261 MainForm
.tbShowMap
.Down
:= ShowMap
;
2262 MainForm
.miMiniMap
.Checked
:= ShowMap
;
2265 procedure ShowEdges();
2267 if drEdge
[3] < 255 then
2270 drEdge
[3] := gAlphaEdge
;
2271 MainForm
.miShowEdges
.Checked
:= drEdge
[3] <> 255;
2274 function SelectedTexture(): String;
2276 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2277 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2282 function IsSpecialTextureSel(): Boolean;
2284 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2285 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2288 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2293 procedure AddInt(x
: Integer);
2295 Res
:= Res
+ IntToStr(x
) + ' ';
2301 if Length(CopyBuf
) = 0 then
2304 Res
:= CLIPBOARD_SIG
+ ' ';
2306 for i
:= 0 to High(CopyBuf
) do
2308 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2309 (CopyBuf
[i
].Panel
= nil) then
2313 AddInt(CopyBuf
[i
].ObjectType
);
2316 // Свойства объекта:
2317 case CopyBuf
[i
].ObjectType
of
2319 with CopyBuf
[i
].Panel
^ do
2326 Res
:= Res
+ '"' + TextureName
+ '" ';
2328 AddInt(IfThen(Blending
, 1, 0));
2332 with CopyBuf
[i
].Item
do
2337 AddInt(IfThen(OnlyDM
, 1, 0));
2338 AddInt(IfThen(Fall
, 1, 0));
2342 with CopyBuf
[i
].Monster
do
2344 AddInt(MonsterType
);
2347 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2351 with CopyBuf
[i
].Area
do
2356 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2360 with CopyBuf
[i
].Trigger
do
2362 AddInt(TriggerType
);
2367 AddInt(ActivateType
);
2369 AddInt(IfThen(Enabled
, 1, 0));
2370 AddInt(TexturePanel
);
2372 for j
:= 0 to 127 do
2373 AddInt(Data
.Default
[j
]);
2381 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
;
2386 function GetNext(): String;
2391 if Str
[1] = '"' then
2403 Result
:= Copy(Str
, 1, p
-1);
2419 Result
:= Copy(Str
, 1, p
-1);
2429 if GetNext() <> CLIPBOARD_SIG
then
2435 t
:= StrToIntDef(GetNext(), 0);
2437 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2438 (GetNext() <> ';') then
2439 begin // Что-то не то => пропускаем:
2447 i
:= Length(CopyBuf
);
2448 SetLength(CopyBuf
, i
+ 1);
2450 CopyBuf
[i
].ObjectType
:= t
;
2451 CopyBuf
[i
].Panel
:= nil;
2453 // Свойства объекта:
2457 New(CopyBuf
[i
].Panel
);
2459 with CopyBuf
[i
].Panel
^ do
2461 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2462 X
:= StrToIntDef(GetNext(), 0);
2463 Y
:= StrToIntDef(GetNext(), 0);
2464 pmin
.X
:= Min(X
, pmin
.X
);
2465 pmin
.Y
:= Min(Y
, pmin
.Y
);
2466 Width
:= StrToIntDef(GetNext(), 16);
2467 Height
:= StrToIntDef(GetNext(), 16);
2468 TextureName
:= GetNext();
2469 Alpha
:= StrToIntDef(GetNext(), 0);
2470 Blending
:= (GetNext() = '1');
2475 with CopyBuf
[i
].Item
do
2477 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2478 X
:= StrToIntDef(GetNext(), 0);
2479 Y
:= StrToIntDef(GetNext(), 0);
2480 pmin
.X
:= Min(X
, pmin
.X
);
2481 pmin
.Y
:= Min(Y
, pmin
.Y
);
2482 OnlyDM
:= (GetNext() = '1');
2483 Fall
:= (GetNext() = '1');
2487 with CopyBuf
[i
].Monster
do
2489 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2490 X
:= StrToIntDef(GetNext(), 0);
2491 Y
:= StrToIntDef(GetNext(), 0);
2492 pmin
.X
:= Min(X
, pmin
.X
);
2493 pmin
.Y
:= Min(Y
, pmin
.Y
);
2495 if GetNext() = '1' then
2498 Direction
:= D_RIGHT
;
2502 with CopyBuf
[i
].Area
do
2504 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2505 X
:= StrToIntDef(GetNext(), 0);
2506 Y
:= StrToIntDef(GetNext(), 0);
2507 pmin
.X
:= Min(X
, pmin
.X
);
2508 pmin
.Y
:= Min(Y
, pmin
.Y
);
2509 if GetNext() = '1' then
2512 Direction
:= D_RIGHT
;
2516 with CopyBuf
[i
].Trigger
do
2518 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2519 X
:= StrToIntDef(GetNext(), 0);
2520 Y
:= StrToIntDef(GetNext(), 0);
2521 pmin
.X
:= Min(X
, pmin
.X
);
2522 pmin
.Y
:= Min(Y
, pmin
.Y
);
2523 Width
:= StrToIntDef(GetNext(), 16);
2524 Height
:= StrToIntDef(GetNext(), 16);
2525 ActivateType
:= StrToIntDef(GetNext(), 0);
2526 Key
:= StrToIntDef(GetNext(), 0);
2527 Enabled
:= (GetNext() = '1');
2528 TexturePanel
:= StrToIntDef(GetNext(), 0);
2530 for j
:= 0 to 127 do
2531 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2536 pmin
.X
:= Min(Data
.TargetPoint
.X
, pmin
.X
);
2537 pmin
.Y
:= Min(Data
.TargetPoint
.Y
, pmin
.Y
);
2539 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
2541 pmin
.X
:= Min(Data
.tX
, pmin
.X
);
2542 pmin
.Y
:= Min(Data
.tY
, pmin
.Y
);
2544 TRIGGER_SPAWNMONSTER
:
2546 pmin
.X
:= Min(Data
.MonPos
.X
, pmin
.X
);
2547 pmin
.Y
:= Min(Data
.MonPos
.Y
, pmin
.Y
);
2551 pmin
.X
:= Min(Data
.ItemPos
.X
, pmin
.X
);
2552 pmin
.Y
:= Min(Data
.ItemPos
.Y
, pmin
.Y
);
2556 pmin
.X
:= Min(Data
.ShotPos
.X
, pmin
.X
);
2557 pmin
.Y
:= Min(Data
.ShotPos
.Y
, pmin
.Y
);
2565 //----------------------------------------
2566 //Закончились вспомогательные процедуры
2567 //----------------------------------------
2570 TRecentHandler
= class
2575 constructor Create (form
: TMainForm
; path
: String);
2576 procedure Execute (Sender
: TObject
);
2579 constructor TRecentHandler
.Create (form
: TMainForm
; path
: String);
2581 Assert(form
<> nil);
2586 procedure TRecentHandler
.Execute (Sender
: TObject
);
2589 fn
:= g_ExtractWadName(FPath
);
2590 if FileExists(fn
) then
2591 OpenMap(fn
, g_ExtractFilePathName(FPath
))
2593 Application
.MessageBox('', 'File not available anymore', MB_OK
);
2594 // if Application.MessageBox(PChar(_lc[I_MSG_DEL_RECENT_PROMT]), PChar(_lc[I_MSG_DEL_RECENT]), MB_ICONQUESTION or MB_YESNO) = idYes then
2596 // RecentFiles.Delete(n);
2597 // RefreshRecentMenu();
2601 procedure TMainForm
.RefillRecentMenu (menu
: TMenuItem
; start
: Integer; fmt
: AnsiString);
2602 var i
: Integer; MI
: TMenuItem
; cb
: TMethod
; h
: TRecentHandler
; s
: AnsiString;
2604 Assert(menu
<> nil);
2606 Assert(start
<= menu
.Count
);
2608 // clear all recent entries from menu
2610 while i
< menu
.Count
do
2612 MI
:= menu
.Items
[i
];
2613 cb
:= TMethod(MI
.OnClick
);
2614 if cb
.Code
= @TRecentHandler
.Execute
then
2616 // this is recent menu entry
2617 // remove it and free callback handler
2618 h
:= TRecentHandler(cb
.Data
);
2627 // fill with a new ones
2628 for i
:= 0 to RecentFiles
.Count
- 1 do
2630 s
:= RecentFiles
[i
];
2631 h
:= TRecentHandler
.Create(self
, s
);
2632 MI
:= TMenuItem
.Create(menu
);
2633 MI
.Caption
:= Format(fmt
, [i
+ 1, g_ExtractWadNameNoPath(s
), g_ExtractFilePathName(s
)]);
2634 MI
.OnClick
:= h
.Execute
;
2635 menu
.Insert(start
+ i
, MI
);
2639 procedure TMainForm
.RefreshRecentMenu();
2642 while RecentFiles
.Count
> RecentCount
do
2643 RecentFiles
.Delete(RecentFiles
.Count
- 1);
2645 if miMacRecentSubMenu
.Visible
then
2647 // Reconstruct OSX-like recent list
2648 RefillRecentMenu(miMacRecentSubMenu
, 0, '%1:s - %2:s');
2649 miMacRecentEnd
.Enabled
:= RecentFiles
.Count
<> 0;
2650 miMacRecentEnd
.Visible
:= RecentFiles
.Count
<> 0;
2653 if miWinRecentStart
.Visible
then
2655 // Reconstruct Windows-like recent list
2656 start
:= miMenuFile
.IndexOf(miWinRecent
);
2657 if start
< 0 then start
:= miMenuFile
.Count
else start
:= start
+ 1;
2658 RefillRecentMenu(miMenuFile
, start
, '%0:d %1:s:%2:s');
2659 miWinRecent
.Enabled
:= False;
2660 miWinRecent
.Visible
:= RecentFiles
.Count
= 0;
2664 procedure TMainForm
.miMacRecentClearClick(Sender
: TObject
);
2666 RecentFiles
.Clear();
2667 RefreshRecentMenu();
2670 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2672 OptionsForm
.ShowModal();
2675 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2685 g_ReadResource(GameWad
, 'FONTS', cfgres
, cfgdata
, cfglen
);
2686 if cfgdata
<> nil then
2688 if not g_CreateTextureWAD('FONT_STD', GameWad
+ ':FONTS\' + texture
) then
2689 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2691 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2692 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2693 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2694 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2696 if g_GetTexture('FONT_STD', ID
) then
2697 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
- 2);
2704 e_WriteLog('Could not load FONT_STD', MSG_WARNING
)
2708 procedure TMainForm
.FormCreate(Sender
: TObject
);
2717 miApple
.Enabled
:= True;
2718 miApple
.Visible
:= True;
2719 miMacRecentSubMenu
.Enabled
:= True;
2720 miMacRecentSubMenu
.Visible
:= True;
2721 miWinRecentStart
.Enabled
:= False;
2722 miWinRecentStart
.Visible
:= False;
2723 miWinRecent
.Enabled
:= False;
2724 miWinRecent
.Visible
:= False;
2725 miLine2
.Enabled
:= False;
2726 miLine2
.Visible
:= False;
2727 miExit
.Enabled
:= False;
2728 miExit
.Visible
:= False;
2729 miOptions
.Enabled
:= False;
2730 miOptions
.Visible
:= False;
2731 miMenuWindow
.Enabled
:= True;
2732 miMenuWindow
.Visible
:= True;
2733 miAbout
.Enabled
:= False;
2734 miAbout
.Visible
:= False;
2736 miApple
.Enabled
:= False;
2737 miApple
.Visible
:= False;
2738 miMacRecentSubMenu
.Enabled
:= False;
2739 miMacRecentSubMenu
.Visible
:= False;
2740 miWinRecentStart
.Enabled
:= True;
2741 miWinRecentStart
.Visible
:= True;
2742 miWinRecent
.Enabled
:= True;
2743 miWinRecent
.Visible
:= True;
2744 miLine2
.Enabled
:= True;
2745 miLine2
.Visible
:= True;
2746 miExit
.Enabled
:= True;
2747 miExit
.Visible
:= True;
2748 miOptions
.Enabled
:= True;
2749 miOptions
.Visible
:= True;
2750 miMenuWindow
.Enabled
:= False;
2751 miMenuWindow
.Visible
:= False;
2752 miAbout
.Enabled
:= True;
2753 miAbout
.Visible
:= True;
2756 miNewMap
.ShortCut
:= ShortCut(VK_N
, [ssModifier
]);
2757 miOpenMap
.ShortCut
:= ShortCut(VK_O
, [ssModifier
]);
2758 miSaveMap
.ShortCut
:= ShortCut(VK_S
, [ssModifier
]);
2760 miSaveMapAs
.ShortCut
:= ShortCut(VK_S
, [ssModifier
, ssShift
]);
2761 miReopenMap
.ShortCut
:= ShortCut(VK_F5
, [ssModifier
]);
2763 miUndo
.ShortCut
:= ShortCut(VK_Z
, [ssModifier
]);
2764 miCopy
.ShortCut
:= ShortCut(VK_C
, [ssModifier
]);
2765 miCut
.ShortCut
:= ShortCut(VK_X
, [ssModifier
]);
2766 miPaste
.ShortCut
:= ShortCut(VK_V
, [ssModifier
]);
2767 miSelectAll
.ShortCut
:= ShortCut(VK_A
, [ssModifier
]);
2768 miToFore
.ShortCut
:= ShortCut(VK_LCL_CLOSE_BRACKET
, [ssModifier
]);
2769 miToBack
.ShortCut
:= ShortCut(VK_LCL_OPEN_BRACKET
, [ssModifier
]);
2771 miMapOptions
.Shortcut
:= ShortCut(VK_P
, [ssModifier
, ssAlt
]);
2772 selectall1
.Shortcut
:= ShortCut(VK_A
, [ssModifier
, ssAlt
]);
2775 e_WriteLog('Doom 2D: Forever Editor version ' + EDITOR_VERSION
, MSG_NOTIFY
);
2776 e_WriteLog('Build date: ' + EDITOR_BUILDDATE
+ ' ' + EDITOR_BUILDTIME
, MSG_NOTIFY
);
2777 e_WriteLog('Build hash: ' + g_GetBuildHash(), MSG_NOTIFY
);
2778 e_WriteLog('Build by: ' + g_GetBuilderName(), MSG_NOTIFY
);
2780 slInvalidTextures
:= TStringList
.Create
;
2782 ShowLayer(LAYER_BACK
, True);
2783 ShowLayer(LAYER_WALLS
, True);
2784 ShowLayer(LAYER_FOREGROUND
, True);
2785 ShowLayer(LAYER_STEPS
, True);
2786 ShowLayer(LAYER_WATER
, True);
2787 ShowLayer(LAYER_ITEMS
, True);
2788 ShowLayer(LAYER_MONSTERS
, True);
2789 ShowLayer(LAYER_AREAS
, True);
2790 ShowLayer(LAYER_TRIGGERS
, True);
2794 FormCaption
:= MainForm
.Caption
;
2798 config
:= TConfig
.CreateFile(CfgFileName
);
2800 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2801 Position
:= poDesktopCenter
2803 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2804 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2805 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2806 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2808 if config
.ReadBool('Editor', 'Maximize', False) then
2809 WindowState
:= wsMaximized
;
2810 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2811 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2812 Splitter1
.Left
:= PanelProps
.Left
;
2813 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2814 Splitter2
.Top
:= PanelObjs
.Top
;
2815 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2816 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2817 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2818 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2819 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2820 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2821 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2822 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2823 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2824 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2825 UseCheckerboard
:= config
.ReadBool('Editor', 'UseCheckerboard', True);
2826 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2827 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2828 if gAlphaEdge
= 255 then
2829 gAlphaEdge
:= ALPHA_EDGE
;
2830 drEdge
[0] := GetRValue(gColorEdge
);
2831 drEdge
[1] := GetGValue(gColorEdge
);
2832 drEdge
[2] := GetBValue(gColorEdge
);
2833 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2836 drEdge
[3] := gAlphaEdge
;
2837 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2838 if gAlphaTriggerLine
= 255 then
2839 gAlphaTriggerLine
:= ALPHA_LINE
;
2840 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2841 if gAlphaTriggerArea
= 255 then
2842 gAlphaTriggerArea
:= ALPHA_AREA
;
2843 gAlphaMonsterRect
:= config
.ReadInt('Editor', 'MonsterRectAlpha', 0);
2844 gAlphaAreaRect
:= config
.ReadInt('Editor', 'AreaRectAlpha', 0);
2845 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2849 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2853 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', MapsDir
);
2854 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', MapsDir
);
2856 s
:= config
.ReadStr('Editor', 'Language', '');
2859 Compress
:= config
.ReadBool('Editor', 'Compress', True);
2860 Backup
:= config
.ReadBool('Editor', 'Backup', True);
2862 TestGameMode
:= config
.ReadStr('TestRun', 'GameMode', 'DM');
2863 TestLimTime
:= config
.ReadStr('TestRun', 'LimTime', '0');
2864 TestLimScore
:= config
.ReadStr('TestRun', 'LimScore', '0');
2865 TestOptionsTwoPlayers
:= config
.ReadBool('TestRun', 'TwoPlayers', False);
2866 TestOptionsTeamDamage
:= config
.ReadBool('TestRun', 'TeamDamage', False);
2867 TestOptionsAllowExit
:= config
.ReadBool('TestRun', 'AllowExit', True);
2868 TestOptionsWeaponStay
:= config
.ReadBool('TestRun', 'WeaponStay', False);
2869 TestOptionsMonstersDM
:= config
.ReadBool('TestRun', 'MonstersDM', False);
2870 TestMapOnce
:= config
.ReadBool('TestRun', 'MapOnce', False);
2871 {$IF DEFINED(DARWIN)}
2872 TestD2dExe
:= config
.ReadStr('TestRun', 'ExeDrawin', GameExeFile
);
2873 {$ELSEIF DEFINED(WINDOWS)}
2874 TestD2dExe
:= config
.ReadStr('TestRun', 'ExeWindows', GameExeFile
);
2876 TestD2dExe
:= config
.ReadStr('TestRun', 'ExeUnix', GameExeFile
);
2878 TestD2DArgs
:= config
.ReadStr('TestRun', 'Args', '');
2880 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2881 if RecentCount
> 10 then
2883 if RecentCount
< 2 then
2886 RecentFiles
:= TStringList
.Create();
2887 for i
:= 0 to RecentCount
-1 do
2890 s
:= config
.ReadStr('RecentFilesWin', IntToStr(i
), '');
2892 s
:= config
.ReadStr('RecentFilesUnix', IntToStr(i
), '');
2897 RefreshRecentMenu();
2901 tbShowMap
.Down
:= ShowMap
;
2902 tbGridOn
.Down
:= DotEnable
;
2903 pcObjects
.ActivePageIndex
:= 0;
2904 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2906 Application
.OnIdle
:= OnIdle
;
2909 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2911 // NOTE: all the font printing routines assume CP1251
2912 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2915 procedure TMainForm
.Draw();
2920 Width
, Height
: Word;
2923 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2932 e_Clear(GL_COLOR_BUFFER_BIT
,
2933 GetRValue(BackColor
)/255,
2934 GetGValue(BackColor
)/255,
2935 GetBValue(BackColor
)/255);
2939 ObjCount
:= SelectedObjectCount();
2941 // Обводим выделенные объекты красной рамкой:
2942 if ObjCount
> 0 then
2944 for a
:= 0 to High(SelectedObjects
) do
2945 if SelectedObjects
[a
].Live
then
2947 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2951 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2952 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2955 // Рисуем точки изменения размеров:
2956 if (ObjCount
= 1) and
2957 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2959 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2960 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2961 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2962 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2964 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2965 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2966 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2967 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2974 if DotEnable
and (PreviewMode
= 0) then
2981 x
:= MapOffset
.X
mod DotStep
;
2982 y
:= MapOffset
.Y
mod DotStep
;
2984 while x
< RenderPanel
.Width
do
2986 while y
< RenderPanel
.Height
do
2988 e_DrawPoint(DotSize
, x
+ a
, y
+ a
,
2989 GetRValue(DotColor
),
2990 GetGValue(DotColor
),
2991 GetBValue(DotColor
));
2995 y
:= MapOffset
.Y
mod DotStep
;
3000 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
3001 (not IsSpecialTextureSel()) and (PreviewMode
= 0) then
3003 if not g_GetTexture(SelectedTexture(), ID
) then
3004 g_GetTexture('NOTEXTURE', ID
);
3005 g_GetTextureSizeByID(ID
, Width
, Height
);
3006 if UseCheckerboard
then
3008 if g_GetTexture('PREVIEW', PID
) then
3009 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
3011 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
3012 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
3013 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
3014 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
3017 // Подсказка при выборе точки Телепорта:
3018 if SelectFlag
= SELECTFLAG_TELEPORT
then
3020 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3021 if Data
.d2d_teleport
then
3022 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
3023 MousePos
.X
+16, MousePos
.Y
-1,
3026 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
3027 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
3029 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
3030 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
3031 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
3034 // Подсказка при выборе точки появления:
3035 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
3037 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
3038 MousePos
.X
+16, MousePos
.Y
-1,
3040 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
3041 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
3042 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
3045 // Подсказка при выборе панели двери:
3046 if SelectFlag
= SELECTFLAG_DOOR
then
3048 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
3049 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
3050 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
3053 // Подсказка при выборе панели с текстурой:
3054 if SelectFlag
= SELECTFLAG_TEXTURE
then
3056 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
3057 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
3058 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
3061 // Подсказка при выборе панели индикации выстрела:
3062 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
3064 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
3065 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
3066 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
3069 // Подсказка при выборе панели лифта:
3070 if SelectFlag
= SELECTFLAG_LIFT
then
3072 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
3073 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
3074 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
3077 // Подсказка при выборе монстра:
3078 if SelectFlag
= SELECTFLAG_MONSTER
then
3080 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
3081 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
3082 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
3085 // Подсказка при выборе области воздействия:
3086 if DrawPressRect
then
3088 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
3089 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
3090 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
3093 // Рисуем текстуры, если чертим панель:
3094 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
3095 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
3096 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
3098 if not g_GetTexture(SelectedTexture(), ID
) then
3099 g_GetTexture('NOTEXTURE', ID
);
3100 g_GetTextureSizeByID(ID
, Width
, Height
);
3102 if (Abs(Right
-Left
) >= Width
) and (Abs(Bottom
-Top
) >= Height
) then
3103 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
3104 Abs(Bottom
-Top
) div Height
, 64, True, False);
3107 // Прямоугольник выделения:
3108 if DrawRect
<> nil then
3110 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
3112 // Чертим мышью панель/триггер или меняем мышью их размер:
3113 if (((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3114 not(ssCtrl
in GetKeyShiftState())) or (MouseAction
= MOUSEACTION_RESIZE
)) and
3115 (DrawPanelSize
) then
3117 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
3118 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
3120 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
3121 begin // Чертим новый
3122 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
3123 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
3124 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
],
3125 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
3127 else // Растягиваем существующий
3128 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
3130 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
3132 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
3133 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
3137 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
3138 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
3141 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
3143 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
3148 // Ближайшая к курсору мыши точка на сетке:
3149 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
3154 // Сколько пикселов карты в 1 пикселе мини-карты:
3155 ScaleSz
:= 16 div Scale
;
3156 // Размеры мини-карты:
3157 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
3158 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
3159 // X-координата на RenderPanel нулевой x-координаты карты:
3160 XX
:= RenderPanel
.Width
- aX
- 1;
3162 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
3163 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
3165 if gPanels
<> nil then
3168 for a
:= 0 to High(gPanels
) do
3170 if PanelType
<> 0 then
3172 // Левый верхний угол:
3173 aX
:= XX
+ (X
div ScaleSz
);
3174 aY
:= 1 + (Y
div ScaleSz
);
3176 aX2
:= max(Width
div ScaleSz
, 1);
3177 aY2
:= max(Height
div ScaleSz
, 1);
3178 // Правый нижний угол:
3179 aX2
:= aX
+ aX2
- 1;
3180 aY2
:= aY
+ aY2
- 1;
3183 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
3184 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
3185 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
3186 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
3187 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
3188 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
3189 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
3190 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
3191 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
3192 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
3193 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
3194 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
3198 // Рисуем красным выделенные панели:
3199 if SelectedObjects
<> nil then
3200 for b
:= 0 to High(SelectedObjects
) do
3201 with SelectedObjects
[b
] do
3202 if Live
and (ObjectType
= OBJECT_PANEL
) then
3203 with gPanels
[SelectedObjects
[b
].ID
] do
3204 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
3206 // Левый верхний угол:
3207 aX
:= XX
+ (X
div ScaleSz
);
3208 aY
:= 1 + (Y
div ScaleSz
);
3210 aX2
:= max(Width
div ScaleSz
, 1);
3211 aY2
:= max(Height
div ScaleSz
, 1);
3212 // Правый нижний угол:
3213 aX2
:= aX
+ aX2
- 1;
3214 aY2
:= aY
+ aY2
- 1;
3216 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
3220 if (gMapInfo
.Width
> RenderPanel
.Width
) or
3221 (gMapInfo
.Height
> RenderPanel
.Height
) then
3223 // Окно, показывающее текущее положение экрана на карте:
3225 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
3226 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
3227 // Левый верхний угол:
3228 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
3229 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
3230 // Правый нижний угол:
3234 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3235 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3240 RenderPanel
.SwapBuffers();
3243 procedure TMainForm
.FormResize(Sender
: TObject
);
3245 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3247 sbHorizontal
.Min
:= Min(gMapInfo
.Width
- RenderPanel
.Width
, -RenderPanel
.Width
div 2);
3248 sbHorizontal
.Max
:= Max(0, gMapInfo
.Width
- RenderPanel
.Width
div 2);
3249 sbVertical
.Min
:= Min(gMapInfo
.Height
- RenderPanel
.Height
, -RenderPanel
.Height
div 2);
3250 sbVertical
.Max
:= Max(0, gMapInfo
.Height
- RenderPanel
.Height
div 2);
3252 MapOffset
.X
:= -sbHorizontal
.Position
;
3253 MapOffset
.Y
:= -sbVertical
.Position
;
3256 procedure TMainForm
.FormWindowStateChange(Sender
: TObject
);
3262 // deactivate all menus when main window minimized
3263 e
:= self
.WindowState
<> wsMinimized
;
3264 miMenuFile
.Enabled
:= e
;
3265 miMenuEdit
.Enabled
:= e
;
3266 miMenuView
.Enabled
:= e
;
3267 miMenuService
.Enabled
:= e
;
3268 miMenuWindow
.Enabled
:= e
;
3269 miMenuHelp
.Enabled
:= e
;
3270 miMenuHidden
.Enabled
:= e
;
3274 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3279 j_max
:= 0; // shut up compiler
3283 res
:= (gPanels
<> nil) and
3284 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3285 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3287 gPanels
[ID
].Height
);
3288 j_max
:= Length(gPanels
) - 1;
3293 res
:= (gItems
<> nil) and
3294 LayerEnabled
[LAYER_ITEMS
] and
3295 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3296 ItemSize
[gItems
[ID
].ItemType
][0],
3297 ItemSize
[gItems
[ID
].ItemType
][1]);
3298 j_max
:= Length(gItems
) - 1;
3303 res
:= (gMonsters
<> nil) and
3304 LayerEnabled
[LAYER_MONSTERS
] and
3305 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3306 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3307 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3308 j_max
:= Length(gMonsters
) - 1;
3313 res
:= (gAreas
<> nil) and
3314 LayerEnabled
[LAYER_AREAS
] and
3315 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3316 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3317 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3318 j_max
:= Length(gAreas
) - 1;
3323 res
:= (gTriggers
<> nil) and
3324 LayerEnabled
[LAYER_TRIGGERS
] and
3325 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3326 gTriggers
[ID
].Width
,
3327 gTriggers
[ID
].Height
);
3328 j_max
:= Length(gTriggers
) - 1;
3338 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3347 if j
= Integer(ID
) then
3352 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3353 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3357 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3358 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3359 ItemSize
[gItems
[j
].ItemType
][0],
3360 ItemSize
[gItems
[j
].ItemType
][1]);
3362 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3363 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3364 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3365 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3367 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3368 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3369 AreaSize
[gAreas
[j
].AreaType
].Width
,
3370 AreaSize
[gAreas
[j
].AreaType
].Height
);
3372 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3373 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3375 gTriggers
[j
].Height
);
3382 SetLength(SelectedObjects
, 1);
3384 SelectedObjects
[0].ObjectType
:= ObjectType
;
3385 SelectedObjects
[0].ID
:= j
;
3386 SelectedObjects
[0].Live
:= True;
3394 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3395 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3399 c1
, c2
, c3
, c4
: Boolean;
3405 MainForm
.ActiveControl
:= RenderPanel
;
3406 RenderPanel
.SetFocus();
3408 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3410 if Button
= mbLeft
then // Left Mouse Button
3412 // Двигаем карту с помощью мыши и мини-карты:
3414 g_CollidePoint(X
, Y
,
3415 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3417 max(gMapInfo
.Width
div (16 div Scale
), 1),
3418 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3421 MouseAction
:= MOUSEACTION_MOVEMAP
;
3423 else // Ставим предмет/монстра/область:
3424 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3425 (not (ssShift
in Shift
)) then
3427 case pcObjects
.ActivePageIndex
of
3429 if lbItemList
.ItemIndex
= -1 then
3430 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3433 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3434 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3435 item
.ItemType
:= item
.ItemType
+ 2;
3436 item
.X
:= MousePos
.X
-MapOffset
.X
;
3437 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3439 if not (ssCtrl
in Shift
) then
3441 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3442 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3445 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3446 item
.Fall
:= cbFall
.Checked
;
3447 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3450 if lbMonsterList
.ItemIndex
= -1 then
3451 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3454 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3455 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3456 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3458 if not (ssCtrl
in Shift
) then
3460 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3461 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3464 if rbMonsterLeft
.Checked
then
3465 monster
.Direction
:= D_LEFT
3467 monster
.Direction
:= D_RIGHT
;
3468 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3471 if lbAreasList
.ItemIndex
= -1 then
3472 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3474 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3476 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3477 area
.X
:= MousePos
.X
-MapOffset
.X
;
3478 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3480 if not (ssCtrl
in Shift
) then
3482 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3483 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3486 if rbAreaLeft
.Checked
then
3487 area
.Direction
:= D_LEFT
3489 area
.Direction
:= D_RIGHT
;
3490 Undo_Add(OBJECT_AREA
, AddArea(area
));
3496 i
:= GetFirstSelected();
3498 // Выбираем объект под текущим:
3499 if (SelectedObjects
<> nil) and
3500 (ssShift
in Shift
) and (i
>= 0) and
3501 (SelectedObjects
[i
].Live
) then
3503 if SelectedObjectCount() = 1 then
3504 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3505 SelectedObjects
[i
].ObjectType
,
3506 SelectedObjects
[i
].ID
);
3510 // Рисуем область триггера "Расширитель":
3511 if DrawPressRect
and (i
>= 0) and
3512 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3513 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3514 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3515 MouseAction
:= MOUSEACTION_DRAWPRESS
3516 else // Рисуем панель:
3517 if pcObjects
.ActivePageIndex
= 0 then
3519 if (lbPanelType
.ItemIndex
>= 0) then
3520 MouseAction
:= MOUSEACTION_DRAWPANEL
3522 else // Рисуем триггер:
3523 if (lbTriggersList
.ItemIndex
>= 0) then
3525 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3529 end; // if Button = mbLeft
3531 if Button
= mbRight
then // Right Mouse Button
3533 // Клик по мини-карте:
3535 g_CollidePoint(X
, Y
,
3536 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3538 max(gMapInfo
.Width
div (16 div Scale
), 1),
3539 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3541 MouseAction
:= MOUSEACTION_NOACTION
;
3543 else // Нужно что-то выбрать мышью:
3544 if SelectFlag
<> SELECTFLAG_NONE
then
3547 SELECTFLAG_TELEPORT
:
3548 // Точку назначения телепортации:
3549 with gTriggers
[SelectedObjects
[
3550 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3552 X
:= MousePos
.X
-MapOffset
.X
;
3553 Y
:= MousePos
.Y
-MapOffset
.Y
;
3556 SELECTFLAG_SPAWNPOINT
:
3557 // Точку создания монстра:
3558 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3559 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3561 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3562 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3564 else if TriggerType
= TRIGGER_SPAWNITEM
then
3565 begin // Точка создания предмета:
3566 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3567 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3569 else if TriggerType
= TRIGGER_SHOT
then
3570 begin // Точка создания выстрела:
3571 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3572 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3578 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3580 2, 2, OBJECT_PANEL
, True);
3581 if IDArray
<> nil then
3583 for i
:= 0 to High(IDArray
) do
3584 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3585 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3587 gTriggers
[SelectedObjects
[
3588 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3593 gTriggers
[SelectedObjects
[
3594 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3598 // Панель с текстурой:
3600 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3602 2, 2, OBJECT_PANEL
, True);
3603 if IDArray
<> nil then
3605 for i
:= 0 to High(IDArray
) do
3606 if ((gPanels
[IDArray
[i
]].PanelType
in
3607 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3608 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3610 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3611 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3612 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3614 gTriggers
[SelectedObjects
[
3615 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3620 gTriggers
[SelectedObjects
[
3621 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3627 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3629 2, 2, OBJECT_PANEL
, True);
3630 if IDArray
<> nil then
3632 for i
:= 0 to High(IDArray
) do
3633 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3634 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3635 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3636 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3638 gTriggers
[SelectedObjects
[
3639 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3644 gTriggers
[SelectedObjects
[
3645 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3651 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3653 2, 2, OBJECT_MONSTER
, False);
3654 if IDArray
<> nil then
3655 gTriggers
[SelectedObjects
[
3656 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3658 gTriggers
[SelectedObjects
[
3659 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3662 SELECTFLAG_SHOTPANEL
:
3663 // Панель индикации выстрела:
3665 if gTriggers
[SelectedObjects
[
3666 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3668 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3670 2, 2, OBJECT_PANEL
, True);
3671 if IDArray
<> nil then
3673 for i
:= 0 to High(IDArray
) do
3674 if ((gPanels
[IDArray
[i
]].PanelType
in
3675 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3676 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3678 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3679 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3680 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3682 gTriggers
[SelectedObjects
[
3683 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3688 gTriggers
[SelectedObjects
[
3689 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3694 SelectFlag
:= SELECTFLAG_SELECTED
;
3696 else // if SelectFlag <> SELECTFLAG_NONE...
3698 // Что уже выбрано и не нажат Ctrl:
3699 if (SelectedObjects
<> nil) and
3700 (not (ssCtrl
in Shift
)) then
3701 for i
:= 0 to High(SelectedObjects
) do
3702 with SelectedObjects
[i
] do
3705 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3706 (SelectedObjectCount() = 1) then
3708 Rect
:= ObjectGetRect(ObjectType
, ID
);
3710 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3711 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3712 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3713 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3714 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3715 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3716 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3717 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3719 // Меняем размер панели или триггера:
3720 if c1
or c2
or c3
or c4
then
3722 MouseAction
:= MOUSEACTION_RESIZE
;
3723 LastMovePoint
:= MousePos
;
3727 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3729 ResizeDirection
:= RESIZEDIR_LEFT
3731 ResizeDirection
:= RESIZEDIR_RIGHT
;
3732 RenderPanel
.Cursor
:= crSizeWE
;
3736 ResizeType
:= RESIZETYPE_VERTICAL
;
3738 ResizeDirection
:= RESIZEDIR_UP
3740 ResizeDirection
:= RESIZEDIR_DOWN
;
3741 RenderPanel
.Cursor
:= crSizeNS
;
3748 // Перемещаем панель или триггер:
3749 if ObjectCollide(ObjectType
, ID
,
3751 Y
-MapOffset
.Y
-1, 2, 2) then
3753 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3754 LastMovePoint
:= MousePos
;
3760 end; // if Button = mbRight
3762 if Button
= mbMiddle
then // Middle Mouse Button
3764 SetCapture(RenderPanel
.Handle
);
3765 RenderPanel
.Cursor
:= crSize
;
3768 MouseMDown
:= Button
= mbMiddle
;
3770 MouseMDownPos
:= Mouse
.CursorPos
;
3772 MouseRDown
:= Button
= mbRight
;
3774 MouseRDownPos
:= MousePos
;
3776 MouseLDown
:= Button
= mbLeft
;
3778 MouseLDownPos
:= MousePos
;
3781 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3782 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3787 rSelectRect
: Boolean;
3788 wWidth
, wHeight
: Word;
3791 procedure SelectObjects(ObjectType
: Byte);
3796 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3797 rRect
.Width
, rRect
.Height
,
3798 ObjectType
, rSelectRect
);
3800 if IDArray
<> nil then
3801 for i
:= 0 to High(IDArray
) do
3802 SelectObject(ObjectType
, IDArray
[i
], (ssCtrl
in Shift
) or rSelectRect
);
3805 if Button
= mbLeft
then
3806 MouseLDown
:= False;
3807 if Button
= mbRight
then
3808 MouseRDown
:= False;
3809 if Button
= mbMiddle
then
3810 MouseMDown
:= False;
3813 ResizeType
:= RESIZETYPE_NONE
;
3816 if Button
= mbLeft
then // Left Mouse Button
3818 if MouseAction
<> MOUSEACTION_NONE
then
3819 begin // Было действие мышью
3820 // Мышь сдвинулась во время удержания клавиши,
3821 // либо активирован режим быстрого рисования:
3822 if ((MousePos
.X
<> MouseLDownPos
.X
) and
3823 (MousePos
.Y
<> MouseLDownPos
.Y
)) or
3824 ((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3825 (ssCtrl
in Shift
)) then
3828 MOUSEACTION_DRAWPANEL
:
3830 // Фон или передний план без текстуры - ошибка:
3831 if (lbPanelType
.ItemIndex
in [1, 2]) and
3832 (lbTextureList
.ItemIndex
= -1) then
3833 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3834 else // Назначаем параметры панели:
3836 case lbPanelType
.ItemIndex
of
3837 0: Panel
.PanelType
:= PANEL_WALL
;
3838 1: Panel
.PanelType
:= PANEL_BACK
;
3839 2: Panel
.PanelType
:= PANEL_FORE
;
3840 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3841 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3842 5: Panel
.PanelType
:= PANEL_STEP
;
3843 6: Panel
.PanelType
:= PANEL_WATER
;
3844 7: Panel
.PanelType
:= PANEL_ACID1
;
3845 8: Panel
.PanelType
:= PANEL_ACID2
;
3846 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3847 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3848 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3849 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3850 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3853 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3854 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3855 if ssCtrl
in Shift
then
3859 if (lbTextureList
.ItemIndex
<> -1) and
3860 (not IsSpecialTextureSel()) then
3862 if not g_GetTexture(SelectedTexture(), TextureID
) then
3863 g_GetTexture('NOTEXTURE', TextureID
);
3864 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
3866 Panel
.Width
:= wWidth
;
3867 Panel
.Height
:= wHeight
;
3871 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3872 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3875 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3876 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3877 (lbTextureList
.ItemIndex
= -1) then
3879 Panel
.TextureHeight
:= 1;
3880 Panel
.TextureWidth
:= 1;
3881 Panel
.TextureName
:= '';
3882 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3884 else // Есть текстура:
3886 Panel
.TextureName
:= SelectedTexture();
3888 // Обычная текстура:
3889 if not IsSpecialTextureSel() then
3891 g_GetTextureSizeByName(Panel
.TextureName
,
3892 Panel
.TextureWidth
, Panel
.TextureHeight
);
3893 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3895 else // Спец.текстура:
3897 Panel
.TextureHeight
:= 1;
3898 Panel
.TextureWidth
:= 1;
3899 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3904 Panel
.Blending
:= False;
3906 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3910 // Рисовали триггер:
3911 MOUSEACTION_DRAWTRIGGER
:
3913 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3914 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3915 if ssCtrl
in Shift
then
3919 trigger
.Width
:= wWidth
;
3920 trigger
.Height
:= wHeight
;
3924 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3925 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3928 trigger
.Enabled
:= True;
3929 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3930 trigger
.TexturePanel
:= -1;
3933 trigger
.ActivateType
:= 0;
3935 if clbActivationType
.Checked
[0] then
3936 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3937 if clbActivationType
.Checked
[1] then
3938 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3939 if clbActivationType
.Checked
[2] then
3940 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3941 if clbActivationType
.Checked
[3] then
3942 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3943 if clbActivationType
.Checked
[4] then
3944 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3945 if clbActivationType
.Checked
[5] then
3946 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3948 // Необходимые для активации ключи:
3951 if clbKeys
.Checked
[0] then
3952 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3953 if clbKeys
.Checked
[1] then
3954 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3955 if clbKeys
.Checked
[2] then
3956 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3957 if clbKeys
.Checked
[3] then
3958 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3959 if clbKeys
.Checked
[4] then
3960 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3962 // Параметры триггера:
3963 FillByte(trigger
.Data
.Default
[0], 128, 0);
3965 case trigger
.TriggerType
of
3966 // Переключаемая панель:
3967 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3968 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3969 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3971 Trigger
.Data
.PanelID
:= -1;
3977 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3978 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3979 trigger
.Data
.d2d_teleport
:= True;
3980 trigger
.Data
.TlpDir
:= 0;
3983 // Изменение других триггеров:
3984 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3987 trigger
.Data
.Count
:= 1;
3993 trigger
.Data
.Volume
:= 255;
3994 trigger
.Data
.Pan
:= 127;
3995 trigger
.Data
.PlayCount
:= 1;
3996 trigger
.Data
.Local
:= True;
3997 trigger
.Data
.SoundSwitch
:= False;
4003 trigger
.Data
.MusicAction
:= 1;
4006 // Создание монстра:
4007 TRIGGER_SPAWNMONSTER
:
4009 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
4010 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
4011 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
4012 trigger
.Data
.MonHealth
:= 0;
4013 trigger
.Data
.MonActive
:= False;
4014 trigger
.Data
.MonCount
:= 1;
4017 // Создание предмета:
4020 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
4021 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
4022 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
4023 trigger
.Data
.ItemOnlyDM
:= False;
4024 trigger
.Data
.ItemFalls
:= False;
4025 trigger
.Data
.ItemCount
:= 1;
4026 trigger
.Data
.ItemMax
:= 0;
4027 trigger
.Data
.ItemDelay
:= 0;
4033 trigger
.Data
.PushAngle
:= 90;
4034 trigger
.Data
.PushForce
:= 10;
4035 trigger
.Data
.ResetVel
:= True;
4040 trigger
.Data
.ScoreCount
:= 1;
4041 trigger
.Data
.ScoreCon
:= True;
4042 trigger
.Data
.ScoreMsg
:= True;
4047 trigger
.Data
.MessageKind
:= 0;
4048 trigger
.Data
.MessageSendTo
:= 0;
4049 trigger
.Data
.MessageText
:= '';
4050 trigger
.Data
.MessageTime
:= 144;
4055 trigger
.Data
.DamageValue
:= 5;
4056 trigger
.Data
.DamageInterval
:= 12;
4061 trigger
.Data
.HealValue
:= 5;
4062 trigger
.Data
.HealInterval
:= 36;
4067 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
4068 trigger
.Data
.ShotSound
:= True;
4069 trigger
.Data
.ShotPanelID
:= -1;
4070 trigger
.Data
.ShotTarget
:= 0;
4071 trigger
.Data
.ShotIntSight
:= 0;
4072 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
4073 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
4074 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
4075 trigger
.Data
.ShotAngle
:= 0;
4076 trigger
.Data
.ShotWait
:= 18;
4077 trigger
.Data
.ShotAccuracy
:= 0;
4078 trigger
.Data
.ShotAmmo
:= 0;
4079 trigger
.Data
.ShotIntReload
:= 0;
4084 trigger
.Data
.FXCount
:= 1;
4085 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
4086 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
4087 trigger
.Data
.FXColorR
:= 0;
4088 trigger
.Data
.FXColorG
:= 0;
4089 trigger
.Data
.FXColorB
:= 255;
4090 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
4091 trigger
.Data
.FXWait
:= 1;
4092 trigger
.Data
.FXVelX
:= 0;
4093 trigger
.Data
.FXVelY
:= -20;
4094 trigger
.Data
.FXSpreadL
:= 5;
4095 trigger
.Data
.FXSpreadR
:= 5;
4096 trigger
.Data
.FXSpreadU
:= 4;
4097 trigger
.Data
.FXSpreadD
:= 0;
4101 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
4104 // Рисовали область триггера "Расширитель":
4105 MOUSEACTION_DRAWPRESS
:
4106 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
4108 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
4109 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
4110 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
4111 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
4113 DrawPressRect
:= False;
4117 MouseAction
:= MOUSEACTION_NONE
;
4119 end // if Button = mbLeft...
4120 else if Button
= mbRight
then // Right Mouse Button:
4122 if MouseAction
= MOUSEACTION_NOACTION
then
4124 MouseAction
:= MOUSEACTION_NONE
;
4128 // Объект передвинут или изменен в размере:
4129 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
4131 RenderPanel
.Cursor
:= crDefault
;
4132 MouseAction
:= MOUSEACTION_NONE
;
4137 // Еще не все выбрали:
4138 if SelectFlag
<> SELECTFLAG_NONE
then
4140 if SelectFlag
= SELECTFLAG_SELECTED
then
4141 SelectFlag
:= SELECTFLAG_NONE
;
4146 // Мышь сдвинулась во время удержания клавиши:
4147 if (MousePos
.X
<> MouseRDownPos
.X
) and
4148 (MousePos
.Y
<> MouseRDownPos
.Y
) then
4150 rSelectRect
:= True;
4152 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
4153 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
4154 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
4155 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
4157 else // Мышь не сдвинулась - нет прямоугольника:
4159 rSelectRect
:= False;
4161 rRect
.X
:= X
-MapOffset
.X
-1;
4162 rRect
.Y
:= Y
-MapOffset
.Y
-1;
4167 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
4168 if not (ssCtrl
in Shift
) then
4169 RemoveSelectFromObjects();
4171 // Выделяем всё в выбранном прямоугольнике:
4172 if (ssCtrl
in Shift
) and (ssAlt
in Shift
) then
4174 SelectObjects(OBJECT_PANEL
);
4175 SelectObjects(OBJECT_ITEM
);
4176 SelectObjects(OBJECT_MONSTER
);
4177 SelectObjects(OBJECT_AREA
);
4178 SelectObjects(OBJECT_TRIGGER
);
4181 SelectObjects(pcObjects
.ActivePageIndex
+1);
4186 else // Middle Mouse Button
4188 RenderPanel
.Cursor
:= crDefault
;
4193 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
4198 function TMainForm
.RenderMousePos(): Types
.TPoint
;
4200 Result
:= RenderPanel
.ScreenToClient(Mouse
.CursorPos
);
4203 procedure TMainForm
.RecountSelectedObjects();
4205 if SelectedObjectCount() = 0 then
4206 StatusBar
.Panels
[0].Text := ''
4208 StatusBar
.Panels
[0].Text := Format(_lc
[I_CAP_STAT_SELECTED
], [SelectedObjectCount()]);
4211 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
4212 Shift
: TShiftState
; X
, Y
: Integer);
4215 dWidth
, dHeight
: Integer;
4218 wWidth
, wHeight
: Word;
4220 _id
:= GetFirstSelected();
4223 // Рисуем панель с текстурой, сетка - размеры текстуры:
4224 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
4225 (lbPanelType
.ItemIndex
in [0..8]) and
4226 (lbTextureList
.ItemIndex
<> -1) and
4227 (not IsSpecialTextureSel()) then
4229 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
4230 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
4233 // Меняем размер панели с текстурой, сетка - размеры текстуры:
4234 if (MouseAction
= MOUSEACTION_RESIZE
) and
4235 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
4236 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
4237 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
4238 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
4240 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
4241 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
4244 // Выравнивание по сетке:
4250 else // Нет выравнивания по сетке:
4256 // Новая позиция мыши:
4258 begin // Зажата левая кнопка мыши
4259 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
4260 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
4264 begin // Зажата правая кнопка мыши
4265 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
4266 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
4269 begin // Кнопки мыши не зажаты
4270 MousePos
.X
:= Round((-MapOffset
.X
+ X
) / sX
) * sX
+ MapOffset
.X
;
4271 MousePos
.Y
:= Round((-MapOffset
.Y
+ Y
) / sY
) * sY
+ MapOffset
.Y
;
4274 // Зажата только правая кнопка мыши:
4275 if (not MouseLDown
) and (MouseRDown
) and (not MouseMDown
) then
4277 // Рисуем прямоугольник выделения:
4278 if MouseAction
= MOUSEACTION_NONE
then
4280 if DrawRect
= nil then
4282 DrawRect
.Top
:= MouseRDownPos
.y
;
4283 DrawRect
.Left
:= MouseRDownPos
.x
;
4284 DrawRect
.Bottom
:= MousePos
.y
;
4285 DrawRect
.Right
:= MousePos
.x
;
4288 // Двигаем выделенные объекты:
4289 if MouseAction
= MOUSEACTION_MOVEOBJ
then
4291 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
4292 MousePos
.X
-LastMovePoint
.X
,
4293 MousePos
.Y
-LastMovePoint
.Y
);
4296 // Меняем размер выделенного объекта:
4297 if MouseAction
= MOUSEACTION_RESIZE
then
4299 if (SelectedObjectCount
= 1) and
4300 (SelectedObjects
[GetFirstSelected
].Live
) then
4302 dWidth
:= MousePos
.X
-LastMovePoint
.X
;
4303 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
;
4306 RESIZETYPE_VERTICAL
: dWidth
:= 0;
4307 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
4310 case ResizeDirection
of
4311 RESIZEDIR_UP
: dHeight
:= -dHeight
;
4312 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
4315 if ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
4316 SelectedObjects
[GetFirstSelected
].ID
,
4317 dWidth
, dHeight
, ResizeDirection
) then
4318 LastMovePoint
:= MousePos
;
4323 // Зажата только левая кнопка мыши:
4324 if (not MouseRDown
) and (MouseLDown
) and (not MouseMDown
) then
4326 // Рисуем прямоугольник планирования панели:
4327 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4328 MOUSEACTION_DRAWTRIGGER
,
4329 MOUSEACTION_DRAWPRESS
] then
4331 if DrawRect
= nil then
4333 if ssCtrl
in Shift
then
4337 if (lbTextureList
.ItemIndex
<> -1) and (not IsSpecialTextureSel()) and
4338 (MouseAction
= MOUSEACTION_DRAWPANEL
) then
4340 if not g_GetTexture(SelectedTexture(), TextureID
) then
4341 g_GetTexture('NOTEXTURE', TextureID
);
4342 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
4344 DrawRect
.Top
:= MouseLDownPos
.y
;
4345 DrawRect
.Left
:= MouseLDownPos
.x
;
4346 DrawRect
.Bottom
:= DrawRect
.Top
+ wHeight
;
4347 DrawRect
.Right
:= DrawRect
.Left
+ wWidth
;
4351 DrawRect
.Top
:= MouseLDownPos
.y
;
4352 DrawRect
.Left
:= MouseLDownPos
.x
;
4353 DrawRect
.Bottom
:= MousePos
.y
;
4354 DrawRect
.Right
:= MousePos
.x
;
4357 else // Двигаем карту:
4358 if MouseAction
= MOUSEACTION_MOVEMAP
then
4364 // Only Middle Mouse Button is pressed
4365 if (not MouseLDown
) and (not MouseRDown
) and (MouseMDown
) then
4367 MapOffset
.X
:= -EnsureRange(-MapOffset
.X
+ MouseMDownPos
.X
- Mouse
.CursorPos
.X
,
4368 sbHorizontal
.Min
, sbHorizontal
.Max
);
4369 sbHorizontal
.Position
:= -MapOffset
.X
;
4370 MapOffset
.Y
:= -EnsureRange(-MapOffset
.Y
+ MouseMDownPos
.Y
- Mouse
.CursorPos
.Y
,
4371 sbVertical
.Min
, sbVertical
.Max
);
4372 sbVertical
.Position
:= -MapOffset
.Y
;
4373 MouseMDownPos
:= Mouse
.CursorPos
;
4376 // Клавиши мыши не зажаты:
4377 if (not MouseRDown
) and (not MouseLDown
) then
4380 // Строка состояния - координаты мыши:
4381 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4382 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4385 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4387 CanClose
:= Application
.MessageBox(PChar(_lc
[I_MSG_EXIT_PROMT
]),
4388 PChar(_lc
[I_MSG_EXIT
]),
4389 MB_ICONQUESTION
or MB_YESNO
or
4390 MB_DEFBUTTON1
) = idYes
;
4393 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4398 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4404 config
:= TConfig
.CreateFile(CfgFileName
);
4406 if WindowState
<> wsMaximized
then
4408 config
.WriteInt('Editor', 'XPos', Left
);
4409 config
.WriteInt('Editor', 'YPos', Top
);
4410 config
.WriteInt('Editor', 'Width', Width
);
4411 config
.WriteInt('Editor', 'Height', Height
);
4415 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4416 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4417 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4418 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4420 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4421 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4422 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4423 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4424 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4425 config
.WriteInt('Editor', 'DotStep', DotStep
);
4426 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4427 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4428 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4429 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4430 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4431 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4432 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4433 config
.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect
);
4434 config
.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect
);
4436 for i
:= 0 to RecentCount
- 1 do
4438 if i
< RecentFiles
.Count
then s
:= RecentFiles
[i
] else s
:= '';
4440 config
.WriteStr('RecentFilesWin', IntToStr(i
), s
);
4442 config
.WriteStr('RecentFilesUnix', IntToStr(i
), s
);
4447 config
.SaveFile(CfgFileName
);
4450 slInvalidTextures
.Free
;
4453 procedure TMainForm
.FormDropFiles(Sender
: TObject
;
4454 const FileNames
: array of String);
4456 if Length(FileNames
) <> 1 then
4459 OpenMapFile(FileNames
[0]);
4462 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4464 if MainForm
.Visible
then
4468 procedure TMainForm
.Splitter1Moved(Sender
: TObject
);
4473 procedure TMainForm
.MapTestCheck(Sender
: TObject
);
4475 if MapTestProcess
<> nil then
4477 if MapTestProcess
.Running
= false then
4479 if MapTestProcess
.ExitCode
<> 0 then
4480 Application
.MessageBox(PChar(_lc
[I_MSG_EXEC_ERROR
]), 'FIXME', MB_OK
or MB_ICONERROR
);
4481 SysUtils
.DeleteFile(MapTestFile
);
4483 FreeAndNil(MapTestProcess
);
4484 tbTestMap
.Enabled
:= True;
4489 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4493 MapOptionsForm
.ShowModal();
4495 ResName
:= OpenedMap
;
4496 while (Pos(':\', ResName
) > 0) do
4497 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4499 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4502 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4504 AboutForm
.ShowModal();
4507 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
4513 if (not EditingProperties
) then
4515 if ssCtrl
in Shift
then
4518 '1': ContourEnabled
[LAYER_BACK
] := not ContourEnabled
[LAYER_BACK
];
4519 '2': ContourEnabled
[LAYER_WALLS
] := not ContourEnabled
[LAYER_WALLS
];
4520 '3': ContourEnabled
[LAYER_FOREGROUND
] := not ContourEnabled
[LAYER_FOREGROUND
];
4521 '4': ContourEnabled
[LAYER_STEPS
] := not ContourEnabled
[LAYER_STEPS
];
4522 '5': ContourEnabled
[LAYER_WATER
] := not ContourEnabled
[LAYER_WATER
];
4523 '6': ContourEnabled
[LAYER_ITEMS
] := not ContourEnabled
[LAYER_ITEMS
];
4524 '7': ContourEnabled
[LAYER_MONSTERS
] := not ContourEnabled
[LAYER_MONSTERS
];
4525 '8': ContourEnabled
[LAYER_AREAS
] := not ContourEnabled
[LAYER_AREAS
];
4526 '9': ContourEnabled
[LAYER_TRIGGERS
] := not ContourEnabled
[LAYER_TRIGGERS
];
4530 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4531 if ContourEnabled
[i
] then
4533 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4534 ContourEnabled
[i
] := not ok
4541 '1': SwitchLayer(LAYER_BACK
);
4542 '2': SwitchLayer(LAYER_WALLS
);
4543 '3': SwitchLayer(LAYER_FOREGROUND
);
4544 '4': SwitchLayer(LAYER_STEPS
);
4545 '5': SwitchLayer(LAYER_WATER
);
4546 '6': SwitchLayer(LAYER_ITEMS
);
4547 '7': SwitchLayer(LAYER_MONSTERS
);
4548 '8': SwitchLayer(LAYER_AREAS
);
4549 '9': SwitchLayer(LAYER_TRIGGERS
);
4550 '0': tbShowClick(tbShow
);
4554 if Key
= Ord('V') then
4555 begin // Поворот монстров и областей:
4556 if (SelectedObjects
<> nil) then
4558 for i
:= 0 to High(SelectedObjects
) do
4559 if (SelectedObjects
[i
].Live
) then
4561 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4563 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4566 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4568 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4574 if pcObjects
.ActivePage
= tsMonsters
then
4576 if rbMonsterLeft
.Checked
then
4577 rbMonsterRight
.Checked
:= True
4579 rbMonsterLeft
.Checked
:= True;
4581 if pcObjects
.ActivePage
= tsAreas
then
4583 if rbAreaLeft
.Checked
then
4584 rbAreaRight
.Checked
:= True
4586 rbAreaLeft
.Checked
:= True;
4591 if not (ssCtrl
in Shift
) then
4593 // Быстрое превью карты:
4594 if Key
= Ord('E') then
4596 if PreviewMode
= 0 then
4600 // Вертикальный скролл карты:
4603 if Key
= Ord('W') then
4606 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4607 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4608 MapOffset
.Y
:= -Position
;
4611 if (MouseLDown
or MouseRDown
) then
4613 if DrawRect
<> nil then
4615 Inc(MouseLDownPos
.y
, dy
);
4616 Inc(MouseRDownPos
.y
, dy
);
4618 Inc(LastMovePoint
.Y
, dy
);
4619 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4623 if Key
= Ord('S') then
4626 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4627 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4628 MapOffset
.Y
:= -Position
;
4631 if (MouseLDown
or MouseRDown
) then
4633 if DrawRect
<> nil then
4635 Inc(MouseLDownPos
.y
, dy
);
4636 Inc(MouseRDownPos
.y
, dy
);
4638 Inc(LastMovePoint
.Y
, dy
);
4639 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4644 // Горизонтальный скролл карты:
4645 with sbHorizontal
do
4647 if Key
= Ord('A') then
4650 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4651 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4652 MapOffset
.X
:= -Position
;
4655 if (MouseLDown
or MouseRDown
) then
4657 if DrawRect
<> nil then
4659 Inc(MouseLDownPos
.x
, dx
);
4660 Inc(MouseRDownPos
.x
, dx
);
4662 Inc(LastMovePoint
.X
, dx
);
4663 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4667 if Key
= Ord('D') then
4670 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4671 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4672 MapOffset
.X
:= -Position
;
4675 if (MouseLDown
or MouseRDown
) then
4677 if DrawRect
<> nil then
4679 Inc(MouseLDownPos
.x
, dx
);
4680 Inc(MouseRDownPos
.x
, dx
);
4682 Inc(LastMovePoint
.X
, dx
);
4683 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4688 else // ssCtrl in Shift
4690 if ssShift
in Shift
then
4692 // Вставка по абсолютному смещению:
4693 if Key
= Ord('V') then
4694 aPasteObjectExecute(Sender
);
4696 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4700 // Удалить выделенные объекты:
4701 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4702 RenderPanel
.Focused() then
4703 DeleteSelectedObjects();
4706 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4707 RemoveSelectFromObjects();
4709 // Передвинуть объекты:
4710 if MainForm
.ActiveControl
= RenderPanel
then
4715 if Key
= VK_NUMPAD4
then
4716 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4717 if Key
= VK_NUMPAD6
then
4718 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4719 if Key
= VK_NUMPAD8
then
4720 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4721 if Key
= VK_NUMPAD5
then
4722 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4724 if (dx
<> 0) or (dy
<> 0) then
4726 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4731 if ssCtrl
in Shift
then
4733 // Выбор панели с текстурой для триггера
4734 if Key
= Ord('T') then
4736 DrawPressRect
:= False;
4737 if SelectFlag
= SELECTFLAG_TEXTURE
then
4739 SelectFlag
:= SELECTFLAG_NONE
;
4742 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4744 SelectFlag
:= SELECTFLAG_TEXTURE
;
4747 if Key
= Ord('D') then
4749 SelectFlag
:= SELECTFLAG_NONE
;
4750 if DrawPressRect
then
4752 DrawPressRect
:= False;
4757 // Выбор области воздействия, в зависимости от типа триггера
4758 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4761 DrawPressRect
:= True;
4764 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4766 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4769 SelectFlag
:= SELECTFLAG_DOOR
;
4772 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4775 SelectFlag
:= SELECTFLAG_LIFT
;
4778 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4781 SelectFlag
:= SELECTFLAG_TELEPORT
;
4784 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4787 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4791 // Выбор основного параметра, в зависимости от типа триггера
4792 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4795 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4796 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
4797 SelectMapForm
.GetMaps(FileName
);
4799 if SelectMapForm
.ShowModal() = mrOK
then
4801 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4802 bApplyProperty
.Click();
4806 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4808 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4811 AddSoundForm
.OKFunction
:= nil;
4812 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4813 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4815 if (AddSoundForm
.ShowModal() = mrOk
) then
4817 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4818 bApplyProperty
.Click();
4822 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4824 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4827 vleObjectProperty
.Row
:= i
;
4828 vleObjectProperty
.SetFocus();
4835 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4837 RemoveSelectFromObjects();
4838 MapOptimizationForm
.ShowModal();
4841 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4843 MapCheckForm
.ShowModal();
4846 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4848 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4849 AddTextureForm
.ShowModal();
4852 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4855 TextureWidth
, TextureHeight
: Word;
4860 if (lbTextureList
.ItemIndex
<> -1) and
4861 (not IsSpecialTextureSel()) then
4863 if g_GetTexture(SelectedTexture(), TextureID
) then
4865 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4867 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4868 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4871 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4872 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4877 lTextureWidth
.Caption
:= '';
4878 lTextureHeight
.Caption
:= '';
4882 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4883 ARect
: TRect
; State
: TOwnerDrawState
);
4885 with Control
as TListBox
do
4887 if LCLType
.odSelected
in State
then
4889 Canvas
.Brush
.Color
:= clHighlight
;
4890 Canvas
.Font
.Color
:= clHighlightText
;
4892 if (Items
<> nil) and (Index
>= 0) then
4893 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4895 Canvas
.Brush
.Color
:= clRed
;
4896 Canvas
.Font
.Color
:= clWhite
;
4898 Canvas
.FillRect(ARect
);
4899 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4903 procedure TMainForm
.miMacMinimizeClick(Sender
: TObject
);
4905 self
.WindowState
:= wsMinimized
;
4906 self
.FormWindowStateChange(Sender
);
4909 procedure TMainForm
.miMacZoomClick(Sender
: TObject
);
4911 if self
.WindowState
= wsMaximized
then
4912 self
.WindowState
:= wsNormal
4914 self
.WindowState
:= wsMaximized
;
4915 self
.FormWindowStateChange(Sender
);
4918 procedure TMainForm
.miReopenMapClick(Sender
: TObject
);
4920 FileName
, Resource
: String;
4922 if OpenedMap
= '' then
4925 if Application
.MessageBox(PChar(_lc
[I_MSG_REOPEN_MAP_PROMT
]),
4926 PChar(_lc
[I_MENU_FILE_REOPEN
]), MB_ICONQUESTION
or MB_YESNO
) <> idYes
then
4929 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, @Resource
);
4930 OpenMap(FileName
, Resource
);
4933 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4934 const KeyName
: String; Values
: TStrings
);
4936 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4938 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4940 Values
.Add(DirNames
[D_LEFT
]);
4941 Values
.Add(DirNames
[D_RIGHT
]);
4943 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4945 Values
.Add(DirNamesAdv
[0]);
4946 Values
.Add(DirNamesAdv
[1]);
4947 Values
.Add(DirNamesAdv
[2]);
4948 Values
.Add(DirNamesAdv
[3]);
4950 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4952 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4953 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4955 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4957 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4958 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4959 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4960 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4961 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4962 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4964 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4966 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4967 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4968 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4969 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4971 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4973 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4974 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4975 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4976 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4978 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4980 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4981 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4983 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4985 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4986 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4987 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4988 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4989 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4990 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4992 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4994 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4995 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4996 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4997 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4998 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4999 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
5000 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
5002 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
5004 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
5005 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
5006 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
5007 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
5009 else if KeyName
= _lc
[I_PROP_TR_DAMAGE_KIND
] then
5011 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_0
]);
5012 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_3
]);
5013 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_4
]);
5014 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_5
]);
5015 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_6
]);
5016 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_7
]);
5017 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_8
]);
5019 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
5020 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
5021 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
5022 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
5023 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
5024 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
5025 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
5026 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
5027 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
5028 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
5029 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
5030 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
5031 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
5032 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
5033 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
5034 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
5035 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
5036 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
5037 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
5039 Values
.Add(BoolNames
[True]);
5040 Values
.Add(BoolNames
[False]);
5045 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
5047 _id
, a
, r
, c
: Integer;
5057 if SelectedObjectCount() <> 1 then
5059 if not SelectedObjects
[GetFirstSelected()].Live
then
5063 if not CheckProperty() then
5069 _id
:= GetFirstSelected();
5071 r
:= vleObjectProperty
.Row
;
5072 c
:= vleObjectProperty
.Col
;
5074 case SelectedObjects
[_id
].ObjectType
of
5077 with gPanels
[SelectedObjects
[_id
].ID
] do
5079 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5080 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5081 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
5082 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
5084 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
5086 // Сброс ссылки на триггеры смены текстуры:
5087 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
5088 if gTriggers
<> nil then
5089 for a
:= 0 to High(gTriggers
) do
5091 if (gTriggers
[a
].TriggerType
<> 0) and
5092 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
5093 gTriggers
[a
].TexturePanel
:= -1;
5094 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
5095 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
5096 gTriggers
[a
].Data
.ShotPanelID
:= -1;
5099 // Сброс ссылки на триггеры лифта:
5100 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
5101 if gTriggers
<> nil then
5102 for a
:= 0 to High(gTriggers
) do
5103 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
5104 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
5105 gTriggers
[a
].Data
.PanelID
:= -1;
5107 // Сброс ссылки на триггеры двери:
5108 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
5109 if gTriggers
<> nil then
5110 for a
:= 0 to High(gTriggers
) do
5111 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5112 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
5113 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
5114 gTriggers
[a
].Data
.PanelID
:= -1;
5116 if IsTexturedPanel(PanelType
) then
5117 begin // Может быть текстура
5118 if TextureName
<> '' then
5119 begin // Была текстура
5120 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
5121 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
5130 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
5132 if TextureName
<> '' then
5133 begin // Есть текстура
5134 // Обычная текстура:
5135 if not IsSpecialTexture(TextureName
) then
5137 g_GetTextureSizeByName(TextureName
,
5138 TextureWidth
, TextureHeight
);
5140 // Проверка кратности размеров панели:
5142 if TextureWidth
<> 0 then
5143 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
5145 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
5149 if Res
and (TextureHeight
<> 0) then
5150 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
5152 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
5159 if not g_GetTexture(TextureName
, TextureID
) then
5160 // Не удалось загрузить текстуру, рисуем NOTEXTURE
5161 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5163 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5164 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
5166 TextureHeight
:= NH
;
5169 TextureID
:= TEXTURE_SPECIAL_NONE
;
5179 TextureID
:= TEXTURE_SPECIAL_NONE
;
5182 else // Спец.текстура
5186 TextureID
:= SpecialTextureID(TextureName
);
5189 else // Нет текстуры
5193 TextureID
:= TEXTURE_SPECIAL_NONE
;
5196 else // Не может быть текстуры
5203 TextureID
:= TEXTURE_SPECIAL_NONE
;
5210 with gItems
[SelectedObjects
[_id
].ID
] do
5212 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5213 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5214 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5215 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5221 with gMonsters
[SelectedObjects
[_id
].ID
] do
5223 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5224 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5225 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5231 with gAreas
[SelectedObjects
[_id
].ID
] do
5233 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5234 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5235 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5241 with gTriggers
[SelectedObjects
[_id
].ID
] do
5243 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5244 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5245 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
5246 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
5247 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
5248 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
5249 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
5254 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]]);
5255 FillByte(Data
.MapName
[0], 16, 0);
5257 Move(s
[1], Data
.MapName
[0], Min(Length(s
), 16));
5262 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
5263 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
5266 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5268 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
5269 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
5270 if Data
.Count
< 1 then
5272 if TriggerType
= TRIGGER_PRESS
then
5273 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
5276 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
5277 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
5280 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5281 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5286 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5287 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
5288 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
5293 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]]);
5294 FillByte(Data
.SoundName
[0], 64, 0);
5296 Move(s
[1], Data
.SoundName
[0], Min(Length(s
), 64));
5298 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
5299 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
5300 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
5301 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
5302 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
5305 TRIGGER_SPAWNMONSTER
:
5307 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
5308 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
5309 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
5310 if Data
.MonHealth
< 0 then
5311 Data
.MonHealth
:= 0;
5312 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
5313 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5314 if Data
.MonCount
< 1 then
5316 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5317 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5318 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5320 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
5322 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
5324 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
5326 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
5328 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
5334 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
5335 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5336 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5337 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5338 if Data
.ItemCount
< 1 then
5339 Data
.ItemCount
:= 1;
5340 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5341 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5342 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5347 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]]);
5348 FillByte(Data
.MusicName
[0], 64, 0);
5350 Move(s
[1], Data
.MusicName
[0], Min(Length(s
), 64));
5352 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
5353 Data
.MusicAction
:= 1
5355 Data
.MusicAction
:= 0;
5360 Data
.PushAngle
:= Min(
5361 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
5362 Data
.PushForce
:= Min(
5363 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
5364 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
5369 Data
.ScoreAction
:= 0;
5370 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
5371 Data
.ScoreAction
:= 1
5372 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
5373 Data
.ScoreAction
:= 2
5374 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
5375 Data
.ScoreAction
:= 3;
5376 Data
.ScoreCount
:= Min(Max(
5377 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5378 Data
.ScoreTeam
:= 0;
5379 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
5381 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
5383 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
5384 Data
.ScoreTeam
:= 3;
5385 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
5386 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
5391 Data
.MessageKind
:= 0;
5392 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
5393 Data
.MessageKind
:= 1;
5395 Data
.MessageSendTo
:= 0;
5396 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
5397 Data
.MessageSendTo
:= 1
5398 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
5399 Data
.MessageSendTo
:= 2
5400 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
5401 Data
.MessageSendTo
:= 3
5402 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
5403 Data
.MessageSendTo
:= 4
5404 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
5405 Data
.MessageSendTo
:= 5;
5407 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]]);
5408 FillByte(Data
.MessageText
[0], 100, 0);
5410 Move(s
[1], Data
.MessageText
[0], Min(Length(s
), 100));
5412 Data
.MessageTime
:= Min(Max(
5413 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
5418 Data
.DamageValue
:= Min(Max(
5419 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
5420 Data
.DamageInterval
:= Min(Max(
5421 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5422 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_KIND
]];
5423 if s
= _lc
[I_PROP_TR_DAMAGE_KIND_3
] then
5424 Data
.DamageKind
:= 3
5425 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_4
] then
5426 Data
.DamageKind
:= 4
5427 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_5
] then
5428 Data
.DamageKind
:= 5
5429 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_6
] then
5430 Data
.DamageKind
:= 6
5431 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_7
] then
5432 Data
.DamageKind
:= 7
5433 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_8
] then
5434 Data
.DamageKind
:= 8
5436 Data
.DamageKind
:= 0;
5441 Data
.HealValue
:= Min(Max(
5442 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
5443 Data
.HealInterval
:= Min(Max(
5444 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5445 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
5446 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5451 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
5452 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
5453 Data
.ShotTarget
:= 0;
5454 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
5455 Data
.ShotTarget
:= 1
5456 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
5457 Data
.ShotTarget
:= 2
5458 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
5459 Data
.ShotTarget
:= 3
5460 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
5461 Data
.ShotTarget
:= 4
5462 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
5463 Data
.ShotTarget
:= 5
5464 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
5465 Data
.ShotTarget
:= 6;
5466 Data
.ShotIntSight
:= Min(Max(
5467 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
5469 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
5471 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
5473 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
5475 Data
.ShotAngle
:= Min(
5476 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
5477 Data
.ShotWait
:= Min(Max(
5478 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5479 Data
.ShotAccuracy
:= Min(Max(
5480 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
5481 Data
.ShotAmmo
:= Min(Max(
5482 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
5483 Data
.ShotIntReload
:= Min(Max(
5484 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
5489 Data
.FXCount
:= Min(Max(
5490 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5491 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
5493 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
5494 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
5495 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
5496 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
5497 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5498 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
5499 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5500 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
5501 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5502 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
5503 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5504 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
5505 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5506 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
5509 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
5510 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
5513 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
5514 Data
.FXColorR
:= a
and $FF;
5515 Data
.FXColorG
:= (a
shr 8) and $FF;
5516 Data
.FXColorB
:= (a
shr 16) and $FF;
5517 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
5521 Data
.FXWait
:= Min(Max(
5522 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5523 Data
.FXVelX
:= Min(Max(
5524 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
5525 Data
.FXVelY
:= Min(Max(
5526 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
5527 Data
.FXSpreadL
:= Min(Max(
5528 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
5529 Data
.FXSpreadR
:= Min(Max(
5530 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
5531 Data
.FXSpreadU
:= Min(Max(
5532 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
5533 Data
.FXSpreadD
:= Min(Max(
5534 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
5543 vleObjectProperty
.Row
:= r
;
5544 vleObjectProperty
.Col
:= c
;
5547 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5551 i
:= lbTextureList
.ItemIndex
;
5555 if Application
.MessageBox(PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5556 [SelectedTexture()])),
5557 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5558 MB_ICONQUESTION
or MB_YESNO
or
5559 MB_DEFBUTTON1
) <> idYes
then
5562 if gPanels
<> nil then
5563 for a
:= 0 to High(gPanels
) do
5564 if (gPanels
[a
].PanelType
<> 0) and
5565 (gPanels
[a
].TextureName
= SelectedTexture()) then
5567 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5571 g_DeleteTexture(SelectedTexture());
5572 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5574 slInvalidTextures
.Delete(i
);
5575 if lbTextureList
.ItemIndex
> -1 then
5576 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5579 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5581 if Application
.MessageBox(PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]), PChar(_lc
[I_MSG_CLEAR_MAP
]), MB_ICONQUESTION
or MB_YESNO
or MB_DEFBUTTON1
) = mrYes
then
5585 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5589 if UndoBuffer
= nil then
5591 if UndoBuffer
[High(UndoBuffer
)] = nil then
5594 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5595 with UndoBuffer
[High(UndoBuffer
)][a
] do
5603 UNDO_DELETE_ITEM
: AddItem(Item
);
5604 UNDO_DELETE_AREA
: AddArea(Area
);
5605 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5606 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5607 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5608 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5609 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5610 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5611 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5615 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5617 RemoveSelectFromObjects();
5619 miUndo
.Enabled
:= UndoBuffer
<> nil;
5623 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5626 CopyBuffer
: TCopyRecArray
;
5630 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5632 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5634 if Result
= 0 then // Одного типа
5635 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5638 procedure QuickSortCopyBuffer(L
, R
: Integer);
5646 P
:= CopyBuffer
[(L
+ R
) shr 1];
5649 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5651 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5657 CopyBuffer
[I
] := CopyBuffer
[J
];
5665 QuickSortCopyBuffer(L
, J
);
5672 if SelectedObjects
= nil then
5678 // Копируем объекты:
5679 for a
:= 0 to High(SelectedObjects
) do
5680 if SelectedObjects
[a
].Live
then
5681 with SelectedObjects
[a
] do
5683 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5684 b
:= High(CopyBuffer
);
5685 CopyBuffer
[b
].ID
:= ID
;
5686 CopyBuffer
[b
].Panel
:= nil;
5691 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5692 New(CopyBuffer
[b
].Panel
);
5693 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5698 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5699 CopyBuffer
[b
].Item
:= gItems
[ID
];
5704 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5705 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5710 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5711 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5716 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5717 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5722 // Сортировка по ID:
5723 if CopyBuffer
<> nil then
5725 QuickSortCopyBuffer(0, b
);
5728 // Пестановка ссылок триггеров:
5729 for a
:= 0 to Length(CopyBuffer
)-1 do
5730 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5732 case CopyBuffer
[a
].Trigger
.TriggerType
of
5733 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5734 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5735 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5736 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5740 for b
:= 0 to Length(CopyBuffer
)-1 do
5741 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5742 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5744 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5749 // Этих панелей нет среди копируемых:
5751 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5754 TRIGGER_PRESS
, TRIGGER_ON
,
5755 TRIGGER_OFF
, TRIGGER_ONOFF
:
5756 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5760 for b
:= 0 to Length(CopyBuffer
)-1 do
5761 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5762 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5764 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5769 // Этих монстров нет среди копируемых:
5771 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5775 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5779 for b
:= 0 to Length(CopyBuffer
)-1 do
5780 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5781 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5783 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5788 // Этих панелей нет среди копируемых:
5790 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5794 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5798 for b
:= 0 to Length(CopyBuffer
)-1 do
5799 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5800 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5802 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5807 // Этих панелей нет среди копируемых:
5809 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5814 str
:= CopyBufferToString(CopyBuffer
);
5815 ClipBoard
.AsText
:= str
;
5817 for a
:= 0 to Length(CopyBuffer
)-1 do
5818 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5819 (CopyBuffer
[a
].Panel
<> nil) then
5820 Dispose(CopyBuffer
[a
].Panel
);
5825 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5828 CopyBuffer
: TCopyRecArray
;
5830 swad
, ssec
, sres
: String;
5836 pmin
.X
:= High(pmin
.X
);
5837 pmin
.Y
:= High(pmin
.Y
);
5839 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
, pmin
);
5840 rel
:= not(ssShift
in GetKeyShiftState());
5842 if CopyBuffer
= nil then
5845 RemoveSelectFromObjects();
5847 h
:= High(CopyBuffer
);
5849 with CopyBuffer
[a
] do
5853 if Panel
<> nil then
5857 Panel
^.X
:= Panel
^.X
- pmin
.X
- MapOffset
.X
+ 32;
5858 Panel
^.Y
:= Panel
^.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5861 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5862 Panel
^.TextureWidth
:= 1;
5863 Panel
^.TextureHeight
:= 1;
5865 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5866 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5867 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5868 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5869 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5870 (Panel
^.TextureName
= '') then
5871 begin // Нет или не может быть текстуры:
5873 else // Есть текстура:
5875 // Обычная текстура:
5876 if not IsSpecialTexture(Panel
^.TextureName
) then
5878 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5882 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5883 AddTexture(swad
, ssec
, sres
, True);
5884 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5888 g_GetTextureSizeByName(Panel
^.TextureName
,
5889 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5891 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5893 Panel
^.TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5894 g_GetTextureSizeByID(NoTextureID
, Panel
^.TextureWidth
, Panel
^.TextureHeight
);
5897 else // Спец.текстура:
5899 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5900 with MainForm
.lbTextureList
.Items
do
5901 if IndexOf(Panel
^.TextureName
) = -1 then
5902 Add(Panel
^.TextureName
);
5906 ID
:= AddPanel(Panel
^);
5908 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5909 SelectObject(OBJECT_PANEL
, ID
, True);
5916 Item
.X
:= Item
.X
- pmin
.X
- MapOffset
.X
+ 32;
5917 Item
.Y
:= Item
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5920 ID
:= AddItem(Item
);
5921 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5922 SelectObject(OBJECT_ITEM
, ID
, True);
5929 Monster
.X
:= Monster
.X
- pmin
.X
- MapOffset
.X
+ 32;
5930 Monster
.Y
:= Monster
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5933 ID
:= AddMonster(Monster
);
5934 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5935 SelectObject(OBJECT_MONSTER
, ID
, True);
5942 Area
.X
:= Area
.X
- pmin
.X
- MapOffset
.X
+ 32;
5943 Area
.Y
:= Area
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5946 ID
:= AddArea(Area
);
5947 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5948 SelectObject(OBJECT_AREA
, ID
, True);
5956 X
:= X
- pmin
.X
- MapOffset
.X
+ 32;
5957 Y
:= Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5962 Data
.TargetPoint
.X
:=
5963 Data
.TargetPoint
.X
- pmin
.X
- MapOffset
.X
+ 32;
5964 Data
.TargetPoint
.Y
:=
5965 Data
.TargetPoint
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5967 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5969 Data
.tX
:= Data
.tX
- pmin
.X
- MapOffset
.X
+ 32;
5970 Data
.tY
:= Data
.tY
- pmin
.Y
- MapOffset
.Y
+ 32;
5972 TRIGGER_SPAWNMONSTER
:
5975 Data
.MonPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5977 Data
.MonPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5982 Data
.ItemPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5984 Data
.ItemPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5989 Data
.ShotPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5991 Data
.ShotPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5996 ID
:= AddTrigger(Trigger
);
5997 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5998 SelectObject(OBJECT_TRIGGER
, ID
, True);
6003 // Переставляем ссылки триггеров:
6004 for a
:= 0 to High(CopyBuffer
) do
6005 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
6007 case CopyBuffer
[a
].Trigger
.TriggerType
of
6008 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6009 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6010 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6011 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
6012 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
6013 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
6015 TRIGGER_PRESS
, TRIGGER_ON
,
6016 TRIGGER_OFF
, TRIGGER_ONOFF
:
6017 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
6018 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
6019 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
6022 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
6023 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
6024 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
6027 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
6028 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
6029 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
6038 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
6041 DeleteSelectedObjects();
6044 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
6046 Key
, FileName
: String;
6049 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
6051 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
6053 with ChooseTypeForm
, vleObjectProperty
do
6054 begin // Выбор типа панели:
6055 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
6056 lbTypeSelect
.Items
.Clear();
6058 for b
:= 0 to High(PANELNAMES
) do
6060 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
6061 if Values
[Key
] = PANELNAMES
[b
] then
6062 lbTypeSelect
.ItemIndex
:= b
;
6065 if ShowModal() = mrOK
then
6067 b
:= lbTypeSelect
.ItemIndex
;
6068 Values
[Key
] := PANELNAMES
[b
];
6069 vleObjectPropertyApply(Sender
);
6073 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
6074 SelectFlag
:= SELECTFLAG_TELEPORT
6075 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
6076 SelectFlag
:= SELECTFLAG_SPAWNPOINT
6077 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
6078 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
6079 SelectFlag
:= SELECTFLAG_DOOR
6080 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
6082 DrawPressRect
:= False;
6083 SelectFlag
:= SELECTFLAG_TEXTURE
;
6085 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
6086 SelectFlag
:= SELECTFLAG_SHOTPANEL
6087 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
6088 SelectFlag
:= SELECTFLAG_LIFT
6089 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
6090 SelectFlag
:= SELECTFLAG_MONSTER
6091 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
6093 SelectFlag
:= SELECTFLAG_NONE
;
6094 DrawPressRect
:= True;
6096 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
6097 begin // Выбор следующей карты:
6098 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
6099 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
6100 SelectMapForm
.GetMaps(FileName
);
6102 if SelectMapForm
.ShowModal() = mrOK
then
6104 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6105 vleObjectPropertyApply(Sender
);
6108 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
6109 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
6110 begin // Выбор файла звука/музыки:
6111 AddSoundForm
.OKFunction
:= nil;
6112 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
6113 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
6115 if (AddSoundForm
.ShowModal() = mrOk
) then
6117 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
6118 vleObjectPropertyApply(Sender
);
6121 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
6122 with ActivationTypeForm
, vleObjectProperty
do
6123 begin // Выбор типов активации:
6124 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
6125 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
6126 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
6127 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
6128 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
6129 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
6131 if ShowModal() = mrOK
then
6134 if cbPlayerCollide
.Checked
then
6135 b
:= ACTIVATE_PLAYERCOLLIDE
;
6136 if cbMonsterCollide
.Checked
then
6137 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
6138 if cbPlayerPress
.Checked
then
6139 b
:= b
or ACTIVATE_PLAYERPRESS
;
6140 if cbMonsterPress
.Checked
then
6141 b
:= b
or ACTIVATE_MONSTERPRESS
;
6142 if cbShot
.Checked
then
6143 b
:= b
or ACTIVATE_SHOT
;
6144 if cbNoMonster
.Checked
then
6145 b
:= b
or ACTIVATE_NOMONSTER
;
6147 Values
[Key
] := ActivateToStr(b
);
6148 vleObjectPropertyApply(Sender
);
6151 else if Key
= _lc
[I_PROP_TR_KEYS
] then
6152 with KeysForm
, vleObjectProperty
do
6153 begin // Выбор необходимых ключей:
6154 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
6155 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
6156 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
6157 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
6158 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
6160 if ShowModal() = mrOK
then
6163 if cbRedKey
.Checked
then
6165 if cbGreenKey
.Checked
then
6166 b
:= b
or KEY_GREEN
;
6167 if cbBlueKey
.Checked
then
6169 if cbRedTeam
.Checked
then
6170 b
:= b
or KEY_REDTEAM
;
6171 if cbBlueTeam
.Checked
then
6172 b
:= b
or KEY_BLUETEAM
;
6174 Values
[Key
] := KeyToStr(b
);
6175 vleObjectPropertyApply(Sender
);
6178 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
6179 with ChooseTypeForm
, vleObjectProperty
do
6180 begin // Выбор типа эффекта:
6181 Caption
:= _lc
[I_CAP_FX_TYPE
];
6182 lbTypeSelect
.Items
.Clear();
6184 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
6185 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6187 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
6189 if ShowModal() = mrOK
then
6191 b
:= lbTypeSelect
.ItemIndex
;
6192 Values
[Key
] := EffectToStr(b
);
6193 vleObjectPropertyApply(Sender
);
6196 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
6197 with ChooseTypeForm
, vleObjectProperty
do
6198 begin // Выбор типа монстра:
6199 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
6200 lbTypeSelect
.Items
.Clear();
6202 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
6203 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
6205 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
6207 if ShowModal() = mrOK
then
6209 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
6210 Values
[Key
] := MonsterToStr(b
);
6211 vleObjectPropertyApply(Sender
);
6214 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
6215 with ChooseTypeForm
, vleObjectProperty
do
6216 begin // Выбор типа предмета:
6217 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
6218 lbTypeSelect
.Items
.Clear();
6220 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
6221 lbTypeSelect
.Items
.Add(ItemToStr(b
));
6222 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
6223 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
6224 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
6225 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
6226 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
6227 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
6229 b
:= StrToItem(Values
[Key
]);
6230 if b
>= ITEM_BOTTLE
then
6232 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
6234 if ShowModal() = mrOK
then
6236 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
6237 if b
>= ITEM_WEAPON_KASTET
then
6239 Values
[Key
] := ItemToStr(b
);
6240 vleObjectPropertyApply(Sender
);
6243 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
6244 with ChooseTypeForm
, vleObjectProperty
do
6245 begin // Выбор типа предмета:
6246 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
6247 lbTypeSelect
.Items
.Clear();
6249 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
6250 lbTypeSelect
.Items
.Add(ShotToStr(b
));
6252 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
6254 if ShowModal() = mrOK
then
6256 b
:= lbTypeSelect
.ItemIndex
;
6257 Values
[Key
] := ShotToStr(b
);
6258 vleObjectPropertyApply(Sender
);
6261 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
6262 with ChooseTypeForm
, vleObjectProperty
do
6263 begin // Выбор типа эффекта:
6264 Caption
:= _lc
[I_CAP_FX_TYPE
];
6265 lbTypeSelect
.Items
.Clear();
6267 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
6268 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
6269 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6270 lbTypeSelect
.ItemIndex
:= 1
6272 lbTypeSelect
.ItemIndex
:= 0;
6274 if ShowModal() = mrOK
then
6276 b
:= lbTypeSelect
.ItemIndex
;
6278 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
6280 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
6281 vleObjectPropertyApply(Sender
);
6284 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
6285 with ChooseTypeForm
, vleObjectProperty
do
6286 begin // Выбор подтипа эффекта:
6287 Caption
:= _lc
[I_CAP_FX_TYPE
];
6288 lbTypeSelect
.Items
.Clear();
6290 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6292 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
6293 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6295 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
6298 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
6299 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
6300 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
6301 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
6302 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
6303 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
6304 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
6305 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
6306 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
6307 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
6308 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
6309 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
6310 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
6311 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
6312 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
6313 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
6314 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
6317 if ShowModal() = mrOK
then
6319 b
:= lbTypeSelect
.ItemIndex
;
6321 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6322 Values
[Key
] := EffectToStr(b
+ 1)
6324 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
6325 if b
= TRIGGER_EFFECT_LLIQUID
then
6326 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
6327 if b
= TRIGGER_EFFECT_DLIQUID
then
6328 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
6329 if b
= TRIGGER_EFFECT_BLOOD
then
6330 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
6331 if b
= TRIGGER_EFFECT_SPARK
then
6332 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
6333 if b
= TRIGGER_EFFECT_BUBBLE
then
6334 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
6337 vleObjectPropertyApply(Sender
);
6340 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
6341 with vleObjectProperty
do
6342 begin // Выбор цвета эффекта:
6343 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
6344 if ColorDialog
.Execute
then
6346 Values
[Key
] := IntToStr(ColorDialog
.Color
);
6347 vleObjectPropertyApply(Sender
);
6350 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
6351 begin // Смена текстуры:
6352 vleObjectProperty
.Values
[Key
] := SelectedTexture();
6353 vleObjectPropertyApply(Sender
);
6357 procedure TMainForm
.vleObjectPropertyApply(Sender
: TObject
);
6359 // hack to prevent empty ID in list
6360 RenderPanel
.SetFocus();
6361 bApplyProperty
.Click();
6362 vleObjectProperty
.SetFocus();
6365 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
6367 FileName
, Section
, Res
: String;
6369 if OpenedMap
= '' then
6371 aSaveMapAsExecute(nil);
6375 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
6377 SaveMap(FileName
+':\'+Res
);
6380 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
6382 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
6384 if OpenDialog
.Execute() then
6386 OpenMapFile(OpenDialog
.FileName
);
6387 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
6391 procedure TMainForm
.OpenMapFile(FileName
: String);
6393 if (Pos('.ini', LowerCase(ExtractFileName(FileName
))) > 0) then
6397 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
6398 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
6399 pLoadProgress
.Show();
6404 LoadMapOld(FileName
);
6406 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(FileName
)]);
6408 pLoadProgress
.Hide();
6409 MainForm
.FormResize(Self
);
6411 else // Карты из WAD:
6413 OpenMap(FileName
, '');
6417 procedure TMainForm
.FormActivate(Sender
: TObject
);
6422 MainForm
.ActiveControl
:= RenderPanel
;
6425 if (gLanguage
= '') and not (fsModal
in SelectLanguageForm
.FormState
) then
6427 lang
:= SelectLanguageForm
.ShowModal();
6429 1: gLanguage
:= LANGUAGE_ENGLISH
;
6430 2: gLanguage
:= LANGUAGE_RUSSIAN
;
6431 else gLanguage
:= LANGUAGE_ENGLISH
;
6434 config
:= TConfig
.CreateFile(CfgFileName
);
6435 config
.WriteStr('Editor', 'Language', gLanguage
);
6436 config
.SaveFile(CfgFileName
);
6440 //e_WriteLog('Read language file', MSG_NOTIFY);
6441 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
6442 g_Language_Set(gLanguage
);
6445 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
6451 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6453 if not OpenDialog
.Execute() then
6456 FileName
:= OpenDialog
.FileName
;
6457 SelectMapForm
.Caption
:= _lc
[I_CAP_REMOVE
];
6458 SelectMapForm
.lbMapList
.Items
.Clear();
6459 SelectMapForm
.GetMaps(FileName
);
6461 if SelectMapForm
.ShowModal() <> mrOK
then
6464 MapName
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6465 if Application
.MessageBox(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
6468 g_DeleteResource(FileName
, '', MapName
, res
);
6471 Application
.MessageBox(PChar('Cant delete map res=' + IntToStr(res
)), PChar('Map not deleted!'), MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
6475 Application
.MessageBox(
6476 PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
], [MapName
])),
6477 PChar(_lc
[I_MSG_MAP_DELETED
]),
6478 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
6481 // Удалили текущую карту - сохранять по старому ее нельзя:
6482 if OpenedMap
= (FileName
+ ':\' + MapName
) then
6486 MainForm
.Caption
:= FormCaption
6490 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
6491 var Key
: Word; Shift
: TShiftState
);
6493 if Key
= VK_RETURN
then
6494 vleObjectPropertyApply(Sender
);
6497 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
6502 if (ID
= 0) and (MoveType
= 0) then
6504 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
6506 if (ID
> DWORD(High(gPanels
))) then
6511 if MoveType
= 0 then // to Back
6513 if gTriggers
<> nil then
6514 for a
:= 0 to High(gTriggers
) do
6515 with gTriggers
[a
] do
6517 if TriggerType
= TRIGGER_NONE
then
6520 if TexturePanel
= _id
then
6523 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
6527 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6528 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6529 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6530 if Data
.PanelID
= _id
then
6533 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
6537 if Data
.ShotPanelID
= _id
then
6538 Data
.ShotPanelID
:= 0
6540 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
6541 Inc(Data
.ShotPanelID
);
6545 tmp
:= gPanels
[_id
];
6547 for a
:= _id
downto 1 do
6548 gPanels
[a
] := gPanels
[a
-1];
6556 if gTriggers
<> nil then
6557 for a
:= 0 to High(gTriggers
) do
6558 with gTriggers
[a
] do
6560 if TriggerType
= TRIGGER_NONE
then
6563 if TexturePanel
= _id
then
6564 TexturePanel
:= High(gPanels
)
6566 if TexturePanel
> _id
then
6570 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6571 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6572 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6573 if Data
.PanelID
= _id
then
6574 Data
.PanelID
:= High(gPanels
)
6576 if Data
.PanelID
> _id
then
6580 if Data
.ShotPanelID
= _id
then
6581 Data
.ShotPanelID
:= High(gPanels
)
6583 if Data
.ShotPanelID
> _id
then
6584 Dec(Data
.ShotPanelID
);
6588 tmp
:= gPanels
[_id
];
6590 for a
:= _id
to High(gPanels
)-1 do
6591 gPanels
[a
] := gPanels
[a
+1];
6593 gPanels
[High(gPanels
)] := tmp
;
6595 ID
:= High(gPanels
);
6599 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6603 if SelectedObjects
= nil then
6606 for a
:= 0 to High(SelectedObjects
) do
6607 with SelectedObjects
[a
] do
6608 if Live
and (ObjectType
= OBJECT_PANEL
) then
6610 SelectedObjects
[0] := SelectedObjects
[a
];
6611 SetLength(SelectedObjects
, 1);
6618 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6622 if SelectedObjects
= nil then
6625 for a
:= 0 to High(SelectedObjects
) do
6626 with SelectedObjects
[a
] do
6627 if Live
and (ObjectType
= OBJECT_PANEL
) then
6629 SelectedObjects
[0] := SelectedObjects
[a
];
6630 SetLength(SelectedObjects
, 1);
6637 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6641 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6643 if not SaveDialog
.Execute() then
6646 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6648 if SaveMapForm
.ShowModal() <> mrOK
then
6651 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6652 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6653 OpenedWAD
:= SaveDialog
.FileName
;
6655 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6656 // Такая карта уже недавно открывалась:
6658 RecentFiles
.Delete(idx
);
6659 RecentFiles
.Insert(0, OpenedMap
);
6664 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6665 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6666 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6669 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6673 RemoveSelectFromObjects();
6675 case pcObjects
.ActivePageIndex
+1 of
6677 if gPanels
<> nil then
6678 for a
:= 0 to High(gPanels
) do
6679 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6680 SelectObject(OBJECT_PANEL
, a
, True);
6682 if gItems
<> nil then
6683 for a
:= 0 to High(gItems
) do
6684 if gItems
[a
].ItemType
<> ITEM_NONE
then
6685 SelectObject(OBJECT_ITEM
, a
, True);
6687 if gMonsters
<> nil then
6688 for a
:= 0 to High(gMonsters
) do
6689 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6690 SelectObject(OBJECT_MONSTER
, a
, True);
6692 if gAreas
<> nil then
6693 for a
:= 0 to High(gAreas
) do
6694 if gAreas
[a
].AreaType
<> AREA_NONE
then
6695 SelectObject(OBJECT_AREA
, a
, True);
6697 if gTriggers
<> nil then
6698 for a
:= 0 to High(gTriggers
) do
6699 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6700 SelectObject(OBJECT_TRIGGER
, a
, True);
6703 RecountSelectedObjects();
6706 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6708 DotEnable
:= not DotEnable
;
6709 (Sender
as TToolButton
).Down
:= DotEnable
;
6712 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6715 // FIXME: this is a shitty hack
6716 if not gDataLoaded
then
6718 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6720 e_WriteLog('Loading data', MSG_NOTIFY
);
6721 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6722 e_WriteLog('Loading more data', MSG_NOTIFY
);
6724 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6725 gDataLoaded
:= True;
6726 MainForm
.FormResize(nil);
6729 if StartMap
<> '' then
6737 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6739 if PreviewMode
= 2 then
6742 if PreviewMode
= 0 then
6744 Splitter2
.Visible
:= False;
6745 Splitter1
.Visible
:= False;
6746 StatusBar
.Visible
:= False;
6747 PanelObjs
.Visible
:= False;
6748 PanelProps
.Visible
:= False;
6749 MainToolBar
.Visible
:= False;
6750 sbHorizontal
.Visible
:= False;
6751 sbVertical
.Visible
:= False;
6755 StatusBar
.Visible
:= True;
6756 PanelObjs
.Visible
:= True;
6757 PanelProps
.Visible
:= True;
6758 Splitter2
.Visible
:= True;
6759 Splitter1
.Visible
:= True;
6760 MainToolBar
.Visible
:= True;
6761 sbHorizontal
.Visible
:= True;
6762 sbVertical
.Visible
:= True;
6765 PreviewMode
:= PreviewMode
xor 1;
6766 (Sender
as TMenuItem
).Checked
:= PreviewMode
> 0;
6771 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6773 SwitchLayer(LAYER_BACK
);
6776 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6778 SwitchLayer(LAYER_WALLS
);
6781 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6783 SwitchLayer(LAYER_FOREGROUND
);
6786 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6788 SwitchLayer(LAYER_STEPS
);
6791 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6793 SwitchLayer(LAYER_WATER
);
6796 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6798 SwitchLayer(LAYER_ITEMS
);
6801 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6803 SwitchLayer(LAYER_MONSTERS
);
6806 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6808 SwitchLayer(LAYER_AREAS
);
6811 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6813 SwitchLayer(LAYER_TRIGGERS
);
6816 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6822 for a
:= 0 to High(LayerEnabled
) do
6823 b
:= b
and LayerEnabled
[a
];
6827 ShowLayer(LAYER_BACK
, b
);
6828 ShowLayer(LAYER_WALLS
, b
);
6829 ShowLayer(LAYER_FOREGROUND
, b
);
6830 ShowLayer(LAYER_STEPS
, b
);
6831 ShowLayer(LAYER_WATER
, b
);
6832 ShowLayer(LAYER_ITEMS
, b
);
6833 ShowLayer(LAYER_MONSTERS
, b
);
6834 ShowLayer(LAYER_AREAS
, b
);
6835 ShowLayer(LAYER_TRIGGERS
, b
);
6838 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6843 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6845 if DotStep
= DotStepOne
then
6846 DotStep
:= DotStepTwo
6848 DotStep
:= DotStepOne
;
6850 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6851 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6854 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6859 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6861 SnapToGrid
:= not SnapToGrid
;
6863 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6864 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6866 miSnapToGrid
.Checked
:= SnapToGrid
;
6869 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6871 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6872 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6874 pcObjects
.ActivePageIndex
:= 0;
6877 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6879 SaveMiniMapForm
.ShowModal();
6882 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6884 lbTextureList
.ItemIndex
:= -1;
6885 lTextureWidth
.Caption
:= '';
6886 lTextureHeight
.Caption
:= '';
6889 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6891 PackMapForm
.ShowModal();
6894 type SSArray
= array of String;
6896 function ParseString (Str
: AnsiString): SSArray
;
6897 function GetStr (var Str
: AnsiString): AnsiString;
6901 if Str
[1] = '"' then
6902 for b
:= 1 to Length(Str
) do
6903 if (b
= Length(Str
)) or (Str
[b
+ 1] = '"') then
6905 Result
:= Copy(Str
, 2, b
- 1);
6906 Delete(Str
, 1, b
+ 1);
6910 for a
:= 1 to Length(Str
) do
6911 if (a
= Length(Str
)) or (Str
[a
+ 1] = ' ') then
6913 Result
:= Copy(Str
, 1, a
);
6914 Delete(Str
, 1, a
+ 1);
6924 SetLength(Result
, Length(Result
)+1);
6925 Result
[High(Result
)] := GetStr(Str
);
6929 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6931 newWAD
, oldWAD
, tempMap
, ext
: String;
6938 // Ignore while map testing in progress
6939 if MapTestProcess
<> nil then
6942 // Сохраняем временную карту:
6945 newWAD
:= Format('%s/temp%.4d', [MapsDir
, time
]);
6947 until not FileExists(newWAD
);
6948 if OpenedMap
<> '' then
6950 oldWad
:= g_ExtractWadName(OpenedMap
);
6951 newWad
:= newWad
+ ExtractFileExt(oldWad
);
6952 if CopyFile(oldWad
, newWad
) = false then
6953 e_WriteLog('MapTest: unable to copy [' + oldWad
+ '] to [' + newWad
+ ']', MSG_WARNING
)
6957 newWad
:= newWad
+ '.wad'
6959 tempMap
:= newWAD
+ ':\' + TEST_MAP_NAME
;
6964 if TestOptionsTwoPlayers
then
6966 if TestOptionsTeamDamage
then
6968 if TestOptionsAllowExit
then
6970 if TestOptionsWeaponStay
then
6972 if TestOptionsMonstersDM
then
6976 proc
:= TProcessUTF8
.Create(nil);
6977 proc
.Executable
:= TestD2dExe
;
6979 // TODO: get real executable name from Info.plist
6980 if LowerCase(ExtractFileExt(TestD2dExe
)) = '.app' then
6981 proc
.Executable
:= TestD2dExe
+ DirectorySeparator
+ 'Contents' + DirectorySeparator
+ 'MacOS' + DirectorySeparator
+ 'Doom2DF';
6983 proc
.Parameters
.Add('-map');
6984 proc
.Parameters
.Add(tempMap
);
6985 proc
.Parameters
.Add('-gm');
6986 proc
.Parameters
.Add(TestGameMode
);
6987 proc
.Parameters
.Add('-limt');
6988 proc
.Parameters
.Add(TestLimTime
);
6989 proc
.Parameters
.Add('-lims');
6990 proc
.Parameters
.Add(TestLimScore
);
6991 proc
.Parameters
.Add('-opt');
6992 proc
.Parameters
.Add(IntToStr(opt
));
6993 proc
.Parameters
.Add('--debug');
6995 proc
.Parameters
.Add('--close');
6997 args
:= ParseString(TestD2DArgs
);
6998 for i
:= 0 to High(args
) do
6999 proc
.Parameters
.Add(args
[i
]);
7009 tbTestMap
.Enabled
:= False;
7010 MapTestFile
:= newWAD
;
7011 MapTestProcess
:= proc
;
7015 Application
.MessageBox(PChar(_lc
[I_MSG_EXEC_ERROR
]), 'FIXME', MB_OK
or MB_ICONERROR
);
7016 SysUtils
.DeleteFile(newWAD
);
7021 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
7022 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
7024 MapOffset
.Y
:= -sbVertical
.Position
;
7027 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
7028 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
7030 MapOffset
.X
:= -sbHorizontal
.Position
;
7033 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
7035 if OpenedWAD
<> '' then
7037 OpenMap(OpenedWAD
, '');
7041 procedure TMainForm
.selectall1Click(Sender
: TObject
);
7045 RemoveSelectFromObjects();
7047 if gPanels
<> nil then
7048 for a
:= 0 to High(gPanels
) do
7049 if gPanels
[a
].PanelType
<> PANEL_NONE
then
7050 SelectObject(OBJECT_PANEL
, a
, True);
7052 if gItems
<> nil then
7053 for a
:= 0 to High(gItems
) do
7054 if gItems
[a
].ItemType
<> ITEM_NONE
then
7055 SelectObject(OBJECT_ITEM
, a
, True);
7057 if gMonsters
<> nil then
7058 for a
:= 0 to High(gMonsters
) do
7059 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
7060 SelectObject(OBJECT_MONSTER
, a
, True);
7062 if gAreas
<> nil then
7063 for a
:= 0 to High(gAreas
) do
7064 if gAreas
[a
].AreaType
<> AREA_NONE
then
7065 SelectObject(OBJECT_AREA
, a
, True);
7067 if gTriggers
<> nil then
7068 for a
:= 0 to High(gTriggers
) do
7069 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
7070 SelectObject(OBJECT_TRIGGER
, a
, True);
7072 RecountSelectedObjects();
7075 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
7076 var NewSize
: Integer; var Accept
: Boolean);
7078 Accept
:= (NewSize
> 140);
7081 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
7082 var NewSize
: Integer; var Accept
: Boolean);
7084 Accept
:= (NewSize
> 110);
7087 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
7089 EditingProperties
:= True;
7092 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
7094 EditingProperties
:= False;
7097 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
7099 // Объекты передвигались:
7100 if MainForm
.ActiveControl
= RenderPanel
then
7102 if (Key
= VK_NUMPAD4
) or
7103 (Key
= VK_NUMPAD6
) or
7104 (Key
= VK_NUMPAD8
) or
7105 (Key
= VK_NUMPAD5
) or
7106 (Key
= Ord('V')) then
7109 // Быстрое превью карты:
7110 if Key
= Ord('E') then
7112 if PreviewMode
= 2 then
7115 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);