8 LCLIntf
, LCLType
, LMessages
, SysUtils
, Variants
, Classes
, Graphics
,
9 Controls
, Forms
, Dialogs
, ImgList
, StdCtrls
, Buttons
,
10 ComCtrls
, ValEdit
, Types
, ToolWin
, Menus
, ExtCtrls
,
14 TMainForm
= class(TForm
)
18 miMenuFile
: TMenuItem
;
22 miSaveMapAs
: TMenuItem
;
23 miOpenWadMap
: TMenuItem
;
25 miSaveMiniMap
: TMenuItem
;
26 miDeleteMap
: TMenuItem
;
31 miMenuEdit
: TMenuItem
;
38 miSelectAll
: TMenuItem
;
43 miMenuTools
: TMenuItem
;
44 miSnapToGrid
: TMenuItem
;
46 miSwitchGrid
: TMenuItem
;
47 miShowEdges
: TMenuItem
;
59 miMenuService
: TMenuItem
;
60 miCheckMap
: TMenuItem
;
61 miOptimmization
: TMenuItem
;
62 miMapPreview
: TMenuItem
;
65 miMenuSettings
: TMenuItem
;
66 miMapOptions
: TMenuItem
;
70 miMapTestSettings
: TMenuItem
;
72 miMenuHelp
: TMenuItem
;
74 // Скрытый пункт меню для Ctrl+Tab:
78 // Панель инструментов:
79 MainToolBar
: TToolBar
;
80 tbNewMap
: TToolButton
;
81 tbOpenMap
: TToolButton
;
82 tbSaveMap
: TToolButton
;
83 tbOpenWadMap
: TToolButton
;
85 tbShowMap
: TToolButton
;
89 tbGridOn
: TToolButton
;
92 tbTestMap
: TToolButton
;
93 // Всплывающее меню для кнопки слоев:
100 miLayerP6
: TMenuItem
;
101 miLayerP7
: TMenuItem
;
102 miLayerP8
: TMenuItem
;
103 miLayerP9
: TMenuItem
;
104 // Всплывающее меню для кнопки теста карты:
105 pmMapTest
: TPopupMenu
;
106 miMapTestPMSet
: TMenuItem
;
110 // Панель отображения карты:
113 pLoadProgress
: TPanel
;
115 pbLoad
: TProgressBar
;
117 sbHorizontal
: TScrollBar
;
118 sbVertical
: TScrollBar
;
122 // Панель применения свойств:
123 PanelPropApply
: TPanel
;
124 bApplyProperty
: TButton
;
125 // Редактор свойств объектов:
126 vleObjectProperty
: TValueListEditor
;
128 // Панель объектов - вкладки:
130 pcObjects
: TPageControl
;
133 lbTextureList
: TListBox
;
134 // Панель настройки текстур:
135 PanelTextures
: TPanel
;
137 lTextureWidth
: TLabel
;
139 lTextureHeight
: TLabel
;
140 cbPreview
: TCheckBox
;
141 bbAddTexture
: TBitBtn
;
142 bbRemoveTexture
: TBitBtn
;
143 bClearTexture
: TButton
;
144 // Панель типов панелей:
145 PanelPanelType
: TPanel
;
146 lbPanelType
: TListBox
;
147 // Вкладка "Предметы":
149 lbItemList
: TListBox
;
152 // Вкладка "Монстры":
153 tsMonsters
: TTabSheet
;
154 lbMonsterList
: TListBox
;
155 rbMonsterLeft
: TRadioButton
;
156 rbMonsterRight
: TRadioButton
;
157 // Вкладка "Области":
159 lbAreasList
: TListBox
;
160 rbAreaLeft
: TRadioButton
;
161 rbAreaRight
: TRadioButton
;
162 // Вкладка "Триггеры":
163 tsTriggers
: TTabSheet
;
164 lbTriggersList
: TListBox
;
165 clbActivationType
: TCheckListBox
;
166 clbKeys
: TCheckListBox
;
169 Splitter1
: TSplitter
;
170 Splitter2
: TSplitter
;
171 StatusBar
: TStatusBar
;
173 // Специальные объекты:
174 ImageList
: TImageList
;
175 ilToolbar
: TImageList
;
176 OpenDialog
: TOpenDialog
;
177 SaveDialog
: TSaveDialog
;
178 selectall1
: TMenuItem
;
179 ColorDialog
: TColorDialog
;
181 procedure aAboutExecute(Sender
: TObject
);
182 procedure aCheckMapExecute(Sender
: TObject
);
183 procedure aMoveToFore(Sender
: TObject
);
184 procedure aMoveToBack(Sender
: TObject
);
185 procedure aCopyObjectExecute(Sender
: TObject
);
186 procedure aCutObjectExecute(Sender
: TObject
);
187 procedure aEditorOptionsExecute(Sender
: TObject
);
188 procedure aExitExecute(Sender
: TObject
);
189 procedure aMapOptionsExecute(Sender
: TObject
);
190 procedure aNewMapExecute(Sender
: TObject
);
191 procedure aOpenMapExecute(Sender
: TObject
);
192 procedure aOptimizeExecute(Sender
: TObject
);
193 procedure aPasteObjectExecute(Sender
: TObject
);
194 procedure aSelectAllExecute(Sender
: TObject
);
195 procedure aSaveMapExecute(Sender
: TObject
);
196 procedure aSaveMapAsExecute(Sender
: TObject
);
197 procedure aUndoExecute(Sender
: TObject
);
198 procedure aDeleteMap(Sender
: TObject
);
199 procedure bApplyPropertyClick(Sender
: TObject
);
200 procedure bbAddTextureClick(Sender
: TObject
);
201 procedure bbRemoveTextureClick(Sender
: TObject
);
202 procedure FormActivate(Sender
: TObject
);
203 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
204 procedure FormCreate(Sender
: TObject
);
205 procedure FormDestroy(Sender
: TObject
);
206 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
207 procedure FormResize(Sender
: TObject
);
208 procedure lbTextureListClick(Sender
: TObject
);
209 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
210 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
211 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
212 procedure RenderPanelResize(Sender
: TObject
);
213 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
214 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
215 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
217 procedure tbGridOnClick(Sender
: TObject
);
218 procedure miMapPreviewClick(Sender
: TObject
);
219 procedure miLayer1Click(Sender
: TObject
);
220 procedure miLayer2Click(Sender
: TObject
);
221 procedure miLayer3Click(Sender
: TObject
);
222 procedure miLayer4Click(Sender
: TObject
);
223 procedure miLayer5Click(Sender
: TObject
);
224 procedure miLayer6Click(Sender
: TObject
);
225 procedure miLayer7Click(Sender
: TObject
);
226 procedure miLayer8Click(Sender
: TObject
);
227 procedure miLayer9Click(Sender
: TObject
);
228 procedure tbShowClick(Sender
: TObject
);
229 procedure miSnapToGridClick(Sender
: TObject
);
230 procedure miMiniMapClick(Sender
: TObject
);
231 procedure miSwitchGridClick(Sender
: TObject
);
232 procedure miShowEdgesClick(Sender
: TObject
);
233 procedure minexttabClick(Sender
: TObject
);
234 procedure miSaveMiniMapClick(Sender
: TObject
);
235 procedure bClearTextureClick(Sender
: TObject
);
236 procedure miPackMapClick(Sender
: TObject
);
237 procedure aRecentFileExecute(Sender
: TObject
);
238 procedure miMapTestSettingsClick(Sender
: TObject
);
239 procedure miTestMapClick(Sender
: TObject
);
240 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
241 var ScrollPos
: Integer);
242 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
243 var ScrollPos
: Integer);
244 procedure miOpenWadMapClick(Sender
: TObject
);
245 procedure selectall1Click(Sender
: TObject
);
246 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
247 var Accept
: Boolean);
248 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
249 var Accept
: Boolean);
250 procedure vleObjectPropertyEnter(Sender
: TObject
);
251 procedure vleObjectPropertyExit(Sender
: TObject
);
252 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
256 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
258 procedure RefreshRecentMenu();
259 { procedure lbTextureListDrawItem(Control: TWinControl; Index: Integer;
260 Rect: TRect; State: TOwnerDrawState); }
266 LAYER_FOREGROUND
= 2;
274 TEST_MAP_NAME
= '$$$_TEST_$$$';
275 LANGUAGE_FILE_NAME
= '_Editor.txt';
286 DotStepOne
, DotStepTwo
: Byte;
288 DrawTexturePanel
: Boolean;
289 DrawPanelSize
: Boolean;
291 PreviewColor
: TColor
;
293 RecentCount
: Integer;
294 RecentFiles
: TStringList
;
295 slInvalidTextures
: TStringList
;
297 TestGameMode
: String;
299 TestLimScore
: String;
300 TestOptionsTwoPlayers
: Boolean;
301 TestOptionsTeamDamage
: Boolean;
302 TestOptionsAllowExit
: Boolean;
303 TestOptionsWeaponStay
: Boolean;
304 TestOptionsMonstersDM
: Boolean;
306 TestMapOnce
: Boolean;
308 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
309 (True, True, True, True, True, True, True, True, True);
310 PreviewMode
: Boolean = False;
316 procedure OpenMap(FileName
: String; mapN
: String);
317 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
318 procedure RemoveSelectFromObjects();
319 procedure ChangeShownProperty(Name
: String; NewValue
: String);
324 f_options
, e_graphics
, e_log
, dglOpenGL
, Math
,
325 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
326 f_mapcheck
, f_addresource_texture
, g_textures
,
327 f_activationtype
, f_keys
, MAPWRITER
, MAPSTRUCT
,
328 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, MAPDEF
,
329 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
330 f_addresource_sound
, f_maptest
, f_choosetype
,
331 g_language
, f_selectlang
, ClipBrd
, Windows
;
334 UNDO_DELETE_PANEL
= 1;
335 UNDO_DELETE_ITEM
= 2;
336 UNDO_DELETE_AREA
= 3;
337 UNDO_DELETE_MONSTER
= 4;
338 UNDO_DELETE_TRIGGER
= 5;
342 UNDO_ADD_MONSTER
= 9;
343 UNDO_ADD_TRIGGER
= 10;
344 UNDO_MOVE_PANEL
= 11;
347 UNDO_MOVE_MONSTER
= 14;
348 UNDO_MOVE_TRIGGER
= 15;
349 UNDO_RESIZE_PANEL
= 16;
350 UNDO_RESIZE_TRIGGER
= 17;
352 MOUSEACTION_NONE
= 0;
353 MOUSEACTION_DRAWPANEL
= 1;
354 MOUSEACTION_DRAWTRIGGER
= 2;
355 MOUSEACTION_MOVEOBJ
= 3;
356 MOUSEACTION_RESIZE
= 4;
357 MOUSEACTION_MOVEMAP
= 5;
358 MOUSEACTION_DRAWPRESS
= 6;
359 MOUSEACTION_NOACTION
= 7;
362 RESIZETYPE_VERTICAL
= 1;
363 RESIZETYPE_HORIZONTAL
= 2;
372 SELECTFLAG_TELEPORT
= 1;
374 SELECTFLAG_TEXTURE
= 3;
376 SELECTFLAG_MONSTER
= 5;
377 SELECTFLAG_SPAWNPOINT
= 6;
378 SELECTFLAG_SHOTPANEL
= 7;
379 SELECTFLAG_SELECTED
= 8;
381 RECENT_FILES_MENU_START
= 11;
383 CLIPBOARD_SIG
= 'DF:ED';
389 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
390 UNDO_DELETE_ITEM
: (Item
: TItem
);
391 UNDO_DELETE_AREA
: (Area
: TArea
);
392 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
393 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
398 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
403 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
405 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
412 OBJECT_PANEL
: (Panel
: ^TPanel
);
413 OBJECT_ITEM
: (Item
: TItem
);
414 OBJECT_AREA
: (Area
: TArea
);
415 OBJECT_MONSTER
: (Monster
: TMonster
);
416 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
419 TCopyRecArray
= Array of TCopyRec
;
425 ShowMap
: Boolean = False;
426 DrawRect
: PRect
= nil;
427 SnapToGrid
: Boolean = True;
429 MousePos
: Types
.TPoint
;
430 LastMovePoint
: Types
.TPoint
;
433 MouseLDownPos
: Types
.TPoint
;
434 MouseRDownPos
: Types
.TPoint
;
436 SelectFlag
: Byte = SELECTFLAG_NONE
;
437 MouseAction
: Byte = MOUSEACTION_NONE
;
438 ResizeType
: Byte = RESIZETYPE_NONE
;
439 ResizeDirection
: Byte = RESIZEDIR_NONE
;
441 DrawPressRect
: Boolean = False;
442 EditingProperties
: Boolean = False;
444 UndoBuffer
: Array of Array of TUndoRec
= nil;
449 //----------------------------------------
450 //Далее идут вспомогательные процедуры
451 //----------------------------------------
453 function NameToBool(Name
: String): Boolean;
455 if Name
= BoolNames
[True] then
461 function NameToDir(Name
: String): TDirection
;
463 if Name
= DirNames
[D_LEFT
] then
469 function NameToDirAdv(Name
: String): Byte;
471 if Name
= DirNamesAdv
[1] then
474 if Name
= DirNamesAdv
[2] then
477 if Name
= DirNamesAdv
[3] then
483 function ActivateToStr(ActivateType
: Byte): String;
487 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
488 Result
:= Result
+ '+PC';
489 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
490 Result
:= Result
+ '+MC';
491 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
492 Result
:= Result
+ '+PP';
493 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
494 Result
:= Result
+ '+MP';
495 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
496 Result
:= Result
+ '+SH';
497 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
498 Result
:= Result
+ '+NM';
500 if (Result
<> '') and (Result
[1] = '+') then
501 Delete(Result
, 1, 1);
504 function StrToActivate(Str
: String): Byte;
508 if Pos('PC', Str
) > 0 then
509 Result
:= ACTIVATE_PLAYERCOLLIDE
;
510 if Pos('MC', Str
) > 0 then
511 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
512 if Pos('PP', Str
) > 0 then
513 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
514 if Pos('MP', Str
) > 0 then
515 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
516 if Pos('SH', Str
) > 0 then
517 Result
:= Result
or ACTIVATE_SHOT
;
518 if Pos('NM', Str
) > 0 then
519 Result
:= Result
or ACTIVATE_NOMONSTER
;
522 function KeyToStr(Key
: Byte): String;
526 if ByteBool(KEY_RED
and Key
) then
527 Result
:= Result
+ '+RK';
528 if ByteBool(KEY_GREEN
and Key
) then
529 Result
:= Result
+ '+GK';
530 if ByteBool(KEY_BLUE
and Key
) then
531 Result
:= Result
+ '+BK';
532 if ByteBool(KEY_REDTEAM
and Key
) then
533 Result
:= Result
+ '+RT';
534 if ByteBool(KEY_BLUETEAM
and Key
) then
535 Result
:= Result
+ '+BT';
537 if (Result
<> '') and (Result
[1] = '+') then
538 Delete(Result
, 1, 1);
541 function StrToKey(Str
: String): Byte;
545 if Pos('RK', Str
) > 0 then
547 if Pos('GK', Str
) > 0 then
548 Result
:= Result
or KEY_GREEN
;
549 if Pos('BK', Str
) > 0 then
550 Result
:= Result
or KEY_BLUE
;
551 if Pos('RT', Str
) > 0 then
552 Result
:= Result
or KEY_REDTEAM
;
553 if Pos('BT', Str
) > 0 then
554 Result
:= Result
or KEY_BLUETEAM
;
557 function EffectToStr(Effect
: Byte): String;
559 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
560 Result
:= EffectNames
[Effect
]
562 Result
:= EffectNames
[EFFECT_NONE
];
565 function StrToEffect(Str
: String): Byte;
569 Result
:= EFFECT_NONE
;
570 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
571 if EffectNames
[i
] = Str
then
578 function MonsterToStr(MonType
: Byte): String;
580 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
581 Result
:= MonsterNames
[MonType
]
583 Result
:= MonsterNames
[MONSTER_ZOMBY
];
586 function StrToMonster(Str
: String): Byte;
590 Result
:= MONSTER_ZOMBY
;
591 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
592 if MonsterNames
[i
] = Str
then
599 function ItemToStr(ItemType
: Byte): String;
601 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
602 Result
:= ItemNames
[ItemType
]
604 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
607 function StrToItem(Str
: String): Byte;
611 Result
:= ITEM_AMMO_BULLETS
;
612 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
613 if ItemNames
[i
] = Str
then
620 function ShotToStr(ShotType
: Byte): String;
622 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
623 Result
:= ShotNames
[ShotType
]
625 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
628 function StrToShot(Str
: String): Byte;
632 Result
:= TRIGGER_SHOT_PISTOL
;
633 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
634 if ShotNames
[i
] = Str
then
641 function SelectedObjectCount(): Word;
647 if SelectedObjects
= nil then
650 for a
:= 0 to High(SelectedObjects
) do
651 if SelectedObjects
[a
].Live
then
652 Result
:= Result
+ 1;
655 function GetFirstSelected(): Integer;
661 if SelectedObjects
= nil then
664 for a
:= 0 to High(SelectedObjects
) do
665 if SelectedObjects
[a
].Live
then
672 function Normalize16(x
: Integer): Integer;
674 Result
:= (x
div 16) * 16;
677 procedure MoveMap(X
, Y
: Integer);
679 rx
, ry
, ScaleSz
: Integer;
681 with MainForm
.RenderPanel
do
683 ScaleSz
:= 16 div Scale
;
684 // Размер видимой части карты:
685 rx
:= min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
686 ry
:= min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
687 // Место клика на мини-карте:
688 MapOffset
.X
:= X
- (Width
-max(gMapInfo
.Width
div ScaleSz
, 1)-1);
689 MapOffset
.Y
:= Y
- 1;
690 // Это же место на "большой" карте:
691 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
692 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
693 // Левый верхний угол новой видимой части карты:
694 MapOffset
.X
:= MapOffset
.X
- rx
;
695 MapOffset
.Y
:= MapOffset
.Y
- ry
;
697 if MapOffset
.X
< 0 then
699 if MapOffset
.Y
< 0 then
701 if MapOffset
.X
> MainForm
.sbHorizontal
.Max
then
702 MapOffset
.X
:= MainForm
.sbHorizontal
.Max
;
703 if MapOffset
.Y
> MainForm
.sbVertical
.Max
then
704 MapOffset
.Y
:= MainForm
.sbVertical
.Max
;
706 MapOffset
.X
:= Normalize16(MapOffset
.X
);
707 MapOffset
.Y
:= Normalize16(MapOffset
.Y
);
710 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
711 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
713 MapOffset
.X
:= -MapOffset
.X
;
714 MapOffset
.Y
:= -MapOffset
.Y
;
719 function IsTexturedPanel(PanelType
: Word): Boolean;
721 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
722 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
723 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
726 procedure FillProperty();
731 MainForm
.vleObjectProperty
.Strings
.Clear();
733 // Отображаем свойства если выделен только один объект:
734 if SelectedObjectCount() <> 1 then
737 _id
:= GetFirstSelected();
738 if not SelectedObjects
[_id
].Live
then
741 with MainForm
.vleObjectProperty
do
742 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
744 EditStyle
:= esSimple
;
748 case SelectedObjects
[0].ObjectType
of
751 with MainForm
.vleObjectProperty
,
752 gPanels
[SelectedObjects
[_id
].ID
] do
754 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
756 EditStyle
:= esSimple
;
760 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
762 EditStyle
:= esSimple
;
766 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
768 EditStyle
:= esSimple
;
772 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
774 EditStyle
:= esSimple
;
778 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
780 EditStyle
:= esEllipsis
;
784 if IsTexturedPanel(PanelType
) then
785 begin // Может быть текстура
786 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
788 EditStyle
:= esEllipsis
;
792 if TextureName
<> '' then
793 begin // Есть текстура
794 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
796 EditStyle
:= esSimple
;
800 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
802 EditStyle
:= esPickList
;
812 with MainForm
.vleObjectProperty
,
813 gItems
[SelectedObjects
[_id
].ID
] do
815 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
817 EditStyle
:= esSimple
;
821 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
823 EditStyle
:= esSimple
;
827 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
829 EditStyle
:= esPickList
;
833 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
835 EditStyle
:= esPickList
;
843 with MainForm
.vleObjectProperty
,
844 gMonsters
[SelectedObjects
[_id
].ID
] do
846 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
848 EditStyle
:= esSimple
;
852 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
854 EditStyle
:= esSimple
;
858 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
860 EditStyle
:= esPickList
;
868 with MainForm
.vleObjectProperty
,
869 gAreas
[SelectedObjects
[_id
].ID
] do
871 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
873 EditStyle
:= esSimple
;
877 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
879 EditStyle
:= esSimple
;
883 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
885 EditStyle
:= esPickList
;
893 with MainForm
.vleObjectProperty
,
894 gTriggers
[SelectedObjects
[_id
].ID
] do
896 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
898 EditStyle
:= esSimple
;
902 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
904 EditStyle
:= esSimple
;
908 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
910 EditStyle
:= esSimple
;
914 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
916 EditStyle
:= esSimple
;
920 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
922 EditStyle
:= esSimple
;
926 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
928 EditStyle
:= esPickList
;
932 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
934 EditStyle
:= esEllipsis
;
938 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
940 EditStyle
:= esEllipsis
;
944 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
946 EditStyle
:= esEllipsis
;
953 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], Data
.MapName
, True)] do
955 EditStyle
:= esEllipsis
;
962 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
964 EditStyle
:= esEllipsis
;
968 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
970 EditStyle
:= esPickList
;
974 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
976 EditStyle
:= esPickList
;
980 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
982 EditStyle
:= esPickList
;
987 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
988 TRIGGER_DOOR
, TRIGGER_DOOR5
:
990 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
992 EditStyle
:= esEllipsis
;
996 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
998 EditStyle
:= esPickList
;
1002 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1004 EditStyle
:= esPickList
;
1009 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1011 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1013 EditStyle
:= esEllipsis
;
1017 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1019 EditStyle
:= esPickList
;
1023 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1025 EditStyle
:= esPickList
;
1030 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1033 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1034 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1036 EditStyle
:= esEllipsis
;
1040 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1042 EditStyle
:= esSimple
;
1046 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1048 EditStyle
:= esSimple
;
1052 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1054 EditStyle
:= esEllipsis
;
1058 if TriggerType
= TRIGGER_PRESS
then
1059 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1061 EditStyle
:= esPickList
;
1069 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1071 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1073 EditStyle
:= esEllipsis
;
1077 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1079 EditStyle
:= esPickList
;
1083 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1085 EditStyle
:= esPickList
;
1092 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1094 EditStyle
:= esPickList
;
1098 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1100 EditStyle
:= esPickList
;
1107 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], Data
.SoundName
, True)] do
1109 EditStyle
:= esEllipsis
;
1113 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1115 EditStyle
:= esSimple
;
1119 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1121 EditStyle
:= esSimple
;
1125 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1127 EditStyle
:= esSimple
;
1131 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1133 EditStyle
:= esPickList
;
1137 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1139 EditStyle
:= esPickList
;
1144 TRIGGER_SPAWNMONSTER
:
1146 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1148 EditStyle
:= esEllipsis
;
1152 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1153 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1155 EditStyle
:= esEllipsis
;
1159 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1161 EditStyle
:= esPickList
;
1165 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1167 EditStyle
:= esSimple
;
1171 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1173 EditStyle
:= esPickList
;
1177 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1179 EditStyle
:= esSimple
;
1183 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1185 EditStyle
:= esEllipsis
;
1189 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1191 EditStyle
:= esSimple
;
1195 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1197 EditStyle
:= esSimple
;
1201 case Data
.MonBehav
of
1202 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1203 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1204 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1205 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1206 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1207 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1209 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1211 EditStyle
:= esPickList
;
1218 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1220 EditStyle
:= esEllipsis
;
1224 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1225 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1227 EditStyle
:= esEllipsis
;
1231 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1233 EditStyle
:= esPickList
;
1237 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1239 EditStyle
:= esPickList
;
1243 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1245 EditStyle
:= esSimple
;
1249 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1251 EditStyle
:= esEllipsis
;
1255 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1257 EditStyle
:= esSimple
;
1261 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1263 EditStyle
:= esSimple
;
1270 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], Data
.MusicName
, True)] do
1272 EditStyle
:= esEllipsis
;
1276 if Data
.MusicAction
= 1 then
1277 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1279 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1281 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1283 EditStyle
:= esPickList
;
1290 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1292 EditStyle
:= esSimple
;
1295 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1297 EditStyle
:= esSimple
;
1300 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1302 EditStyle
:= esPickList
;
1309 case Data
.ScoreAction
of
1310 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1311 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1312 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1313 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1315 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1317 EditStyle
:= esPickList
;
1320 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1322 EditStyle
:= esSimple
;
1325 case Data
.ScoreTeam
of
1326 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1327 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1328 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1329 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1331 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1333 EditStyle
:= esPickList
;
1336 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1338 EditStyle
:= esPickList
;
1341 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1343 EditStyle
:= esPickList
;
1350 case Data
.MessageKind
of
1351 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1352 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1354 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1356 EditStyle
:= esPickList
;
1359 case Data
.MessageSendTo
of
1360 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1361 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1362 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1363 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1364 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1365 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1367 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1369 EditStyle
:= esPickList
;
1372 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], Data
.MessageText
, True)] do
1374 EditStyle
:= esSimple
;
1377 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1379 EditStyle
:= esSimple
;
1386 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1388 EditStyle
:= esSimple
;
1391 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1393 EditStyle
:= esSimple
;
1400 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1402 EditStyle
:= esSimple
;
1405 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1407 EditStyle
:= esSimple
;
1410 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1412 EditStyle
:= esPickList
;
1415 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1417 EditStyle
:= esPickList
;
1424 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1426 EditStyle
:= esEllipsis
;
1430 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1432 EditStyle
:= esPickList
;
1436 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1438 EditStyle
:= esEllipsis
;
1442 case Data
.ShotTarget
of
1443 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1444 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1445 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1446 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1447 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1448 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1449 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1451 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1453 EditStyle
:= esPickList
;
1457 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1459 EditStyle
:= esSimple
;
1463 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ALLMAP
], BoolNames
[Data
.ShotAllMap
], True)] do
1465 EditStyle
:= esPickList
;
1469 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1470 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1472 EditStyle
:= esEllipsis
;
1476 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1478 EditStyle
:= esSimple
;
1482 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1484 EditStyle
:= esSimple
;
1488 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1490 EditStyle
:= esSimple
;
1494 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1496 EditStyle
:= esSimple
;
1500 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1502 EditStyle
:= esSimple
;
1509 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1511 EditStyle
:= esSimple
;
1515 if Data
.FXType
= 0 then
1516 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1518 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1519 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1521 EditStyle
:= esEllipsis
;
1526 if Data
.FXType
= 0 then
1527 case Data
.FXSubType
of
1528 TRIGGER_EFFECT_SLIQUID
:
1529 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1530 TRIGGER_EFFECT_LLIQUID
:
1531 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1532 TRIGGER_EFFECT_DLIQUID
:
1533 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1534 TRIGGER_EFFECT_BLOOD
:
1535 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1536 TRIGGER_EFFECT_SPARK
:
1537 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1538 TRIGGER_EFFECT_BUBBLE
:
1539 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1541 if Data
.FXType
= 1 then
1543 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1544 Data
.FXSubType
:= EFFECT_TELEPORT
;
1545 str
:= EffectToStr(Data
.FXSubType
);
1547 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1549 EditStyle
:= esEllipsis
;
1553 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1555 EditStyle
:= esEllipsis
;
1559 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1561 EditStyle
:= esPickList
;
1565 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1567 EditStyle
:= esSimple
;
1571 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1573 EditStyle
:= esSimple
;
1577 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1579 EditStyle
:= esSimple
;
1583 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1585 EditStyle
:= esSimple
;
1589 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1591 EditStyle
:= esSimple
;
1595 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1597 EditStyle
:= esSimple
;
1601 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1603 EditStyle
:= esSimple
;
1607 end; //case TriggerType
1609 end; // OBJECT_TRIGGER:
1613 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1617 if SelectedObjectCount() <> 1 then
1619 if not SelectedObjects
[GetFirstSelected()].Live
then
1622 // Есть ли такой ключ:
1623 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1625 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1629 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1638 // Уже выделен - убираем:
1639 if SelectedObjects
<> nil then
1640 for a
:= 0 to High(SelectedObjects
) do
1641 with SelectedObjects
[a
] do
1642 if Live
and (ID
= fID
) and
1643 (ObjectType
= fObjectType
) then
1652 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1654 with SelectedObjects
[High(SelectedObjects
)] do
1656 ObjectType
:= fObjectType
;
1663 SetLength(SelectedObjects
, 1);
1665 with SelectedObjects
[0] do
1667 ObjectType
:= fObjectType
;
1673 MainForm
.miCopy
.Enabled
:= True;
1674 MainForm
.miCut
.Enabled
:= True;
1676 if fObjectType
= OBJECT_PANEL
then
1678 MainForm
.miToFore
.Enabled
:= True;
1679 MainForm
.miToBack
.Enabled
:= True;
1683 procedure RemoveSelectFromObjects();
1685 SelectedObjects
:= nil;
1686 DrawPressRect
:= False;
1687 MouseLDown
:= False;
1688 MouseRDown
:= False;
1689 MouseAction
:= MOUSEACTION_NONE
;
1690 SelectFlag
:= SELECTFLAG_NONE
;
1691 ResizeType
:= RESIZETYPE_NONE
;
1692 ResizeDirection
:= RESIZEDIR_NONE
;
1694 MainForm
.vleObjectProperty
.Strings
.Clear();
1696 MainForm
.miCopy
.Enabled
:= False;
1697 MainForm
.miCut
.Enabled
:= False;
1698 MainForm
.miToFore
.Enabled
:= False;
1699 MainForm
.miToBack
.Enabled
:= False;
1702 procedure DeleteSelectedObjects();
1707 if SelectedObjects
= nil then
1713 for a
:= 0 to High(SelectedObjects
) do
1714 with SelectedObjects
[a
] do
1719 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1720 i
:= High(UndoBuffer
);
1724 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1725 ii
:= High(UndoBuffer
[i
]);
1730 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1731 New(UndoBuffer
[i
, ii
].Panel
);
1732 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1736 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1737 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1741 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1742 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1746 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1747 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1751 RemoveObject(ID
, ObjectType
);
1754 RemoveSelectFromObjects();
1756 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1759 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1763 if (not Group
) or (Length(UndoBuffer
) = 0) then
1764 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1765 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1766 i
:= High(UndoBuffer
);
1767 ii
:= High(UndoBuffer
[i
]);
1771 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1773 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1775 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1777 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1779 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1782 UndoBuffer
[i
, ii
].AddID
:= ID
;
1784 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1787 procedure FullClear();
1789 RemoveSelectFromObjects();
1792 slInvalidTextures
.Clear();
1793 MapCheckForm
.lbErrorList
.Clear();
1794 MapCheckForm
.mErrorDescription
.Clear();
1796 MainForm
.miUndo
.Enabled
:= False;
1797 MainForm
.sbHorizontal
.Position
:= 0;
1798 MainForm
.sbVertical
.Position
:= 0;
1799 MainForm
.FormResize(nil);
1800 MainForm
.Caption
:= FormCaption
;
1805 procedure ErrorMessageBox(str
: String);
1807 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1808 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1811 function CheckProperty(): Boolean;
1817 _id
:= GetFirstSelected();
1819 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1820 with gPanels
[SelectedObjects
[_id
].ID
] do
1822 if TextureWidth
<> 0 then
1823 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1825 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1830 if TextureHeight
<> 0 then
1831 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1833 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1838 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1839 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1841 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1846 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1847 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1848 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1850 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1854 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1855 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1857 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1864 procedure SelectTexture(ID
: Integer);
1866 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1867 MainForm
.lbTextureListClick(nil);
1870 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1875 ResourceName
: String;
1876 FullResourceName
: String;
1877 SectionName
: String;
1879 Width
, Height
: Word;
1882 if aSection
= '..' then
1885 SectionName
:= aSection
;
1887 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1889 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1890 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1892 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1895 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1896 begin // Спец. текстуры
1898 ResourceName
:= aTex
;
1901 begin // Внешний WAD
1902 FileName
:= EditorDir
+'wads\'+aWAD
;
1903 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1908 // Есть ли уже такая текстура:
1909 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1910 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1913 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1918 // Название ресурса <= 64 символов:
1919 if Length(ResourceName
) > 64 then
1922 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1930 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1932 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1939 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1941 if IsAnim(FullResourceName
) then
1942 begin // Аним. текстура
1943 GetFrame(FullResourceName
, Data
, Width
, Height
);
1945 if g_CreateTextureMemorySize(Data
, ResourceName
, 0, 0, Width
, Height
, 1) then
1946 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1948 else // Обычная текстура
1950 if g_CreateTextureWAD(ResourceName
, FullResourceName
) then
1951 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1953 if (a
> -1) and (not silent
) then
1960 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
1963 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
1964 Caption
:= FormCaption
1967 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
1969 if (sFile
<> '') and (sRes
<> '') then
1970 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
1972 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
1975 procedure OpenMap(FileName
: String; mapN
: String);
1980 SelectMapForm
.GetMaps(FileName
);
1982 if (FileName
= OpenedWAD
) and
1983 (OpenedMap
<> '') then
1985 MapName
:= OpenedMap
;
1986 while (Pos(':\', MapName
) > 0) do
1987 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
1989 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
1990 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
1993 if SelectMapForm
.lbMapList
.Count
> 0 then
1994 SelectMapForm
.lbMapList
.ItemIndex
:= 0
1996 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2001 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2005 if (SelectMapForm
.ShowModal() = mrOK
) and
2006 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2007 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2012 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2018 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2019 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2020 pLoadProgress
.Show();
2022 OpenedMap
:= FileName
+':\'+MapName
;
2023 OpenedWAD
:= FileName
;
2025 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2026 // Такая карта уже недавно открывалась:
2028 RecentFiles
.Delete(idx
);
2029 RecentFiles
.Insert(0, OpenedMap
);
2030 RefreshRecentMenu();
2034 pLoadProgress
.Hide();
2037 lbTextureList
.Sorted
:= True;
2038 lbTextureList
.Sorted
:= False;
2040 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2044 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2049 if SelectedObjects
= nil then
2056 for a
:= 0 to High(SelectedObjects
) do
2057 if SelectedObjects
[a
].Live
then
2059 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2062 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2065 if (not okX
) or (not okY
) then
2071 for a
:= 0 to High(SelectedObjects
) do
2072 if SelectedObjects
[a
].Live
then
2075 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2078 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2080 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2082 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2083 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2084 begin // Двигаем зону Расширителя
2086 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2088 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2091 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2092 begin // Двигаем точку назначения Телепорта
2094 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2096 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2099 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2100 begin // Двигаем точку создания монстра
2102 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2104 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2107 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2108 begin // Двигаем точку создания предмета
2110 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2112 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2115 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2116 begin // Двигаем точку создания выстрела
2118 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2120 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2125 LastMovePoint
:= MousePos
;
2129 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2131 LayerEnabled
[Layer
] := show
;
2136 MainForm
.miLayer1
.Checked
:= show
;
2137 MainForm
.miLayerP1
.Checked
:= show
;
2141 MainForm
.miLayer2
.Checked
:= show
;
2142 MainForm
.miLayerP2
.Checked
:= show
;
2146 MainForm
.miLayer3
.Checked
:= show
;
2147 MainForm
.miLayerP3
.Checked
:= show
;
2151 MainForm
.miLayer4
.Checked
:= show
;
2152 MainForm
.miLayerP4
.Checked
:= show
;
2156 MainForm
.miLayer5
.Checked
:= show
;
2157 MainForm
.miLayerP5
.Checked
:= show
;
2161 MainForm
.miLayer6
.Checked
:= show
;
2162 MainForm
.miLayerP6
.Checked
:= show
;
2166 MainForm
.miLayer7
.Checked
:= show
;
2167 MainForm
.miLayerP7
.Checked
:= show
;
2171 MainForm
.miLayer8
.Checked
:= show
;
2172 MainForm
.miLayerP8
.Checked
:= show
;
2176 MainForm
.miLayer9
.Checked
:= show
;
2177 MainForm
.miLayerP9
.Checked
:= show
;
2181 RemoveSelectFromObjects();
2184 procedure SwitchLayer(Layer
: Byte);
2186 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2189 procedure SwitchMap();
2191 ShowMap
:= not ShowMap
;
2192 MainForm
.tbShowMap
.Down
:= ShowMap
;
2195 procedure ShowEdges();
2197 if drEdge
[3] < 255 then
2200 drEdge
[3] := gAlphaEdge
;
2203 function SelectedTexture(): String;
2205 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2206 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2211 function IsSpecialTextureSel(): Boolean;
2213 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2214 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2217 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2222 procedure AddInt(x
: Integer);
2224 Res
:= Res
+ IntToStr(x
) + ' ';
2230 if Length(CopyBuf
) = 0 then
2233 Res
:= CLIPBOARD_SIG
+ ' ';
2235 for i
:= 0 to High(CopyBuf
) do
2237 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2238 (CopyBuf
[i
].Panel
= nil) then
2242 AddInt(CopyBuf
[i
].ObjectType
);
2245 // Свойства объекта:
2246 case CopyBuf
[i
].ObjectType
of
2248 with CopyBuf
[i
].Panel
^ do
2255 Res
:= Res
+ '"' + TextureName
+ '" ';
2257 AddInt(IfThen(Blending
, 1, 0));
2261 with CopyBuf
[i
].Item
do
2266 AddInt(IfThen(OnlyDM
, 1, 0));
2267 AddInt(IfThen(Fall
, 1, 0));
2271 with CopyBuf
[i
].Monster
do
2273 AddInt(MonsterType
);
2276 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2280 with CopyBuf
[i
].Area
do
2285 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2289 with CopyBuf
[i
].Trigger
do
2291 AddInt(TriggerType
);
2296 AddInt(ActivateType
);
2298 AddInt(IfThen(Enabled
, 1, 0));
2299 AddInt(TexturePanel
);
2301 for j
:= 0 to 127 do
2302 AddInt(Data
.Default
[j
]);
2310 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
);
2314 function GetNext(): String;
2319 if Str
[1] = '"' then
2331 Result
:= Copy(Str
, 1, p
-1);
2347 Result
:= Copy(Str
, 1, p
-1);
2357 if GetNext() <> CLIPBOARD_SIG
then
2363 t
:= StrToIntDef(GetNext(), 0);
2365 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2366 (GetNext() <> ';') then
2367 begin // Что-то не то => пропускаем:
2375 i
:= Length(CopyBuf
);
2376 SetLength(CopyBuf
, i
+ 1);
2378 CopyBuf
[i
].ObjectType
:= t
;
2379 CopyBuf
[i
].Panel
:= nil;
2381 // Свойства объекта:
2385 New(CopyBuf
[i
].Panel
);
2387 with CopyBuf
[i
].Panel
^ do
2389 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2390 X
:= StrToIntDef(GetNext(), 0);
2391 Y
:= StrToIntDef(GetNext(), 0);
2392 Width
:= StrToIntDef(GetNext(), 16);
2393 Height
:= StrToIntDef(GetNext(), 16);
2394 TextureName
:= GetNext();
2395 Alpha
:= StrToIntDef(GetNext(), 0);
2396 Blending
:= (GetNext() = '1');
2401 with CopyBuf
[i
].Item
do
2403 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2404 X
:= StrToIntDef(GetNext(), 0);
2405 Y
:= StrToIntDef(GetNext(), 0);
2406 OnlyDM
:= (GetNext() = '1');
2407 Fall
:= (GetNext() = '1');
2411 with CopyBuf
[i
].Monster
do
2413 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2414 X
:= StrToIntDef(GetNext(), 0);
2415 Y
:= StrToIntDef(GetNext(), 0);
2417 if GetNext() = '1' then
2420 Direction
:= D_RIGHT
;
2424 with CopyBuf
[i
].Area
do
2426 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2427 X
:= StrToIntDef(GetNext(), 0);
2428 Y
:= StrToIntDef(GetNext(), 0);
2429 if GetNext() = '1' then
2432 Direction
:= D_RIGHT
;
2436 with CopyBuf
[i
].Trigger
do
2438 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2439 X
:= StrToIntDef(GetNext(), 0);
2440 Y
:= StrToIntDef(GetNext(), 0);
2441 Width
:= StrToIntDef(GetNext(), 16);
2442 Height
:= StrToIntDef(GetNext(), 16);
2443 ActivateType
:= StrToIntDef(GetNext(), 0);
2444 Key
:= StrToIntDef(GetNext(), 0);
2445 Enabled
:= (GetNext() = '1');
2446 TexturePanel
:= StrToIntDef(GetNext(), 0);
2448 for j
:= 0 to 127 do
2449 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2455 //----------------------------------------
2456 //Закончились вспомогательные процедуры
2457 //----------------------------------------
2459 procedure TMainForm
.RefreshRecentMenu();
2464 // Лишние запомненные карты:
2465 while RecentFiles
.Count
> RecentCount
do
2466 RecentFiles
.Delete(RecentFiles
.Count
-1);
2468 // Лишние строки меню:
2469 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2470 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2472 // Отделение списка карт от строки "Выход":
2473 if RecentFiles
.Count
> 0 then
2475 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2477 MainMenu
.Items
[0].Add(MI
);
2480 // Добавление в меню списка запомненных карт:
2481 for i
:= 0 to RecentFiles
.Count
-1 do
2483 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2484 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2485 MI
.OnClick
:= aRecentFileExecute
;
2486 MainMenu
.Items
[0].Add(MI
);
2490 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2495 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2496 Delete(s
, Pos('&', s
), 1);
2497 s
:= Trim(Copy(s
, 1, 2));
2498 n
:= StrToIntDef(s
, 0) - 1;
2500 if (n
< 0) or (n
>= RecentFiles
.Count
) then
2503 s
:= RecentFiles
[n
];
2504 pw
:= Pos('.wad:\', LowerCase(s
));
2507 begin // Map name included
2508 fn
:= Copy(s
, 1, pw
+ 3);
2509 Delete(s
, 1, pw
+ 5);
2510 if (FileExists(fn
)) then
2513 else // Only wad name
2514 if (FileExists(s
)) then
2518 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2520 OptionsForm
.ShowModal();
2523 procedure TMainForm
.FormCreate(Sender
: TObject
);
2525 PixelFormat
: GLuint
;
2526 pfd
: TPIXELFORMATDESCRIPTOR
;
2533 EditorDir
:= ExtractFilePath(Application
.ExeName
);
2535 e_InitLog(EditorDir
+'Editor.log', WM_NEWFILE
);
2537 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
2540 hDC
:= GetDC(RenderPanel
.Handle
);
2542 FillChar(pfd
, SizeOf(pfd
), 0);
2545 nSize
:= SizeOf(pfd
);
2547 dwFlags
:= PFD_DRAW_TO_WINDOW
or PFD_SUPPORT_OPENGL
or PFD_DOUBLEBUFFER
;
2548 dwLayerMask
:= PFD_MAIN_PLANE
;
2549 iPixelType
:= PFD_TYPE_RGBA
;
2552 iLayerType
:= PFD_MAIN_PLANE
;
2554 PixelFormat
:= ChoosePixelFormat (hDC
, @pfd
);
2555 SetPixelFormat(hDC
, PixelFormat
, @pfd
);
2557 hRC
:= wglCreateContext(hDC
);
2558 ActivateRenderingContext(hDC
, hRC
);
2562 gEditorFont
:= e_SimpleFontCreate('Arial Cyr', 12, FW_BOLD
, hDC
);
2564 slInvalidTextures
:= TStringList
.Create
;
2566 e_WriteLog('Loading data', MSG_NOTIFY
);
2569 ShowLayer(LAYER_BACK
, True);
2570 ShowLayer(LAYER_WALLS
, True);
2571 ShowLayer(LAYER_FOREGROUND
, True);
2572 ShowLayer(LAYER_STEPS
, True);
2573 ShowLayer(LAYER_WATER
, True);
2574 ShowLayer(LAYER_ITEMS
, True);
2575 ShowLayer(LAYER_MONSTERS
, True);
2576 ShowLayer(LAYER_AREAS
, True);
2577 ShowLayer(LAYER_TRIGGERS
, True);
2581 FormCaption
:= MainForm
.Caption
;
2585 config
:= TConfig
.CreateFile(EditorDir
+'\Editor.cfg');
2587 if config
.ReadBool('Editor', 'Maximize', False) then
2588 WindowState
:= wsMaximized
;
2589 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2590 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2591 Splitter1
.Left
:= PanelProps
.Left
;
2592 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2593 Splitter2
.Top
:= PanelObjs
.Top
;
2594 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2595 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2596 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2597 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2598 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2599 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2600 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2601 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2602 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2603 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2604 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2605 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2606 if gAlphaEdge
= 255 then
2607 gAlphaEdge
:= ALPHA_EDGE
;
2608 drEdge
[0] := GetRValue(gColorEdge
);
2609 drEdge
[1] := GetGValue(gColorEdge
);
2610 drEdge
[2] := GetBValue(gColorEdge
);
2611 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2614 drEdge
[3] := gAlphaEdge
;
2615 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2616 if gAlphaTriggerLine
= 255 then
2617 gAlphaTriggerLine
:= ALPHA_LINE
;
2618 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2619 if gAlphaTriggerArea
= 255 then
2620 gAlphaTriggerArea
:= ALPHA_AREA
;
2621 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2625 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2629 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2630 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2632 s
:= config
.ReadStr('Editor', 'Language', '');
2635 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2636 if RecentCount
> 10 then
2638 if RecentCount
< 2 then
2641 RecentFiles
:= TStringList
.Create();
2642 for i
:= 0 to RecentCount
-1 do
2644 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2648 RefreshRecentMenu();
2652 tbShowMap
.Down
:= ShowMap
;
2653 tbGridOn
.Down
:= DotEnable
;
2654 pcObjects
.ActivePageIndex
:= 0;
2655 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2657 Application
.OnIdle
:= OnIdle
;
2660 procedure TMainForm
.Draw();
2666 Width
, Height
: Word;
2669 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2671 BeginPaint(Handle
, ps
);
2674 e_Clear(GL_COLOR_BUFFER_BIT
,
2675 GetRValue(BackColor
)/255,
2676 GetGValue(BackColor
)/255,
2677 GetBValue(BackColor
)/255);
2681 ObjCount
:= SelectedObjectCount();
2683 // Обводим выделенные объекты красной рамкой:
2684 if ObjCount
> 0 then
2686 for a
:= 0 to High(SelectedObjects
) do
2687 if SelectedObjects
[a
].Live
then
2689 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2693 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2694 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2697 // Рисуем точки изменения размеров:
2698 if (ObjCount
= 1) and
2699 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2701 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2702 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2703 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2704 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2706 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2707 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2708 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2709 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2716 if DotEnable
and (not PreviewMode
) then
2723 for x
:= 0 to (RenderPanel
.Width
div DotStep
) do
2724 for y
:= 0 to (RenderPanel
.Height
div DotStep
) do
2725 e_DrawPoint(DotSize
, x
*DotStep
+ a
, y
*DotStep
+ a
,
2726 GetRValue(DotColor
),
2727 GetGValue(DotColor
),
2728 GetBValue(DotColor
));
2732 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2733 (not IsSpecialTextureSel()) and (not PreviewMode
) then
2735 if not g_GetTexture(SelectedTexture(), ID
) then
2736 g_GetTexture('NOTEXTURE', ID
);
2737 g_GetTextureSizeByID(ID
, Width
, Height
);
2738 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
2739 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
2740 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
2741 e_Draw(ID
, RenderPanel
.Width
-Width
-1, RenderPanel
.Height
-Height
-1, 0, True, False);
2744 // Подсказка при выборе точки Телепорта:
2745 if SelectFlag
= SELECTFLAG_TELEPORT
then
2747 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2748 if Data
.d2d_teleport
then
2749 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2750 MousePos
.X
+16, MousePos
.Y
-1,
2753 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2754 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2756 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2757 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2758 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_TELEPORT
]), gEditorFont
, 0, 0, 0);
2761 // Подсказка при выборе точки появления:
2762 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2764 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2765 MousePos
.X
+16, MousePos
.Y
-1,
2767 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2768 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2769 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_SPAWN
]), gEditorFont
, 0, 0, 0);
2772 // Подсказка при выборе панели двери:
2773 if SelectFlag
= SELECTFLAG_DOOR
then
2775 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2776 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2777 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_PANEL_DOOR
]), gEditorFont
, 0, 0, 0);
2780 // Подсказка при выборе панели с текстурой:
2781 if SelectFlag
= SELECTFLAG_TEXTURE
then
2783 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2784 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2785 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_PANEL_TEXTURE
]), gEditorFont
, 0, 0, 0);
2788 // Подсказка при выборе панели индикации выстрела:
2789 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2791 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2792 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2793 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_PANEL_SHOT
]), gEditorFont
, 0, 0, 0);
2796 // Подсказка при выборе панели лифта:
2797 if SelectFlag
= SELECTFLAG_LIFT
then
2799 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2800 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2801 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_PANEL_LIFT
]), gEditorFont
, 0, 0, 0);
2804 // Подсказка при выборе монстра:
2805 if SelectFlag
= SELECTFLAG_MONSTER
then
2807 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2808 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2809 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_MONSTER
]), gEditorFont
, 0, 0, 0);
2812 // Подсказка при выборе области воздействия:
2813 if DrawPressRect
then
2815 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2816 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2817 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(_lc
[I_HINT_EXT_AREA
]), gEditorFont
, 0, 0, 0);
2820 // Рисуем текстуры, если чертим панель:
2821 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2822 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2823 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2825 if not g_GetTexture(SelectedTexture(), ID
) then
2826 g_GetTexture('NOTEXTURE', ID
);
2827 g_GetTextureSizeByID(ID
, Width
, Height
);
2829 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2830 Abs(Bottom
-Top
) div Height
, 0, True, False);
2833 // Прямоугольник выделения:
2834 if DrawRect
<> nil then
2836 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2838 // Чертим мышью панель/триггер или меняем мышью их размер:
2839 if (MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
, MOUSEACTION_RESIZE
]) and
2840 (DrawPanelSize
) then
2842 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2843 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2845 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2846 begin // Чертим новый
2847 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(Format(_lc
[I_HINT_WIDTH
],
2848 [Abs(MousePos
.X
-MouseLDownPos
.X
)])), gEditorFont
, 0, 0, 0);
2849 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+28, PChar(Format(_lc
[I_HINT_HEIGHT
],
2850 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)])), gEditorFont
, 0, 0, 0);
2852 else // Растягиваем существующий
2853 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2855 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2857 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2858 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2862 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2863 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2866 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+14, PChar(Format(_lc
[I_HINT_WIDTH
], [Width
])),
2867 gEditorFont
, 0, 0, 0);
2868 e_SimpleFontPrint(MousePos
.X
+8, MousePos
.Y
+28, PChar(Format(_lc
[I_HINT_HEIGHT
], [Height
])),
2869 gEditorFont
, 0, 0, 0);
2873 // Ближайшая к курсору мыши точка на сетке:
2874 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
2879 // Сколько пикселов карты в 1 пикселе мини-карты:
2880 ScaleSz
:= 16 div Scale
;
2881 // Размеры мини-карты:
2882 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
2883 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
2884 // X-координата на RenderPanel нулевой x-координаты карты:
2885 XX
:= RenderPanel
.Width
- aX
- 1;
2887 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
2888 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
2890 if gPanels
<> nil then
2893 for a
:= 0 to High(gPanels
) do
2895 if PanelType
<> 0 then
2897 // Левый верхний угол:
2898 aX
:= XX
+ (X
div ScaleSz
);
2899 aY
:= 1 + (Y
div ScaleSz
);
2901 aX2
:= max(Width
div ScaleSz
, 1);
2902 aY2
:= max(Height
div ScaleSz
, 1);
2903 // Правый нижний угол:
2904 aX2
:= aX
+ aX2
- 1;
2905 aY2
:= aY
+ aY2
- 1;
2908 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
2909 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
2910 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
2911 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
2912 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
2913 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
2914 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
2915 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
2916 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
2917 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
2918 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
2919 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
2923 // Рисуем красным выделенные панели:
2924 if SelectedObjects
<> nil then
2925 for b
:= 0 to High(SelectedObjects
) do
2926 with SelectedObjects
[b
] do
2927 if Live
and (ObjectType
= OBJECT_PANEL
) then
2928 with gPanels
[SelectedObjects
[b
].ID
] do
2929 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
2931 // Левый верхний угол:
2932 aX
:= XX
+ (X
div ScaleSz
);
2933 aY
:= 1 + (Y
div ScaleSz
);
2935 aX2
:= max(Width
div ScaleSz
, 1);
2936 aY2
:= max(Height
div ScaleSz
, 1);
2937 // Правый нижний угол:
2938 aX2
:= aX
+ aX2
- 1;
2939 aY2
:= aY
+ aY2
- 1;
2941 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
2945 if (gMapInfo
.Width
> RenderPanel
.Width
) or
2946 (gMapInfo
.Height
> RenderPanel
.Height
) then
2948 // Окно, показывающее текущее положение экрана на карте:
2950 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
2951 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
2952 // Левый верхний угол:
2953 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
2954 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
2955 // Правый нижний угол:
2959 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
2960 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
2966 EndPaint(Handle
, ps
);
2969 procedure TMainForm
.FormResize(Sender
: TObject
);
2971 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
2973 if gMapInfo
.Width
>= RenderPanel
.Width
then
2974 sbHorizontal
.Max
:= Normalize16(gMapInfo
.Width
-RenderPanel
.Width
+16)
2976 sbHorizontal
.Max
:= 0;
2978 if gMapInfo
.Height
>= RenderPanel
.Height
then
2979 sbVertical
.Max
:= Normalize16(gMapInfo
.Height
-RenderPanel
.Height
+16)
2981 sbVertical
.Max
:= 0;
2983 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
2984 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
2987 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
2992 j_max
:= 0; // shut up compiler
2996 res
:= (gPanels
<> nil) and
2997 PanelInShownLayer(gPanels
[ID
].PanelType
) and
2998 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3000 gPanels
[ID
].Height
);
3001 j_max
:= Length(gPanels
) - 1;
3006 res
:= (gItems
<> nil) and
3007 LayerEnabled
[LAYER_ITEMS
] and
3008 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3009 ItemSize
[gItems
[ID
].ItemType
][0],
3010 ItemSize
[gItems
[ID
].ItemType
][1]);
3011 j_max
:= Length(gItems
) - 1;
3016 res
:= (gMonsters
<> nil) and
3017 LayerEnabled
[LAYER_MONSTERS
] and
3018 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3019 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3020 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3021 j_max
:= Length(gMonsters
) - 1;
3026 res
:= (gAreas
<> nil) and
3027 LayerEnabled
[LAYER_AREAS
] and
3028 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3029 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3030 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3031 j_max
:= Length(gAreas
) - 1;
3036 res
:= (gTriggers
<> nil) and
3037 LayerEnabled
[LAYER_TRIGGERS
] and
3038 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3039 gTriggers
[ID
].Width
,
3040 gTriggers
[ID
].Height
);
3041 j_max
:= Length(gTriggers
) - 1;
3051 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3060 if j
= Integer(ID
) then
3065 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3066 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3070 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3071 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3072 ItemSize
[gItems
[j
].ItemType
][0],
3073 ItemSize
[gItems
[j
].ItemType
][1]);
3075 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3076 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3077 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3078 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3080 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3081 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3082 AreaSize
[gAreas
[j
].AreaType
].Width
,
3083 AreaSize
[gAreas
[j
].AreaType
].Height
);
3085 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3086 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3088 gTriggers
[j
].Height
);
3095 SetLength(SelectedObjects
, 1);
3097 SelectedObjects
[0].ObjectType
:= ObjectType
;
3098 SelectedObjects
[0].ID
:= j
;
3099 SelectedObjects
[0].Live
:= True;
3107 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3108 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3112 c1
, c2
, c3
, c4
: Boolean;
3118 MainForm
.ActiveControl
:= RenderPanel
;
3119 RenderPanel
.SetFocus();
3121 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3123 if Button
= mbLeft
then // Left Mouse Button
3125 // Двигаем карту с помощью мыши и мини-карты:
3127 g_CollidePoint(X
, Y
,
3128 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3130 max(gMapInfo
.Width
div (16 div Scale
), 1),
3131 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3134 MouseAction
:= MOUSEACTION_MOVEMAP
;
3136 else // Ставим предмет/монстра/область:
3137 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3138 (not (ssShift
in Shift
)) then
3140 case pcObjects
.ActivePageIndex
of
3142 if lbItemList
.ItemIndex
= -1 then
3143 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3146 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3147 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3148 item
.ItemType
:= item
.ItemType
+ 2;
3149 item
.X
:= MousePos
.X
-MapOffset
.X
;
3150 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3152 if not (ssCtrl
in Shift
) then
3154 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3155 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3158 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3159 item
.Fall
:= cbFall
.Checked
;
3160 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3163 if lbMonsterList
.ItemIndex
= -1 then
3164 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3167 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3168 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3169 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3171 if not (ssCtrl
in Shift
) then
3173 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3174 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3177 if rbMonsterLeft
.Checked
then
3178 monster
.Direction
:= D_LEFT
3180 monster
.Direction
:= D_RIGHT
;
3181 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3184 if lbAreasList
.ItemIndex
= -1 then
3185 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3187 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3189 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3190 area
.X
:= MousePos
.X
-MapOffset
.X
;
3191 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3193 if not (ssCtrl
in Shift
) then
3195 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3196 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3199 if rbAreaLeft
.Checked
then
3200 area
.Direction
:= D_LEFT
3202 area
.Direction
:= D_RIGHT
;
3203 Undo_Add(OBJECT_AREA
, AddArea(area
));
3209 i
:= GetFirstSelected();
3211 // Выбираем объект под текущим:
3212 if (SelectedObjects
<> nil) and
3213 (ssShift
in Shift
) and (i
>= 0) and
3214 (SelectedObjects
[i
].Live
) then
3216 if SelectedObjectCount() = 1 then
3217 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3218 SelectedObjects
[i
].ObjectType
,
3219 SelectedObjects
[i
].ID
);
3223 // Рисуем область триггера "Расширитель":
3224 if DrawPressRect
and (i
>= 0) and
3225 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3226 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3227 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3228 MouseAction
:= MOUSEACTION_DRAWPRESS
3229 else // Рисуем панель:
3230 if pcObjects
.ActivePageIndex
= 0 then
3232 if (lbPanelType
.ItemIndex
>= 0) then
3233 MouseAction
:= MOUSEACTION_DRAWPANEL
3235 else // Рисуем триггер:
3236 if (lbTriggersList
.ItemIndex
>= 0) then
3238 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3242 end; // if Button = mbLeft
3244 if Button
= mbRight
then // Right Mouse Button
3246 // Клик по мини-карте:
3248 g_CollidePoint(X
, Y
,
3249 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3251 max(gMapInfo
.Width
div (16 div Scale
), 1),
3252 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3254 MouseAction
:= MOUSEACTION_NOACTION
;
3256 else // Нужно что-то выбрать мышью:
3257 if SelectFlag
<> SELECTFLAG_NONE
then
3260 SELECTFLAG_TELEPORT
:
3261 // Точку назначения телепортации:
3262 with gTriggers
[SelectedObjects
[
3263 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3265 X
:= MousePos
.X
-MapOffset
.X
;
3266 Y
:= MousePos
.Y
-MapOffset
.Y
;
3269 SELECTFLAG_SPAWNPOINT
:
3270 // Точку создания монстра:
3271 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3272 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3274 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3275 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3277 else if TriggerType
= TRIGGER_SPAWNITEM
then
3278 begin // Точка создания предмета:
3279 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3280 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3282 else if TriggerType
= TRIGGER_SHOT
then
3283 begin // Точка создания выстрела:
3284 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3285 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3291 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3293 2, 2, OBJECT_PANEL
, True);
3294 if IDArray
<> nil then
3296 for i
:= 0 to High(IDArray
) do
3297 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3298 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3300 gTriggers
[SelectedObjects
[
3301 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3306 gTriggers
[SelectedObjects
[
3307 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3311 // Панель с текстурой:
3313 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3315 2, 2, OBJECT_PANEL
, True);
3316 if IDArray
<> nil then
3318 for i
:= 0 to High(IDArray
) do
3319 if ((gPanels
[IDArray
[i
]].PanelType
in
3320 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3321 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3323 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3324 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3325 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3327 gTriggers
[SelectedObjects
[
3328 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3333 gTriggers
[SelectedObjects
[
3334 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3340 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3342 2, 2, OBJECT_PANEL
, True);
3343 if IDArray
<> nil then
3345 for i
:= 0 to High(IDArray
) do
3346 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3347 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3348 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3349 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3351 gTriggers
[SelectedObjects
[
3352 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3357 gTriggers
[SelectedObjects
[
3358 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3364 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3366 2, 2, OBJECT_MONSTER
, False);
3367 if IDArray
<> nil then
3368 gTriggers
[SelectedObjects
[
3369 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3371 gTriggers
[SelectedObjects
[
3372 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3375 SELECTFLAG_SHOTPANEL
:
3376 // Панель индикации выстрела:
3378 if gTriggers
[SelectedObjects
[
3379 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
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
in
3388 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3389 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3391 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3392 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3393 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3395 gTriggers
[SelectedObjects
[
3396 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3401 gTriggers
[SelectedObjects
[
3402 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3407 SelectFlag
:= SELECTFLAG_SELECTED
;
3409 else // if SelectFlag <> SELECTFLAG_NONE...
3411 // Что уже выбрано и не нажат Ctrl:
3412 if (SelectedObjects
<> nil) and
3413 (not (ssCtrl
in Shift
)) then
3414 for i
:= 0 to High(SelectedObjects
) do
3415 with SelectedObjects
[i
] do
3418 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3419 (SelectedObjectCount() = 1) then
3421 Rect
:= ObjectGetRect(ObjectType
, ID
);
3423 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3424 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3425 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3426 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3427 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3428 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3429 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3430 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3432 // Меняем размер панели или триггера:
3433 if c1
or c2
or c3
or c4
then
3435 MouseAction
:= MOUSEACTION_RESIZE
;
3436 LastMovePoint
:= MousePos
;
3440 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3442 ResizeDirection
:= RESIZEDIR_LEFT
3444 ResizeDirection
:= RESIZEDIR_RIGHT
;
3445 RenderPanel
.Cursor
:= crSizeWE
;
3449 ResizeType
:= RESIZETYPE_VERTICAL
;
3451 ResizeDirection
:= RESIZEDIR_UP
3453 ResizeDirection
:= RESIZEDIR_DOWN
;
3454 RenderPanel
.Cursor
:= crSizeNS
;
3461 // Перемещаем панель или триггер:
3462 if ObjectCollide(ObjectType
, ID
,
3464 Y
-MapOffset
.Y
-1, 2, 2) then
3466 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3467 LastMovePoint
:= MousePos
;
3473 end; // if Button = mbRight
3475 MouseRDown
:= Button
= mbRight
;
3477 MouseRDownPos
:= MousePos
;
3479 MouseLDown
:= Button
= mbLeft
;
3481 MouseLDownPos
:= MousePos
;
3484 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3485 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3492 rSelectRect
: Boolean;
3494 if Button
= mbLeft
then
3495 MouseLDown
:= False;
3496 if Button
= mbRight
then
3497 MouseRDown
:= False;
3500 ResizeType
:= RESIZETYPE_NONE
;
3502 if Button
= mbLeft
then // Left Mouse Button
3504 if MouseAction
<> MOUSEACTION_NONE
then
3505 begin // Было действие мышью
3506 // Мышь сдвинулась во время удержания клавиши:
3507 if (MousePos
.X
<> MouseLDownPos
.X
) and
3508 (MousePos
.Y
<> MouseLDownPos
.Y
) then
3511 MOUSEACTION_DRAWPANEL
:
3513 // Фон или передний план без текстуры - ошибка:
3514 if (lbPanelType
.ItemIndex
in [1, 2]) and
3515 (lbTextureList
.ItemIndex
= -1) then
3516 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3517 else // Назначаем параметры панели:
3519 case lbPanelType
.ItemIndex
of
3520 0: Panel
.PanelType
:= PANEL_WALL
;
3521 1: Panel
.PanelType
:= PANEL_BACK
;
3522 2: Panel
.PanelType
:= PANEL_FORE
;
3523 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3524 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3525 5: Panel
.PanelType
:= PANEL_STEP
;
3526 6: Panel
.PanelType
:= PANEL_WATER
;
3527 7: Panel
.PanelType
:= PANEL_ACID1
;
3528 8: Panel
.PanelType
:= PANEL_ACID2
;
3529 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3530 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3531 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3532 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3533 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3536 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3537 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3538 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3539 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3541 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3542 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3543 (lbTextureList
.ItemIndex
= -1) then
3545 Panel
.TextureHeight
:= 1;
3546 Panel
.TextureWidth
:= 1;
3547 Panel
.TextureName
:= '';
3548 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3550 else // Есть текстура:
3552 Panel
.TextureName
:= SelectedTexture();
3554 // Обычная текстура:
3555 if not IsSpecialTextureSel() then
3557 g_GetTextureSizeByName(Panel
.TextureName
,
3558 Panel
.TextureWidth
, Panel
.TextureHeight
);
3559 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3561 else // Спец.текстура:
3563 Panel
.TextureHeight
:= 1;
3564 Panel
.TextureWidth
:= 1;
3565 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3570 Panel
.Blending
:= False;
3572 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3576 // Рисовали триггер:
3577 MOUSEACTION_DRAWTRIGGER
:
3579 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3580 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3581 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3582 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3584 trigger
.Enabled
:= True;
3585 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3586 trigger
.TexturePanel
:= -1;
3589 trigger
.ActivateType
:= 0;
3591 if clbActivationType
.Checked
[0] then
3592 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3593 if clbActivationType
.Checked
[1] then
3594 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3595 if clbActivationType
.Checked
[2] then
3596 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3597 if clbActivationType
.Checked
[3] then
3598 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3599 if clbActivationType
.Checked
[4] then
3600 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3601 if clbActivationType
.Checked
[5] then
3602 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3604 // Необходимые для активации ключи:
3607 if clbKeys
.Checked
[0] then
3608 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3609 if clbKeys
.Checked
[1] then
3610 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3611 if clbKeys
.Checked
[2] then
3612 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3613 if clbKeys
.Checked
[3] then
3614 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3615 if clbKeys
.Checked
[4] then
3616 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3618 // Параметры триггера:
3619 ZeroMemory(@trigger
.Data
.Default
[0], 128);
3621 case trigger
.TriggerType
of
3622 // Переключаемая панель:
3623 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3624 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3625 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3627 Trigger
.Data
.PanelID
:= -1;
3633 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3634 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3635 trigger
.Data
.d2d_teleport
:= True;
3636 trigger
.Data
.TlpDir
:= 0;
3639 // Изменение других триггеров:
3640 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3643 trigger
.Data
.Count
:= 1;
3649 trigger
.Data
.Volume
:= 255;
3650 trigger
.Data
.Pan
:= 127;
3651 trigger
.Data
.PlayCount
:= 1;
3652 trigger
.Data
.Local
:= True;
3653 trigger
.Data
.SoundSwitch
:= False;
3659 trigger
.Data
.MusicAction
:= 1;
3662 // Создание монстра:
3663 TRIGGER_SPAWNMONSTER
:
3665 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3666 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3667 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3668 trigger
.Data
.MonHealth
:= 0;
3669 trigger
.Data
.MonActive
:= False;
3670 trigger
.Data
.MonCount
:= 1;
3673 // Создание предмета:
3676 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3677 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3678 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3679 trigger
.Data
.ItemOnlyDM
:= False;
3680 trigger
.Data
.ItemFalls
:= False;
3681 trigger
.Data
.ItemCount
:= 1;
3682 trigger
.Data
.ItemMax
:= 0;
3683 trigger
.Data
.ItemDelay
:= 0;
3689 trigger
.Data
.PushAngle
:= 90;
3690 trigger
.Data
.PushForce
:= 10;
3691 trigger
.Data
.ResetVel
:= True;
3696 trigger
.Data
.ScoreCount
:= 1;
3697 trigger
.Data
.ScoreCon
:= True;
3698 trigger
.Data
.ScoreMsg
:= True;
3703 trigger
.Data
.MessageKind
:= 0;
3704 trigger
.Data
.MessageSendTo
:= 0;
3705 trigger
.Data
.MessageText
:= '';
3706 trigger
.Data
.MessageTime
:= 144;
3711 trigger
.Data
.DamageValue
:= 5;
3712 trigger
.Data
.DamageInterval
:= 12;
3717 trigger
.Data
.HealValue
:= 5;
3718 trigger
.Data
.HealInterval
:= 36;
3723 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3724 trigger
.Data
.ShotSound
:= True;
3725 trigger
.Data
.ShotPanelID
:= -1;
3726 trigger
.Data
.ShotTarget
:= 0;
3727 trigger
.Data
.ShotIntSight
:= 0;
3728 trigger
.Data
.ShotAllMap
:= False;
3729 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3730 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3731 trigger
.Data
.ShotAngle
:= 0;
3732 trigger
.Data
.ShotWait
:= 18;
3733 trigger
.Data
.ShotAccuracy
:= 0;
3734 trigger
.Data
.ShotAmmo
:= 0;
3735 trigger
.Data
.ShotIntReload
:= 0;
3740 trigger
.Data
.FXCount
:= 1;
3741 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3742 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3743 trigger
.Data
.FXColorR
:= 0;
3744 trigger
.Data
.FXColorG
:= 0;
3745 trigger
.Data
.FXColorB
:= 255;
3746 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3747 trigger
.Data
.FXWait
:= 1;
3748 trigger
.Data
.FXVelX
:= 0;
3749 trigger
.Data
.FXVelY
:= -20;
3750 trigger
.Data
.FXSpreadL
:= 5;
3751 trigger
.Data
.FXSpreadR
:= 5;
3752 trigger
.Data
.FXSpreadU
:= 4;
3753 trigger
.Data
.FXSpreadD
:= 0;
3757 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3760 // Рисовали область триггера "Расширитель":
3761 MOUSEACTION_DRAWPRESS
:
3762 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3764 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3765 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3766 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3767 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3769 DrawPressRect
:= False;
3773 MouseAction
:= MOUSEACTION_NONE
;
3775 end // if Button = mbLeft...
3776 else // Right Mouse Button:
3778 if MouseAction
= MOUSEACTION_NOACTION
then
3780 MouseAction
:= MOUSEACTION_NONE
;
3784 // Объект передвинут или изменен в размере:
3785 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3787 MouseAction
:= MOUSEACTION_NONE
;
3792 // Еще не все выбрали:
3793 if SelectFlag
<> SELECTFLAG_NONE
then
3795 if SelectFlag
= SELECTFLAG_SELECTED
then
3796 SelectFlag
:= SELECTFLAG_NONE
;
3801 // Мышь сдвинулась во время удержания клавиши:
3802 if (MousePos
.X
<> MouseRDownPos
.X
) and
3803 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3805 rSelectRect
:= True;
3807 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3808 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3809 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3810 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3812 else // Мышь не сдвинулась - нет прямоугольника:
3814 rSelectRect
:= False;
3816 rRect
.X
:= X
-MapOffset
.X
-1;
3817 rRect
.Y
:= Y
-MapOffset
.Y
-1;
3822 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
3823 if not (ssCtrl
in Shift
) then
3824 RemoveSelectFromObjects();
3826 // Выделяем всё в выбранном прямоугольнике:
3827 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3828 rRect
.Width
, rRect
.Height
,
3829 pcObjects
.ActivePageIndex
+1, rSelectRect
);
3831 if IDArray
<> nil then
3832 for i
:= 0 to High(IDArray
) do
3833 SelectObject(pcObjects
.ActivePageIndex
+1, IDArray
[i
],
3834 (ssCtrl
in Shift
) or rSelectRect
);
3840 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
3841 Shift
: TShiftState
; X
, Y
: Integer);
3844 dWidth
, dHeight
: Integer;
3847 _id
:= GetFirstSelected();
3849 // Рисуем панель с текстурой, сетка - размеры текстуры:
3850 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
3851 (lbPanelType
.ItemIndex
in [0..8]) and
3852 (lbTextureList
.ItemIndex
<> -1) and
3853 (not IsSpecialTextureSel()) then
3855 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
3856 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
3859 // Меняем размер панели с текстурой, сетка - размеры текстуры:
3860 if (MouseAction
= MOUSEACTION_RESIZE
) and
3861 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
3862 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
3863 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
3864 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
3866 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
3867 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
3870 // Выравнивание по сетке:
3876 else // Нет выравнивания по сетке:
3882 // Новая позиция мыши:
3884 begin // Зажата левая кнопка мыши
3885 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
3886 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
3890 begin // Зажата правая кнопка мыши
3891 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
3892 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
3895 begin // Кнопки мыши не зажаты
3896 MousePos
.X
:= (Round(X
/sX
)*sX
);
3897 MousePos
.Y
:= (Round(Y
/sY
)*sY
);
3900 // Изменение размера закончилось - ставим обычный курсор:
3901 if ResizeType
= RESIZETYPE_NONE
then
3902 RenderPanel
.Cursor
:= crDefault
;
3904 // Зажата только правая кнопка мыши:
3905 if (not MouseLDown
) and (MouseRDown
) then
3907 // Рисуем прямоугольник выделения:
3908 if MouseAction
= MOUSEACTION_NONE
then
3910 if DrawRect
= nil then
3912 DrawRect
.TopLeft
:= MouseRDownPos
;
3913 DrawRect
.BottomRight
:= MousePos
;
3916 // Двигаем выделенные объекты:
3917 if MouseAction
= MOUSEACTION_MOVEOBJ
then
3919 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
3920 MousePos
.X
-LastMovePoint
.X
,
3921 MousePos
.Y
-LastMovePoint
.Y
);
3924 // Меняем размер выделенного объекта:
3925 if MouseAction
= MOUSEACTION_RESIZE
then
3927 if (SelectedObjectCount
= 1) and
3928 (SelectedObjects
[GetFirstSelected
].Live
) then
3930 dWidth
:= MousePos
.X
-LastMovePoint
.X
;
3931 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
;
3934 RESIZETYPE_VERTICAL
: dWidth
:= 0;
3935 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
3938 case ResizeDirection
of
3939 RESIZEDIR_UP
: dHeight
:= -dHeight
;
3940 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
3943 ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
3944 SelectedObjects
[GetFirstSelected
].ID
,
3945 dWidth
, dHeight
, ResizeDirection
);
3947 LastMovePoint
:= MousePos
;
3952 // Зажата только левая кнопка мыши:
3953 if (not MouseRDown
) and (MouseLDown
) then
3955 // Рисуем прямоугольник планирования панели:
3956 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
3957 MOUSEACTION_DRAWTRIGGER
,
3958 MOUSEACTION_DRAWPRESS
] then
3960 if DrawRect
= nil then
3962 DrawRect
.TopLeft
:= MouseLDownPos
;
3963 DrawRect
.BottomRight
:= MousePos
;
3965 else // Двигаем карту:
3966 if MouseAction
= MOUSEACTION_MOVEMAP
then
3972 // Клавиши мыши не зажаты:
3973 if (not MouseRDown
) and (not MouseLDown
) then
3976 // Строка состояния - координаты мыши:
3977 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
3978 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
3981 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
3983 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
3984 PChar(_lc
[I_MSG_EXIT
]),
3985 MB_ICONQUESTION
or MB_YESNO
or
3986 MB_TASKMODAL
or MB_DEFBUTTON1
) = idYes
;
3989 procedure TMainForm
.aExitExecute(Sender
: TObject
);
3994 procedure TMainForm
.FormDestroy(Sender
: TObject
);
3999 config
:= TConfig
.CreateFile(EditorDir
+'\Editor.cfg');
4001 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4002 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4003 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4004 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4005 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4006 config
.WriteInt('Editor', 'DotStep', DotStep
);
4007 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4008 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4009 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4010 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4011 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4012 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4013 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4015 for i
:= 0 to RecentCount
-1 do
4016 if i
< RecentFiles
.Count
then
4017 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4019 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4022 config
.SaveFile(EditorDir
+'\Editor.cfg');
4025 slInvalidTextures
.Free
;
4027 wglDeleteContext(hRC
);
4030 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4032 if MainForm
.Visible
then
4036 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4040 MapOptionsForm
.ShowModal();
4042 ResName
:= OpenedMap
;
4043 while (Pos(':\', ResName
) > 0) do
4044 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4046 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4049 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4051 AboutForm
.ShowModal();
4054 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word;
4055 Shift
: TShiftState
);
4060 if (not EditingProperties
) then
4062 if Key
= Ord('1') then
4063 SwitchLayer(LAYER_BACK
);
4064 if Key
= Ord('2') then
4065 SwitchLayer(LAYER_WALLS
);
4066 if Key
= Ord('3') then
4067 SwitchLayer(LAYER_FOREGROUND
);
4068 if Key
= Ord('4') then
4069 SwitchLayer(LAYER_STEPS
);
4070 if Key
= Ord('5') then
4071 SwitchLayer(LAYER_WATER
);
4072 if Key
= Ord('6') then
4073 SwitchLayer(LAYER_ITEMS
);
4074 if Key
= Ord('7') then
4075 SwitchLayer(LAYER_MONSTERS
);
4076 if Key
= Ord('8') then
4077 SwitchLayer(LAYER_AREAS
);
4078 if Key
= Ord('9') then
4079 SwitchLayer(LAYER_TRIGGERS
);
4080 if Key
= Ord('0') then
4081 tbShowClick(tbShow
);
4083 if Key
= Ord('V') then
4084 begin // Поворот монстров и областей:
4085 if (SelectedObjects
<> nil) then
4087 for i
:= 0 to High(SelectedObjects
) do
4088 if (SelectedObjects
[i
].Live
) then
4090 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4092 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4095 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4097 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4103 if pcObjects
.ActivePage
= tsMonsters
then
4105 if rbMonsterLeft
.Checked
then
4106 rbMonsterRight
.Checked
:= True
4108 rbMonsterLeft
.Checked
:= True;
4110 if pcObjects
.ActivePage
= tsAreas
then
4112 if rbAreaLeft
.Checked
then
4113 rbAreaRight
.Checked
:= True
4115 rbAreaLeft
.Checked
:= True;
4120 if not (ssCtrl
in Shift
) then
4122 // Вертикальный скролл карты:
4125 if Key
= Ord('W') then
4127 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4128 MapOffset
.Y
:= -Round(Position
/16) * 16;
4131 if Key
= Ord('S') then
4133 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4134 MapOffset
.Y
:= -Round(Position
/16) * 16;
4138 // Горизонтальный скролл карты:
4139 with sbHorizontal
do
4141 if Key
= Ord('A') then
4143 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4144 MapOffset
.X
:= -Round(Position
/16) * 16;
4147 if Key
= Ord('D') then
4149 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4150 MapOffset
.X
:= -Round(Position
/16) * 16;
4156 // Удалить выделенные объекты:
4157 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4158 RenderPanel
.Focused() then
4159 DeleteSelectedObjects();
4162 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4163 RemoveSelectFromObjects();
4165 // Передвинуть объекты:
4166 if MainForm
.ActiveControl
= RenderPanel
then
4171 if Key
= VK_NUMPAD4
then
4172 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4173 if Key
= VK_NUMPAD6
then
4174 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4175 if Key
= VK_NUMPAD8
then
4176 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4177 if Key
= VK_NUMPAD5
then
4178 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4180 if (dx
<> 0) or (dy
<> 0) then
4182 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4187 if ssCtrl
in Shift
then
4189 // Выбор панели с текстурой для триггера
4190 if Key
= Ord('T') then
4192 DrawPressRect
:= False;
4193 if SelectFlag
= SELECTFLAG_TEXTURE
then
4195 SelectFlag
:= SELECTFLAG_NONE
;
4198 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4200 SelectFlag
:= SELECTFLAG_TEXTURE
;
4203 if Key
= Ord('D') then
4205 SelectFlag
:= SELECTFLAG_NONE
;
4206 if DrawPressRect
then
4208 DrawPressRect
:= False;
4212 // Выбор области воздействия, в зависимости от типа триггера
4213 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4216 DrawPressRect
:= True;
4219 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4221 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4224 SelectFlag
:= SELECTFLAG_DOOR
;
4227 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4230 SelectFlag
:= SELECTFLAG_LIFT
;
4233 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4236 SelectFlag
:= SELECTFLAG_TELEPORT
;
4239 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4242 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4246 // Выбор основного параметра, в зависимости от типа триггера
4247 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4250 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4251 SelectMapForm
.GetMaps(FileName
);
4253 if SelectMapForm
.ShowModal() = mrOK
then
4255 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4256 bApplyProperty
.Click();
4260 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4262 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4265 AddSoundForm
.OKFunction
:= nil;
4266 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4267 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4269 if (AddSoundForm
.ShowModal() = mrOk
) then
4271 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4272 bApplyProperty
.Click();
4276 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4278 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4281 vleObjectProperty
.Row
:= i
;
4282 vleObjectProperty
.SetFocus();
4289 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4291 RemoveSelectFromObjects();
4292 MapOptimizationForm
.ShowModal();
4295 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4297 MapCheckForm
.ShowModal();
4300 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4302 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4303 AddTextureForm
.ShowModal();
4306 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4309 TextureWidth
, TextureHeight
: Word;
4311 if (lbTextureList
.ItemIndex
<> -1) and
4312 (not IsSpecialTextureSel()) then
4314 if g_GetTexture(SelectedTexture(), TextureID
) then
4316 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4318 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4319 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4322 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4323 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4328 lTextureWidth
.Caption
:= '';
4329 lTextureHeight
.Caption
:= '';
4333 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4334 const KeyName
: String; Values
: TStrings
);
4336 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4338 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4340 Values
.Add(DirNames
[D_LEFT
]);
4341 Values
.Add(DirNames
[D_RIGHT
]);
4343 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4345 Values
.Add(DirNamesAdv
[0]);
4346 Values
.Add(DirNamesAdv
[1]);
4347 Values
.Add(DirNamesAdv
[2]);
4348 Values
.Add(DirNamesAdv
[3]);
4350 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4352 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4353 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4355 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4357 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4358 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4359 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4360 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4361 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4362 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4364 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4366 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4367 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4368 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4369 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4371 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4373 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4374 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4375 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4376 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4378 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4380 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4381 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4383 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4385 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4386 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4387 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4388 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4389 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4390 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4392 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4394 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4395 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4396 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4397 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4398 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4399 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4400 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4402 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4403 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4404 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4405 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4406 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4407 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4408 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4409 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4410 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4411 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4412 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4413 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4414 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4415 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4416 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4417 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4418 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4419 (KeyName
= _lc
[I_PROP_TR_SHOT_ALLMAP
]) or
4420 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4421 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4423 Values
.Add(BoolNames
[True]);
4424 Values
.Add(BoolNames
[False]);
4429 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4431 _id
, a
, r
, c
: Integer;
4437 if SelectedObjectCount() <> 1 then
4439 if not SelectedObjects
[GetFirstSelected()].Live
then
4443 if not CheckProperty() then
4449 _id
:= GetFirstSelected();
4451 r
:= vleObjectProperty
.Row
;
4452 c
:= vleObjectProperty
.Col
;
4454 case SelectedObjects
[_id
].ObjectType
of
4457 with gPanels
[SelectedObjects
[_id
].ID
] do
4459 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4460 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4461 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4462 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4464 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4466 // Сброс ссылки на триггеры смены текстуры:
4467 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4468 if gTriggers
<> nil then
4469 for a
:= 0 to High(gTriggers
) do
4471 if (gTriggers
[a
].TriggerType
<> 0) and
4472 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4473 gTriggers
[a
].TexturePanel
:= -1;
4474 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4475 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4476 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4479 // Сброс ссылки на триггеры лифта:
4480 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4481 if gTriggers
<> nil then
4482 for a
:= 0 to High(gTriggers
) do
4483 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4484 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4485 gTriggers
[a
].Data
.PanelID
:= -1;
4487 // Сброс ссылки на триггеры двери:
4488 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4489 if gTriggers
<> nil then
4490 for a
:= 0 to High(gTriggers
) do
4491 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4492 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4493 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4494 gTriggers
[a
].Data
.PanelID
:= -1;
4496 if IsTexturedPanel(PanelType
) then
4497 begin // Может быть текстура
4498 if TextureName
<> '' then
4499 begin // Была текстура
4500 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4501 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4510 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4512 if TextureName
<> '' then
4513 begin // Есть текстура
4514 // Обычная текстура:
4515 if not IsSpecialTexture(TextureName
) then
4517 g_GetTextureSizeByName(TextureName
,
4518 TextureWidth
, TextureHeight
);
4520 // Проверка кратности размеров панели:
4522 if TextureWidth
<> 0 then
4523 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4525 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4529 if Res
and (TextureHeight
<> 0) then
4530 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4532 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4539 if not g_GetTexture(TextureName
, TextureID
) then
4540 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4541 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4543 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4544 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4546 TextureHeight
:= NH
;
4549 TextureID
:= TEXTURE_SPECIAL_NONE
;
4559 TextureID
:= TEXTURE_SPECIAL_NONE
;
4562 else // Спец.текстура
4566 TextureID
:= SpecialTextureID(TextureName
);
4569 else // Нет текстуры
4573 TextureID
:= TEXTURE_SPECIAL_NONE
;
4576 else // Не может быть текстуры
4583 TextureID
:= TEXTURE_SPECIAL_NONE
;
4590 with gItems
[SelectedObjects
[_id
].ID
] do
4592 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4593 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4594 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
4595 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
4601 with gMonsters
[SelectedObjects
[_id
].ID
] do
4603 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4604 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4605 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4611 with gAreas
[SelectedObjects
[_id
].ID
] do
4613 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4614 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4615 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4621 with gTriggers
[SelectedObjects
[_id
].ID
] do
4623 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4624 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4625 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4626 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4627 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
4628 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
4629 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
4634 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]];
4635 ZeroMemory(@Data
.MapName
[0], 16);
4637 CopyMemory(@Data
.MapName
[0], @s
[1], Min(Length(s
), 16));
4642 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
4643 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
4646 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
4648 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
4649 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
4650 if Data
.Count
< 1 then
4652 if TriggerType
= TRIGGER_PRESS
then
4653 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
4656 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
4657 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
4660 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
4661 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
4666 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
4667 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
4668 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
4673 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]];
4674 ZeroMemory(@Data
.SoundName
[0], 64);
4676 CopyMemory(@Data
.SoundName
[0], @s
[1], Min(Length(s
), 64));
4678 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
4679 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
4680 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
4681 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
4682 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
4685 TRIGGER_SPAWNMONSTER
:
4687 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
4688 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
4689 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
4690 if Data
.MonHealth
< 0 then
4691 Data
.MonHealth
:= 0;
4692 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
4693 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
4694 if Data
.MonCount
< 1 then
4696 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
4697 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
4698 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
4700 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
4702 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
4704 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
4706 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
4708 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
4714 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
4715 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
4716 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
4717 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
4718 if Data
.ItemCount
< 1 then
4719 Data
.ItemCount
:= 1;
4720 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
4721 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
4722 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
4727 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]];
4728 ZeroMemory(@Data
.MusicName
[0], 64);
4730 CopyMemory(@Data
.MusicName
[0], @s
[1], Min(Length(s
), 64));
4732 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
4733 Data
.MusicAction
:= 1
4735 Data
.MusicAction
:= 2;
4740 Data
.PushAngle
:= Min(
4741 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
4742 Data
.PushForce
:= Min(
4743 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
4744 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
4749 Data
.ScoreAction
:= 0;
4750 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
4751 Data
.ScoreAction
:= 1
4752 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
4753 Data
.ScoreAction
:= 2
4754 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
4755 Data
.ScoreAction
:= 3;
4756 Data
.ScoreCount
:= Min(Max(
4757 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
4758 Data
.ScoreTeam
:= 0;
4759 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
4761 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
4763 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
4764 Data
.ScoreTeam
:= 3;
4765 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
4766 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
4771 Data
.MessageKind
:= 0;
4772 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
4773 Data
.MessageKind
:= 1;
4775 Data
.MessageSendTo
:= 0;
4776 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
4777 Data
.MessageSendTo
:= 1
4778 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
4779 Data
.MessageSendTo
:= 2
4780 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
4781 Data
.MessageSendTo
:= 3
4782 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
4783 Data
.MessageSendTo
:= 4
4784 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
4785 Data
.MessageSendTo
:= 5;
4787 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]];
4788 ZeroMemory(@Data
.MessageText
[0], 100);
4790 CopyMemory(@Data
.MessageText
[0], @s
[1], Min(Length(s
), 100));
4792 Data
.MessageTime
:= Min(Max(
4793 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
4798 Data
.DamageValue
:= Min(Max(
4799 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
4800 Data
.DamageInterval
:= Min(Max(
4801 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
4806 Data
.HealValue
:= Min(Max(
4807 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
4808 Data
.HealInterval
:= Min(Max(
4809 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
4810 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
4811 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
4816 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
4817 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
4818 Data
.ShotTarget
:= 0;
4819 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
4820 Data
.ShotTarget
:= 1
4821 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
4822 Data
.ShotTarget
:= 2
4823 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
4824 Data
.ShotTarget
:= 3
4825 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
4826 Data
.ShotTarget
:= 4
4827 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
4828 Data
.ShotTarget
:= 5
4829 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
4830 Data
.ShotTarget
:= 6;
4831 Data
.ShotIntSight
:= Min(Max(
4832 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
4833 Data
.ShotAllMap
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ALLMAP
]]);
4834 Data
.ShotAngle
:= Min(
4835 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
4836 Data
.ShotWait
:= Min(Max(
4837 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
4838 Data
.ShotAccuracy
:= Min(Max(
4839 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
4840 Data
.ShotAmmo
:= Min(Max(
4841 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
4842 Data
.ShotIntReload
:= Min(Max(
4843 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
4848 Data
.FXCount
:= Min(Max(
4849 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
4850 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
4852 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
4853 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
4854 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
4855 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
4856 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
4857 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
4858 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
4859 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
4860 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
4861 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
4862 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
4863 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
4864 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
4865 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
4868 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
4869 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
4872 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
4873 Data
.FXColorR
:= a
and $FF;
4874 Data
.FXColorG
:= (a
shr 8) and $FF;
4875 Data
.FXColorB
:= (a
shr 16) and $FF;
4876 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
4880 Data
.FXWait
:= Min(Max(
4881 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
4882 Data
.FXVelX
:= Min(Max(
4883 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
4884 Data
.FXVelY
:= Min(Max(
4885 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
4886 Data
.FXSpreadL
:= Min(Max(
4887 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
4888 Data
.FXSpreadR
:= Min(Max(
4889 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
4890 Data
.FXSpreadU
:= Min(Max(
4891 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
4892 Data
.FXSpreadD
:= Min(Max(
4893 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
4902 vleObjectProperty
.Row
:= r
;
4903 vleObjectProperty
.Col
:= c
;
4906 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
4910 i
:= lbTextureList
.ItemIndex
;
4914 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
4915 [SelectedTexture()])),
4916 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
4917 MB_ICONQUESTION
or MB_YESNO
or
4918 MB_TASKMODAL
or MB_DEFBUTTON1
) <> idYes
then
4921 if gPanels
<> nil then
4922 for a
:= 0 to High(gPanels
) do
4923 if (gPanels
[a
].PanelType
<> 0) and
4924 (gPanels
[a
].TextureName
= SelectedTexture()) then
4926 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
4930 g_DeleteTexture(SelectedTexture());
4931 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
4933 slInvalidTextures
.Delete(i
);
4934 if lbTextureList
.ItemIndex
> -1 then
4935 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
4938 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
4940 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
4941 PChar(_lc
[I_MSG_CLEAR_MAP
]),
4942 MB_ICONQUESTION
or MB_YESNO
or
4943 MB_TASKMODAL
or MB_DEFBUTTON1
) = mrYes
) then
4947 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
4951 if UndoBuffer
= nil then
4953 if UndoBuffer
[High(UndoBuffer
)] = nil then
4956 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
4957 with UndoBuffer
[High(UndoBuffer
)][a
] do
4965 UNDO_DELETE_ITEM
: AddItem(Item
);
4966 UNDO_DELETE_AREA
: AddArea(Area
);
4967 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
4968 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
4969 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
4970 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
4971 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
4972 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
4973 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
4977 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
4979 RemoveSelectFromObjects();
4981 miUndo
.Enabled
:= UndoBuffer
<> nil;
4985 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
4988 CopyBuffer
: TCopyRecArray
;
4992 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
4994 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
4996 if Result
= 0 then // Одного типа
4997 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5000 procedure QuickSortCopyBuffer(L
, R
: Integer);
5008 P
:= CopyBuffer
[(L
+ R
) shr 1];
5011 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5013 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5019 CopyBuffer
[I
] := CopyBuffer
[J
];
5027 QuickSortCopyBuffer(L
, J
);
5034 if SelectedObjects
= nil then
5040 // Копируем объекты:
5041 for a
:= 0 to High(SelectedObjects
) do
5042 if SelectedObjects
[a
].Live
then
5043 with SelectedObjects
[a
] do
5045 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5046 b
:= High(CopyBuffer
);
5047 CopyBuffer
[b
].ID
:= ID
;
5048 CopyBuffer
[b
].Panel
:= nil;
5053 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5054 New(CopyBuffer
[b
].Panel
);
5055 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5060 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5061 CopyBuffer
[b
].Item
:= gItems
[ID
];
5066 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5067 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5072 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5073 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5078 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5079 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5084 // Сортировка по ID:
5085 if CopyBuffer
<> nil then
5087 QuickSortCopyBuffer(0, b
);
5090 // Пестановка ссылок триггеров:
5091 for a
:= 0 to Length(CopyBuffer
)-1 do
5092 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5094 case CopyBuffer
[a
].Trigger
.TriggerType
of
5095 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5096 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5097 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5098 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5102 for b
:= 0 to Length(CopyBuffer
)-1 do
5103 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5104 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5106 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5111 // Этих панелей нет среди копируемых:
5113 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5116 TRIGGER_PRESS
, TRIGGER_ON
,
5117 TRIGGER_OFF
, TRIGGER_ONOFF
:
5118 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5122 for b
:= 0 to Length(CopyBuffer
)-1 do
5123 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5124 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5126 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5131 // Этих монстров нет среди копируемых:
5133 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5137 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5141 for b
:= 0 to Length(CopyBuffer
)-1 do
5142 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5143 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5145 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5150 // Этих панелей нет среди копируемых:
5152 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5156 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5160 for b
:= 0 to Length(CopyBuffer
)-1 do
5161 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5162 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5164 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5169 // Этих панелей нет среди копируемых:
5171 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5176 str
:= CopyBufferToString(CopyBuffer
);
5177 ClipBoard
.AsText
:= str
;
5179 for a
:= 0 to Length(CopyBuffer
)-1 do
5180 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5181 (CopyBuffer
[a
].Panel
<> nil) then
5182 Dispose(CopyBuffer
[a
].Panel
);
5187 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5190 CopyBuffer
: TCopyRecArray
;
5192 swad
, ssec
, sres
: String;
5196 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
);
5198 if CopyBuffer
= nil then
5201 RemoveSelectFromObjects();
5203 h
:= High(CopyBuffer
);
5205 with CopyBuffer
[a
] do
5209 if Panel
<> nil then
5211 Panel
^.X
:= Panel
^.X
+ 16;
5212 Panel
^.Y
:= Panel
^.Y
+ 16;
5214 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5215 Panel
^.TextureWidth
:= 1;
5216 Panel
^.TextureHeight
:= 1;
5218 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5219 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5220 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5221 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5222 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5223 (Panel
^.TextureName
= '') then
5224 begin // Нет или не может быть текстуры:
5226 else // Есть текстура:
5228 // Обычная текстура:
5229 if not IsSpecialTexture(Panel
^.TextureName
) then
5231 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5235 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5236 AddTexture(swad
, ssec
, sres
, True);
5237 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5241 g_GetTextureSizeByName(Panel
^.TextureName
,
5242 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5244 Panel
^.TextureName
:= '';
5246 else // Спец.текстура:
5248 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5249 with MainForm
.lbTextureList
.Items
do
5250 if IndexOf(Panel
^.TextureName
) = -1 then
5251 Add(Panel
^.TextureName
);
5255 ID
:= AddPanel(Panel
^);
5257 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5258 SelectObject(OBJECT_PANEL
, ID
, True);
5263 Item
.X
:= Item
.X
+ 16;
5264 Item
.Y
:= Item
.Y
+ 16;
5266 ID
:= AddItem(Item
);
5267 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5268 SelectObject(OBJECT_ITEM
, ID
, True);
5273 Monster
.X
:= Monster
.X
+ 16;
5274 Monster
.Y
:= Monster
.Y
+ 16;
5276 ID
:= AddMonster(Monster
);
5277 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5278 SelectObject(OBJECT_MONSTER
, ID
, True);
5283 Area
.X
:= Area
.X
+ 16;
5284 Area
.Y
:= Area
.Y
+ 16;
5286 ID
:= AddArea(Area
);
5287 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5288 SelectObject(OBJECT_AREA
, ID
, True);
5293 Trigger
.X
:= Trigger
.X
+ 16;
5294 Trigger
.Y
:= Trigger
.Y
+ 16;
5296 ID
:= AddTrigger(Trigger
);
5297 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5298 SelectObject(OBJECT_TRIGGER
, ID
, True);
5303 // Переставляем ссылки триггеров:
5304 for a
:= 0 to High(CopyBuffer
) do
5305 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5307 case CopyBuffer
[a
].Trigger
.TriggerType
of
5308 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5309 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5310 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5311 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5312 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5313 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5315 TRIGGER_PRESS
, TRIGGER_ON
,
5316 TRIGGER_OFF
, TRIGGER_ONOFF
:
5317 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5318 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5319 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5322 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5323 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5324 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5327 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5328 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5329 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5338 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5341 DeleteSelectedObjects();
5344 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5346 Key
, FileName
: String;
5349 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5351 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5353 with ChooseTypeForm
, vleObjectProperty
do
5354 begin // Выбор типа панели:
5355 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5356 lbTypeSelect
.Items
.Clear();
5358 for b
:= 0 to High(PANELNAMES
) do
5360 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5361 if Values
[Key
] = PANELNAMES
[b
] then
5362 lbTypeSelect
.ItemIndex
:= b
;
5365 if ShowModal() = mrOK
then
5367 b
:= lbTypeSelect
.ItemIndex
;
5368 Values
[Key
] := PANELNAMES
[b
];
5369 bApplyProperty
.Click();
5373 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5374 SelectFlag
:= SELECTFLAG_TELEPORT
5375 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5376 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5377 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5378 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5379 SelectFlag
:= SELECTFLAG_DOOR
5380 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5382 DrawPressRect
:= False;
5383 SelectFlag
:= SELECTFLAG_TEXTURE
;
5385 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5386 SelectFlag
:= SELECTFLAG_SHOTPANEL
5387 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5388 SelectFlag
:= SELECTFLAG_LIFT
5389 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5390 SelectFlag
:= SELECTFLAG_MONSTER
5391 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5393 SelectFlag
:= SELECTFLAG_NONE
;
5394 DrawPressRect
:= True;
5396 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5397 begin // Выбор следующей карты:
5398 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5399 SelectMapForm
.GetMaps(FileName
);
5401 if SelectMapForm
.ShowModal() = mrOK
then
5403 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5404 bApplyProperty
.Click();
5407 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5408 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5409 begin // Выбор файла звука/музыки:
5410 AddSoundForm
.OKFunction
:= nil;
5411 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5412 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
5414 if (AddSoundForm
.ShowModal() = mrOk
) then
5416 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
5417 bApplyProperty
.Click();
5420 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5421 with ActivationTypeForm
, vleObjectProperty
do
5422 begin // Выбор типов активации:
5423 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5424 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5425 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5426 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5427 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5428 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5430 if ShowModal() = mrOK
then
5433 if cbPlayerCollide
.Checked
then
5434 b
:= ACTIVATE_PLAYERCOLLIDE
;
5435 if cbMonsterCollide
.Checked
then
5436 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5437 if cbPlayerPress
.Checked
then
5438 b
:= b
or ACTIVATE_PLAYERPRESS
;
5439 if cbMonsterPress
.Checked
then
5440 b
:= b
or ACTIVATE_MONSTERPRESS
;
5441 if cbShot
.Checked
then
5442 b
:= b
or ACTIVATE_SHOT
;
5443 if cbNoMonster
.Checked
then
5444 b
:= b
or ACTIVATE_NOMONSTER
;
5446 Values
[Key
] := ActivateToStr(b
);
5447 bApplyProperty
.Click();
5450 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5451 with KeysForm
, vleObjectProperty
do
5452 begin // Выбор необходимых ключей:
5453 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5454 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5455 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5456 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5457 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5459 if ShowModal() = mrOK
then
5462 if cbRedKey
.Checked
then
5464 if cbGreenKey
.Checked
then
5465 b
:= b
or KEY_GREEN
;
5466 if cbBlueKey
.Checked
then
5468 if cbRedTeam
.Checked
then
5469 b
:= b
or KEY_REDTEAM
;
5470 if cbBlueTeam
.Checked
then
5471 b
:= b
or KEY_BLUETEAM
;
5473 Values
[Key
] := KeyToStr(b
);
5474 bApplyProperty
.Click();
5477 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
5478 with ChooseTypeForm
, vleObjectProperty
do
5479 begin // Выбор типа эффекта:
5480 Caption
:= _lc
[I_CAP_FX_TYPE
];
5481 lbTypeSelect
.Items
.Clear();
5483 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
5484 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5486 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
5488 if ShowModal() = mrOK
then
5490 b
:= lbTypeSelect
.ItemIndex
;
5491 Values
[Key
] := EffectToStr(b
);
5492 bApplyProperty
.Click();
5495 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
5496 with ChooseTypeForm
, vleObjectProperty
do
5497 begin // Выбор типа монстра:
5498 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
5499 lbTypeSelect
.Items
.Clear();
5501 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
5502 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
5504 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
5506 if ShowModal() = mrOK
then
5508 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
5509 Values
[Key
] := MonsterToStr(b
);
5510 bApplyProperty
.Click();
5513 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
5514 with ChooseTypeForm
, vleObjectProperty
do
5515 begin // Выбор типа предмета:
5516 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
5517 lbTypeSelect
.Items
.Clear();
5519 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
5520 lbTypeSelect
.Items
.Add(ItemToStr(b
));
5521 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
5522 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
5523 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
5524 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
5526 b
:= StrToItem(Values
[Key
]);
5527 if b
>= ITEM_BOTTLE
then
5529 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
5531 if ShowModal() = mrOK
then
5533 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
5534 if b
>= ITEM_WEAPON_KASTET
then
5536 Values
[Key
] := ItemToStr(b
);
5537 bApplyProperty
.Click();
5540 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
5541 with ChooseTypeForm
, vleObjectProperty
do
5542 begin // Выбор типа предмета:
5543 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
5544 lbTypeSelect
.Items
.Clear();
5546 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
5547 lbTypeSelect
.Items
.Add(ShotToStr(b
));
5549 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
5551 if ShowModal() = mrOK
then
5553 b
:= lbTypeSelect
.ItemIndex
;
5554 Values
[Key
] := ShotToStr(b
);
5555 bApplyProperty
.Click();
5558 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
5559 with ChooseTypeForm
, vleObjectProperty
do
5560 begin // Выбор типа эффекта:
5561 Caption
:= _lc
[I_CAP_FX_TYPE
];
5562 lbTypeSelect
.Items
.Clear();
5564 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
5565 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
5566 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5567 lbTypeSelect
.ItemIndex
:= 1
5569 lbTypeSelect
.ItemIndex
:= 0;
5571 if ShowModal() = mrOK
then
5573 b
:= lbTypeSelect
.ItemIndex
;
5575 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
5577 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
5578 bApplyProperty
.Click();
5581 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
5582 with ChooseTypeForm
, vleObjectProperty
do
5583 begin // Выбор подтипа эффекта:
5584 Caption
:= _lc
[I_CAP_FX_TYPE
];
5585 lbTypeSelect
.Items
.Clear();
5587 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5589 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
5590 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5592 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
5595 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
5596 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
5597 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
5598 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
5599 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
5600 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
5601 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
5602 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5603 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
5604 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5605 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
5606 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5607 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
5608 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5609 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
5610 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5611 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
5614 if ShowModal() = mrOK
then
5616 b
:= lbTypeSelect
.ItemIndex
;
5618 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5619 Values
[Key
] := EffectToStr(b
+ 1)
5621 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
5622 if b
= TRIGGER_EFFECT_LLIQUID
then
5623 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
5624 if b
= TRIGGER_EFFECT_DLIQUID
then
5625 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
5626 if b
= TRIGGER_EFFECT_BLOOD
then
5627 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
5628 if b
= TRIGGER_EFFECT_SPARK
then
5629 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
5630 if b
= TRIGGER_EFFECT_BUBBLE
then
5631 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
5634 bApplyProperty
.Click();
5637 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
5638 with vleObjectProperty
do
5639 begin // Выбор цвета эффекта:
5640 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
5641 if ColorDialog
.Execute
then
5643 Values
[Key
] := IntToStr(ColorDialog
.Color
);
5644 bApplyProperty
.Click();
5647 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
5648 begin // Смена текстуры:
5649 vleObjectProperty
.Values
[Key
] := SelectedTexture();
5650 bApplyProperty
.Click();
5654 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
5656 FileName
, Section
, Res
: String;
5658 if OpenedMap
= '' then
5660 aSaveMapAsExecute(nil);
5664 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
5666 SaveMap(FileName
+':\'+Res
);
5669 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
5671 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
5673 if OpenDialog
.Execute() then
5675 if (Pos('.ini', LowerCase(ExtractFileName(OpenDialog
.FileName
))) > 0) then
5679 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
5680 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
5681 pLoadProgress
.Show();
5686 LoadMapOld(OpenDialog
.FileName
);
5688 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(OpenDialog
.FileName
)]);
5690 pLoadProgress
.Hide();
5691 MainForm
.FormResize(Self
);
5693 else // Карты из WAD:
5695 OpenMap(OpenDialog
.FileName
, '');
5698 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
5702 procedure TMainForm
.FormActivate(Sender
: TObject
);
5707 MainForm
.ActiveControl
:= RenderPanel
;
5710 if gLanguage
= '' then
5712 lang
:= SelectLanguageForm
.ShowModal();
5714 1: gLanguage
:= LANGUAGE_ENGLISH
;
5715 else gLanguage
:= LANGUAGE_RUSSIAN
;
5718 config
:= TConfig
.CreateFile(EditorDir
+'\Editor.cfg');
5719 config
.WriteStr('Editor', 'Language', gLanguage
);
5720 config
.SaveFile(EditorDir
+'\Editor.cfg');
5724 //e_WriteLog('Read language file', MSG_NOTIFY);
5725 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
5726 g_Language_Set(gLanguage
);
5729 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
5737 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
5739 if not OpenDialog
.Execute() then
5742 WAD
:= TWADEditor_1
.Create();
5744 if not WAD
.ReadFile(OpenDialog
.FileName
) then
5752 MapList
:= WAD
.GetResourcesList('');
5754 SelectMapForm
.lbMapList
.Items
.Clear();
5756 if MapList
<> nil then
5757 for a
:= 0 to High(MapList
) do
5758 SelectMapForm
.lbMapList
.Items
.Add(MapList
[a
]);
5760 if (SelectMapForm
.ShowModal() = mrOK
) then
5762 str
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5764 CopyMemory(@MapName
[0], @str
[1], Min(16, Length(str
)));
5766 if MessageBox(0, PChar(Format(_lc
[I_MSG_DELETE_MAP_PROMT
],
5767 [MapName
, OpenDialog
.FileName
])),
5768 PChar(_lc
[I_MSG_DELETE_MAP
]),
5769 MB_ICONQUESTION
or MB_YESNO
or
5770 MB_TASKMODAL
or MB_DEFBUTTON2
) <> mrYes
then
5773 WAD
.RemoveResource('', MapName
);
5775 MessageBox(0, PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
],
5777 PChar(_lc
[I_MSG_MAP_DELETED
]),
5778 MB_ICONINFORMATION
or MB_OK
or
5779 MB_TASKMODAL
or MB_DEFBUTTON1
);
5781 WAD
.SaveTo(OpenDialog
.FileName
);
5783 // Удалили текущую карту - сохранять по старому ее нельзя:
5784 if OpenedMap
= (OpenDialog
.FileName
+':\'+MapName
) then
5788 MainForm
.Caption
:= FormCaption
;
5795 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
5796 var Key
: Word; Shift
: TShiftState
);
5798 if Key
= VK_RETURN
then
5799 bApplyProperty
.Click();
5802 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
5807 if (ID
= 0) and (MoveType
= 0) then
5809 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
5811 if (ID
> DWORD(High(gPanels
))) then
5816 if MoveType
= 0 then // to Back
5818 if gTriggers
<> nil then
5819 for a
:= 0 to High(gTriggers
) do
5820 with gTriggers
[a
] do
5822 if TriggerType
= TRIGGER_NONE
then
5825 if TexturePanel
= _id
then
5828 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
5832 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5833 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5834 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5835 if Data
.PanelID
= _id
then
5838 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
5842 if Data
.ShotPanelID
= _id
then
5843 Data
.ShotPanelID
:= 0
5845 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
5846 Inc(Data
.ShotPanelID
);
5850 tmp
:= gPanels
[_id
];
5852 for a
:= _id
downto 1 do
5853 gPanels
[a
] := gPanels
[a
-1];
5861 if gTriggers
<> nil then
5862 for a
:= 0 to High(gTriggers
) do
5863 with gTriggers
[a
] do
5865 if TriggerType
= TRIGGER_NONE
then
5868 if TexturePanel
= _id
then
5869 TexturePanel
:= High(gPanels
)
5871 if TexturePanel
> _id
then
5875 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5876 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5877 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5878 if Data
.PanelID
= _id
then
5879 Data
.PanelID
:= High(gPanels
)
5881 if Data
.PanelID
> _id
then
5885 if Data
.ShotPanelID
= _id
then
5886 Data
.ShotPanelID
:= High(gPanels
)
5888 if Data
.ShotPanelID
> _id
then
5889 Dec(Data
.ShotPanelID
);
5893 tmp
:= gPanels
[_id
];
5895 for a
:= _id
to High(gPanels
)-1 do
5896 gPanels
[a
] := gPanels
[a
+1];
5898 gPanels
[High(gPanels
)] := tmp
;
5900 ID
:= High(gPanels
);
5904 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
5908 if SelectedObjects
= nil then
5911 for a
:= 0 to High(SelectedObjects
) do
5912 with SelectedObjects
[a
] do
5913 if Live
and (ObjectType
= OBJECT_PANEL
) then
5915 SelectedObjects
[0] := SelectedObjects
[a
];
5916 SetLength(SelectedObjects
, 1);
5923 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
5927 if SelectedObjects
= nil then
5930 for a
:= 0 to High(SelectedObjects
) do
5931 with SelectedObjects
[a
] do
5932 if Live
and (ObjectType
= OBJECT_PANEL
) then
5934 SelectedObjects
[0] := SelectedObjects
[a
];
5935 SetLength(SelectedObjects
, 1);
5942 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
5946 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
5948 if not SaveDialog
.Execute() then
5951 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
5953 if SaveMapForm
.ShowModal() <> mrOK
then
5956 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
5957 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
5958 OpenedWAD
:= SaveDialog
.FileName
;
5960 idx
:= RecentFiles
.IndexOf(OpenedMap
);
5961 // Такая карта уже недавно открывалась:
5963 RecentFiles
.Delete(idx
);
5964 RecentFiles
.Insert(0, OpenedMap
);
5969 gMapInfo
.FileName
:= SaveDialog
.FileName
;
5970 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
5971 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
5974 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
5978 RemoveSelectFromObjects();
5980 case pcObjects
.ActivePageIndex
+1 of
5982 if gPanels
<> nil then
5983 for a
:= 0 to High(gPanels
) do
5984 if gPanels
[a
].PanelType
<> PANEL_NONE
then
5985 SelectObject(OBJECT_PANEL
, a
, True);
5987 if gItems
<> nil then
5988 for a
:= 0 to High(gItems
) do
5989 if gItems
[a
].ItemType
<> ITEM_NONE
then
5990 SelectObject(OBJECT_ITEM
, a
, True);
5992 if gMonsters
<> nil then
5993 for a
:= 0 to High(gMonsters
) do
5994 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
5995 SelectObject(OBJECT_MONSTER
, a
, True);
5997 if gAreas
<> nil then
5998 for a
:= 0 to High(gAreas
) do
5999 if gAreas
[a
].AreaType
<> AREA_NONE
then
6000 SelectObject(OBJECT_AREA
, a
, True);
6002 if gTriggers
<> nil then
6003 for a
:= 0 to High(gTriggers
) do
6004 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6005 SelectObject(OBJECT_TRIGGER
, a
, True);
6009 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6011 DotEnable
:= not DotEnable
;
6012 (Sender
as TToolButton
).Down
:= DotEnable
;
6015 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6020 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6022 if not PreviewMode
then
6024 Splitter2
.Visible
:= False;
6025 Splitter1
.Visible
:= False;
6026 StatusBar
.Visible
:= False;
6027 PanelObjs
.Visible
:= False;
6028 PanelProps
.Visible
:= False;
6029 MainToolBar
.Visible
:= False;
6030 sbHorizontal
.Visible
:= False;
6031 sbVertical
.Visible
:= False;
6035 StatusBar
.Visible
:= True;
6036 PanelObjs
.Visible
:= True;
6037 PanelProps
.Visible
:= True;
6038 Splitter2
.Visible
:= True;
6039 Splitter1
.Visible
:= True;
6040 MainToolBar
.Visible
:= True;
6041 sbHorizontal
.Visible
:= True;
6042 sbVertical
.Visible
:= True;
6045 PreviewMode
:= not PreviewMode
;
6046 (Sender
as TMenuItem
).Checked
:= PreviewMode
;
6049 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6051 SwitchLayer(LAYER_BACK
);
6054 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6056 SwitchLayer(LAYER_WALLS
);
6059 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6061 SwitchLayer(LAYER_FOREGROUND
);
6064 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6066 SwitchLayer(LAYER_STEPS
);
6069 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6071 SwitchLayer(LAYER_WATER
);
6074 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6076 SwitchLayer(LAYER_ITEMS
);
6079 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6081 SwitchLayer(LAYER_MONSTERS
);
6084 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6086 SwitchLayer(LAYER_AREAS
);
6089 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6091 SwitchLayer(LAYER_TRIGGERS
);
6094 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6100 for a
:= 0 to High(LayerEnabled
) do
6101 b
:= b
and LayerEnabled
[a
];
6105 ShowLayer(LAYER_BACK
, b
);
6106 ShowLayer(LAYER_WALLS
, b
);
6107 ShowLayer(LAYER_FOREGROUND
, b
);
6108 ShowLayer(LAYER_STEPS
, b
);
6109 ShowLayer(LAYER_WATER
, b
);
6110 ShowLayer(LAYER_ITEMS
, b
);
6111 ShowLayer(LAYER_MONSTERS
, b
);
6112 ShowLayer(LAYER_AREAS
, b
);
6113 ShowLayer(LAYER_TRIGGERS
, b
);
6116 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6121 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6123 if DotStep
= DotStepOne
then
6124 DotStep
:= DotStepTwo
6126 DotStep
:= DotStepOne
;
6128 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6129 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6132 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6137 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6139 SnapToGrid
:= not SnapToGrid
;
6141 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6142 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6144 miSnapToGrid
.Checked
:= SnapToGrid
;
6147 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6149 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6150 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6152 pcObjects
.ActivePageIndex
:= 0;
6155 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6157 SaveMiniMapForm
.ShowModal();
6160 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6162 lbTextureList
.ItemIndex
:= -1;
6163 lTextureWidth
.Caption
:= '';
6164 lTextureHeight
.Caption
:= '';
6167 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6169 PackMapForm
.ShowModal();
6172 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6174 MapTestForm
.ShowModal();
6177 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6179 cmd
, mapWAD
, mapToRun
: String;
6184 // Сохраняем временную карту:
6187 mapWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps\temp%.4d.wad', [time
]);
6189 until not FileExists(mapWAD
);
6190 mapToRun
:= mapWAD
+ ':\' + TEST_MAP_NAME
;
6193 mapToRun
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps\', mapToRun
);
6197 if TestOptionsTwoPlayers
then
6199 if TestOptionsTeamDamage
then
6201 if TestOptionsAllowExit
then
6203 if TestOptionsWeaponStay
then
6205 if TestOptionsMonstersDM
then
6208 // Составляем командную строку:
6209 cmd
:= ' -map "' + mapToRun
+ '"';
6210 cmd
:= cmd
+ ' -gm ' + TestGameMode
;
6211 cmd
:= cmd
+ ' -limt ' + TestLimTime
;
6212 cmd
:= cmd
+ ' -lims ' + TestLimScore
;
6213 cmd
:= cmd
+ ' -opt ' + IntToStr(opt
);
6216 cmd
:= cmd
+ ' --close';
6218 cmd
:= cmd
+ ' --debug';
6219 cmd
:= cmd
+ ' --tempdelete';
6222 Application
.Minimize();
6223 if ExecuteProcess(TestD2dExe
, cmd
) < 0 then
6225 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
or FORMAT_MESSAGE_FROM_SYSTEM
,
6226 nil, GetLastError(), LANG_SYSTEM_DEFAULT
,
6228 MessageBox(0, lpMsgBuf
,
6229 PChar(_lc
[I_MSG_EXEC_ERROR
]),
6230 MB_OK
or MB_ICONERROR
);
6233 SysUtils
.DeleteFile(mapWAD
);
6234 Application
.Restore();
6237 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6238 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6240 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
6243 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6244 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6246 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
6249 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6251 if OpenedWAD
<> '' then
6253 OpenMap(OpenedWAD
, '');
6257 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6261 RemoveSelectFromObjects();
6263 if gPanels
<> nil then
6264 for a
:= 0 to High(gPanels
) do
6265 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6266 SelectObject(OBJECT_PANEL
, a
, True);
6268 if gItems
<> nil then
6269 for a
:= 0 to High(gItems
) do
6270 if gItems
[a
].ItemType
<> ITEM_NONE
then
6271 SelectObject(OBJECT_ITEM
, a
, True);
6273 if gMonsters
<> nil then
6274 for a
:= 0 to High(gMonsters
) do
6275 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6276 SelectObject(OBJECT_MONSTER
, a
, True);
6278 if gAreas
<> nil then
6279 for a
:= 0 to High(gAreas
) do
6280 if gAreas
[a
].AreaType
<> AREA_NONE
then
6281 SelectObject(OBJECT_AREA
, a
, True);
6283 if gTriggers
<> nil then
6284 for a
:= 0 to High(gTriggers
) do
6285 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6286 SelectObject(OBJECT_TRIGGER
, a
, True);
6289 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6290 var NewSize
: Integer; var Accept
: Boolean);
6292 Accept
:= (NewSize
> 140);
6295 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6296 var NewSize
: Integer; var Accept
: Boolean);
6298 Accept
:= (NewSize
> 110);
6301 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6303 EditingProperties
:= True;
6306 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6308 EditingProperties
:= False;
6311 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word;
6312 Shift
: TShiftState
);
6314 // Объекты передвигались:
6315 if MainForm
.ActiveControl
= RenderPanel
then
6317 if (Key
= VK_NUMPAD4
) or
6318 (Key
= VK_NUMPAD6
) or
6319 (Key
= VK_NUMPAD8
) or
6320 (Key
= VK_NUMPAD5
) or
6321 (Key
= Ord('V')) then
6327 procedure TMainForm.lbTextureListDrawItem(Control: TWinControl; Index: Integer;
6328 Rect: TRect; State: LCLType.TOwnerDrawState);
6330 with Control as TListBox do
6332 if LCLType.odSelected in State then
6334 Canvas.Brush.Color := clHighlight;
6335 Canvas.Font.Color := clHighlightText;
6337 if (Items <> nil) and (Index >= 0) then
6338 if slInvalidTextures.IndexOf(Items[Index]) > -1 then
6340 Canvas.Brush.Color := clRed;
6341 Canvas.Font.Color := clWhite;
6343 Canvas.FillRect(Rect);
6344 Canvas.TextRect(Rect, Rect.Left, Rect.Top, Items[Index]);