3 {$INCLUDE ../shared/a_modes.inc}
8 LCLIntf
, LCLType
, LMessages
, SysUtils
, Variants
, Classes
, Graphics
,
9 Controls
, Forms
, Dialogs
, ImgList
, StdCtrls
, Buttons
,
10 ComCtrls
, ValEdit
, Types
, ToolWin
, Menus
, ExtCtrls
,
11 CheckLst
, Grids
, OpenGLContext
, utils
, UTF8Process
;
17 TMainForm
= class(TForm
)
22 miMenuFile
: TMenuItem
;
26 miSaveMapAs
: TMenuItem
;
27 miOpenWadMap
: TMenuItem
;
29 miSaveMiniMap
: TMenuItem
;
30 miDeleteMap
: TMenuItem
;
35 miMenuEdit
: TMenuItem
;
42 miSelectAll
: TMenuItem
;
47 miMenuTools
: TMenuItem
;
48 miSnapToGrid
: TMenuItem
;
50 miSwitchGrid
: TMenuItem
;
51 miShowEdges
: TMenuItem
;
63 miMenuService
: TMenuItem
;
64 miCheckMap
: TMenuItem
;
65 miOptimmization
: TMenuItem
;
66 miMapPreview
: TMenuItem
;
69 miMenuSettings
: TMenuItem
;
70 miMapOptions
: TMenuItem
;
74 miMapTestSettings
: TMenuItem
;
76 miMenuHelp
: TMenuItem
;
78 // Скрытый пункт меню для Ctrl+Tab:
82 // Панель инструментов:
83 MainToolBar
: TToolBar
;
85 pLoadProgress
: TPanel
;
86 RenderPanel
: TOpenGLControl
;
87 tbNewMap
: TToolButton
;
88 tbOpenMap
: TToolButton
;
89 tbSaveMap
: TToolButton
;
90 tbOpenWadMap
: TToolButton
;
92 tbShowMap
: TToolButton
;
96 tbGridOn
: TToolButton
;
99 tbTestMap
: TToolButton
;
100 // Всплывающее меню для кнопки слоев:
102 miLayerP1
: TMenuItem
;
103 miLayerP2
: TMenuItem
;
104 miLayerP3
: TMenuItem
;
105 miLayerP4
: TMenuItem
;
106 miLayerP5
: TMenuItem
;
107 miLayerP6
: TMenuItem
;
108 miLayerP7
: TMenuItem
;
109 miLayerP8
: TMenuItem
;
110 miLayerP9
: TMenuItem
;
111 // Всплывающее меню для кнопки теста карты:
112 pmMapTest
: TPopupMenu
;
113 miMapTestPMSet
: TMenuItem
;
118 sbHorizontal
: TScrollBar
;
119 sbVertical
: TScrollBar
;
123 // Панель применения свойств:
124 PanelPropApply
: TPanel
;
125 bApplyProperty
: TButton
;
126 // Редактор свойств объектов:
127 vleObjectProperty
: TValueListEditor
;
129 // Панель объектов - вкладки:
131 pcObjects
: TPageControl
;
134 lbTextureList
: TListBox
;
135 // Панель настройки текстур:
136 PanelTextures
: TPanel
;
138 lTextureWidth
: TLabel
;
140 lTextureHeight
: TLabel
;
141 cbPreview
: TCheckBox
;
142 bbAddTexture
: TBitBtn
;
143 bbRemoveTexture
: TBitBtn
;
144 bClearTexture
: TButton
;
145 // Панель типов панелей:
146 PanelPanelType
: TPanel
;
147 lbPanelType
: TListBox
;
148 // Вкладка "Предметы":
150 lbItemList
: TListBox
;
153 // Вкладка "Монстры":
154 tsMonsters
: TTabSheet
;
155 lbMonsterList
: TListBox
;
156 rbMonsterLeft
: TRadioButton
;
157 rbMonsterRight
: TRadioButton
;
158 // Вкладка "Области":
160 lbAreasList
: TListBox
;
161 rbAreaLeft
: TRadioButton
;
162 rbAreaRight
: TRadioButton
;
163 // Вкладка "Триггеры":
164 tsTriggers
: TTabSheet
;
165 lbTriggersList
: TListBox
;
166 clbActivationType
: TCheckListBox
;
167 clbKeys
: TCheckListBox
;
170 Splitter1
: TSplitter
;
171 Splitter2
: TSplitter
;
172 StatusBar
: TStatusBar
;
174 // Специальные объекты:
175 ImageList
: TImageList
;
176 ilToolbar
: TImageList
;
177 OpenDialog
: TOpenDialog
;
178 SaveDialog
: TSaveDialog
;
179 selectall1
: TMenuItem
;
180 ColorDialog
: TColorDialog
;
182 procedure aAboutExecute(Sender
: TObject
);
183 procedure aCheckMapExecute(Sender
: TObject
);
184 procedure aMoveToFore(Sender
: TObject
);
185 procedure aMoveToBack(Sender
: TObject
);
186 procedure aCopyObjectExecute(Sender
: TObject
);
187 procedure aCutObjectExecute(Sender
: TObject
);
188 procedure aEditorOptionsExecute(Sender
: TObject
);
189 procedure aExitExecute(Sender
: TObject
);
190 procedure aMapOptionsExecute(Sender
: TObject
);
191 procedure aNewMapExecute(Sender
: TObject
);
192 procedure aOpenMapExecute(Sender
: TObject
);
193 procedure aOptimizeExecute(Sender
: TObject
);
194 procedure aPasteObjectExecute(Sender
: TObject
);
195 procedure aSelectAllExecute(Sender
: TObject
);
196 procedure aSaveMapExecute(Sender
: TObject
);
197 procedure aSaveMapAsExecute(Sender
: TObject
);
198 procedure aUndoExecute(Sender
: TObject
);
199 procedure aDeleteMap(Sender
: TObject
);
200 procedure bApplyPropertyClick(Sender
: TObject
);
201 procedure bbAddTextureClick(Sender
: TObject
);
202 procedure bbRemoveTextureClick(Sender
: TObject
);
203 procedure FormActivate(Sender
: TObject
);
204 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
205 procedure FormCreate(Sender
: TObject
);
206 procedure FormDestroy(Sender
: TObject
);
207 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
208 procedure FormResize(Sender
: TObject
);
209 procedure lbTextureListClick(Sender
: TObject
);
210 procedure lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
211 ARect
: TRect
; State
: TOwnerDrawState
);
212 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
213 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
214 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
215 procedure RenderPanelPaint(Sender
: TObject
);
216 procedure RenderPanelResize(Sender
: TObject
);
217 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
218 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
219 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
221 procedure tbGridOnClick(Sender
: TObject
);
222 procedure miMapPreviewClick(Sender
: TObject
);
223 procedure miLayer1Click(Sender
: TObject
);
224 procedure miLayer2Click(Sender
: TObject
);
225 procedure miLayer3Click(Sender
: TObject
);
226 procedure miLayer4Click(Sender
: TObject
);
227 procedure miLayer5Click(Sender
: TObject
);
228 procedure miLayer6Click(Sender
: TObject
);
229 procedure miLayer7Click(Sender
: TObject
);
230 procedure miLayer8Click(Sender
: TObject
);
231 procedure miLayer9Click(Sender
: TObject
);
232 procedure tbShowClick(Sender
: TObject
);
233 procedure miSnapToGridClick(Sender
: TObject
);
234 procedure miMiniMapClick(Sender
: TObject
);
235 procedure miSwitchGridClick(Sender
: TObject
);
236 procedure miShowEdgesClick(Sender
: TObject
);
237 procedure minexttabClick(Sender
: TObject
);
238 procedure miSaveMiniMapClick(Sender
: TObject
);
239 procedure bClearTextureClick(Sender
: TObject
);
240 procedure miPackMapClick(Sender
: TObject
);
241 procedure aRecentFileExecute(Sender
: TObject
);
242 procedure miMapTestSettingsClick(Sender
: TObject
);
243 procedure miTestMapClick(Sender
: TObject
);
244 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
245 var ScrollPos
: Integer);
246 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
247 var ScrollPos
: Integer);
248 procedure miOpenWadMapClick(Sender
: TObject
);
249 procedure selectall1Click(Sender
: TObject
);
250 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
251 var Accept
: Boolean);
252 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
253 var Accept
: Boolean);
254 procedure vleObjectPropertyEnter(Sender
: TObject
);
255 procedure vleObjectPropertyExit(Sender
: TObject
);
256 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
260 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
262 procedure RefreshRecentMenu();
268 LAYER_FOREGROUND
= 2;
276 TEST_MAP_NAME
= '$$$_TEST_$$$';
277 LANGUAGE_FILE_NAME
= '_Editor.txt';
288 DotStepOne
, DotStepTwo
: Byte;
290 DrawTexturePanel
: Boolean;
291 DrawPanelSize
: Boolean;
293 PreviewColor
: TColor
;
295 RecentCount
: Integer;
296 RecentFiles
: TStringList
;
297 slInvalidTextures
: TStringList
;
299 TestGameMode
: String;
301 TestLimScore
: String;
302 TestOptionsTwoPlayers
: Boolean;
303 TestOptionsTeamDamage
: Boolean;
304 TestOptionsAllowExit
: Boolean;
305 TestOptionsWeaponStay
: Boolean;
306 TestOptionsMonstersDM
: Boolean;
308 TestMapOnce
: Boolean;
310 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
311 (True, True, True, True, True, True, True, True, True);
312 PreviewMode
: Boolean = False;
318 procedure OpenMap(FileName
: String; mapN
: String);
319 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
320 procedure RemoveSelectFromObjects();
321 procedure ChangeShownProperty(Name
: String; NewValue
: String);
326 f_options
, e_graphics
, e_log
, GL
, GLExt
, Math
,
327 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
328 f_mapcheck
, f_addresource_texture
, g_textures
,
329 f_activationtype
, f_keys
, MAPWRITER
, MAPSTRUCT
,
330 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, WADSTRUCT
, MAPDEF
,
331 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
332 f_addresource_sound
, f_maptest
, f_choosetype
,
333 g_language
, f_selectlang
, ClipBrd
;
336 UNDO_DELETE_PANEL
= 1;
337 UNDO_DELETE_ITEM
= 2;
338 UNDO_DELETE_AREA
= 3;
339 UNDO_DELETE_MONSTER
= 4;
340 UNDO_DELETE_TRIGGER
= 5;
344 UNDO_ADD_MONSTER
= 9;
345 UNDO_ADD_TRIGGER
= 10;
346 UNDO_MOVE_PANEL
= 11;
349 UNDO_MOVE_MONSTER
= 14;
350 UNDO_MOVE_TRIGGER
= 15;
351 UNDO_RESIZE_PANEL
= 16;
352 UNDO_RESIZE_TRIGGER
= 17;
354 MOUSEACTION_NONE
= 0;
355 MOUSEACTION_DRAWPANEL
= 1;
356 MOUSEACTION_DRAWTRIGGER
= 2;
357 MOUSEACTION_MOVEOBJ
= 3;
358 MOUSEACTION_RESIZE
= 4;
359 MOUSEACTION_MOVEMAP
= 5;
360 MOUSEACTION_DRAWPRESS
= 6;
361 MOUSEACTION_NOACTION
= 7;
364 RESIZETYPE_VERTICAL
= 1;
365 RESIZETYPE_HORIZONTAL
= 2;
374 SELECTFLAG_TELEPORT
= 1;
376 SELECTFLAG_TEXTURE
= 3;
378 SELECTFLAG_MONSTER
= 5;
379 SELECTFLAG_SPAWNPOINT
= 6;
380 SELECTFLAG_SHOTPANEL
= 7;
381 SELECTFLAG_SELECTED
= 8;
383 RECENT_FILES_MENU_START
= 11;
385 CLIPBOARD_SIG
= 'DF:ED';
391 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
392 UNDO_DELETE_ITEM
: (Item
: TItem
);
393 UNDO_DELETE_AREA
: (Area
: TArea
);
394 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
395 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
400 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
405 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
407 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
414 OBJECT_PANEL
: (Panel
: ^TPanel
);
415 OBJECT_ITEM
: (Item
: TItem
);
416 OBJECT_AREA
: (Area
: TArea
);
417 OBJECT_MONSTER
: (Monster
: TMonster
);
418 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
421 TCopyRecArray
= Array of TCopyRec
;
425 gDataLoaded
: Boolean = False;
426 ShowMap
: Boolean = False;
427 DrawRect
: PRect
= nil;
428 SnapToGrid
: Boolean = True;
430 MousePos
: Types
.TPoint
;
431 LastMovePoint
: Types
.TPoint
;
434 MouseLDownPos
: Types
.TPoint
;
435 MouseRDownPos
: Types
.TPoint
;
437 SelectFlag
: Byte = SELECTFLAG_NONE
;
438 MouseAction
: Byte = MOUSEACTION_NONE
;
439 ResizeType
: Byte = RESIZETYPE_NONE
;
440 ResizeDirection
: Byte = RESIZEDIR_NONE
;
442 DrawPressRect
: Boolean = False;
443 EditingProperties
: Boolean = False;
445 UndoBuffer
: Array of Array of TUndoRec
= nil;
450 //----------------------------------------
451 //Далее идут вспомогательные процедуры
452 //----------------------------------------
454 function NameToBool(Name
: String): Boolean;
456 if Name
= BoolNames
[True] then
462 function NameToDir(Name
: String): TDirection
;
464 if Name
= DirNames
[D_LEFT
] then
470 function NameToDirAdv(Name
: String): Byte;
472 if Name
= DirNamesAdv
[1] then
475 if Name
= DirNamesAdv
[2] then
478 if Name
= DirNamesAdv
[3] then
484 function ActivateToStr(ActivateType
: Byte): String;
488 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
489 Result
:= Result
+ '+PC';
490 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
491 Result
:= Result
+ '+MC';
492 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
493 Result
:= Result
+ '+PP';
494 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
495 Result
:= Result
+ '+MP';
496 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
497 Result
:= Result
+ '+SH';
498 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
499 Result
:= Result
+ '+NM';
501 if (Result
<> '') and (Result
[1] = '+') then
502 Delete(Result
, 1, 1);
505 function StrToActivate(Str
: String): Byte;
509 if Pos('PC', Str
) > 0 then
510 Result
:= ACTIVATE_PLAYERCOLLIDE
;
511 if Pos('MC', Str
) > 0 then
512 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
513 if Pos('PP', Str
) > 0 then
514 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
515 if Pos('MP', Str
) > 0 then
516 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
517 if Pos('SH', Str
) > 0 then
518 Result
:= Result
or ACTIVATE_SHOT
;
519 if Pos('NM', Str
) > 0 then
520 Result
:= Result
or ACTIVATE_NOMONSTER
;
523 function KeyToStr(Key
: Byte): String;
527 if ByteBool(KEY_RED
and Key
) then
528 Result
:= Result
+ '+RK';
529 if ByteBool(KEY_GREEN
and Key
) then
530 Result
:= Result
+ '+GK';
531 if ByteBool(KEY_BLUE
and Key
) then
532 Result
:= Result
+ '+BK';
533 if ByteBool(KEY_REDTEAM
and Key
) then
534 Result
:= Result
+ '+RT';
535 if ByteBool(KEY_BLUETEAM
and Key
) then
536 Result
:= Result
+ '+BT';
538 if (Result
<> '') and (Result
[1] = '+') then
539 Delete(Result
, 1, 1);
542 function StrToKey(Str
: String): Byte;
546 if Pos('RK', Str
) > 0 then
548 if Pos('GK', Str
) > 0 then
549 Result
:= Result
or KEY_GREEN
;
550 if Pos('BK', Str
) > 0 then
551 Result
:= Result
or KEY_BLUE
;
552 if Pos('RT', Str
) > 0 then
553 Result
:= Result
or KEY_REDTEAM
;
554 if Pos('BT', Str
) > 0 then
555 Result
:= Result
or KEY_BLUETEAM
;
558 function EffectToStr(Effect
: Byte): String;
560 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
561 Result
:= EffectNames
[Effect
]
563 Result
:= EffectNames
[EFFECT_NONE
];
566 function StrToEffect(Str
: String): Byte;
570 Result
:= EFFECT_NONE
;
571 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
572 if EffectNames
[i
] = Str
then
579 function MonsterToStr(MonType
: Byte): String;
581 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
582 Result
:= MonsterNames
[MonType
]
584 Result
:= MonsterNames
[MONSTER_ZOMBY
];
587 function StrToMonster(Str
: String): Byte;
591 Result
:= MONSTER_ZOMBY
;
592 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
593 if MonsterNames
[i
] = Str
then
600 function ItemToStr(ItemType
: Byte): String;
602 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
603 Result
:= ItemNames
[ItemType
]
605 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
608 function StrToItem(Str
: String): Byte;
612 Result
:= ITEM_AMMO_BULLETS
;
613 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
614 if ItemNames
[i
] = Str
then
621 function ShotToStr(ShotType
: Byte): String;
623 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
624 Result
:= ShotNames
[ShotType
]
626 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
629 function StrToShot(Str
: String): Byte;
633 Result
:= TRIGGER_SHOT_PISTOL
;
634 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
635 if ShotNames
[i
] = Str
then
642 function SelectedObjectCount(): Word;
648 if SelectedObjects
= nil then
651 for a
:= 0 to High(SelectedObjects
) do
652 if SelectedObjects
[a
].Live
then
653 Result
:= Result
+ 1;
656 function GetFirstSelected(): Integer;
662 if SelectedObjects
= nil then
665 for a
:= 0 to High(SelectedObjects
) do
666 if SelectedObjects
[a
].Live
then
673 function Normalize16(x
: Integer): Integer;
675 Result
:= (x
div 16) * 16;
678 procedure MoveMap(X
, Y
: Integer);
680 rx
, ry
, ScaleSz
: Integer;
682 with MainForm
.RenderPanel
do
684 ScaleSz
:= 16 div Scale
;
685 // Размер видимой части карты:
686 rx
:= min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
687 ry
:= min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
688 // Место клика на мини-карте:
689 MapOffset
.X
:= X
- (Width
-max(gMapInfo
.Width
div ScaleSz
, 1)-1);
690 MapOffset
.Y
:= Y
- 1;
691 // Это же место на "большой" карте:
692 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
693 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
694 // Левый верхний угол новой видимой части карты:
695 MapOffset
.X
:= MapOffset
.X
- rx
;
696 MapOffset
.Y
:= MapOffset
.Y
- ry
;
698 if MapOffset
.X
< 0 then
700 if MapOffset
.Y
< 0 then
702 if MapOffset
.X
> MainForm
.sbHorizontal
.Max
then
703 MapOffset
.X
:= MainForm
.sbHorizontal
.Max
;
704 if MapOffset
.Y
> MainForm
.sbVertical
.Max
then
705 MapOffset
.Y
:= MainForm
.sbVertical
.Max
;
707 MapOffset
.X
:= Normalize16(MapOffset
.X
);
708 MapOffset
.Y
:= Normalize16(MapOffset
.Y
);
711 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
712 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
714 MapOffset
.X
:= -MapOffset
.X
;
715 MapOffset
.Y
:= -MapOffset
.Y
;
720 function IsTexturedPanel(PanelType
: Word): Boolean;
722 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
723 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
724 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
727 procedure FillProperty();
732 MainForm
.vleObjectProperty
.Strings
.Clear();
734 // Отображаем свойства если выделен только один объект:
735 if SelectedObjectCount() <> 1 then
738 _id
:= GetFirstSelected();
739 if not SelectedObjects
[_id
].Live
then
742 with MainForm
.vleObjectProperty
do
743 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
745 EditStyle
:= esSimple
;
749 case SelectedObjects
[0].ObjectType
of
752 with MainForm
.vleObjectProperty
,
753 gPanels
[SelectedObjects
[_id
].ID
] do
755 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
757 EditStyle
:= esSimple
;
761 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
763 EditStyle
:= esSimple
;
767 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
769 EditStyle
:= esSimple
;
773 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
775 EditStyle
:= esSimple
;
779 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
781 EditStyle
:= esEllipsis
;
785 if IsTexturedPanel(PanelType
) then
786 begin // Может быть текстура
787 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
789 EditStyle
:= esEllipsis
;
793 if TextureName
<> '' then
794 begin // Есть текстура
795 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
797 EditStyle
:= esSimple
;
801 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
803 EditStyle
:= esPickList
;
813 with MainForm
.vleObjectProperty
,
814 gItems
[SelectedObjects
[_id
].ID
] do
816 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
818 EditStyle
:= esSimple
;
822 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
824 EditStyle
:= esSimple
;
828 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
830 EditStyle
:= esPickList
;
834 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
836 EditStyle
:= esPickList
;
844 with MainForm
.vleObjectProperty
,
845 gMonsters
[SelectedObjects
[_id
].ID
] do
847 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
849 EditStyle
:= esSimple
;
853 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
855 EditStyle
:= esSimple
;
859 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
861 EditStyle
:= esPickList
;
869 with MainForm
.vleObjectProperty
,
870 gAreas
[SelectedObjects
[_id
].ID
] do
872 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
874 EditStyle
:= esSimple
;
878 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
880 EditStyle
:= esSimple
;
884 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
886 EditStyle
:= esPickList
;
894 with MainForm
.vleObjectProperty
,
895 gTriggers
[SelectedObjects
[_id
].ID
] do
897 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
899 EditStyle
:= esSimple
;
903 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
905 EditStyle
:= esSimple
;
909 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
911 EditStyle
:= esSimple
;
915 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
917 EditStyle
:= esSimple
;
921 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
923 EditStyle
:= esSimple
;
927 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
929 EditStyle
:= esPickList
;
933 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
935 EditStyle
:= esEllipsis
;
939 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
941 EditStyle
:= esEllipsis
;
945 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
947 EditStyle
:= esEllipsis
;
954 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], Data
.MapName
, True)] do
956 EditStyle
:= esEllipsis
;
963 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
965 EditStyle
:= esEllipsis
;
969 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
971 EditStyle
:= esPickList
;
975 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
977 EditStyle
:= esPickList
;
981 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
983 EditStyle
:= esPickList
;
988 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
989 TRIGGER_DOOR
, TRIGGER_DOOR5
:
991 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
993 EditStyle
:= esEllipsis
;
997 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
999 EditStyle
:= esPickList
;
1003 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1005 EditStyle
:= esPickList
;
1010 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1012 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1014 EditStyle
:= esEllipsis
;
1018 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1020 EditStyle
:= esPickList
;
1024 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1026 EditStyle
:= esPickList
;
1031 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1034 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1035 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1037 EditStyle
:= esEllipsis
;
1041 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1043 EditStyle
:= esSimple
;
1047 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1049 EditStyle
:= esSimple
;
1053 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1055 EditStyle
:= esEllipsis
;
1059 if TriggerType
= TRIGGER_PRESS
then
1060 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1062 EditStyle
:= esPickList
;
1070 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1072 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1074 EditStyle
:= esEllipsis
;
1078 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1080 EditStyle
:= esPickList
;
1084 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1086 EditStyle
:= esPickList
;
1093 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1095 EditStyle
:= esPickList
;
1099 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1101 EditStyle
:= esPickList
;
1108 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], Data
.SoundName
, True)] do
1110 EditStyle
:= esEllipsis
;
1114 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1116 EditStyle
:= esSimple
;
1120 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1122 EditStyle
:= esSimple
;
1126 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1128 EditStyle
:= esSimple
;
1132 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1134 EditStyle
:= esPickList
;
1138 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1140 EditStyle
:= esPickList
;
1145 TRIGGER_SPAWNMONSTER
:
1147 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1149 EditStyle
:= esEllipsis
;
1153 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1154 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1156 EditStyle
:= esEllipsis
;
1160 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1162 EditStyle
:= esPickList
;
1166 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1168 EditStyle
:= esSimple
;
1172 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1174 EditStyle
:= esPickList
;
1178 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1180 EditStyle
:= esSimple
;
1184 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1186 EditStyle
:= esEllipsis
;
1190 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1192 EditStyle
:= esSimple
;
1196 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1198 EditStyle
:= esSimple
;
1202 case Data
.MonBehav
of
1203 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1204 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1205 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1206 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1207 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1208 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1210 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1212 EditStyle
:= esPickList
;
1219 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1221 EditStyle
:= esEllipsis
;
1225 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1226 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1228 EditStyle
:= esEllipsis
;
1232 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1234 EditStyle
:= esPickList
;
1238 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1240 EditStyle
:= esPickList
;
1244 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1246 EditStyle
:= esSimple
;
1250 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1252 EditStyle
:= esEllipsis
;
1256 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1258 EditStyle
:= esSimple
;
1262 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1264 EditStyle
:= esSimple
;
1271 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], Data
.MusicName
, True)] do
1273 EditStyle
:= esEllipsis
;
1277 if Data
.MusicAction
= 1 then
1278 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1280 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1282 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1284 EditStyle
:= esPickList
;
1291 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1293 EditStyle
:= esSimple
;
1296 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1298 EditStyle
:= esSimple
;
1301 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1303 EditStyle
:= esPickList
;
1310 case Data
.ScoreAction
of
1311 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1312 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1313 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1314 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1316 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1318 EditStyle
:= esPickList
;
1321 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1323 EditStyle
:= esSimple
;
1326 case Data
.ScoreTeam
of
1327 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1328 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1329 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1330 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1332 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1334 EditStyle
:= esPickList
;
1337 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1339 EditStyle
:= esPickList
;
1342 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1344 EditStyle
:= esPickList
;
1351 case Data
.MessageKind
of
1352 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1353 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1355 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1357 EditStyle
:= esPickList
;
1360 case Data
.MessageSendTo
of
1361 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1362 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1363 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1364 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1365 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1366 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1368 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1370 EditStyle
:= esPickList
;
1373 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], Data
.MessageText
, True)] do
1375 EditStyle
:= esSimple
;
1378 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1380 EditStyle
:= esSimple
;
1387 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1389 EditStyle
:= esSimple
;
1392 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1394 EditStyle
:= esSimple
;
1401 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1403 EditStyle
:= esSimple
;
1406 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1408 EditStyle
:= esSimple
;
1411 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1413 EditStyle
:= esPickList
;
1416 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1418 EditStyle
:= esPickList
;
1425 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1427 EditStyle
:= esEllipsis
;
1431 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1433 EditStyle
:= esPickList
;
1437 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1439 EditStyle
:= esEllipsis
;
1443 case Data
.ShotTarget
of
1444 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1445 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1446 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1447 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1448 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1449 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1450 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1452 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1454 EditStyle
:= esPickList
;
1458 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1460 EditStyle
:= esSimple
;
1464 case Data
.ShotAim
of
1465 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1466 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1467 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1468 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1470 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)-1] do
1472 EditStyle
:= esPickList
;
1476 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1477 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1479 EditStyle
:= esEllipsis
;
1483 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1485 EditStyle
:= esSimple
;
1489 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1491 EditStyle
:= esSimple
;
1495 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1497 EditStyle
:= esSimple
;
1501 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1503 EditStyle
:= esSimple
;
1507 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1509 EditStyle
:= esSimple
;
1516 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1518 EditStyle
:= esSimple
;
1522 if Data
.FXType
= 0 then
1523 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1525 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1526 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1528 EditStyle
:= esEllipsis
;
1533 if Data
.FXType
= 0 then
1534 case Data
.FXSubType
of
1535 TRIGGER_EFFECT_SLIQUID
:
1536 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1537 TRIGGER_EFFECT_LLIQUID
:
1538 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1539 TRIGGER_EFFECT_DLIQUID
:
1540 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1541 TRIGGER_EFFECT_BLOOD
:
1542 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1543 TRIGGER_EFFECT_SPARK
:
1544 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1545 TRIGGER_EFFECT_BUBBLE
:
1546 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1548 if Data
.FXType
= 1 then
1550 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1551 Data
.FXSubType
:= EFFECT_TELEPORT
;
1552 str
:= EffectToStr(Data
.FXSubType
);
1554 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1556 EditStyle
:= esEllipsis
;
1560 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1562 EditStyle
:= esEllipsis
;
1566 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1568 EditStyle
:= esPickList
;
1572 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1574 EditStyle
:= esSimple
;
1578 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1580 EditStyle
:= esSimple
;
1584 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1586 EditStyle
:= esSimple
;
1590 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1592 EditStyle
:= esSimple
;
1596 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1598 EditStyle
:= esSimple
;
1602 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1604 EditStyle
:= esSimple
;
1608 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1610 EditStyle
:= esSimple
;
1614 end; //case TriggerType
1616 end; // OBJECT_TRIGGER:
1620 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1624 if SelectedObjectCount() <> 1 then
1626 if not SelectedObjects
[GetFirstSelected()].Live
then
1629 // Есть ли такой ключ:
1630 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1632 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1636 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1645 // Уже выделен - убираем:
1646 if SelectedObjects
<> nil then
1647 for a
:= 0 to High(SelectedObjects
) do
1648 with SelectedObjects
[a
] do
1649 if Live
and (ID
= fID
) and
1650 (ObjectType
= fObjectType
) then
1659 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1661 with SelectedObjects
[High(SelectedObjects
)] do
1663 ObjectType
:= fObjectType
;
1670 SetLength(SelectedObjects
, 1);
1672 with SelectedObjects
[0] do
1674 ObjectType
:= fObjectType
;
1680 MainForm
.miCopy
.Enabled
:= True;
1681 MainForm
.miCut
.Enabled
:= True;
1683 if fObjectType
= OBJECT_PANEL
then
1685 MainForm
.miToFore
.Enabled
:= True;
1686 MainForm
.miToBack
.Enabled
:= True;
1690 procedure RemoveSelectFromObjects();
1692 SelectedObjects
:= nil;
1693 DrawPressRect
:= False;
1694 MouseLDown
:= False;
1695 MouseRDown
:= False;
1696 MouseAction
:= MOUSEACTION_NONE
;
1697 SelectFlag
:= SELECTFLAG_NONE
;
1698 ResizeType
:= RESIZETYPE_NONE
;
1699 ResizeDirection
:= RESIZEDIR_NONE
;
1701 MainForm
.vleObjectProperty
.Strings
.Clear();
1703 MainForm
.miCopy
.Enabled
:= False;
1704 MainForm
.miCut
.Enabled
:= False;
1705 MainForm
.miToFore
.Enabled
:= False;
1706 MainForm
.miToBack
.Enabled
:= False;
1709 procedure DeleteSelectedObjects();
1714 if SelectedObjects
= nil then
1720 for a
:= 0 to High(SelectedObjects
) do
1721 with SelectedObjects
[a
] do
1726 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1727 i
:= High(UndoBuffer
);
1731 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1732 ii
:= High(UndoBuffer
[i
]);
1737 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1738 New(UndoBuffer
[i
, ii
].Panel
);
1739 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1743 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1744 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1748 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1749 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1753 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1754 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1758 RemoveObject(ID
, ObjectType
);
1761 RemoveSelectFromObjects();
1763 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1766 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1770 if (not Group
) or (Length(UndoBuffer
) = 0) then
1771 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1772 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1773 i
:= High(UndoBuffer
);
1774 ii
:= High(UndoBuffer
[i
]);
1778 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1780 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1782 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1784 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1786 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1789 UndoBuffer
[i
, ii
].AddID
:= ID
;
1791 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1794 procedure FullClear();
1796 RemoveSelectFromObjects();
1798 LoadSky(gMapInfo
.SkyName
);
1800 slInvalidTextures
.Clear();
1801 MapCheckForm
.lbErrorList
.Clear();
1802 MapCheckForm
.mErrorDescription
.Clear();
1804 MainForm
.miUndo
.Enabled
:= False;
1805 MainForm
.sbHorizontal
.Position
:= 0;
1806 MainForm
.sbVertical
.Position
:= 0;
1807 MainForm
.FormResize(nil);
1808 MainForm
.Caption
:= FormCaption
;
1813 procedure ErrorMessageBox(str
: String);
1815 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1816 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1819 function CheckProperty(): Boolean;
1825 _id
:= GetFirstSelected();
1827 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1828 with gPanels
[SelectedObjects
[_id
].ID
] do
1830 if TextureWidth
<> 0 then
1831 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1833 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1838 if TextureHeight
<> 0 then
1839 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1841 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1846 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1847 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1849 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1854 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1855 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1856 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1858 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1862 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1863 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1865 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1872 procedure SelectTexture(ID
: Integer);
1874 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1875 MainForm
.lbTextureListClick(nil);
1878 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1880 a
, FrameLen
: Integer;
1883 ResourceName
: String;
1884 UResourceName
: String;
1885 FullResourceName
: String;
1886 SectionName
: String;
1888 Width
, Height
: Word;
1891 if aSection
= '..' then
1894 SectionName
:= aSection
;
1896 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1898 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1899 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1901 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1904 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1905 begin // Спец. текстуры
1907 ResourceName
:= aTex
;
1910 begin // Внешний WAD
1911 FileName
:= EditorDir
+'wads/'+aWAD
;
1912 ResourceName
:= utf2win(aWAD
)+':'+SectionName
+'\'+aTex
;
1916 UResourceName
:= win2utf(ResourceName
);
1918 // Есть ли уже такая текстура:
1919 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1920 if UResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1923 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1928 // Название ресурса <= 64 символов:
1929 if Length(ResourceName
) > 64 then
1932 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1940 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1942 a
:= MainForm
.lbTextureList
.Items
.Add(UResourceName
);
1949 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1951 if IsAnim(FullResourceName
) then
1952 begin // Аним. текстура
1953 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
1955 if g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
1956 a
:= MainForm
.lbTextureList
.Items
.Add(UResourceName
);
1958 else // Обычная текстура
1960 if g_CreateTextureWAD(ResourceName
, FullResourceName
) then
1961 a
:= MainForm
.lbTextureList
.Items
.Add(UResourceName
);
1963 if (a
> -1) and (not silent
) then
1970 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
1973 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
1974 Caption
:= FormCaption
1977 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
1979 if (sFile
<> '') and (sRes
<> '') then
1980 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
1982 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
1985 procedure OpenMap(FileName
: String; mapN
: String);
1990 SelectMapForm
.GetMaps(FileName
);
1992 if (FileName
= OpenedWAD
) and
1993 (OpenedMap
<> '') then
1995 MapName
:= OpenedMap
;
1996 while (Pos(':\', MapName
) > 0) do
1997 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
1999 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2000 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2003 if SelectMapForm
.lbMapList
.Count
> 0 then
2004 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2006 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2011 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2015 if (SelectMapForm
.ShowModal() = mrOK
) and
2016 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2017 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2022 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2028 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2029 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2030 pLoadProgress
.Show();
2032 OpenedMap
:= FileName
+':\'+MapName
;
2033 OpenedWAD
:= FileName
;
2035 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2036 // Такая карта уже недавно открывалась:
2038 RecentFiles
.Delete(idx
);
2039 RecentFiles
.Insert(0, OpenedMap
);
2040 RefreshRecentMenu();
2044 pLoadProgress
.Hide();
2047 lbTextureList
.Sorted
:= True;
2048 lbTextureList
.Sorted
:= False;
2050 UpdateCaption(win2utf(gMapInfo
.Name
), ExtractFileName(FileName
), MapName
);
2054 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2059 if SelectedObjects
= nil then
2066 for a
:= 0 to High(SelectedObjects
) do
2067 if SelectedObjects
[a
].Live
then
2069 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2072 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2075 if (not okX
) or (not okY
) then
2081 for a
:= 0 to High(SelectedObjects
) do
2082 if SelectedObjects
[a
].Live
then
2085 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2088 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2090 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2092 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2093 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2094 begin // Двигаем зону Расширителя
2096 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2098 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2101 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2102 begin // Двигаем точку назначения Телепорта
2104 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2106 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2109 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2110 begin // Двигаем точку создания монстра
2112 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2114 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2117 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2118 begin // Двигаем точку создания предмета
2120 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2122 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2125 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2126 begin // Двигаем точку создания выстрела
2128 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2130 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2135 LastMovePoint
:= MousePos
;
2139 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2141 LayerEnabled
[Layer
] := show
;
2146 MainForm
.miLayer1
.Checked
:= show
;
2147 MainForm
.miLayerP1
.Checked
:= show
;
2151 MainForm
.miLayer2
.Checked
:= show
;
2152 MainForm
.miLayerP2
.Checked
:= show
;
2156 MainForm
.miLayer3
.Checked
:= show
;
2157 MainForm
.miLayerP3
.Checked
:= show
;
2161 MainForm
.miLayer4
.Checked
:= show
;
2162 MainForm
.miLayerP4
.Checked
:= show
;
2166 MainForm
.miLayer5
.Checked
:= show
;
2167 MainForm
.miLayerP5
.Checked
:= show
;
2171 MainForm
.miLayer6
.Checked
:= show
;
2172 MainForm
.miLayerP6
.Checked
:= show
;
2176 MainForm
.miLayer7
.Checked
:= show
;
2177 MainForm
.miLayerP7
.Checked
:= show
;
2181 MainForm
.miLayer8
.Checked
:= show
;
2182 MainForm
.miLayerP8
.Checked
:= show
;
2186 MainForm
.miLayer9
.Checked
:= show
;
2187 MainForm
.miLayerP9
.Checked
:= show
;
2191 RemoveSelectFromObjects();
2194 procedure SwitchLayer(Layer
: Byte);
2196 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2199 procedure SwitchMap();
2201 ShowMap
:= not ShowMap
;
2202 MainForm
.tbShowMap
.Down
:= ShowMap
;
2205 procedure ShowEdges();
2207 if drEdge
[3] < 255 then
2210 drEdge
[3] := gAlphaEdge
;
2213 function SelectedTexture(): String;
2215 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2216 Result
:= utf2win(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
])
2221 function IsSpecialTextureSel(): Boolean;
2223 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2224 IsSpecialTexture(utf2win(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]));
2227 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2232 procedure AddInt(x
: Integer);
2234 Res
:= Res
+ IntToStr(x
) + ' ';
2240 if Length(CopyBuf
) = 0 then
2243 Res
:= CLIPBOARD_SIG
+ ' ';
2245 for i
:= 0 to High(CopyBuf
) do
2247 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2248 (CopyBuf
[i
].Panel
= nil) then
2252 AddInt(CopyBuf
[i
].ObjectType
);
2255 // Свойства объекта:
2256 case CopyBuf
[i
].ObjectType
of
2258 with CopyBuf
[i
].Panel
^ do
2265 Res
:= Res
+ '"' + TextureName
+ '" ';
2267 AddInt(IfThen(Blending
, 1, 0));
2271 with CopyBuf
[i
].Item
do
2276 AddInt(IfThen(OnlyDM
, 1, 0));
2277 AddInt(IfThen(Fall
, 1, 0));
2281 with CopyBuf
[i
].Monster
do
2283 AddInt(MonsterType
);
2286 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2290 with CopyBuf
[i
].Area
do
2295 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2299 with CopyBuf
[i
].Trigger
do
2301 AddInt(TriggerType
);
2306 AddInt(ActivateType
);
2308 AddInt(IfThen(Enabled
, 1, 0));
2309 AddInt(TexturePanel
);
2311 for j
:= 0 to 127 do
2312 AddInt(Data
.Default
[j
]);
2320 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
);
2324 function GetNext(): String;
2329 if Str
[1] = '"' then
2341 Result
:= Copy(Str
, 1, p
-1);
2357 Result
:= Copy(Str
, 1, p
-1);
2367 if GetNext() <> CLIPBOARD_SIG
then
2373 t
:= StrToIntDef(GetNext(), 0);
2375 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2376 (GetNext() <> ';') then
2377 begin // Что-то не то => пропускаем:
2385 i
:= Length(CopyBuf
);
2386 SetLength(CopyBuf
, i
+ 1);
2388 CopyBuf
[i
].ObjectType
:= t
;
2389 CopyBuf
[i
].Panel
:= nil;
2391 // Свойства объекта:
2395 New(CopyBuf
[i
].Panel
);
2397 with CopyBuf
[i
].Panel
^ do
2399 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2400 X
:= StrToIntDef(GetNext(), 0);
2401 Y
:= StrToIntDef(GetNext(), 0);
2402 Width
:= StrToIntDef(GetNext(), 16);
2403 Height
:= StrToIntDef(GetNext(), 16);
2404 TextureName
:= GetNext();
2405 Alpha
:= StrToIntDef(GetNext(), 0);
2406 Blending
:= (GetNext() = '1');
2411 with CopyBuf
[i
].Item
do
2413 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2414 X
:= StrToIntDef(GetNext(), 0);
2415 Y
:= StrToIntDef(GetNext(), 0);
2416 OnlyDM
:= (GetNext() = '1');
2417 Fall
:= (GetNext() = '1');
2421 with CopyBuf
[i
].Monster
do
2423 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2424 X
:= StrToIntDef(GetNext(), 0);
2425 Y
:= StrToIntDef(GetNext(), 0);
2427 if GetNext() = '1' then
2430 Direction
:= D_RIGHT
;
2434 with CopyBuf
[i
].Area
do
2436 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2437 X
:= StrToIntDef(GetNext(), 0);
2438 Y
:= StrToIntDef(GetNext(), 0);
2439 if GetNext() = '1' then
2442 Direction
:= D_RIGHT
;
2446 with CopyBuf
[i
].Trigger
do
2448 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2449 X
:= StrToIntDef(GetNext(), 0);
2450 Y
:= StrToIntDef(GetNext(), 0);
2451 Width
:= StrToIntDef(GetNext(), 16);
2452 Height
:= StrToIntDef(GetNext(), 16);
2453 ActivateType
:= StrToIntDef(GetNext(), 0);
2454 Key
:= StrToIntDef(GetNext(), 0);
2455 Enabled
:= (GetNext() = '1');
2456 TexturePanel
:= StrToIntDef(GetNext(), 0);
2458 for j
:= 0 to 127 do
2459 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2465 //----------------------------------------
2466 //Закончились вспомогательные процедуры
2467 //----------------------------------------
2469 procedure TMainForm
.RefreshRecentMenu();
2474 // Лишние запомненные карты:
2475 while RecentFiles
.Count
> RecentCount
do
2476 RecentFiles
.Delete(RecentFiles
.Count
-1);
2478 // Лишние строки меню:
2479 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2480 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2482 // Отделение списка карт от строки "Выход":
2483 if RecentFiles
.Count
> 0 then
2485 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2487 MainMenu
.Items
[0].Add(MI
);
2490 // Добавление в меню списка запомненных карт:
2491 for i
:= 0 to RecentFiles
.Count
-1 do
2493 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2494 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2495 MI
.OnClick
:= aRecentFileExecute
;
2496 MainMenu
.Items
[0].Add(MI
);
2500 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2506 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2507 Delete(s
, Pos('&', s
), 1);
2508 s
:= Trim(Copy(s
, 1, 2));
2509 n
:= StrToIntDef(s
, 0) - 1;
2511 if (n
< 0) or (n
>= RecentFiles
.Count
) then
2514 s
:= RecentFiles
[n
];
2515 pw
:= Pos('.wad:\', LowerCase(s
));
2519 begin // Map name included
2520 fn
:= Copy(s
, 1, pw
+ 3);
2521 Delete(s
, 1, pw
+ 5);
2522 if (FileExists(fn
)) then
2528 else // Only wad name
2529 if (FileExists(s
)) then
2535 if (not b
) and (MessageBox(0, PChar(_lc
[I_MSG_DEL_RECENT_PROMT
]),
2536 PChar(_lc
[I_MSG_DEL_RECENT
]), MB_ICONQUESTION
or MB_YESNO
) = idYes
) then
2538 RecentFiles
.Delete(n
);
2539 RefreshRecentMenu();
2543 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2545 OptionsForm
.ShowModal();
2548 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2560 wad
:= TWADEditor_1
.Create
;
2561 if wad
.ReadFile(EditorDir
+'data/Game.wad') then
2562 wad
.GetResource('FONTS', cfgres
, cfgdata
, cfglen
);
2567 if not g_CreateTextureWAD('FONT_STD', EditorDir
+'data/Game.wad:FONTS\'+texture
) then
2568 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2570 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2571 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2572 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2573 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2575 if g_GetTexture('FONT_STD', ID
) then
2576 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
-2);
2581 e_WriteLog('Could not load FONT_STD', MSG_WARNING
);
2583 if cfglen
<> 0 then FreeMem(cfgdata
);
2586 procedure TMainForm
.FormCreate(Sender
: TObject
);
2594 EditorDir
:= ExtractFilePath(Application
.ExeName
);
2596 e_InitLog(EditorDir
+'Editor.log', WM_NEWFILE
);
2598 slInvalidTextures
:= TStringList
.Create
;
2600 ShowLayer(LAYER_BACK
, True);
2601 ShowLayer(LAYER_WALLS
, True);
2602 ShowLayer(LAYER_FOREGROUND
, True);
2603 ShowLayer(LAYER_STEPS
, True);
2604 ShowLayer(LAYER_WATER
, True);
2605 ShowLayer(LAYER_ITEMS
, True);
2606 ShowLayer(LAYER_MONSTERS
, True);
2607 ShowLayer(LAYER_AREAS
, True);
2608 ShowLayer(LAYER_TRIGGERS
, True);
2612 FormCaption
:= MainForm
.Caption
;
2616 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
2618 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2619 Position
:= poDesktopCenter
2621 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2622 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2623 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2624 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2626 if config
.ReadBool('Editor', 'Maximize', False) then
2627 WindowState
:= wsMaximized
;
2628 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2629 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2630 Splitter1
.Left
:= PanelProps
.Left
;
2631 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2632 Splitter2
.Top
:= PanelObjs
.Top
;
2633 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2634 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2635 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2636 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2637 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2638 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2639 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2640 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2641 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2642 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2643 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2644 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2645 if gAlphaEdge
= 255 then
2646 gAlphaEdge
:= ALPHA_EDGE
;
2647 drEdge
[0] := GetRValue(gColorEdge
);
2648 drEdge
[1] := GetGValue(gColorEdge
);
2649 drEdge
[2] := GetBValue(gColorEdge
);
2650 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2653 drEdge
[3] := gAlphaEdge
;
2654 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2655 if gAlphaTriggerLine
= 255 then
2656 gAlphaTriggerLine
:= ALPHA_LINE
;
2657 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2658 if gAlphaTriggerArea
= 255 then
2659 gAlphaTriggerArea
:= ALPHA_AREA
;
2660 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2664 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2668 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2669 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2671 s
:= config
.ReadStr('Editor', 'Language', '');
2674 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2675 if RecentCount
> 10 then
2677 if RecentCount
< 2 then
2680 RecentFiles
:= TStringList
.Create();
2681 for i
:= 0 to RecentCount
-1 do
2683 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2687 RefreshRecentMenu();
2691 tbShowMap
.Down
:= ShowMap
;
2692 tbGridOn
.Down
:= DotEnable
;
2693 pcObjects
.ActivePageIndex
:= 0;
2694 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2696 Application
.OnIdle
:= OnIdle
;
2699 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2701 // NOTE: all the font printing routines assume CP1251
2702 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2705 procedure TMainForm
.Draw();
2710 Width
, Height
: Word;
2713 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2717 e_Clear(GL_COLOR_BUFFER_BIT
,
2718 GetRValue(BackColor
)/255,
2719 GetGValue(BackColor
)/255,
2720 GetBValue(BackColor
)/255);
2724 ObjCount
:= SelectedObjectCount();
2726 // Обводим выделенные объекты красной рамкой:
2727 if ObjCount
> 0 then
2729 for a
:= 0 to High(SelectedObjects
) do
2730 if SelectedObjects
[a
].Live
then
2732 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2736 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2737 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2740 // Рисуем точки изменения размеров:
2741 if (ObjCount
= 1) and
2742 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2744 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2745 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2746 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2747 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2749 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2750 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2751 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2752 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2759 if DotEnable
and (not PreviewMode
) then
2766 for x
:= 0 to (RenderPanel
.Width
div DotStep
) do
2767 for y
:= 0 to (RenderPanel
.Height
div DotStep
) do
2768 e_DrawPoint(DotSize
, x
*DotStep
+ a
, y
*DotStep
+ a
,
2769 GetRValue(DotColor
),
2770 GetGValue(DotColor
),
2771 GetBValue(DotColor
));
2775 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2776 (not IsSpecialTextureSel()) and (not PreviewMode
) then
2778 if not g_GetTexture(SelectedTexture(), ID
) then
2779 g_GetTexture('NOTEXTURE', ID
);
2780 g_GetTextureSizeByID(ID
, Width
, Height
);
2781 if g_GetTexture('PREVIEW', PID
) then
2782 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
2783 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
2786 // Подсказка при выборе точки Телепорта:
2787 if SelectFlag
= SELECTFLAG_TELEPORT
then
2789 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2790 if Data
.d2d_teleport
then
2791 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2792 MousePos
.X
+16, MousePos
.Y
-1,
2795 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2796 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2798 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2799 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2800 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
2803 // Подсказка при выборе точки появления:
2804 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2806 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2807 MousePos
.X
+16, MousePos
.Y
-1,
2809 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2810 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2811 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
2814 // Подсказка при выборе панели двери:
2815 if SelectFlag
= SELECTFLAG_DOOR
then
2817 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2818 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2819 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
2822 // Подсказка при выборе панели с текстурой:
2823 if SelectFlag
= SELECTFLAG_TEXTURE
then
2825 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2826 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2827 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
2830 // Подсказка при выборе панели индикации выстрела:
2831 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2833 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2834 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2835 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
2838 // Подсказка при выборе панели лифта:
2839 if SelectFlag
= SELECTFLAG_LIFT
then
2841 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2842 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2843 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
2846 // Подсказка при выборе монстра:
2847 if SelectFlag
= SELECTFLAG_MONSTER
then
2849 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2850 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2851 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
2854 // Подсказка при выборе области воздействия:
2855 if DrawPressRect
then
2857 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2858 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2859 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
2862 // Рисуем текстуры, если чертим панель:
2863 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2864 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2865 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2867 if not g_GetTexture(SelectedTexture(), ID
) then
2868 g_GetTexture('NOTEXTURE', ID
);
2869 g_GetTextureSizeByID(ID
, Width
, Height
);
2871 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2872 Abs(Bottom
-Top
) div Height
, 0, True, False);
2875 // Прямоугольник выделения:
2876 if DrawRect
<> nil then
2878 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2880 // Чертим мышью панель/триггер или меняем мышью их размер:
2881 if (MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
, MOUSEACTION_RESIZE
]) and
2882 (DrawPanelSize
) then
2884 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2885 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2887 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2888 begin // Чертим новый
2889 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
2890 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
2891 PrintBlack(MousePos
.X
+2, MousePos
.Y
+14, Format(_glc
[I_HINT_HEIGHT
],
2892 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
2894 else // Растягиваем существующий
2895 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2897 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2899 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2900 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2904 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2905 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2908 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
2910 PrintBlack(MousePos
.X
+2, MousePos
.Y
+14, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
2915 // Ближайшая к курсору мыши точка на сетке:
2916 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
2921 // Сколько пикселов карты в 1 пикселе мини-карты:
2922 ScaleSz
:= 16 div Scale
;
2923 // Размеры мини-карты:
2924 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
2925 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
2926 // X-координата на RenderPanel нулевой x-координаты карты:
2927 XX
:= RenderPanel
.Width
- aX
- 1;
2929 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
2930 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
2932 if gPanels
<> nil then
2935 for a
:= 0 to High(gPanels
) do
2937 if PanelType
<> 0 then
2939 // Левый верхний угол:
2940 aX
:= XX
+ (X
div ScaleSz
);
2941 aY
:= 1 + (Y
div ScaleSz
);
2943 aX2
:= max(Width
div ScaleSz
, 1);
2944 aY2
:= max(Height
div ScaleSz
, 1);
2945 // Правый нижний угол:
2946 aX2
:= aX
+ aX2
- 1;
2947 aY2
:= aY
+ aY2
- 1;
2950 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
2951 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
2952 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
2953 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
2954 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
2955 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
2956 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
2957 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
2958 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
2959 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
2960 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
2961 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
2965 // Рисуем красным выделенные панели:
2966 if SelectedObjects
<> nil then
2967 for b
:= 0 to High(SelectedObjects
) do
2968 with SelectedObjects
[b
] do
2969 if Live
and (ObjectType
= OBJECT_PANEL
) then
2970 with gPanels
[SelectedObjects
[b
].ID
] do
2971 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
2973 // Левый верхний угол:
2974 aX
:= XX
+ (X
div ScaleSz
);
2975 aY
:= 1 + (Y
div ScaleSz
);
2977 aX2
:= max(Width
div ScaleSz
, 1);
2978 aY2
:= max(Height
div ScaleSz
, 1);
2979 // Правый нижний угол:
2980 aX2
:= aX
+ aX2
- 1;
2981 aY2
:= aY
+ aY2
- 1;
2983 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
2987 if (gMapInfo
.Width
> RenderPanel
.Width
) or
2988 (gMapInfo
.Height
> RenderPanel
.Height
) then
2990 // Окно, показывающее текущее положение экрана на карте:
2992 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
2993 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
2994 // Левый верхний угол:
2995 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
2996 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
2997 // Правый нижний угол:
3001 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3002 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3007 RenderPanel
.SwapBuffers();
3010 procedure TMainForm
.FormResize(Sender
: TObject
);
3012 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3014 if gMapInfo
.Width
>= RenderPanel
.Width
then
3015 sbHorizontal
.Max
:= Normalize16(gMapInfo
.Width
-RenderPanel
.Width
+16)
3017 sbHorizontal
.Max
:= 0;
3019 if gMapInfo
.Height
>= RenderPanel
.Height
then
3020 sbVertical
.Max
:= Normalize16(gMapInfo
.Height
-RenderPanel
.Height
+16)
3022 sbVertical
.Max
:= 0;
3024 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
3025 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
3028 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3033 j_max
:= 0; // shut up compiler
3037 res
:= (gPanels
<> nil) and
3038 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3039 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3041 gPanels
[ID
].Height
);
3042 j_max
:= Length(gPanels
) - 1;
3047 res
:= (gItems
<> nil) and
3048 LayerEnabled
[LAYER_ITEMS
] and
3049 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3050 ItemSize
[gItems
[ID
].ItemType
][0],
3051 ItemSize
[gItems
[ID
].ItemType
][1]);
3052 j_max
:= Length(gItems
) - 1;
3057 res
:= (gMonsters
<> nil) and
3058 LayerEnabled
[LAYER_MONSTERS
] and
3059 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3060 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3061 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3062 j_max
:= Length(gMonsters
) - 1;
3067 res
:= (gAreas
<> nil) and
3068 LayerEnabled
[LAYER_AREAS
] and
3069 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3070 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3071 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3072 j_max
:= Length(gAreas
) - 1;
3077 res
:= (gTriggers
<> nil) and
3078 LayerEnabled
[LAYER_TRIGGERS
] and
3079 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3080 gTriggers
[ID
].Width
,
3081 gTriggers
[ID
].Height
);
3082 j_max
:= Length(gTriggers
) - 1;
3092 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3101 if j
= Integer(ID
) then
3106 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3107 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3111 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3112 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3113 ItemSize
[gItems
[j
].ItemType
][0],
3114 ItemSize
[gItems
[j
].ItemType
][1]);
3116 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3117 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3118 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3119 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3121 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3122 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3123 AreaSize
[gAreas
[j
].AreaType
].Width
,
3124 AreaSize
[gAreas
[j
].AreaType
].Height
);
3126 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3127 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3129 gTriggers
[j
].Height
);
3136 SetLength(SelectedObjects
, 1);
3138 SelectedObjects
[0].ObjectType
:= ObjectType
;
3139 SelectedObjects
[0].ID
:= j
;
3140 SelectedObjects
[0].Live
:= True;
3148 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3149 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3153 c1
, c2
, c3
, c4
: Boolean;
3159 MainForm
.ActiveControl
:= RenderPanel
;
3160 RenderPanel
.SetFocus();
3162 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3164 if Button
= mbLeft
then // Left Mouse Button
3166 // Двигаем карту с помощью мыши и мини-карты:
3168 g_CollidePoint(X
, Y
,
3169 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3171 max(gMapInfo
.Width
div (16 div Scale
), 1),
3172 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3175 MouseAction
:= MOUSEACTION_MOVEMAP
;
3177 else // Ставим предмет/монстра/область:
3178 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3179 (not (ssShift
in Shift
)) then
3181 case pcObjects
.ActivePageIndex
of
3183 if lbItemList
.ItemIndex
= -1 then
3184 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3187 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3188 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3189 item
.ItemType
:= item
.ItemType
+ 2;
3190 item
.X
:= MousePos
.X
-MapOffset
.X
;
3191 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3193 if not (ssCtrl
in Shift
) then
3195 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3196 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3199 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3200 item
.Fall
:= cbFall
.Checked
;
3201 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3204 if lbMonsterList
.ItemIndex
= -1 then
3205 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3208 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3209 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3210 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3212 if not (ssCtrl
in Shift
) then
3214 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3215 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3218 if rbMonsterLeft
.Checked
then
3219 monster
.Direction
:= D_LEFT
3221 monster
.Direction
:= D_RIGHT
;
3222 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3225 if lbAreasList
.ItemIndex
= -1 then
3226 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3228 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3230 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3231 area
.X
:= MousePos
.X
-MapOffset
.X
;
3232 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3234 if not (ssCtrl
in Shift
) then
3236 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3237 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3240 if rbAreaLeft
.Checked
then
3241 area
.Direction
:= D_LEFT
3243 area
.Direction
:= D_RIGHT
;
3244 Undo_Add(OBJECT_AREA
, AddArea(area
));
3250 i
:= GetFirstSelected();
3252 // Выбираем объект под текущим:
3253 if (SelectedObjects
<> nil) and
3254 (ssShift
in Shift
) and (i
>= 0) and
3255 (SelectedObjects
[i
].Live
) then
3257 if SelectedObjectCount() = 1 then
3258 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3259 SelectedObjects
[i
].ObjectType
,
3260 SelectedObjects
[i
].ID
);
3264 // Рисуем область триггера "Расширитель":
3265 if DrawPressRect
and (i
>= 0) and
3266 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3267 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3268 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3269 MouseAction
:= MOUSEACTION_DRAWPRESS
3270 else // Рисуем панель:
3271 if pcObjects
.ActivePageIndex
= 0 then
3273 if (lbPanelType
.ItemIndex
>= 0) then
3274 MouseAction
:= MOUSEACTION_DRAWPANEL
3276 else // Рисуем триггер:
3277 if (lbTriggersList
.ItemIndex
>= 0) then
3279 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3283 end; // if Button = mbLeft
3285 if Button
= mbRight
then // Right Mouse Button
3287 // Клик по мини-карте:
3289 g_CollidePoint(X
, Y
,
3290 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3292 max(gMapInfo
.Width
div (16 div Scale
), 1),
3293 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3295 MouseAction
:= MOUSEACTION_NOACTION
;
3297 else // Нужно что-то выбрать мышью:
3298 if SelectFlag
<> SELECTFLAG_NONE
then
3301 SELECTFLAG_TELEPORT
:
3302 // Точку назначения телепортации:
3303 with gTriggers
[SelectedObjects
[
3304 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3306 X
:= MousePos
.X
-MapOffset
.X
;
3307 Y
:= MousePos
.Y
-MapOffset
.Y
;
3310 SELECTFLAG_SPAWNPOINT
:
3311 // Точку создания монстра:
3312 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3313 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3315 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3316 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3318 else if TriggerType
= TRIGGER_SPAWNITEM
then
3319 begin // Точка создания предмета:
3320 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3321 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3323 else if TriggerType
= TRIGGER_SHOT
then
3324 begin // Точка создания выстрела:
3325 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3326 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3332 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3334 2, 2, OBJECT_PANEL
, True);
3335 if IDArray
<> nil then
3337 for i
:= 0 to High(IDArray
) do
3338 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3339 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3341 gTriggers
[SelectedObjects
[
3342 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3347 gTriggers
[SelectedObjects
[
3348 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3352 // Панель с текстурой:
3354 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3356 2, 2, OBJECT_PANEL
, True);
3357 if IDArray
<> nil then
3359 for i
:= 0 to High(IDArray
) do
3360 if ((gPanels
[IDArray
[i
]].PanelType
in
3361 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3362 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3364 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3365 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3366 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3368 gTriggers
[SelectedObjects
[
3369 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3374 gTriggers
[SelectedObjects
[
3375 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3381 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3383 2, 2, OBJECT_PANEL
, True);
3384 if IDArray
<> nil then
3386 for i
:= 0 to High(IDArray
) do
3387 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3388 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3389 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3390 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3392 gTriggers
[SelectedObjects
[
3393 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3398 gTriggers
[SelectedObjects
[
3399 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3405 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3407 2, 2, OBJECT_MONSTER
, False);
3408 if IDArray
<> nil then
3409 gTriggers
[SelectedObjects
[
3410 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3412 gTriggers
[SelectedObjects
[
3413 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3416 SELECTFLAG_SHOTPANEL
:
3417 // Панель индикации выстрела:
3419 if gTriggers
[SelectedObjects
[
3420 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3422 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3424 2, 2, OBJECT_PANEL
, True);
3425 if IDArray
<> nil then
3427 for i
:= 0 to High(IDArray
) do
3428 if ((gPanels
[IDArray
[i
]].PanelType
in
3429 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3430 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3432 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3433 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3434 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3436 gTriggers
[SelectedObjects
[
3437 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3442 gTriggers
[SelectedObjects
[
3443 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3448 SelectFlag
:= SELECTFLAG_SELECTED
;
3450 else // if SelectFlag <> SELECTFLAG_NONE...
3452 // Что уже выбрано и не нажат Ctrl:
3453 if (SelectedObjects
<> nil) and
3454 (not (ssCtrl
in Shift
)) then
3455 for i
:= 0 to High(SelectedObjects
) do
3456 with SelectedObjects
[i
] do
3459 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3460 (SelectedObjectCount() = 1) then
3462 Rect
:= ObjectGetRect(ObjectType
, ID
);
3464 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3465 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3466 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3467 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3468 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3469 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3470 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3471 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3473 // Меняем размер панели или триггера:
3474 if c1
or c2
or c3
or c4
then
3476 MouseAction
:= MOUSEACTION_RESIZE
;
3477 LastMovePoint
:= MousePos
;
3481 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3483 ResizeDirection
:= RESIZEDIR_LEFT
3485 ResizeDirection
:= RESIZEDIR_RIGHT
;
3486 RenderPanel
.Cursor
:= crSizeWE
;
3490 ResizeType
:= RESIZETYPE_VERTICAL
;
3492 ResizeDirection
:= RESIZEDIR_UP
3494 ResizeDirection
:= RESIZEDIR_DOWN
;
3495 RenderPanel
.Cursor
:= crSizeNS
;
3502 // Перемещаем панель или триггер:
3503 if ObjectCollide(ObjectType
, ID
,
3505 Y
-MapOffset
.Y
-1, 2, 2) then
3507 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3508 LastMovePoint
:= MousePos
;
3514 end; // if Button = mbRight
3516 MouseRDown
:= Button
= mbRight
;
3518 MouseRDownPos
:= MousePos
;
3520 MouseLDown
:= Button
= mbLeft
;
3522 MouseLDownPos
:= MousePos
;
3525 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3526 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3533 rSelectRect
: Boolean;
3535 if Button
= mbLeft
then
3536 MouseLDown
:= False;
3537 if Button
= mbRight
then
3538 MouseRDown
:= False;
3541 ResizeType
:= RESIZETYPE_NONE
;
3543 if Button
= mbLeft
then // Left Mouse Button
3545 if MouseAction
<> MOUSEACTION_NONE
then
3546 begin // Было действие мышью
3547 // Мышь сдвинулась во время удержания клавиши:
3548 if (MousePos
.X
<> MouseLDownPos
.X
) and
3549 (MousePos
.Y
<> MouseLDownPos
.Y
) then
3552 MOUSEACTION_DRAWPANEL
:
3554 // Фон или передний план без текстуры - ошибка:
3555 if (lbPanelType
.ItemIndex
in [1, 2]) and
3556 (lbTextureList
.ItemIndex
= -1) then
3557 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3558 else // Назначаем параметры панели:
3560 case lbPanelType
.ItemIndex
of
3561 0: Panel
.PanelType
:= PANEL_WALL
;
3562 1: Panel
.PanelType
:= PANEL_BACK
;
3563 2: Panel
.PanelType
:= PANEL_FORE
;
3564 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3565 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3566 5: Panel
.PanelType
:= PANEL_STEP
;
3567 6: Panel
.PanelType
:= PANEL_WATER
;
3568 7: Panel
.PanelType
:= PANEL_ACID1
;
3569 8: Panel
.PanelType
:= PANEL_ACID2
;
3570 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3571 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3572 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3573 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3574 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3577 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3578 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3579 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3580 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3582 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3583 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3584 (lbTextureList
.ItemIndex
= -1) then
3586 Panel
.TextureHeight
:= 1;
3587 Panel
.TextureWidth
:= 1;
3588 Panel
.TextureName
:= '';
3589 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3591 else // Есть текстура:
3593 Panel
.TextureName
:= SelectedTexture();
3595 // Обычная текстура:
3596 if not IsSpecialTextureSel() then
3598 g_GetTextureSizeByName(Panel
.TextureName
,
3599 Panel
.TextureWidth
, Panel
.TextureHeight
);
3600 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3602 else // Спец.текстура:
3604 Panel
.TextureHeight
:= 1;
3605 Panel
.TextureWidth
:= 1;
3606 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3611 Panel
.Blending
:= False;
3613 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3617 // Рисовали триггер:
3618 MOUSEACTION_DRAWTRIGGER
:
3620 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3621 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3622 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3623 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3625 trigger
.Enabled
:= True;
3626 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3627 trigger
.TexturePanel
:= -1;
3630 trigger
.ActivateType
:= 0;
3632 if clbActivationType
.Checked
[0] then
3633 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3634 if clbActivationType
.Checked
[1] then
3635 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3636 if clbActivationType
.Checked
[2] then
3637 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3638 if clbActivationType
.Checked
[3] then
3639 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3640 if clbActivationType
.Checked
[4] then
3641 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3642 if clbActivationType
.Checked
[5] then
3643 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3645 // Необходимые для активации ключи:
3648 if clbKeys
.Checked
[0] then
3649 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3650 if clbKeys
.Checked
[1] then
3651 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3652 if clbKeys
.Checked
[2] then
3653 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3654 if clbKeys
.Checked
[3] then
3655 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3656 if clbKeys
.Checked
[4] then
3657 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3659 // Параметры триггера:
3660 FillByte(trigger
.Data
.Default
[0], 128, 0);
3662 case trigger
.TriggerType
of
3663 // Переключаемая панель:
3664 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3665 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3666 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3668 Trigger
.Data
.PanelID
:= -1;
3674 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3675 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3676 trigger
.Data
.d2d_teleport
:= True;
3677 trigger
.Data
.TlpDir
:= 0;
3680 // Изменение других триггеров:
3681 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3684 trigger
.Data
.Count
:= 1;
3690 trigger
.Data
.Volume
:= 255;
3691 trigger
.Data
.Pan
:= 127;
3692 trigger
.Data
.PlayCount
:= 1;
3693 trigger
.Data
.Local
:= True;
3694 trigger
.Data
.SoundSwitch
:= False;
3700 trigger
.Data
.MusicAction
:= 1;
3703 // Создание монстра:
3704 TRIGGER_SPAWNMONSTER
:
3706 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3707 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3708 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3709 trigger
.Data
.MonHealth
:= 0;
3710 trigger
.Data
.MonActive
:= False;
3711 trigger
.Data
.MonCount
:= 1;
3714 // Создание предмета:
3717 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3718 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3719 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3720 trigger
.Data
.ItemOnlyDM
:= False;
3721 trigger
.Data
.ItemFalls
:= False;
3722 trigger
.Data
.ItemCount
:= 1;
3723 trigger
.Data
.ItemMax
:= 0;
3724 trigger
.Data
.ItemDelay
:= 0;
3730 trigger
.Data
.PushAngle
:= 90;
3731 trigger
.Data
.PushForce
:= 10;
3732 trigger
.Data
.ResetVel
:= True;
3737 trigger
.Data
.ScoreCount
:= 1;
3738 trigger
.Data
.ScoreCon
:= True;
3739 trigger
.Data
.ScoreMsg
:= True;
3744 trigger
.Data
.MessageKind
:= 0;
3745 trigger
.Data
.MessageSendTo
:= 0;
3746 trigger
.Data
.MessageText
:= '';
3747 trigger
.Data
.MessageTime
:= 144;
3752 trigger
.Data
.DamageValue
:= 5;
3753 trigger
.Data
.DamageInterval
:= 12;
3758 trigger
.Data
.HealValue
:= 5;
3759 trigger
.Data
.HealInterval
:= 36;
3764 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3765 trigger
.Data
.ShotSound
:= True;
3766 trigger
.Data
.ShotPanelID
:= -1;
3767 trigger
.Data
.ShotTarget
:= 0;
3768 trigger
.Data
.ShotIntSight
:= 0;
3769 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
3770 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3771 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3772 trigger
.Data
.ShotAngle
:= 0;
3773 trigger
.Data
.ShotWait
:= 18;
3774 trigger
.Data
.ShotAccuracy
:= 0;
3775 trigger
.Data
.ShotAmmo
:= 0;
3776 trigger
.Data
.ShotIntReload
:= 0;
3781 trigger
.Data
.FXCount
:= 1;
3782 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3783 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3784 trigger
.Data
.FXColorR
:= 0;
3785 trigger
.Data
.FXColorG
:= 0;
3786 trigger
.Data
.FXColorB
:= 255;
3787 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3788 trigger
.Data
.FXWait
:= 1;
3789 trigger
.Data
.FXVelX
:= 0;
3790 trigger
.Data
.FXVelY
:= -20;
3791 trigger
.Data
.FXSpreadL
:= 5;
3792 trigger
.Data
.FXSpreadR
:= 5;
3793 trigger
.Data
.FXSpreadU
:= 4;
3794 trigger
.Data
.FXSpreadD
:= 0;
3798 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3801 // Рисовали область триггера "Расширитель":
3802 MOUSEACTION_DRAWPRESS
:
3803 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3805 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3806 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3807 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3808 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3810 DrawPressRect
:= False;
3814 MouseAction
:= MOUSEACTION_NONE
;
3816 end // if Button = mbLeft...
3817 else // Right Mouse Button:
3819 if MouseAction
= MOUSEACTION_NOACTION
then
3821 MouseAction
:= MOUSEACTION_NONE
;
3825 // Объект передвинут или изменен в размере:
3826 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3828 MouseAction
:= MOUSEACTION_NONE
;
3833 // Еще не все выбрали:
3834 if SelectFlag
<> SELECTFLAG_NONE
then
3836 if SelectFlag
= SELECTFLAG_SELECTED
then
3837 SelectFlag
:= SELECTFLAG_NONE
;
3842 // Мышь сдвинулась во время удержания клавиши:
3843 if (MousePos
.X
<> MouseRDownPos
.X
) and
3844 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3846 rSelectRect
:= True;
3848 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3849 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3850 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3851 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3853 else // Мышь не сдвинулась - нет прямоугольника:
3855 rSelectRect
:= False;
3857 rRect
.X
:= X
-MapOffset
.X
-1;
3858 rRect
.Y
:= Y
-MapOffset
.Y
-1;
3863 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
3864 if not (ssCtrl
in Shift
) then
3865 RemoveSelectFromObjects();
3867 // Выделяем всё в выбранном прямоугольнике:
3868 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3869 rRect
.Width
, rRect
.Height
,
3870 pcObjects
.ActivePageIndex
+1, rSelectRect
);
3872 if IDArray
<> nil then
3873 for i
:= 0 to High(IDArray
) do
3874 SelectObject(pcObjects
.ActivePageIndex
+1, IDArray
[i
],
3875 (ssCtrl
in Shift
) or rSelectRect
);
3881 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
3886 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
3887 Shift
: TShiftState
; X
, Y
: Integer);
3890 dWidth
, dHeight
: Integer;
3893 _id
:= GetFirstSelected();
3895 // Рисуем панель с текстурой, сетка - размеры текстуры:
3896 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
3897 (lbPanelType
.ItemIndex
in [0..8]) and
3898 (lbTextureList
.ItemIndex
<> -1) and
3899 (not IsSpecialTextureSel()) then
3901 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
3902 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
3905 // Меняем размер панели с текстурой, сетка - размеры текстуры:
3906 if (MouseAction
= MOUSEACTION_RESIZE
) and
3907 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
3908 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
3909 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
3910 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
3912 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
3913 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
3916 // Выравнивание по сетке:
3922 else // Нет выравнивания по сетке:
3928 // Новая позиция мыши:
3930 begin // Зажата левая кнопка мыши
3931 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
3932 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
3936 begin // Зажата правая кнопка мыши
3937 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
3938 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
3941 begin // Кнопки мыши не зажаты
3942 MousePos
.X
:= (Round(X
/sX
)*sX
);
3943 MousePos
.Y
:= (Round(Y
/sY
)*sY
);
3946 // Изменение размера закончилось - ставим обычный курсор:
3947 if ResizeType
= RESIZETYPE_NONE
then
3948 RenderPanel
.Cursor
:= crDefault
;
3950 // Зажата только правая кнопка мыши:
3951 if (not MouseLDown
) and (MouseRDown
) then
3953 // Рисуем прямоугольник выделения:
3954 if MouseAction
= MOUSEACTION_NONE
then
3956 if DrawRect
= nil then
3958 DrawRect
.Top
:= MouseRDownPos
.y
;
3959 DrawRect
.Left
:= MouseRDownPos
.x
;
3960 DrawRect
.Bottom
:= MousePos
.y
;
3961 DrawRect
.Right
:= MousePos
.x
;
3964 // Двигаем выделенные объекты:
3965 if MouseAction
= MOUSEACTION_MOVEOBJ
then
3967 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
3968 MousePos
.X
-LastMovePoint
.X
,
3969 MousePos
.Y
-LastMovePoint
.Y
);
3972 // Меняем размер выделенного объекта:
3973 if MouseAction
= MOUSEACTION_RESIZE
then
3975 if (SelectedObjectCount
= 1) and
3976 (SelectedObjects
[GetFirstSelected
].Live
) then
3978 dWidth
:= MousePos
.X
-LastMovePoint
.X
;
3979 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
;
3982 RESIZETYPE_VERTICAL
: dWidth
:= 0;
3983 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
3986 case ResizeDirection
of
3987 RESIZEDIR_UP
: dHeight
:= -dHeight
;
3988 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
3991 ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
3992 SelectedObjects
[GetFirstSelected
].ID
,
3993 dWidth
, dHeight
, ResizeDirection
);
3995 LastMovePoint
:= MousePos
;
4000 // Зажата только левая кнопка мыши:
4001 if (not MouseRDown
) and (MouseLDown
) then
4003 // Рисуем прямоугольник планирования панели:
4004 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4005 MOUSEACTION_DRAWTRIGGER
,
4006 MOUSEACTION_DRAWPRESS
] then
4008 if DrawRect
= nil then
4010 DrawRect
.Top
:= MouseLDownPos
.y
;
4011 DrawRect
.Left
:= MouseLDownPos
.x
;
4012 DrawRect
.Bottom
:= MousePos
.y
;
4013 DrawRect
.Right
:= MousePos
.x
;
4015 else // Двигаем карту:
4016 if MouseAction
= MOUSEACTION_MOVEMAP
then
4022 // Клавиши мыши не зажаты:
4023 if (not MouseRDown
) and (not MouseLDown
) then
4026 // Строка состояния - координаты мыши:
4027 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4028 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4031 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4033 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
4034 PChar(_lc
[I_MSG_EXIT
]),
4035 MB_ICONQUESTION
or MB_YESNO
or
4036 MB_DEFBUTTON1
) = idYes
;
4039 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4044 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4049 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
4051 if WindowState
<> wsMaximized
then
4053 config
.WriteInt('Editor', 'XPos', Left
);
4054 config
.WriteInt('Editor', 'YPos', Top
);
4055 config
.WriteInt('Editor', 'Width', Width
);
4056 config
.WriteInt('Editor', 'Height', Height
);
4060 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4061 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4062 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4063 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4065 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4066 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4067 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4068 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4069 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4070 config
.WriteInt('Editor', 'DotStep', DotStep
);
4071 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4072 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4073 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4074 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4075 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4076 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4077 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4079 for i
:= 0 to RecentCount
-1 do
4080 if i
< RecentFiles
.Count
then
4081 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4083 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4086 config
.SaveFile(EditorDir
+'Editor.cfg');
4089 slInvalidTextures
.Free
;
4092 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4094 if MainForm
.Visible
then
4098 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4102 MapOptionsForm
.ShowModal();
4104 ResName
:= OpenedMap
;
4105 while (Pos(':\', ResName
) > 0) do
4106 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4108 UpdateCaption(win2utf(gMapInfo
.Name
), ExtractFileName(OpenedWAD
), ResName
);
4111 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4113 AboutForm
.ShowModal();
4116 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word;
4117 Shift
: TShiftState
);
4122 if (not EditingProperties
) then
4124 if Key
= Ord('1') then
4125 SwitchLayer(LAYER_BACK
);
4126 if Key
= Ord('2') then
4127 SwitchLayer(LAYER_WALLS
);
4128 if Key
= Ord('3') then
4129 SwitchLayer(LAYER_FOREGROUND
);
4130 if Key
= Ord('4') then
4131 SwitchLayer(LAYER_STEPS
);
4132 if Key
= Ord('5') then
4133 SwitchLayer(LAYER_WATER
);
4134 if Key
= Ord('6') then
4135 SwitchLayer(LAYER_ITEMS
);
4136 if Key
= Ord('7') then
4137 SwitchLayer(LAYER_MONSTERS
);
4138 if Key
= Ord('8') then
4139 SwitchLayer(LAYER_AREAS
);
4140 if Key
= Ord('9') then
4141 SwitchLayer(LAYER_TRIGGERS
);
4142 if Key
= Ord('0') then
4143 tbShowClick(tbShow
);
4145 if Key
= Ord('V') then
4146 begin // Поворот монстров и областей:
4147 if (SelectedObjects
<> nil) then
4149 for i
:= 0 to High(SelectedObjects
) do
4150 if (SelectedObjects
[i
].Live
) then
4152 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4154 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4157 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4159 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4165 if pcObjects
.ActivePage
= tsMonsters
then
4167 if rbMonsterLeft
.Checked
then
4168 rbMonsterRight
.Checked
:= True
4170 rbMonsterLeft
.Checked
:= True;
4172 if pcObjects
.ActivePage
= tsAreas
then
4174 if rbAreaLeft
.Checked
then
4175 rbAreaRight
.Checked
:= True
4177 rbAreaLeft
.Checked
:= True;
4182 if not (ssCtrl
in Shift
) then
4184 // Вертикальный скролл карты:
4187 if Key
= Ord('W') then
4189 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4190 MapOffset
.Y
:= -Round(Position
/16) * 16;
4193 if Key
= Ord('S') then
4195 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4196 MapOffset
.Y
:= -Round(Position
/16) * 16;
4200 // Горизонтальный скролл карты:
4201 with sbHorizontal
do
4203 if Key
= Ord('A') then
4205 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4206 MapOffset
.X
:= -Round(Position
/16) * 16;
4209 if Key
= Ord('D') then
4211 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4212 MapOffset
.X
:= -Round(Position
/16) * 16;
4218 // Удалить выделенные объекты:
4219 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4220 RenderPanel
.Focused() then
4221 DeleteSelectedObjects();
4224 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4225 RemoveSelectFromObjects();
4227 // Передвинуть объекты:
4228 if MainForm
.ActiveControl
= RenderPanel
then
4233 if Key
= VK_NUMPAD4
then
4234 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4235 if Key
= VK_NUMPAD6
then
4236 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4237 if Key
= VK_NUMPAD8
then
4238 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4239 if Key
= VK_NUMPAD5
then
4240 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4242 if (dx
<> 0) or (dy
<> 0) then
4244 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4249 if ssCtrl
in Shift
then
4251 // Выбор панели с текстурой для триггера
4252 if Key
= Ord('T') then
4254 DrawPressRect
:= False;
4255 if SelectFlag
= SELECTFLAG_TEXTURE
then
4257 SelectFlag
:= SELECTFLAG_NONE
;
4260 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4262 SelectFlag
:= SELECTFLAG_TEXTURE
;
4265 if Key
= Ord('D') then
4267 SelectFlag
:= SELECTFLAG_NONE
;
4268 if DrawPressRect
then
4270 DrawPressRect
:= False;
4274 // Выбор области воздействия, в зависимости от типа триггера
4275 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4278 DrawPressRect
:= True;
4281 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4283 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4286 SelectFlag
:= SELECTFLAG_DOOR
;
4289 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4292 SelectFlag
:= SELECTFLAG_LIFT
;
4295 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4298 SelectFlag
:= SELECTFLAG_TELEPORT
;
4301 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4304 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4308 // Выбор основного параметра, в зависимости от типа триггера
4309 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4312 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4313 SelectMapForm
.GetMaps(FileName
);
4315 if SelectMapForm
.ShowModal() = mrOK
then
4317 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4318 bApplyProperty
.Click();
4322 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4324 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4327 AddSoundForm
.OKFunction
:= nil;
4328 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4329 AddSoundForm
.SetResource
:= utf2win(vleObjectProperty
.Cells
[1, i
]);
4331 if (AddSoundForm
.ShowModal() = mrOk
) then
4333 vleObjectProperty
.Cells
[1, i
] := win2utf(AddSoundForm
.ResourceName
);
4334 bApplyProperty
.Click();
4338 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4340 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4343 vleObjectProperty
.Row
:= i
;
4344 vleObjectProperty
.SetFocus();
4351 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4353 RemoveSelectFromObjects();
4354 MapOptimizationForm
.ShowModal();
4357 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4359 MapCheckForm
.ShowModal();
4362 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4364 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4365 AddTextureForm
.ShowModal();
4368 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4371 TextureWidth
, TextureHeight
: Word;
4373 if (lbTextureList
.ItemIndex
<> -1) and
4374 (not IsSpecialTextureSel()) then
4376 if g_GetTexture(SelectedTexture(), TextureID
) then
4378 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4380 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4381 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4384 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4385 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4390 lTextureWidth
.Caption
:= '';
4391 lTextureHeight
.Caption
:= '';
4395 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4396 ARect
: TRect
; State
: TOwnerDrawState
);
4398 with Control
as TListBox
do
4400 if LCLType
.odSelected
in State
then
4402 Canvas
.Brush
.Color
:= clHighlight
;
4403 Canvas
.Font
.Color
:= clHighlightText
;
4405 if (Items
<> nil) and (Index
>= 0) then
4406 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4408 Canvas
.Brush
.Color
:= clRed
;
4409 Canvas
.Font
.Color
:= clWhite
;
4411 Canvas
.FillRect(ARect
);
4412 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4416 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4417 const KeyName
: String; Values
: TStrings
);
4419 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4421 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4423 Values
.Add(DirNames
[D_LEFT
]);
4424 Values
.Add(DirNames
[D_RIGHT
]);
4426 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4428 Values
.Add(DirNamesAdv
[0]);
4429 Values
.Add(DirNamesAdv
[1]);
4430 Values
.Add(DirNamesAdv
[2]);
4431 Values
.Add(DirNamesAdv
[3]);
4433 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4435 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4436 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4438 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4440 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4441 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4442 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4443 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4444 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4445 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4447 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4449 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4450 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4451 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4452 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4454 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4456 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4457 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4458 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4459 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4461 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4463 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4464 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4466 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4468 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4469 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4470 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4471 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4472 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4473 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4475 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4477 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4478 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4479 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4480 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4481 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4482 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4483 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4485 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
4487 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
4488 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
4489 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
4490 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
4492 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4493 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4494 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4495 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4496 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4497 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4498 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4499 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4500 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4501 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4502 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4503 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4504 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4505 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4506 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4507 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4508 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4509 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4510 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4512 Values
.Add(BoolNames
[True]);
4513 Values
.Add(BoolNames
[False]);
4518 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4520 _id
, a
, r
, c
: Integer;
4526 if SelectedObjectCount() <> 1 then
4528 if not SelectedObjects
[GetFirstSelected()].Live
then
4532 if not CheckProperty() then
4538 _id
:= GetFirstSelected();
4540 r
:= vleObjectProperty
.Row
;
4541 c
:= vleObjectProperty
.Col
;
4543 case SelectedObjects
[_id
].ObjectType
of
4546 with gPanels
[SelectedObjects
[_id
].ID
] do
4548 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4549 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4550 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4551 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4553 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4555 // Сброс ссылки на триггеры смены текстуры:
4556 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4557 if gTriggers
<> nil then
4558 for a
:= 0 to High(gTriggers
) do
4560 if (gTriggers
[a
].TriggerType
<> 0) and
4561 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4562 gTriggers
[a
].TexturePanel
:= -1;
4563 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4564 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4565 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4568 // Сброс ссылки на триггеры лифта:
4569 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4570 if gTriggers
<> nil then
4571 for a
:= 0 to High(gTriggers
) do
4572 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4573 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4574 gTriggers
[a
].Data
.PanelID
:= -1;
4576 // Сброс ссылки на триггеры двери:
4577 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4578 if gTriggers
<> nil then
4579 for a
:= 0 to High(gTriggers
) do
4580 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4581 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4582 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4583 gTriggers
[a
].Data
.PanelID
:= -1;
4585 if IsTexturedPanel(PanelType
) then
4586 begin // Может быть текстура
4587 if TextureName
<> '' then
4588 begin // Была текстура
4589 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4590 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4599 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4601 if TextureName
<> '' then
4602 begin // Есть текстура
4603 // Обычная текстура:
4604 if not IsSpecialTexture(TextureName
) then
4606 g_GetTextureSizeByName(TextureName
,
4607 TextureWidth
, TextureHeight
);
4609 // Проверка кратности размеров панели:
4611 if TextureWidth
<> 0 then
4612 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4614 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4618 if Res
and (TextureHeight
<> 0) then
4619 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4621 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4628 if not g_GetTexture(TextureName
, TextureID
) then
4629 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4630 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4632 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4633 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4635 TextureHeight
:= NH
;
4638 TextureID
:= TEXTURE_SPECIAL_NONE
;
4648 TextureID
:= TEXTURE_SPECIAL_NONE
;
4651 else // Спец.текстура
4655 TextureID
:= SpecialTextureID(TextureName
);
4658 else // Нет текстуры
4662 TextureID
:= TEXTURE_SPECIAL_NONE
;
4665 else // Не может быть текстуры
4672 TextureID
:= TEXTURE_SPECIAL_NONE
;
4679 with gItems
[SelectedObjects
[_id
].ID
] do
4681 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4682 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4683 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
4684 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
4690 with gMonsters
[SelectedObjects
[_id
].ID
] do
4692 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4693 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4694 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4700 with gAreas
[SelectedObjects
[_id
].ID
] do
4702 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4703 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4704 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4710 with gTriggers
[SelectedObjects
[_id
].ID
] do
4712 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4713 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4714 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4715 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4716 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
4717 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
4718 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
4723 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]];
4724 FillByte(Data
.MapName
[0], 16, 0);
4726 Move(Data
.MapName
[0], s
[1], Min(Length(s
), 16));
4731 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
4732 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
4735 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
4737 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
4738 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
4739 if Data
.Count
< 1 then
4741 if TriggerType
= TRIGGER_PRESS
then
4742 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
4745 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
4746 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
4749 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
4750 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
4755 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
4756 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
4757 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
4762 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]];
4763 FillByte(Data
.SoundName
[0], 64, 0);
4765 Move(Data
.SoundName
[0], s
[1], Min(Length(s
), 64));
4767 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
4768 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
4769 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
4770 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
4771 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
4774 TRIGGER_SPAWNMONSTER
:
4776 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
4777 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
4778 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
4779 if Data
.MonHealth
< 0 then
4780 Data
.MonHealth
:= 0;
4781 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
4782 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
4783 if Data
.MonCount
< 1 then
4785 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
4786 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
4787 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
4789 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
4791 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
4793 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
4795 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
4797 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
4803 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
4804 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
4805 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
4806 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
4807 if Data
.ItemCount
< 1 then
4808 Data
.ItemCount
:= 1;
4809 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
4810 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
4811 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
4816 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]];
4817 FillByte(Data
.MusicName
[0], 64, 0);
4819 Move(Data
.MusicName
[0], s
[1], Min(Length(s
), 64));
4821 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
4822 Data
.MusicAction
:= 1
4824 Data
.MusicAction
:= 2;
4829 Data
.PushAngle
:= Min(
4830 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
4831 Data
.PushForce
:= Min(
4832 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
4833 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
4838 Data
.ScoreAction
:= 0;
4839 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
4840 Data
.ScoreAction
:= 1
4841 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
4842 Data
.ScoreAction
:= 2
4843 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
4844 Data
.ScoreAction
:= 3;
4845 Data
.ScoreCount
:= Min(Max(
4846 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
4847 Data
.ScoreTeam
:= 0;
4848 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
4850 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
4852 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
4853 Data
.ScoreTeam
:= 3;
4854 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
4855 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
4860 Data
.MessageKind
:= 0;
4861 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
4862 Data
.MessageKind
:= 1;
4864 Data
.MessageSendTo
:= 0;
4865 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
4866 Data
.MessageSendTo
:= 1
4867 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
4868 Data
.MessageSendTo
:= 2
4869 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
4870 Data
.MessageSendTo
:= 3
4871 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
4872 Data
.MessageSendTo
:= 4
4873 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
4874 Data
.MessageSendTo
:= 5;
4876 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]];
4877 FillByte(Data
.MessageText
[0], 100, 0);
4879 Move(Data
.MessageText
[0], s
[1], Min(Length(s
), 100));
4881 Data
.MessageTime
:= Min(Max(
4882 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
4887 Data
.DamageValue
:= Min(Max(
4888 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
4889 Data
.DamageInterval
:= Min(Max(
4890 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
4895 Data
.HealValue
:= Min(Max(
4896 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
4897 Data
.HealInterval
:= Min(Max(
4898 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
4899 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
4900 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
4905 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
4906 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
4907 Data
.ShotTarget
:= 0;
4908 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
4909 Data
.ShotTarget
:= 1
4910 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
4911 Data
.ShotTarget
:= 2
4912 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
4913 Data
.ShotTarget
:= 3
4914 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
4915 Data
.ShotTarget
:= 4
4916 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
4917 Data
.ShotTarget
:= 5
4918 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
4919 Data
.ShotTarget
:= 6;
4920 Data
.ShotIntSight
:= Min(Max(
4921 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
4923 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
4925 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
4927 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
4929 Data
.ShotAngle
:= Min(
4930 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
4931 Data
.ShotWait
:= Min(Max(
4932 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
4933 Data
.ShotAccuracy
:= Min(Max(
4934 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
4935 Data
.ShotAmmo
:= Min(Max(
4936 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
4937 Data
.ShotIntReload
:= Min(Max(
4938 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
4943 Data
.FXCount
:= Min(Max(
4944 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
4945 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
4947 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
4948 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
4949 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
4950 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
4951 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
4952 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
4953 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
4954 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
4955 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
4956 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
4957 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
4958 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
4959 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
4960 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
4963 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
4964 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
4967 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
4968 Data
.FXColorR
:= a
and $FF;
4969 Data
.FXColorG
:= (a
shr 8) and $FF;
4970 Data
.FXColorB
:= (a
shr 16) and $FF;
4971 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
4975 Data
.FXWait
:= Min(Max(
4976 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
4977 Data
.FXVelX
:= Min(Max(
4978 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
4979 Data
.FXVelY
:= Min(Max(
4980 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
4981 Data
.FXSpreadL
:= Min(Max(
4982 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
4983 Data
.FXSpreadR
:= Min(Max(
4984 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
4985 Data
.FXSpreadU
:= Min(Max(
4986 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
4987 Data
.FXSpreadD
:= Min(Max(
4988 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
4997 vleObjectProperty
.Row
:= r
;
4998 vleObjectProperty
.Col
:= c
;
5001 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5005 i
:= lbTextureList
.ItemIndex
;
5009 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5010 [SelectedTexture()])),
5011 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5012 MB_ICONQUESTION
or MB_YESNO
or
5013 MB_DEFBUTTON1
) <> idYes
then
5016 if gPanels
<> nil then
5017 for a
:= 0 to High(gPanels
) do
5018 if (gPanels
[a
].PanelType
<> 0) and
5019 (gPanels
[a
].TextureName
= SelectedTexture()) then
5021 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5025 g_DeleteTexture(SelectedTexture());
5026 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5028 slInvalidTextures
.Delete(i
);
5029 if lbTextureList
.ItemIndex
> -1 then
5030 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5033 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5035 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
5036 PChar(_lc
[I_MSG_CLEAR_MAP
]),
5037 MB_ICONQUESTION
or MB_YESNO
or
5038 MB_DEFBUTTON1
) = mrYes
) then
5042 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5046 if UndoBuffer
= nil then
5048 if UndoBuffer
[High(UndoBuffer
)] = nil then
5051 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5052 with UndoBuffer
[High(UndoBuffer
)][a
] do
5060 UNDO_DELETE_ITEM
: AddItem(Item
);
5061 UNDO_DELETE_AREA
: AddArea(Area
);
5062 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5063 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5064 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5065 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5066 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5067 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5068 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5072 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5074 RemoveSelectFromObjects();
5076 miUndo
.Enabled
:= UndoBuffer
<> nil;
5080 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5083 CopyBuffer
: TCopyRecArray
;
5087 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5089 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5091 if Result
= 0 then // Одного типа
5092 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5095 procedure QuickSortCopyBuffer(L
, R
: Integer);
5103 P
:= CopyBuffer
[(L
+ R
) shr 1];
5106 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5108 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5114 CopyBuffer
[I
] := CopyBuffer
[J
];
5122 QuickSortCopyBuffer(L
, J
);
5129 if SelectedObjects
= nil then
5135 // Копируем объекты:
5136 for a
:= 0 to High(SelectedObjects
) do
5137 if SelectedObjects
[a
].Live
then
5138 with SelectedObjects
[a
] do
5140 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5141 b
:= High(CopyBuffer
);
5142 CopyBuffer
[b
].ID
:= ID
;
5143 CopyBuffer
[b
].Panel
:= nil;
5148 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5149 New(CopyBuffer
[b
].Panel
);
5150 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5155 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5156 CopyBuffer
[b
].Item
:= gItems
[ID
];
5161 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5162 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5167 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5168 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5173 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5174 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5179 // Сортировка по ID:
5180 if CopyBuffer
<> nil then
5182 QuickSortCopyBuffer(0, b
);
5185 // Пестановка ссылок триггеров:
5186 for a
:= 0 to Length(CopyBuffer
)-1 do
5187 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5189 case CopyBuffer
[a
].Trigger
.TriggerType
of
5190 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5191 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5192 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5193 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5197 for b
:= 0 to Length(CopyBuffer
)-1 do
5198 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5199 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5201 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5206 // Этих панелей нет среди копируемых:
5208 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5211 TRIGGER_PRESS
, TRIGGER_ON
,
5212 TRIGGER_OFF
, TRIGGER_ONOFF
:
5213 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5217 for b
:= 0 to Length(CopyBuffer
)-1 do
5218 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5219 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5221 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5226 // Этих монстров нет среди копируемых:
5228 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5232 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5236 for b
:= 0 to Length(CopyBuffer
)-1 do
5237 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5238 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5240 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5245 // Этих панелей нет среди копируемых:
5247 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5251 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5255 for b
:= 0 to Length(CopyBuffer
)-1 do
5256 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5257 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5259 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5264 // Этих панелей нет среди копируемых:
5266 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5271 str
:= CopyBufferToString(CopyBuffer
);
5272 ClipBoard
.AsText
:= str
;
5274 for a
:= 0 to Length(CopyBuffer
)-1 do
5275 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5276 (CopyBuffer
[a
].Panel
<> nil) then
5277 Dispose(CopyBuffer
[a
].Panel
);
5282 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5285 CopyBuffer
: TCopyRecArray
;
5287 swad
, ssec
, sres
: String;
5291 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
);
5293 if CopyBuffer
= nil then
5296 RemoveSelectFromObjects();
5298 h
:= High(CopyBuffer
);
5300 with CopyBuffer
[a
] do
5304 if Panel
<> nil then
5306 Panel
^.X
:= Panel
^.X
+ 16;
5307 Panel
^.Y
:= Panel
^.Y
+ 16;
5309 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5310 Panel
^.TextureWidth
:= 1;
5311 Panel
^.TextureHeight
:= 1;
5313 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5314 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5315 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5316 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5317 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5318 (Panel
^.TextureName
= '') then
5319 begin // Нет или не может быть текстуры:
5321 else // Есть текстура:
5323 // Обычная текстура:
5324 if not IsSpecialTexture(Panel
^.TextureName
) then
5326 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5330 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5331 AddTexture(swad
, ssec
, sres
, True);
5332 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5336 g_GetTextureSizeByName(Panel
^.TextureName
,
5337 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5339 Panel
^.TextureName
:= '';
5341 else // Спец.текстура:
5343 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5344 with MainForm
.lbTextureList
.Items
do
5345 if IndexOf(win2utf(Panel
^.TextureName
)) = -1 then
5346 Add(win2utf(Panel
^.TextureName
));
5350 ID
:= AddPanel(Panel
^);
5352 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5353 SelectObject(OBJECT_PANEL
, ID
, True);
5358 Item
.X
:= Item
.X
+ 16;
5359 Item
.Y
:= Item
.Y
+ 16;
5361 ID
:= AddItem(Item
);
5362 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5363 SelectObject(OBJECT_ITEM
, ID
, True);
5368 Monster
.X
:= Monster
.X
+ 16;
5369 Monster
.Y
:= Monster
.Y
+ 16;
5371 ID
:= AddMonster(Monster
);
5372 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5373 SelectObject(OBJECT_MONSTER
, ID
, True);
5378 Area
.X
:= Area
.X
+ 16;
5379 Area
.Y
:= Area
.Y
+ 16;
5381 ID
:= AddArea(Area
);
5382 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5383 SelectObject(OBJECT_AREA
, ID
, True);
5388 Trigger
.X
:= Trigger
.X
+ 16;
5389 Trigger
.Y
:= Trigger
.Y
+ 16;
5391 ID
:= AddTrigger(Trigger
);
5392 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5393 SelectObject(OBJECT_TRIGGER
, ID
, True);
5398 // Переставляем ссылки триггеров:
5399 for a
:= 0 to High(CopyBuffer
) do
5400 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5402 case CopyBuffer
[a
].Trigger
.TriggerType
of
5403 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5404 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5405 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5406 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5407 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5408 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5410 TRIGGER_PRESS
, TRIGGER_ON
,
5411 TRIGGER_OFF
, TRIGGER_ONOFF
:
5412 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5413 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5414 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5417 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5418 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5419 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5422 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5423 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5424 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5433 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5436 DeleteSelectedObjects();
5439 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5441 Key
, FileName
: String;
5444 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5446 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5448 with ChooseTypeForm
, vleObjectProperty
do
5449 begin // Выбор типа панели:
5450 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5451 lbTypeSelect
.Items
.Clear();
5453 for b
:= 0 to High(PANELNAMES
) do
5455 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5456 if Values
[Key
] = PANELNAMES
[b
] then
5457 lbTypeSelect
.ItemIndex
:= b
;
5460 if ShowModal() = mrOK
then
5462 b
:= lbTypeSelect
.ItemIndex
;
5463 Values
[Key
] := PANELNAMES
[b
];
5464 bApplyProperty
.Click();
5468 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5469 SelectFlag
:= SELECTFLAG_TELEPORT
5470 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5471 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5472 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5473 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5474 SelectFlag
:= SELECTFLAG_DOOR
5475 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5477 DrawPressRect
:= False;
5478 SelectFlag
:= SELECTFLAG_TEXTURE
;
5480 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5481 SelectFlag
:= SELECTFLAG_SHOTPANEL
5482 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5483 SelectFlag
:= SELECTFLAG_LIFT
5484 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5485 SelectFlag
:= SELECTFLAG_MONSTER
5486 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5488 SelectFlag
:= SELECTFLAG_NONE
;
5489 DrawPressRect
:= True;
5491 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5492 begin // Выбор следующей карты:
5493 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5494 SelectMapForm
.GetMaps(FileName
);
5496 if SelectMapForm
.ShowModal() = mrOK
then
5498 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5499 bApplyProperty
.Click();
5502 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5503 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5504 begin // Выбор файла звука/музыки:
5505 AddSoundForm
.OKFunction
:= nil;
5506 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5507 AddSoundForm
.SetResource
:= utf2win(vleObjectProperty
.Values
[Key
]);
5509 if (AddSoundForm
.ShowModal() = mrOk
) then
5511 vleObjectProperty
.Values
[Key
] := utf2win(AddSoundForm
.ResourceName
);
5512 bApplyProperty
.Click();
5515 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5516 with ActivationTypeForm
, vleObjectProperty
do
5517 begin // Выбор типов активации:
5518 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5519 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5520 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5521 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5522 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5523 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5525 if ShowModal() = mrOK
then
5528 if cbPlayerCollide
.Checked
then
5529 b
:= ACTIVATE_PLAYERCOLLIDE
;
5530 if cbMonsterCollide
.Checked
then
5531 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5532 if cbPlayerPress
.Checked
then
5533 b
:= b
or ACTIVATE_PLAYERPRESS
;
5534 if cbMonsterPress
.Checked
then
5535 b
:= b
or ACTIVATE_MONSTERPRESS
;
5536 if cbShot
.Checked
then
5537 b
:= b
or ACTIVATE_SHOT
;
5538 if cbNoMonster
.Checked
then
5539 b
:= b
or ACTIVATE_NOMONSTER
;
5541 Values
[Key
] := ActivateToStr(b
);
5542 bApplyProperty
.Click();
5545 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5546 with KeysForm
, vleObjectProperty
do
5547 begin // Выбор необходимых ключей:
5548 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5549 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5550 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5551 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5552 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5554 if ShowModal() = mrOK
then
5557 if cbRedKey
.Checked
then
5559 if cbGreenKey
.Checked
then
5560 b
:= b
or KEY_GREEN
;
5561 if cbBlueKey
.Checked
then
5563 if cbRedTeam
.Checked
then
5564 b
:= b
or KEY_REDTEAM
;
5565 if cbBlueTeam
.Checked
then
5566 b
:= b
or KEY_BLUETEAM
;
5568 Values
[Key
] := KeyToStr(b
);
5569 bApplyProperty
.Click();
5572 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
5573 with ChooseTypeForm
, vleObjectProperty
do
5574 begin // Выбор типа эффекта:
5575 Caption
:= _lc
[I_CAP_FX_TYPE
];
5576 lbTypeSelect
.Items
.Clear();
5578 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
5579 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5581 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
5583 if ShowModal() = mrOK
then
5585 b
:= lbTypeSelect
.ItemIndex
;
5586 Values
[Key
] := EffectToStr(b
);
5587 bApplyProperty
.Click();
5590 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
5591 with ChooseTypeForm
, vleObjectProperty
do
5592 begin // Выбор типа монстра:
5593 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
5594 lbTypeSelect
.Items
.Clear();
5596 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
5597 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
5599 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
5601 if ShowModal() = mrOK
then
5603 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
5604 Values
[Key
] := MonsterToStr(b
);
5605 bApplyProperty
.Click();
5608 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
5609 with ChooseTypeForm
, vleObjectProperty
do
5610 begin // Выбор типа предмета:
5611 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
5612 lbTypeSelect
.Items
.Clear();
5614 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
5615 lbTypeSelect
.Items
.Add(ItemToStr(b
));
5616 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
5617 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
5618 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
5619 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
5620 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
5621 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
5623 b
:= StrToItem(Values
[Key
]);
5624 if b
>= ITEM_BOTTLE
then
5626 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
5628 if ShowModal() = mrOK
then
5630 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
5631 if b
>= ITEM_WEAPON_KASTET
then
5633 Values
[Key
] := ItemToStr(b
);
5634 bApplyProperty
.Click();
5637 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
5638 with ChooseTypeForm
, vleObjectProperty
do
5639 begin // Выбор типа предмета:
5640 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
5641 lbTypeSelect
.Items
.Clear();
5643 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
5644 lbTypeSelect
.Items
.Add(ShotToStr(b
));
5646 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
5648 if ShowModal() = mrOK
then
5650 b
:= lbTypeSelect
.ItemIndex
;
5651 Values
[Key
] := ShotToStr(b
);
5652 bApplyProperty
.Click();
5655 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
5656 with ChooseTypeForm
, vleObjectProperty
do
5657 begin // Выбор типа эффекта:
5658 Caption
:= _lc
[I_CAP_FX_TYPE
];
5659 lbTypeSelect
.Items
.Clear();
5661 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
5662 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
5663 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5664 lbTypeSelect
.ItemIndex
:= 1
5666 lbTypeSelect
.ItemIndex
:= 0;
5668 if ShowModal() = mrOK
then
5670 b
:= lbTypeSelect
.ItemIndex
;
5672 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
5674 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
5675 bApplyProperty
.Click();
5678 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
5679 with ChooseTypeForm
, vleObjectProperty
do
5680 begin // Выбор подтипа эффекта:
5681 Caption
:= _lc
[I_CAP_FX_TYPE
];
5682 lbTypeSelect
.Items
.Clear();
5684 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5686 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
5687 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5689 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
5692 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
5693 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
5694 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
5695 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
5696 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
5697 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
5698 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
5699 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5700 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
5701 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5702 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
5703 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5704 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
5705 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5706 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
5707 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5708 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
5711 if ShowModal() = mrOK
then
5713 b
:= lbTypeSelect
.ItemIndex
;
5715 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5716 Values
[Key
] := EffectToStr(b
+ 1)
5718 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
5719 if b
= TRIGGER_EFFECT_LLIQUID
then
5720 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
5721 if b
= TRIGGER_EFFECT_DLIQUID
then
5722 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
5723 if b
= TRIGGER_EFFECT_BLOOD
then
5724 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
5725 if b
= TRIGGER_EFFECT_SPARK
then
5726 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
5727 if b
= TRIGGER_EFFECT_BUBBLE
then
5728 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
5731 bApplyProperty
.Click();
5734 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
5735 with vleObjectProperty
do
5736 begin // Выбор цвета эффекта:
5737 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
5738 if ColorDialog
.Execute
then
5740 Values
[Key
] := IntToStr(ColorDialog
.Color
);
5741 bApplyProperty
.Click();
5744 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
5745 begin // Смена текстуры:
5746 vleObjectProperty
.Values
[Key
] := SelectedTexture();
5747 bApplyProperty
.Click();
5751 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
5753 FileName
, Section
, Res
: String;
5755 if OpenedMap
= '' then
5757 aSaveMapAsExecute(nil);
5761 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
5763 SaveMap(FileName
+':\'+Res
);
5766 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
5768 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
5770 if OpenDialog
.Execute() then
5772 if (Pos('.ini', LowerCase(ExtractFileName(OpenDialog
.FileName
))) > 0) then
5776 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
5777 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
5778 pLoadProgress
.Show();
5783 LoadMapOld(OpenDialog
.FileName
);
5785 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(OpenDialog
.FileName
)]);
5787 pLoadProgress
.Hide();
5788 MainForm
.FormResize(Self
);
5790 else // Карты из WAD:
5792 OpenMap(OpenDialog
.FileName
, '');
5795 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
5799 procedure TMainForm
.FormActivate(Sender
: TObject
);
5804 MainForm
.ActiveControl
:= RenderPanel
;
5807 if gLanguage
= '' then
5809 lang
:= SelectLanguageForm
.ShowModal();
5811 1: gLanguage
:= LANGUAGE_ENGLISH
;
5812 else gLanguage
:= LANGUAGE_RUSSIAN
;
5815 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
5816 config
.WriteStr('Editor', 'Language', gLanguage
);
5817 config
.SaveFile(EditorDir
+'Editor.cfg');
5821 //e_WriteLog('Read language file', MSG_NOTIFY);
5822 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
5823 g_Language_Set(gLanguage
);
5826 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
5834 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
5836 if not OpenDialog
.Execute() then
5839 WAD
:= TWADEditor_1
.Create();
5841 if not WAD
.ReadFile(OpenDialog
.FileName
) then
5849 MapList
:= WAD
.GetResourcesList('');
5851 SelectMapForm
.lbMapList
.Items
.Clear();
5853 if MapList
<> nil then
5854 for a
:= 0 to High(MapList
) do
5855 SelectMapForm
.lbMapList
.Items
.Add(MapList
[a
]);
5857 if (SelectMapForm
.ShowModal() = mrOK
) then
5859 str
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5861 Move(MapName
[0], str
[1], Min(16, Length(str
)));
5863 if MessageBox(0, PChar(Format(_lc
[I_MSG_DELETE_MAP_PROMT
],
5864 [MapName
, OpenDialog
.FileName
])),
5865 PChar(_lc
[I_MSG_DELETE_MAP
]),
5866 MB_ICONQUESTION
or MB_YESNO
or
5867 MB_DEFBUTTON2
) <> mrYes
then
5870 WAD
.RemoveResource('', MapName
);
5872 MessageBox(0, PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
],
5874 PChar(_lc
[I_MSG_MAP_DELETED
]),
5875 MB_ICONINFORMATION
or MB_OK
or
5878 WAD
.SaveTo(OpenDialog
.FileName
);
5880 // Удалили текущую карту - сохранять по старому ее нельзя:
5881 if OpenedMap
= (OpenDialog
.FileName
+':\'+MapName
) then
5885 MainForm
.Caption
:= FormCaption
;
5892 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
5893 var Key
: Word; Shift
: TShiftState
);
5895 if Key
= VK_RETURN
then
5896 bApplyProperty
.Click();
5899 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
5904 if (ID
= 0) and (MoveType
= 0) then
5906 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
5908 if (ID
> DWORD(High(gPanels
))) then
5913 if MoveType
= 0 then // to Back
5915 if gTriggers
<> nil then
5916 for a
:= 0 to High(gTriggers
) do
5917 with gTriggers
[a
] do
5919 if TriggerType
= TRIGGER_NONE
then
5922 if TexturePanel
= _id
then
5925 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
5929 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5930 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5931 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5932 if Data
.PanelID
= _id
then
5935 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
5939 if Data
.ShotPanelID
= _id
then
5940 Data
.ShotPanelID
:= 0
5942 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
5943 Inc(Data
.ShotPanelID
);
5947 tmp
:= gPanels
[_id
];
5949 for a
:= _id
downto 1 do
5950 gPanels
[a
] := gPanels
[a
-1];
5958 if gTriggers
<> nil then
5959 for a
:= 0 to High(gTriggers
) do
5960 with gTriggers
[a
] do
5962 if TriggerType
= TRIGGER_NONE
then
5965 if TexturePanel
= _id
then
5966 TexturePanel
:= High(gPanels
)
5968 if TexturePanel
> _id
then
5972 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5973 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5974 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5975 if Data
.PanelID
= _id
then
5976 Data
.PanelID
:= High(gPanels
)
5978 if Data
.PanelID
> _id
then
5982 if Data
.ShotPanelID
= _id
then
5983 Data
.ShotPanelID
:= High(gPanels
)
5985 if Data
.ShotPanelID
> _id
then
5986 Dec(Data
.ShotPanelID
);
5990 tmp
:= gPanels
[_id
];
5992 for a
:= _id
to High(gPanels
)-1 do
5993 gPanels
[a
] := gPanels
[a
+1];
5995 gPanels
[High(gPanels
)] := tmp
;
5997 ID
:= High(gPanels
);
6001 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6005 if SelectedObjects
= nil then
6008 for a
:= 0 to High(SelectedObjects
) do
6009 with SelectedObjects
[a
] do
6010 if Live
and (ObjectType
= OBJECT_PANEL
) then
6012 SelectedObjects
[0] := SelectedObjects
[a
];
6013 SetLength(SelectedObjects
, 1);
6020 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6024 if SelectedObjects
= nil then
6027 for a
:= 0 to High(SelectedObjects
) do
6028 with SelectedObjects
[a
] do
6029 if Live
and (ObjectType
= OBJECT_PANEL
) then
6031 SelectedObjects
[0] := SelectedObjects
[a
];
6032 SetLength(SelectedObjects
, 1);
6039 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6043 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6045 if not SaveDialog
.Execute() then
6048 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6050 if SaveMapForm
.ShowModal() <> mrOK
then
6053 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6054 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6055 OpenedWAD
:= SaveDialog
.FileName
;
6057 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6058 // Такая карта уже недавно открывалась:
6060 RecentFiles
.Delete(idx
);
6061 RecentFiles
.Insert(0, OpenedMap
);
6066 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6067 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6068 UpdateCaption(win2utf(gMapInfo
.Name
), ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6071 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6075 RemoveSelectFromObjects();
6077 case pcObjects
.ActivePageIndex
+1 of
6079 if gPanels
<> nil then
6080 for a
:= 0 to High(gPanels
) do
6081 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6082 SelectObject(OBJECT_PANEL
, a
, True);
6084 if gItems
<> nil then
6085 for a
:= 0 to High(gItems
) do
6086 if gItems
[a
].ItemType
<> ITEM_NONE
then
6087 SelectObject(OBJECT_ITEM
, a
, True);
6089 if gMonsters
<> nil then
6090 for a
:= 0 to High(gMonsters
) do
6091 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6092 SelectObject(OBJECT_MONSTER
, a
, True);
6094 if gAreas
<> nil then
6095 for a
:= 0 to High(gAreas
) do
6096 if gAreas
[a
].AreaType
<> AREA_NONE
then
6097 SelectObject(OBJECT_AREA
, a
, True);
6099 if gTriggers
<> nil then
6100 for a
:= 0 to High(gTriggers
) do
6101 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6102 SelectObject(OBJECT_TRIGGER
, a
, True);
6106 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6108 DotEnable
:= not DotEnable
;
6109 (Sender
as TToolButton
).Down
:= DotEnable
;
6112 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6114 // FIXME: this is a shitty hack
6115 if not gDataLoaded
then
6117 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6119 e_WriteLog('Loading data', MSG_NOTIFY
);
6120 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6121 e_WriteLog('Loading more data', MSG_NOTIFY
);
6123 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6124 gDataLoaded
:= True;
6125 MainForm
.FormResize(nil);
6130 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6132 if not PreviewMode
then
6134 Splitter2
.Visible
:= False;
6135 Splitter1
.Visible
:= False;
6136 StatusBar
.Visible
:= False;
6137 PanelObjs
.Visible
:= False;
6138 PanelProps
.Visible
:= False;
6139 MainToolBar
.Visible
:= False;
6140 sbHorizontal
.Visible
:= False;
6141 sbVertical
.Visible
:= False;
6145 StatusBar
.Visible
:= True;
6146 PanelObjs
.Visible
:= True;
6147 PanelProps
.Visible
:= True;
6148 Splitter2
.Visible
:= True;
6149 Splitter1
.Visible
:= True;
6150 MainToolBar
.Visible
:= True;
6151 sbHorizontal
.Visible
:= True;
6152 sbVertical
.Visible
:= True;
6155 PreviewMode
:= not PreviewMode
;
6156 (Sender
as TMenuItem
).Checked
:= PreviewMode
;
6161 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6163 SwitchLayer(LAYER_BACK
);
6166 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6168 SwitchLayer(LAYER_WALLS
);
6171 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6173 SwitchLayer(LAYER_FOREGROUND
);
6176 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6178 SwitchLayer(LAYER_STEPS
);
6181 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6183 SwitchLayer(LAYER_WATER
);
6186 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6188 SwitchLayer(LAYER_ITEMS
);
6191 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6193 SwitchLayer(LAYER_MONSTERS
);
6196 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6198 SwitchLayer(LAYER_AREAS
);
6201 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6203 SwitchLayer(LAYER_TRIGGERS
);
6206 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6212 for a
:= 0 to High(LayerEnabled
) do
6213 b
:= b
and LayerEnabled
[a
];
6217 ShowLayer(LAYER_BACK
, b
);
6218 ShowLayer(LAYER_WALLS
, b
);
6219 ShowLayer(LAYER_FOREGROUND
, b
);
6220 ShowLayer(LAYER_STEPS
, b
);
6221 ShowLayer(LAYER_WATER
, b
);
6222 ShowLayer(LAYER_ITEMS
, b
);
6223 ShowLayer(LAYER_MONSTERS
, b
);
6224 ShowLayer(LAYER_AREAS
, b
);
6225 ShowLayer(LAYER_TRIGGERS
, b
);
6228 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6233 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6235 if DotStep
= DotStepOne
then
6236 DotStep
:= DotStepTwo
6238 DotStep
:= DotStepOne
;
6240 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6241 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6244 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6249 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6251 SnapToGrid
:= not SnapToGrid
;
6253 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6254 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6256 miSnapToGrid
.Checked
:= SnapToGrid
;
6259 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6261 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6262 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6264 pcObjects
.ActivePageIndex
:= 0;
6267 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6269 SaveMiniMapForm
.ShowModal();
6272 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6274 lbTextureList
.ItemIndex
:= -1;
6275 lTextureWidth
.Caption
:= '';
6276 lTextureHeight
.Caption
:= '';
6279 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6281 PackMapForm
.ShowModal();
6284 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6286 MapTestForm
.ShowModal();
6289 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6291 cmd
, mapWAD
, mapToRun
, tempWAD
: String;
6298 if OpenedMap
<> '' then
6300 // Указываем текущую карту для теста:
6301 g_ProcessResourceStr(OpenedMap
, @mapWAD
, nil, @mapToRun
);
6302 mapToRun
:= mapWAD
+ ':\' + mapToRun
;
6303 mapToRun
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', mapToRun
);
6305 // Сохраняем временную карту:
6308 mapWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps/temp%.4d.wad', [time
]);
6310 until not FileExists(mapWAD
);
6311 tempWAD
:= mapWAD
+ ':\' + TEST_MAP_NAME
;
6314 tempWAD
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', tempWAD
);
6315 // Если карта не была открыта, указываем временную в качестве текущей:
6316 if mapToRun
= '' then
6317 mapToRun
:= tempWAD
;
6321 if TestOptionsTwoPlayers
then
6323 if TestOptionsTeamDamage
then
6325 if TestOptionsAllowExit
then
6327 if TestOptionsWeaponStay
then
6329 if TestOptionsMonstersDM
then
6332 // Составляем командную строку:
6333 cmd
:= '-map "' + mapToRun
+ '"';
6334 cmd
:= cmd
+ ' -testmap "' + tempWAD
+ '"';
6335 cmd
:= cmd
+ ' -gm ' + TestGameMode
;
6336 cmd
:= cmd
+ ' -limt ' + TestLimTime
;
6337 cmd
:= cmd
+ ' -lims ' + TestLimScore
;
6338 cmd
:= cmd
+ ' -opt ' + IntToStr(opt
);
6341 cmd
:= cmd
+ ' --close';
6343 cmd
:= cmd
+ ' --debug';
6346 proc
:= TProcessUTF8
.Create(nil);
6347 proc
.Executable
:= TestD2dExe
;
6348 proc
.Parameters
.Add(cmd
);
6357 Application
.Minimize();
6360 if (not res
) or (proc
.ExitCode
< 0) then
6362 MessageBox(0, 'FIXME',
6363 PChar(_lc
[I_MSG_EXEC_ERROR
]),
6364 MB_OK
or MB_ICONERROR
);
6368 SysUtils
.DeleteFile(mapWAD
);
6369 Application
.Restore();
6372 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6373 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6375 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
6378 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6379 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6381 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
6384 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6386 if OpenedWAD
<> '' then
6388 OpenMap(OpenedWAD
, '');
6392 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6396 RemoveSelectFromObjects();
6398 if gPanels
<> nil then
6399 for a
:= 0 to High(gPanels
) do
6400 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6401 SelectObject(OBJECT_PANEL
, a
, True);
6403 if gItems
<> nil then
6404 for a
:= 0 to High(gItems
) do
6405 if gItems
[a
].ItemType
<> ITEM_NONE
then
6406 SelectObject(OBJECT_ITEM
, a
, True);
6408 if gMonsters
<> nil then
6409 for a
:= 0 to High(gMonsters
) do
6410 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6411 SelectObject(OBJECT_MONSTER
, a
, True);
6413 if gAreas
<> nil then
6414 for a
:= 0 to High(gAreas
) do
6415 if gAreas
[a
].AreaType
<> AREA_NONE
then
6416 SelectObject(OBJECT_AREA
, a
, True);
6418 if gTriggers
<> nil then
6419 for a
:= 0 to High(gTriggers
) do
6420 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6421 SelectObject(OBJECT_TRIGGER
, a
, True);
6424 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6425 var NewSize
: Integer; var Accept
: Boolean);
6427 Accept
:= (NewSize
> 140);
6430 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6431 var NewSize
: Integer; var Accept
: Boolean);
6433 Accept
:= (NewSize
> 110);
6436 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6438 EditingProperties
:= True;
6441 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6443 EditingProperties
:= False;
6446 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word;
6447 Shift
: TShiftState
);
6449 // Объекты передвигались:
6450 if MainForm
.ActiveControl
= RenderPanel
then
6452 if (Key
= VK_NUMPAD4
) or
6453 (Key
= VK_NUMPAD6
) or
6454 (Key
= VK_NUMPAD8
) or
6455 (Key
= VK_NUMPAD5
) or
6456 (Key
= Ord('V')) then