3 {$INCLUDE ../shared/a_modes.inc}
8 LCLIntf
, LCLType
, SysUtils
, Variants
, Classes
, Graphics
,
9 Controls
, Forms
, Dialogs
, StdCtrls
, Buttons
,
10 ComCtrls
, ValEdit
, Types
, Menus
, ExtCtrls
,
11 CheckLst
, Grids
, OpenGLContext
, Utils
, UTF8Process
;
17 TMainForm
= class(TForm
)
22 miMenuFile
: TMenuItem
;
26 miSaveMapAs
: TMenuItem
;
27 miOpenWadMap
: TMenuItem
;
29 miReopenMap
: TMenuItem
;
30 miSaveMiniMap
: TMenuItem
;
31 miDeleteMap
: TMenuItem
;
36 miMenuEdit
: TMenuItem
;
43 miSelectAll
: TMenuItem
;
48 miMenuTools
: TMenuItem
;
49 miSnapToGrid
: TMenuItem
;
51 miSwitchGrid
: TMenuItem
;
52 miShowEdges
: TMenuItem
;
64 miMenuService
: TMenuItem
;
65 miCheckMap
: TMenuItem
;
66 miOptimmization
: TMenuItem
;
67 miMapPreview
: TMenuItem
;
70 miMenuSettings
: TMenuItem
;
71 miMapOptions
: TMenuItem
;
75 miMapTestSettings
: TMenuItem
;
77 miMenuHelp
: TMenuItem
;
79 // Скрытый пункт меню для Ctrl+Tab:
83 // Панель инструментов:
84 MainToolBar
: TToolBar
;
86 pLoadProgress
: TPanel
;
87 RenderPanel
: TOpenGLControl
;
88 tbNewMap
: TToolButton
;
89 tbOpenMap
: TToolButton
;
90 tbSaveMap
: TToolButton
;
91 tbOpenWadMap
: TToolButton
;
93 tbShowMap
: TToolButton
;
97 tbGridOn
: TToolButton
;
100 tbTestMap
: TToolButton
;
101 // Всплывающее меню для кнопки слоев:
103 miLayerP1
: TMenuItem
;
104 miLayerP2
: TMenuItem
;
105 miLayerP3
: TMenuItem
;
106 miLayerP4
: TMenuItem
;
107 miLayerP5
: TMenuItem
;
108 miLayerP6
: TMenuItem
;
109 miLayerP7
: TMenuItem
;
110 miLayerP8
: TMenuItem
;
111 miLayerP9
: TMenuItem
;
112 // Всплывающее меню для кнопки теста карты:
113 pmMapTest
: TPopupMenu
;
114 miMapTestPMSet
: TMenuItem
;
119 sbHorizontal
: TScrollBar
;
120 sbVertical
: TScrollBar
;
124 // Панель применения свойств:
125 PanelPropApply
: TPanel
;
126 bApplyProperty
: TButton
;
127 // Редактор свойств объектов:
128 vleObjectProperty
: TValueListEditor
;
130 // Панель объектов - вкладки:
132 pcObjects
: TPageControl
;
135 lbTextureList
: TListBox
;
136 // Панель настройки текстур:
137 PanelTextures
: TPanel
;
139 lTextureWidth
: TLabel
;
141 lTextureHeight
: TLabel
;
142 cbPreview
: TCheckBox
;
143 bbAddTexture
: TBitBtn
;
144 bbRemoveTexture
: TBitBtn
;
145 bClearTexture
: TButton
;
146 // Панель типов панелей:
147 PanelPanelType
: TPanel
;
148 lbPanelType
: TListBox
;
149 // Вкладка "Предметы":
151 lbItemList
: TListBox
;
154 // Вкладка "Монстры":
155 tsMonsters
: TTabSheet
;
156 lbMonsterList
: TListBox
;
157 rbMonsterLeft
: TRadioButton
;
158 rbMonsterRight
: TRadioButton
;
159 // Вкладка "Области":
161 lbAreasList
: TListBox
;
162 rbAreaLeft
: TRadioButton
;
163 rbAreaRight
: TRadioButton
;
164 // Вкладка "Триггеры":
165 tsTriggers
: TTabSheet
;
166 lbTriggersList
: TListBox
;
167 clbActivationType
: TCheckListBox
;
168 clbKeys
: TCheckListBox
;
171 Splitter1
: TSplitter
;
172 Splitter2
: TSplitter
;
173 StatusBar
: TStatusBar
;
175 // Специальные объекты:
176 ImageList
: TImageList
;
177 ilToolbar
: TImageList
;
178 OpenDialog
: TOpenDialog
;
179 SaveDialog
: TSaveDialog
;
180 selectall1
: TMenuItem
;
181 ColorDialog
: TColorDialog
;
183 procedure aAboutExecute(Sender
: TObject
);
184 procedure aCheckMapExecute(Sender
: TObject
);
185 procedure aMoveToFore(Sender
: TObject
);
186 procedure aMoveToBack(Sender
: TObject
);
187 procedure aCopyObjectExecute(Sender
: TObject
);
188 procedure aCutObjectExecute(Sender
: TObject
);
189 procedure aEditorOptionsExecute(Sender
: TObject
);
190 procedure aExitExecute(Sender
: TObject
);
191 procedure aMapOptionsExecute(Sender
: TObject
);
192 procedure aNewMapExecute(Sender
: TObject
);
193 procedure aOpenMapExecute(Sender
: TObject
);
194 procedure aOptimizeExecute(Sender
: TObject
);
195 procedure aPasteObjectExecute(Sender
: TObject
);
196 procedure aSelectAllExecute(Sender
: TObject
);
197 procedure aSaveMapExecute(Sender
: TObject
);
198 procedure aSaveMapAsExecute(Sender
: TObject
);
199 procedure aUndoExecute(Sender
: TObject
);
200 procedure aDeleteMap(Sender
: TObject
);
201 procedure bApplyPropertyClick(Sender
: TObject
);
202 procedure bbAddTextureClick(Sender
: TObject
);
203 procedure bbRemoveTextureClick(Sender
: TObject
);
204 procedure FormActivate(Sender
: TObject
);
205 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
206 procedure FormCreate(Sender
: TObject
);
207 procedure FormDestroy(Sender
: TObject
);
208 procedure FormDropFiles(Sender
: TObject
; const FileNames
: array of String);
209 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
210 procedure FormResize(Sender
: TObject
);
211 procedure lbTextureListClick(Sender
: TObject
);
212 procedure lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
213 ARect
: TRect
; State
: TOwnerDrawState
);
214 procedure miReopenMapClick(Sender
: TObject
);
215 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
216 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
217 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
218 procedure RenderPanelPaint(Sender
: TObject
);
219 procedure RenderPanelResize(Sender
: TObject
);
220 procedure Splitter1Moved(Sender
: TObject
);
221 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
222 procedure vleObjectPropertyApply(Sender
: TObject
);
223 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
224 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
226 procedure tbGridOnClick(Sender
: TObject
);
227 procedure miMapPreviewClick(Sender
: TObject
);
228 procedure miLayer1Click(Sender
: TObject
);
229 procedure miLayer2Click(Sender
: TObject
);
230 procedure miLayer3Click(Sender
: TObject
);
231 procedure miLayer4Click(Sender
: TObject
);
232 procedure miLayer5Click(Sender
: TObject
);
233 procedure miLayer6Click(Sender
: TObject
);
234 procedure miLayer7Click(Sender
: TObject
);
235 procedure miLayer8Click(Sender
: TObject
);
236 procedure miLayer9Click(Sender
: TObject
);
237 procedure tbShowClick(Sender
: TObject
);
238 procedure miSnapToGridClick(Sender
: TObject
);
239 procedure miMiniMapClick(Sender
: TObject
);
240 procedure miSwitchGridClick(Sender
: TObject
);
241 procedure miShowEdgesClick(Sender
: TObject
);
242 procedure minexttabClick(Sender
: TObject
);
243 procedure miSaveMiniMapClick(Sender
: TObject
);
244 procedure bClearTextureClick(Sender
: TObject
);
245 procedure miPackMapClick(Sender
: TObject
);
246 procedure aRecentFileExecute(Sender
: TObject
);
247 procedure miMapTestSettingsClick(Sender
: TObject
);
248 procedure miTestMapClick(Sender
: TObject
);
249 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
250 var ScrollPos
: Integer);
251 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
252 var ScrollPos
: Integer);
253 procedure miOpenWadMapClick(Sender
: TObject
);
254 procedure selectall1Click(Sender
: TObject
);
255 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
256 var Accept
: Boolean);
257 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
258 var Accept
: Boolean);
259 procedure vleObjectPropertyEnter(Sender
: TObject
);
260 procedure vleObjectPropertyExit(Sender
: TObject
);
261 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
265 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
267 procedure RefreshRecentMenu();
268 procedure OpenMapFile(FileName
: String);
269 function RenderMousePos(): TPoint
;
270 procedure RecountSelectedObjects();
276 LAYER_FOREGROUND
= 2;
284 TEST_MAP_NAME
= '$$$_TEST_$$$';
285 LANGUAGE_FILE_NAME
= '_Editor.txt';
295 DotStepOne
, DotStepTwo
: Word;
297 DrawTexturePanel
: Boolean;
298 DrawPanelSize
: Boolean;
300 PreviewColor
: TColor
;
301 UseCheckerboard
: Boolean;
303 RecentCount
: Integer;
304 RecentFiles
: TStringList
;
305 slInvalidTextures
: TStringList
;
307 TestGameMode
: String;
309 TestLimScore
: String;
310 TestOptionsTwoPlayers
: Boolean;
311 TestOptionsTeamDamage
: Boolean;
312 TestOptionsAllowExit
: Boolean;
313 TestOptionsWeaponStay
: Boolean;
314 TestOptionsMonstersDM
: Boolean;
315 TestD2dExe
, TestD2DArgs
: String;
316 TestMapOnce
: Boolean;
318 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
319 (True, True, True, True, True, True, True, True, True);
320 ContourEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
321 (False, False, False, False, False, False, False, False, False);
322 PreviewMode
: Byte = 0;
328 procedure OpenMap(FileName
: String; mapN
: String);
329 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
330 procedure RemoveSelectFromObjects();
331 procedure ChangeShownProperty(Name
: String; NewValue
: String);
336 f_options
, e_graphics
, e_log
, GL
, Math
,
337 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
338 f_mapcheck
, f_addresource_texture
, g_textures
,
339 f_activationtype
, f_keys
, wadreader
, fileutil
,
340 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, MAPDEF
,
341 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
342 f_addresource_sound
, f_maptest
, f_choosetype
,
343 g_language
, f_selectlang
, ClipBrd
, g_resources
, g_options
;
346 UNDO_DELETE_PANEL
= 1;
347 UNDO_DELETE_ITEM
= 2;
348 UNDO_DELETE_AREA
= 3;
349 UNDO_DELETE_MONSTER
= 4;
350 UNDO_DELETE_TRIGGER
= 5;
354 UNDO_ADD_MONSTER
= 9;
355 UNDO_ADD_TRIGGER
= 10;
356 UNDO_MOVE_PANEL
= 11;
359 UNDO_MOVE_MONSTER
= 14;
360 UNDO_MOVE_TRIGGER
= 15;
361 UNDO_RESIZE_PANEL
= 16;
362 UNDO_RESIZE_TRIGGER
= 17;
364 MOUSEACTION_NONE
= 0;
365 MOUSEACTION_DRAWPANEL
= 1;
366 MOUSEACTION_DRAWTRIGGER
= 2;
367 MOUSEACTION_MOVEOBJ
= 3;
368 MOUSEACTION_RESIZE
= 4;
369 MOUSEACTION_MOVEMAP
= 5;
370 MOUSEACTION_DRAWPRESS
= 6;
371 MOUSEACTION_NOACTION
= 7;
374 RESIZETYPE_VERTICAL
= 1;
375 RESIZETYPE_HORIZONTAL
= 2;
384 SELECTFLAG_TELEPORT
= 1;
386 SELECTFLAG_TEXTURE
= 3;
388 SELECTFLAG_MONSTER
= 5;
389 SELECTFLAG_SPAWNPOINT
= 6;
390 SELECTFLAG_SHOTPANEL
= 7;
391 SELECTFLAG_SELECTED
= 8;
393 RECENT_FILES_MENU_START
= 12;
395 CLIPBOARD_SIG
= 'DF:ED';
401 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
402 UNDO_DELETE_ITEM
: (Item
: TItem
);
403 UNDO_DELETE_AREA
: (Area
: TArea
);
404 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
405 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
410 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
415 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
417 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
424 OBJECT_PANEL
: (Panel
: ^TPanel
);
425 OBJECT_ITEM
: (Item
: TItem
);
426 OBJECT_AREA
: (Area
: TArea
);
427 OBJECT_MONSTER
: (Monster
: TMonster
);
428 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
431 TCopyRecArray
= Array of TCopyRec
;
435 gDataLoaded
: Boolean = False;
436 ShowMap
: Boolean = False;
437 DrawRect
: PRect
= nil;
438 SnapToGrid
: Boolean = True;
440 MousePos
: Types
.TPoint
;
441 LastMovePoint
: Types
.TPoint
;
445 MouseLDownPos
: Types
.TPoint
;
446 MouseRDownPos
: Types
.TPoint
;
447 MouseMDownPos
: Types
.TPoint
;
449 SelectFlag
: Byte = SELECTFLAG_NONE
;
450 MouseAction
: Byte = MOUSEACTION_NONE
;
451 ResizeType
: Byte = RESIZETYPE_NONE
;
452 ResizeDirection
: Byte = RESIZEDIR_NONE
;
454 DrawPressRect
: Boolean = False;
455 EditingProperties
: Boolean = False;
457 UndoBuffer
: Array of Array of TUndoRec
= nil;
462 //----------------------------------------
463 //Далее идут вспомогательные процедуры
464 //----------------------------------------
466 function NameToBool(Name
: String): Boolean;
468 if Name
= BoolNames
[True] then
474 function NameToDir(Name
: String): TDirection
;
476 if Name
= DirNames
[D_LEFT
] then
482 function NameToDirAdv(Name
: String): Byte;
484 if Name
= DirNamesAdv
[1] then
487 if Name
= DirNamesAdv
[2] then
490 if Name
= DirNamesAdv
[3] then
496 function ActivateToStr(ActivateType
: Byte): String;
500 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
501 Result
:= Result
+ '+PC';
502 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
503 Result
:= Result
+ '+MC';
504 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
505 Result
:= Result
+ '+PP';
506 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
507 Result
:= Result
+ '+MP';
508 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
509 Result
:= Result
+ '+SH';
510 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
511 Result
:= Result
+ '+NM';
513 if (Result
<> '') and (Result
[1] = '+') then
514 Delete(Result
, 1, 1);
517 function StrToActivate(Str
: String): Byte;
521 if Pos('PC', Str
) > 0 then
522 Result
:= ACTIVATE_PLAYERCOLLIDE
;
523 if Pos('MC', Str
) > 0 then
524 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
525 if Pos('PP', Str
) > 0 then
526 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
527 if Pos('MP', Str
) > 0 then
528 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
529 if Pos('SH', Str
) > 0 then
530 Result
:= Result
or ACTIVATE_SHOT
;
531 if Pos('NM', Str
) > 0 then
532 Result
:= Result
or ACTIVATE_NOMONSTER
;
535 function KeyToStr(Key
: Byte): String;
539 if ByteBool(KEY_RED
and Key
) then
540 Result
:= Result
+ '+RK';
541 if ByteBool(KEY_GREEN
and Key
) then
542 Result
:= Result
+ '+GK';
543 if ByteBool(KEY_BLUE
and Key
) then
544 Result
:= Result
+ '+BK';
545 if ByteBool(KEY_REDTEAM
and Key
) then
546 Result
:= Result
+ '+RT';
547 if ByteBool(KEY_BLUETEAM
and Key
) then
548 Result
:= Result
+ '+BT';
550 if (Result
<> '') and (Result
[1] = '+') then
551 Delete(Result
, 1, 1);
554 function StrToKey(Str
: String): Byte;
558 if Pos('RK', Str
) > 0 then
560 if Pos('GK', Str
) > 0 then
561 Result
:= Result
or KEY_GREEN
;
562 if Pos('BK', Str
) > 0 then
563 Result
:= Result
or KEY_BLUE
;
564 if Pos('RT', Str
) > 0 then
565 Result
:= Result
or KEY_REDTEAM
;
566 if Pos('BT', Str
) > 0 then
567 Result
:= Result
or KEY_BLUETEAM
;
570 function EffectToStr(Effect
: Byte): String;
572 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
573 Result
:= EffectNames
[Effect
]
575 Result
:= EffectNames
[EFFECT_NONE
];
578 function StrToEffect(Str
: String): Byte;
582 Result
:= EFFECT_NONE
;
583 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
584 if EffectNames
[i
] = Str
then
591 function MonsterToStr(MonType
: Byte): String;
593 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
594 Result
:= MonsterNames
[MonType
]
596 Result
:= MonsterNames
[MONSTER_ZOMBY
];
599 function StrToMonster(Str
: String): Byte;
603 Result
:= MONSTER_ZOMBY
;
604 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
605 if MonsterNames
[i
] = Str
then
612 function ItemToStr(ItemType
: Byte): String;
614 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
615 Result
:= ItemNames
[ItemType
]
617 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
620 function StrToItem(Str
: String): Byte;
624 Result
:= ITEM_AMMO_BULLETS
;
625 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
626 if ItemNames
[i
] = Str
then
633 function ShotToStr(ShotType
: Byte): String;
635 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
636 Result
:= ShotNames
[ShotType
]
638 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
641 function StrToShot(Str
: String): Byte;
645 Result
:= TRIGGER_SHOT_PISTOL
;
646 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
647 if ShotNames
[i
] = Str
then
654 function SelectedObjectCount(): Word;
660 if SelectedObjects
= nil then
663 for a
:= 0 to High(SelectedObjects
) do
664 if SelectedObjects
[a
].Live
then
665 Result
:= Result
+ 1;
668 function GetFirstSelected(): Integer;
674 if SelectedObjects
= nil then
677 for a
:= 0 to High(SelectedObjects
) do
678 if SelectedObjects
[a
].Live
then
685 function Normalize16(x
: Integer): Integer;
687 Result
:= (x
div 16) * 16;
690 procedure MoveMap(X
, Y
: Integer);
692 rx
, ry
, ScaleSz
: Integer;
694 with MainForm
.RenderPanel
do
696 ScaleSz
:= 16 div Scale
;
697 // Размер видимой части карты:
698 rx
:= Min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
699 ry
:= Min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
700 // Место клика на мини-карте:
701 MapOffset
.X
:= X
- (Width
- Max(gMapInfo
.Width
div ScaleSz
, 1) - 1);
702 MapOffset
.Y
:= Y
- 1;
703 // Это же место на "большой" карте:
704 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
705 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
706 // Левый верхний угол новой видимой части карты:
707 MapOffset
.X
:= MapOffset
.X
- rx
;
708 MapOffset
.Y
:= MapOffset
.Y
- ry
;
710 MapOffset
.X
:= EnsureRange(MapOffset
.X
, MainForm
.sbHorizontal
.Min
, MainForm
.sbHorizontal
.Max
);
711 MapOffset
.Y
:= EnsureRange(MapOffset
.Y
, MainForm
.sbVertical
.Min
, MainForm
.sbVertical
.Max
);
713 // MapOffset.X := Normalize16(MapOffset.X);
714 // MapOffset.Y := Normalize16(MapOffset.Y);
717 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
718 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
720 MapOffset
.X
:= -MapOffset
.X
;
721 MapOffset
.Y
:= -MapOffset
.Y
;
726 function IsTexturedPanel(PanelType
: Word): Boolean;
728 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
729 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
730 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
733 procedure FillProperty();
738 MainForm
.vleObjectProperty
.Strings
.Clear();
739 MainForm
.RecountSelectedObjects();
741 // Отображаем свойства если выделен только один объект:
742 if SelectedObjectCount() <> 1 then
745 _id
:= GetFirstSelected();
746 if not SelectedObjects
[_id
].Live
then
749 with MainForm
.vleObjectProperty
do
750 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
752 EditStyle
:= esSimple
;
756 case SelectedObjects
[0].ObjectType
of
759 with MainForm
.vleObjectProperty
,
760 gPanels
[SelectedObjects
[_id
].ID
] do
762 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
764 EditStyle
:= esSimple
;
768 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
770 EditStyle
:= esSimple
;
774 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
776 EditStyle
:= esSimple
;
780 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
782 EditStyle
:= esSimple
;
786 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
788 EditStyle
:= esEllipsis
;
792 if IsTexturedPanel(PanelType
) then
793 begin // Может быть текстура
794 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
796 EditStyle
:= esEllipsis
;
800 if TextureName
<> '' then
801 begin // Есть текстура
802 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
804 EditStyle
:= esSimple
;
808 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
810 EditStyle
:= esPickList
;
820 with MainForm
.vleObjectProperty
,
821 gItems
[SelectedObjects
[_id
].ID
] do
823 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
825 EditStyle
:= esSimple
;
829 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
831 EditStyle
:= esSimple
;
835 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
837 EditStyle
:= esPickList
;
841 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
843 EditStyle
:= esPickList
;
851 with MainForm
.vleObjectProperty
,
852 gMonsters
[SelectedObjects
[_id
].ID
] do
854 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
856 EditStyle
:= esSimple
;
860 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
862 EditStyle
:= esSimple
;
866 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
868 EditStyle
:= esPickList
;
876 with MainForm
.vleObjectProperty
,
877 gAreas
[SelectedObjects
[_id
].ID
] do
879 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
881 EditStyle
:= esSimple
;
885 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
887 EditStyle
:= esSimple
;
891 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
893 EditStyle
:= esPickList
;
901 with MainForm
.vleObjectProperty
,
902 gTriggers
[SelectedObjects
[_id
].ID
] do
904 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
906 EditStyle
:= esSimple
;
910 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
912 EditStyle
:= esSimple
;
916 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
918 EditStyle
:= esSimple
;
922 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
924 EditStyle
:= esSimple
;
928 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
930 EditStyle
:= esSimple
;
934 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
936 EditStyle
:= esPickList
;
940 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
942 EditStyle
:= esEllipsis
;
946 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
948 EditStyle
:= esEllipsis
;
952 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
954 EditStyle
:= esEllipsis
;
961 str
:= win2utf(Data
.MapName
);
962 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], str
, True)] do
964 EditStyle
:= esEllipsis
;
971 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
973 EditStyle
:= esEllipsis
;
977 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
979 EditStyle
:= esPickList
;
983 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
985 EditStyle
:= esPickList
;
989 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
991 EditStyle
:= esPickList
;
996 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
997 TRIGGER_DOOR
, TRIGGER_DOOR5
:
999 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
1001 EditStyle
:= esEllipsis
;
1005 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1007 EditStyle
:= esPickList
;
1011 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1013 EditStyle
:= esPickList
;
1018 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1020 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1022 EditStyle
:= esEllipsis
;
1026 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1028 EditStyle
:= esPickList
;
1032 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1034 EditStyle
:= esPickList
;
1039 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1042 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1043 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1045 EditStyle
:= esEllipsis
;
1049 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1051 EditStyle
:= esSimple
;
1055 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1057 EditStyle
:= esSimple
;
1061 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1063 EditStyle
:= esEllipsis
;
1067 if TriggerType
= TRIGGER_PRESS
then
1068 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1070 EditStyle
:= esPickList
;
1078 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1080 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1082 EditStyle
:= esEllipsis
;
1086 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1088 EditStyle
:= esPickList
;
1092 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1094 EditStyle
:= esPickList
;
1101 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1103 EditStyle
:= esPickList
;
1107 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1109 EditStyle
:= esPickList
;
1116 str
:= win2utf(Data
.SoundName
);
1117 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], str
, True)] do
1119 EditStyle
:= esEllipsis
;
1123 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1125 EditStyle
:= esSimple
;
1129 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1131 EditStyle
:= esSimple
;
1135 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1137 EditStyle
:= esSimple
;
1141 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1143 EditStyle
:= esPickList
;
1147 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1149 EditStyle
:= esPickList
;
1154 TRIGGER_SPAWNMONSTER
:
1156 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1158 EditStyle
:= esEllipsis
;
1162 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1163 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1165 EditStyle
:= esEllipsis
;
1169 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1171 EditStyle
:= esPickList
;
1175 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1177 EditStyle
:= esSimple
;
1181 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1183 EditStyle
:= esPickList
;
1187 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1189 EditStyle
:= esSimple
;
1193 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1195 EditStyle
:= esEllipsis
;
1199 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1201 EditStyle
:= esSimple
;
1205 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1207 EditStyle
:= esSimple
;
1211 case Data
.MonBehav
of
1212 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1213 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1214 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1215 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1216 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1217 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1219 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1221 EditStyle
:= esPickList
;
1228 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1230 EditStyle
:= esEllipsis
;
1234 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1235 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1237 EditStyle
:= esEllipsis
;
1241 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1243 EditStyle
:= esPickList
;
1247 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1249 EditStyle
:= esPickList
;
1253 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1255 EditStyle
:= esSimple
;
1259 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1261 EditStyle
:= esEllipsis
;
1265 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1267 EditStyle
:= esSimple
;
1271 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1273 EditStyle
:= esSimple
;
1280 str
:= win2utf(Data
.MusicName
);
1281 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], str
, True)] do
1283 EditStyle
:= esEllipsis
;
1287 if Data
.MusicAction
= 1 then
1288 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1290 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1292 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1294 EditStyle
:= esPickList
;
1301 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1303 EditStyle
:= esSimple
;
1306 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1308 EditStyle
:= esSimple
;
1311 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1313 EditStyle
:= esPickList
;
1320 case Data
.ScoreAction
of
1321 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1322 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1323 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1324 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1326 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1328 EditStyle
:= esPickList
;
1331 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1333 EditStyle
:= esSimple
;
1336 case Data
.ScoreTeam
of
1337 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1338 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1339 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1340 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1342 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1344 EditStyle
:= esPickList
;
1347 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1349 EditStyle
:= esPickList
;
1352 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1354 EditStyle
:= esPickList
;
1361 case Data
.MessageKind
of
1362 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1363 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1365 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1367 EditStyle
:= esPickList
;
1370 case Data
.MessageSendTo
of
1371 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1372 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1373 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1374 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1375 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1376 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1378 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1380 EditStyle
:= esPickList
;
1383 str
:= win2utf(Data
.MessageText
);
1384 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], str
, True)] do
1386 EditStyle
:= esSimple
;
1389 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1391 EditStyle
:= esSimple
;
1398 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1400 EditStyle
:= esSimple
;
1403 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1405 EditStyle
:= esSimple
;
1408 case Data
.DamageKind
of
1409 3: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_3
];
1410 4: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_4
];
1411 5: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_5
];
1412 6: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_6
];
1413 7: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_7
];
1414 8: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_8
];
1415 else str
:= _lc
[I_PROP_TR_DAMAGE_KIND_0
];
1417 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_KIND
], str
, True)] do
1419 EditStyle
:= esPickList
;
1426 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1428 EditStyle
:= esSimple
;
1431 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1433 EditStyle
:= esSimple
;
1436 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1438 EditStyle
:= esPickList
;
1441 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1443 EditStyle
:= esPickList
;
1450 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1452 EditStyle
:= esEllipsis
;
1456 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1458 EditStyle
:= esPickList
;
1462 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1464 EditStyle
:= esEllipsis
;
1468 case Data
.ShotTarget
of
1469 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1470 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1471 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1472 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1473 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1474 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1475 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1477 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1479 EditStyle
:= esPickList
;
1483 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1485 EditStyle
:= esSimple
;
1489 case Data
.ShotAim
of
1490 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1491 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1492 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1493 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1495 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)] do
1497 EditStyle
:= esPickList
;
1501 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1502 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1504 EditStyle
:= esEllipsis
;
1508 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1510 EditStyle
:= esSimple
;
1514 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1516 EditStyle
:= esSimple
;
1520 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1522 EditStyle
:= esSimple
;
1526 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1528 EditStyle
:= esSimple
;
1532 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1534 EditStyle
:= esSimple
;
1541 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1543 EditStyle
:= esSimple
;
1547 if Data
.FXType
= 0 then
1548 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1550 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1551 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1553 EditStyle
:= esEllipsis
;
1558 if Data
.FXType
= 0 then
1559 case Data
.FXSubType
of
1560 TRIGGER_EFFECT_SLIQUID
:
1561 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1562 TRIGGER_EFFECT_LLIQUID
:
1563 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1564 TRIGGER_EFFECT_DLIQUID
:
1565 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1566 TRIGGER_EFFECT_BLOOD
:
1567 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1568 TRIGGER_EFFECT_SPARK
:
1569 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1570 TRIGGER_EFFECT_BUBBLE
:
1571 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1573 if Data
.FXType
= 1 then
1575 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1576 Data
.FXSubType
:= EFFECT_TELEPORT
;
1577 str
:= EffectToStr(Data
.FXSubType
);
1579 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1581 EditStyle
:= esEllipsis
;
1585 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1587 EditStyle
:= esEllipsis
;
1591 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1593 EditStyle
:= esPickList
;
1597 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1599 EditStyle
:= esSimple
;
1603 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1605 EditStyle
:= esSimple
;
1609 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1611 EditStyle
:= esSimple
;
1615 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1617 EditStyle
:= esSimple
;
1621 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1623 EditStyle
:= esSimple
;
1627 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1629 EditStyle
:= esSimple
;
1633 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1635 EditStyle
:= esSimple
;
1639 end; //case TriggerType
1641 end; // OBJECT_TRIGGER:
1645 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1649 if SelectedObjectCount() <> 1 then
1651 if not SelectedObjects
[GetFirstSelected()].Live
then
1654 // Есть ли такой ключ:
1655 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1657 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1661 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1670 // Уже выделен - убираем:
1671 if SelectedObjects
<> nil then
1672 for a
:= 0 to High(SelectedObjects
) do
1673 with SelectedObjects
[a
] do
1674 if Live
and (ID
= fID
) and
1675 (ObjectType
= fObjectType
) then
1684 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1686 with SelectedObjects
[High(SelectedObjects
)] do
1688 ObjectType
:= fObjectType
;
1695 SetLength(SelectedObjects
, 1);
1697 with SelectedObjects
[0] do
1699 ObjectType
:= fObjectType
;
1705 MainForm
.miCopy
.Enabled
:= True;
1706 MainForm
.miCut
.Enabled
:= True;
1708 if fObjectType
= OBJECT_PANEL
then
1710 MainForm
.miToFore
.Enabled
:= True;
1711 MainForm
.miToBack
.Enabled
:= True;
1715 procedure RemoveSelectFromObjects();
1717 SelectedObjects
:= nil;
1718 DrawPressRect
:= False;
1719 MouseLDown
:= False;
1720 MouseRDown
:= False;
1721 MouseAction
:= MOUSEACTION_NONE
;
1722 SelectFlag
:= SELECTFLAG_NONE
;
1723 ResizeType
:= RESIZETYPE_NONE
;
1724 ResizeDirection
:= RESIZEDIR_NONE
;
1726 MainForm
.vleObjectProperty
.Strings
.Clear();
1728 MainForm
.miCopy
.Enabled
:= False;
1729 MainForm
.miCut
.Enabled
:= False;
1730 MainForm
.miToFore
.Enabled
:= False;
1731 MainForm
.miToBack
.Enabled
:= False;
1734 procedure DeleteSelectedObjects();
1739 if SelectedObjects
= nil then
1745 for a
:= 0 to High(SelectedObjects
) do
1746 with SelectedObjects
[a
] do
1751 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1752 i
:= High(UndoBuffer
);
1756 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1757 ii
:= High(UndoBuffer
[i
]);
1762 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1763 New(UndoBuffer
[i
, ii
].Panel
);
1764 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1768 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1769 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1773 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1774 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1778 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1779 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1783 RemoveObject(ID
, ObjectType
);
1786 RemoveSelectFromObjects();
1788 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1789 MainForm
.RecountSelectedObjects();
1792 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1796 if (not Group
) or (Length(UndoBuffer
) = 0) then
1797 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1798 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1799 i
:= High(UndoBuffer
);
1800 ii
:= High(UndoBuffer
[i
]);
1804 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1806 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1808 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1810 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1812 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1815 UndoBuffer
[i
, ii
].AddID
:= ID
;
1817 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1820 procedure FullClear();
1822 RemoveSelectFromObjects();
1824 LoadSky(gMapInfo
.SkyName
);
1826 slInvalidTextures
.Clear();
1827 MapCheckForm
.lbErrorList
.Clear();
1828 MapCheckForm
.mErrorDescription
.Clear();
1830 MainForm
.miUndo
.Enabled
:= False;
1831 MainForm
.sbHorizontal
.Position
:= 0;
1832 MainForm
.sbVertical
.Position
:= 0;
1833 MainForm
.FormResize(nil);
1834 MainForm
.Caption
:= FormCaption
;
1839 procedure ErrorMessageBox(str
: String);
1841 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1842 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1845 function CheckProperty(): Boolean;
1851 _id
:= GetFirstSelected();
1853 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1854 with gPanels
[SelectedObjects
[_id
].ID
] do
1856 if TextureWidth
<> 0 then
1857 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1859 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1864 if TextureHeight
<> 0 then
1865 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1867 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1872 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1873 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1875 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1880 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1881 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1882 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1884 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1888 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1889 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1891 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1898 procedure SelectTexture(ID
: Integer);
1900 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1901 MainForm
.lbTextureListClick(nil);
1904 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1906 a
, FrameLen
: Integer;
1909 ResourceName
: String;
1910 FullResourceName
: String;
1911 SectionName
: String;
1913 Width
, Height
: Word;
1921 if aSection
= '..' then
1924 SectionName
:= aSection
;
1927 aWAD
:= _lc
[I_WAD_SPECIAL_MAP
];
1929 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1931 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1932 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1934 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1937 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1938 begin // Спец. текстуры
1940 ResourceName
:= aTex
;
1943 begin // Внешний WAD
1944 FileName
:= EditorDir
+'wads/'+aWAD
;
1945 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1950 // Есть ли уже такая текстура:
1951 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1952 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1955 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1960 // Название ресурса <= 64 символов:
1961 if Length(ResourceName
) > 64 then
1964 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1972 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1974 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1981 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1983 if IsAnim(FullResourceName
) then
1984 begin // Аним. текстура
1985 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
1987 if not g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
1989 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1991 else // Обычная текстура
1993 if not g_CreateTextureWAD(ResourceName
, FullResourceName
) then
1995 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1997 if (not ok
) and (slInvalidTextures
.IndexOf(ResourceName
) = -1) then
1999 slInvalidTextures
.Add(ResourceName
);
2002 if (a
> -1) and (not silent
) then
2009 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
2012 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
2013 Caption
:= FormCaption
2016 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
2018 if (sFile
<> '') and (sRes
<> '') then
2019 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
2021 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
2024 procedure OpenMap(FileName
: String; mapN
: String);
2029 SelectMapForm
.Caption
:= _lc
[I_CAP_OPEN
];
2030 SelectMapForm
.GetMaps(FileName
);
2032 if (FileName
= OpenedWAD
) and
2033 (OpenedMap
<> '') then
2035 MapName
:= OpenedMap
;
2036 while (Pos(':\', MapName
) > 0) do
2037 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
2039 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2040 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2043 if SelectMapForm
.lbMapList
.Count
> 0 then
2044 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2046 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2051 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2055 if (SelectMapForm
.ShowModal() = mrOK
) and
2056 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2057 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2062 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2068 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2069 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2070 pLoadProgress
.Show();
2072 OpenedMap
:= FileName
+':\'+MapName
;
2073 OpenedWAD
:= FileName
;
2075 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2076 // Такая карта уже недавно открывалась:
2078 RecentFiles
.Delete(idx
);
2079 RecentFiles
.Insert(0, OpenedMap
);
2080 RefreshRecentMenu();
2084 pLoadProgress
.Hide();
2087 lbTextureList
.Sorted
:= True;
2088 lbTextureList
.Sorted
:= False;
2090 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2094 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2099 if SelectedObjects
= nil then
2106 for a
:= 0 to High(SelectedObjects
) do
2107 if SelectedObjects
[a
].Live
then
2109 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2112 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2115 if (not okX
) or (not okY
) then
2121 for a
:= 0 to High(SelectedObjects
) do
2122 if SelectedObjects
[a
].Live
then
2125 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2128 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2130 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2132 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2133 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2134 begin // Двигаем зону Расширителя
2136 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2138 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2141 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2142 begin // Двигаем точку назначения Телепорта
2144 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2146 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2149 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2150 begin // Двигаем точку создания монстра
2152 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2154 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2157 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2158 begin // Двигаем точку создания предмета
2160 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2162 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2165 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2166 begin // Двигаем точку создания выстрела
2168 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2170 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2175 LastMovePoint
:= MousePos
;
2179 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2181 LayerEnabled
[Layer
] := show
;
2186 MainForm
.miLayer1
.Checked
:= show
;
2187 MainForm
.miLayerP1
.Checked
:= show
;
2191 MainForm
.miLayer2
.Checked
:= show
;
2192 MainForm
.miLayerP2
.Checked
:= show
;
2196 MainForm
.miLayer3
.Checked
:= show
;
2197 MainForm
.miLayerP3
.Checked
:= show
;
2201 MainForm
.miLayer4
.Checked
:= show
;
2202 MainForm
.miLayerP4
.Checked
:= show
;
2206 MainForm
.miLayer5
.Checked
:= show
;
2207 MainForm
.miLayerP5
.Checked
:= show
;
2211 MainForm
.miLayer6
.Checked
:= show
;
2212 MainForm
.miLayerP6
.Checked
:= show
;
2216 MainForm
.miLayer7
.Checked
:= show
;
2217 MainForm
.miLayerP7
.Checked
:= show
;
2221 MainForm
.miLayer8
.Checked
:= show
;
2222 MainForm
.miLayerP8
.Checked
:= show
;
2226 MainForm
.miLayer9
.Checked
:= show
;
2227 MainForm
.miLayerP9
.Checked
:= show
;
2231 RemoveSelectFromObjects();
2234 procedure SwitchLayer(Layer
: Byte);
2236 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2239 procedure SwitchMap();
2241 ShowMap
:= not ShowMap
;
2242 MainForm
.tbShowMap
.Down
:= ShowMap
;
2245 procedure ShowEdges();
2247 if drEdge
[3] < 255 then
2250 drEdge
[3] := gAlphaEdge
;
2253 function SelectedTexture(): String;
2255 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2256 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2261 function IsSpecialTextureSel(): Boolean;
2263 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2264 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2267 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2272 procedure AddInt(x
: Integer);
2274 Res
:= Res
+ IntToStr(x
) + ' ';
2280 if Length(CopyBuf
) = 0 then
2283 Res
:= CLIPBOARD_SIG
+ ' ';
2285 for i
:= 0 to High(CopyBuf
) do
2287 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2288 (CopyBuf
[i
].Panel
= nil) then
2292 AddInt(CopyBuf
[i
].ObjectType
);
2295 // Свойства объекта:
2296 case CopyBuf
[i
].ObjectType
of
2298 with CopyBuf
[i
].Panel
^ do
2305 Res
:= Res
+ '"' + TextureName
+ '" ';
2307 AddInt(IfThen(Blending
, 1, 0));
2311 with CopyBuf
[i
].Item
do
2316 AddInt(IfThen(OnlyDM
, 1, 0));
2317 AddInt(IfThen(Fall
, 1, 0));
2321 with CopyBuf
[i
].Monster
do
2323 AddInt(MonsterType
);
2326 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2330 with CopyBuf
[i
].Area
do
2335 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2339 with CopyBuf
[i
].Trigger
do
2341 AddInt(TriggerType
);
2346 AddInt(ActivateType
);
2348 AddInt(IfThen(Enabled
, 1, 0));
2349 AddInt(TexturePanel
);
2351 for j
:= 0 to 127 do
2352 AddInt(Data
.Default
[j
]);
2360 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
;
2365 function GetNext(): String;
2370 if Str
[1] = '"' then
2382 Result
:= Copy(Str
, 1, p
-1);
2398 Result
:= Copy(Str
, 1, p
-1);
2408 if GetNext() <> CLIPBOARD_SIG
then
2414 t
:= StrToIntDef(GetNext(), 0);
2416 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2417 (GetNext() <> ';') then
2418 begin // Что-то не то => пропускаем:
2426 i
:= Length(CopyBuf
);
2427 SetLength(CopyBuf
, i
+ 1);
2429 CopyBuf
[i
].ObjectType
:= t
;
2430 CopyBuf
[i
].Panel
:= nil;
2432 // Свойства объекта:
2436 New(CopyBuf
[i
].Panel
);
2438 with CopyBuf
[i
].Panel
^ do
2440 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2441 X
:= StrToIntDef(GetNext(), 0);
2442 Y
:= StrToIntDef(GetNext(), 0);
2443 pmin
.X
:= Min(X
, pmin
.X
);
2444 pmin
.Y
:= Min(Y
, pmin
.Y
);
2445 Width
:= StrToIntDef(GetNext(), 16);
2446 Height
:= StrToIntDef(GetNext(), 16);
2447 TextureName
:= GetNext();
2448 Alpha
:= StrToIntDef(GetNext(), 0);
2449 Blending
:= (GetNext() = '1');
2454 with CopyBuf
[i
].Item
do
2456 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2457 X
:= StrToIntDef(GetNext(), 0);
2458 Y
:= StrToIntDef(GetNext(), 0);
2459 pmin
.X
:= Min(X
, pmin
.X
);
2460 pmin
.Y
:= Min(Y
, pmin
.Y
);
2461 OnlyDM
:= (GetNext() = '1');
2462 Fall
:= (GetNext() = '1');
2466 with CopyBuf
[i
].Monster
do
2468 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2469 X
:= StrToIntDef(GetNext(), 0);
2470 Y
:= StrToIntDef(GetNext(), 0);
2471 pmin
.X
:= Min(X
, pmin
.X
);
2472 pmin
.Y
:= Min(Y
, pmin
.Y
);
2474 if GetNext() = '1' then
2477 Direction
:= D_RIGHT
;
2481 with CopyBuf
[i
].Area
do
2483 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2484 X
:= StrToIntDef(GetNext(), 0);
2485 Y
:= StrToIntDef(GetNext(), 0);
2486 pmin
.X
:= Min(X
, pmin
.X
);
2487 pmin
.Y
:= Min(Y
, pmin
.Y
);
2488 if GetNext() = '1' then
2491 Direction
:= D_RIGHT
;
2495 with CopyBuf
[i
].Trigger
do
2497 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2498 X
:= StrToIntDef(GetNext(), 0);
2499 Y
:= StrToIntDef(GetNext(), 0);
2500 pmin
.X
:= Min(X
, pmin
.X
);
2501 pmin
.Y
:= Min(Y
, pmin
.Y
);
2502 Width
:= StrToIntDef(GetNext(), 16);
2503 Height
:= StrToIntDef(GetNext(), 16);
2504 ActivateType
:= StrToIntDef(GetNext(), 0);
2505 Key
:= StrToIntDef(GetNext(), 0);
2506 Enabled
:= (GetNext() = '1');
2507 TexturePanel
:= StrToIntDef(GetNext(), 0);
2509 for j
:= 0 to 127 do
2510 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2515 pmin
.X
:= Min(Data
.TargetPoint
.X
, pmin
.X
);
2516 pmin
.Y
:= Min(Data
.TargetPoint
.Y
, pmin
.Y
);
2518 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
2520 pmin
.X
:= Min(Data
.tX
, pmin
.X
);
2521 pmin
.Y
:= Min(Data
.tY
, pmin
.Y
);
2523 TRIGGER_SPAWNMONSTER
:
2525 pmin
.X
:= Min(Data
.MonPos
.X
, pmin
.X
);
2526 pmin
.Y
:= Min(Data
.MonPos
.Y
, pmin
.Y
);
2530 pmin
.X
:= Min(Data
.ItemPos
.X
, pmin
.X
);
2531 pmin
.Y
:= Min(Data
.ItemPos
.Y
, pmin
.Y
);
2535 pmin
.X
:= Min(Data
.ShotPos
.X
, pmin
.X
);
2536 pmin
.Y
:= Min(Data
.ShotPos
.Y
, pmin
.Y
);
2544 //----------------------------------------
2545 //Закончились вспомогательные процедуры
2546 //----------------------------------------
2548 procedure TMainForm
.RefreshRecentMenu();
2553 // Лишние запомненные карты:
2554 while RecentFiles
.Count
> RecentCount
do
2555 RecentFiles
.Delete(RecentFiles
.Count
-1);
2557 // Лишние строки меню:
2558 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2559 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2561 // Отделение списка карт от строки "Выход":
2562 if RecentFiles
.Count
> 0 then
2564 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2566 MainMenu
.Items
[0].Add(MI
);
2569 // Добавление в меню списка запомненных карт:
2570 for i
:= 0 to RecentFiles
.Count
-1 do
2572 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2573 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2574 MI
.OnClick
:= aRecentFileExecute
;
2575 MainMenu
.Items
[0].Add(MI
);
2579 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2584 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2585 Delete(s
, Pos('&', s
), 1);
2586 s
:= Trim(Copy(s
, 1, 2));
2587 n
:= StrToIntDef(s
, 0) - 1;
2588 if (n
>= 0) and (n
<= RecentFiles
.Count
) then
2590 fn
:= g_ExtractWadName(RecentFiles
[n
]);
2591 if FileExists(fn
) then
2593 s
:= g_ExtractFilePathName(RecentFiles
[n
]);
2596 else if MessageBox(0, PChar(_lc
[I_MSG_DEL_RECENT_PROMT
]), PChar(_lc
[I_MSG_DEL_RECENT
]), MB_ICONQUESTION
or MB_YESNO
) = idYes
then
2598 RecentFiles
.Delete(n
);
2599 RefreshRecentMenu();
2604 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2606 OptionsForm
.ShowModal();
2609 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2619 g_ReadResource(GameWad
, 'FONTS', cfgres
, cfgdata
, cfglen
);
2620 if cfgdata
<> nil then
2622 if not g_CreateTextureWAD('FONT_STD', GameWad
+ ':FONTS\' + texture
) then
2623 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2625 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2626 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2627 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2628 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2630 if g_GetTexture('FONT_STD', ID
) then
2631 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
- 2);
2638 e_WriteLog('Could not load FONT_STD', MSG_WARNING
)
2642 procedure TMainForm
.FormCreate(Sender
: TObject
);
2650 e_WriteLog('Doom 2D: Forever Editor version ' + EDITOR_VERSION
, MSG_NOTIFY
);
2651 e_WriteLog('Build date: ' + EDITOR_BUILDDATE
+ ' ' + EDITOR_BUILDTIME
, MSG_NOTIFY
);
2652 e_WriteLog('Build hash: ' + g_GetBuildHash(), MSG_NOTIFY
);
2653 e_WriteLog('Build by: ' + g_GetBuilderName(), MSG_NOTIFY
);
2655 slInvalidTextures
:= TStringList
.Create
;
2657 ShowLayer(LAYER_BACK
, True);
2658 ShowLayer(LAYER_WALLS
, True);
2659 ShowLayer(LAYER_FOREGROUND
, True);
2660 ShowLayer(LAYER_STEPS
, True);
2661 ShowLayer(LAYER_WATER
, True);
2662 ShowLayer(LAYER_ITEMS
, True);
2663 ShowLayer(LAYER_MONSTERS
, True);
2664 ShowLayer(LAYER_AREAS
, True);
2665 ShowLayer(LAYER_TRIGGERS
, True);
2669 FormCaption
:= MainForm
.Caption
;
2673 config
:= TConfig
.CreateFile(CfgFileName
);
2675 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2676 Position
:= poDesktopCenter
2678 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2679 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2680 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2681 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2683 if config
.ReadBool('Editor', 'Maximize', False) then
2684 WindowState
:= wsMaximized
;
2685 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2686 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2687 Splitter1
.Left
:= PanelProps
.Left
;
2688 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2689 Splitter2
.Top
:= PanelObjs
.Top
;
2690 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2691 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2692 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2693 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2694 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2695 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2696 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2697 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2698 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2699 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2700 UseCheckerboard
:= config
.ReadBool('Editor', 'UseCheckerboard', True);
2701 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2702 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2703 if gAlphaEdge
= 255 then
2704 gAlphaEdge
:= ALPHA_EDGE
;
2705 drEdge
[0] := GetRValue(gColorEdge
);
2706 drEdge
[1] := GetGValue(gColorEdge
);
2707 drEdge
[2] := GetBValue(gColorEdge
);
2708 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2711 drEdge
[3] := gAlphaEdge
;
2712 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2713 if gAlphaTriggerLine
= 255 then
2714 gAlphaTriggerLine
:= ALPHA_LINE
;
2715 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2716 if gAlphaTriggerArea
= 255 then
2717 gAlphaTriggerArea
:= ALPHA_AREA
;
2718 gAlphaMonsterRect
:= config
.ReadInt('Editor', 'MonsterRectAlpha', 0);
2719 gAlphaAreaRect
:= config
.ReadInt('Editor', 'AreaRectAlpha', 0);
2720 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2724 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2728 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2729 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2731 s
:= config
.ReadStr('Editor', 'Language', '');
2734 Compress
:= config
.ReadBool('Editor', 'Compress', True);
2735 Backup
:= config
.ReadBool('Editor', 'Backup', True);
2737 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2738 if RecentCount
> 10 then
2740 if RecentCount
< 2 then
2743 RecentFiles
:= TStringList
.Create();
2744 for i
:= 0 to RecentCount
-1 do
2746 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2750 RefreshRecentMenu();
2754 tbShowMap
.Down
:= ShowMap
;
2755 tbGridOn
.Down
:= DotEnable
;
2756 pcObjects
.ActivePageIndex
:= 0;
2757 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2759 Application
.OnIdle
:= OnIdle
;
2762 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2764 // NOTE: all the font printing routines assume CP1251
2765 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2768 procedure TMainForm
.Draw();
2773 Width
, Height
: Word;
2776 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2785 e_Clear(GL_COLOR_BUFFER_BIT
,
2786 GetRValue(BackColor
)/255,
2787 GetGValue(BackColor
)/255,
2788 GetBValue(BackColor
)/255);
2792 ObjCount
:= SelectedObjectCount();
2794 // Обводим выделенные объекты красной рамкой:
2795 if ObjCount
> 0 then
2797 for a
:= 0 to High(SelectedObjects
) do
2798 if SelectedObjects
[a
].Live
then
2800 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2804 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2805 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2808 // Рисуем точки изменения размеров:
2809 if (ObjCount
= 1) and
2810 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2812 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2813 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2814 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2815 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2817 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2818 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2819 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2820 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2827 if DotEnable
and (PreviewMode
= 0) then
2834 x
:= MapOffset
.X
mod DotStep
;
2835 y
:= MapOffset
.Y
mod DotStep
;
2837 while x
< RenderPanel
.Width
do
2839 while y
< RenderPanel
.Height
do
2841 e_DrawPoint(DotSize
, x
+ a
, y
+ a
,
2842 GetRValue(DotColor
),
2843 GetGValue(DotColor
),
2844 GetBValue(DotColor
));
2848 y
:= MapOffset
.Y
mod DotStep
;
2853 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2854 (not IsSpecialTextureSel()) and (PreviewMode
= 0) then
2856 if not g_GetTexture(SelectedTexture(), ID
) then
2857 g_GetTexture('NOTEXTURE', ID
);
2858 g_GetTextureSizeByID(ID
, Width
, Height
);
2859 if UseCheckerboard
then
2861 if g_GetTexture('PREVIEW', PID
) then
2862 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
2864 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
2865 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
2866 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
2867 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
2870 // Подсказка при выборе точки Телепорта:
2871 if SelectFlag
= SELECTFLAG_TELEPORT
then
2873 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2874 if Data
.d2d_teleport
then
2875 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2876 MousePos
.X
+16, MousePos
.Y
-1,
2879 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2880 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2882 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2883 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2884 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
2887 // Подсказка при выборе точки появления:
2888 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2890 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2891 MousePos
.X
+16, MousePos
.Y
-1,
2893 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2894 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2895 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
2898 // Подсказка при выборе панели двери:
2899 if SelectFlag
= SELECTFLAG_DOOR
then
2901 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2902 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2903 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
2906 // Подсказка при выборе панели с текстурой:
2907 if SelectFlag
= SELECTFLAG_TEXTURE
then
2909 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2910 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2911 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
2914 // Подсказка при выборе панели индикации выстрела:
2915 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2917 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2918 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2919 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
2922 // Подсказка при выборе панели лифта:
2923 if SelectFlag
= SELECTFLAG_LIFT
then
2925 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2926 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2927 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
2930 // Подсказка при выборе монстра:
2931 if SelectFlag
= SELECTFLAG_MONSTER
then
2933 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2934 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2935 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
2938 // Подсказка при выборе области воздействия:
2939 if DrawPressRect
then
2941 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2942 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2943 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
2946 // Рисуем текстуры, если чертим панель:
2947 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2948 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2949 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2951 if not g_GetTexture(SelectedTexture(), ID
) then
2952 g_GetTexture('NOTEXTURE', ID
);
2953 g_GetTextureSizeByID(ID
, Width
, Height
);
2955 if (Abs(Right
-Left
) >= Width
) and (Abs(Bottom
-Top
) >= Height
) then
2956 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2957 Abs(Bottom
-Top
) div Height
, 64, True, False);
2960 // Прямоугольник выделения:
2961 if DrawRect
<> nil then
2963 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2965 // Чертим мышью панель/триггер или меняем мышью их размер:
2966 if (((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
2967 not(ssCtrl
in GetKeyShiftState())) or (MouseAction
= MOUSEACTION_RESIZE
)) and
2968 (DrawPanelSize
) then
2970 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2971 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2973 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2974 begin // Чертим новый
2975 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
2976 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
2977 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
],
2978 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
2980 else // Растягиваем существующий
2981 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2983 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2985 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2986 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2990 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2991 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2994 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
2996 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
3001 // Ближайшая к курсору мыши точка на сетке:
3002 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
3007 // Сколько пикселов карты в 1 пикселе мини-карты:
3008 ScaleSz
:= 16 div Scale
;
3009 // Размеры мини-карты:
3010 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
3011 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
3012 // X-координата на RenderPanel нулевой x-координаты карты:
3013 XX
:= RenderPanel
.Width
- aX
- 1;
3015 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
3016 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
3018 if gPanels
<> nil then
3021 for a
:= 0 to High(gPanels
) do
3023 if PanelType
<> 0 then
3025 // Левый верхний угол:
3026 aX
:= XX
+ (X
div ScaleSz
);
3027 aY
:= 1 + (Y
div ScaleSz
);
3029 aX2
:= max(Width
div ScaleSz
, 1);
3030 aY2
:= max(Height
div ScaleSz
, 1);
3031 // Правый нижний угол:
3032 aX2
:= aX
+ aX2
- 1;
3033 aY2
:= aY
+ aY2
- 1;
3036 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
3037 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
3038 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
3039 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
3040 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
3041 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
3042 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
3043 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
3044 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
3045 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
3046 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
3047 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
3051 // Рисуем красным выделенные панели:
3052 if SelectedObjects
<> nil then
3053 for b
:= 0 to High(SelectedObjects
) do
3054 with SelectedObjects
[b
] do
3055 if Live
and (ObjectType
= OBJECT_PANEL
) then
3056 with gPanels
[SelectedObjects
[b
].ID
] do
3057 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
3059 // Левый верхний угол:
3060 aX
:= XX
+ (X
div ScaleSz
);
3061 aY
:= 1 + (Y
div ScaleSz
);
3063 aX2
:= max(Width
div ScaleSz
, 1);
3064 aY2
:= max(Height
div ScaleSz
, 1);
3065 // Правый нижний угол:
3066 aX2
:= aX
+ aX2
- 1;
3067 aY2
:= aY
+ aY2
- 1;
3069 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
3073 if (gMapInfo
.Width
> RenderPanel
.Width
) or
3074 (gMapInfo
.Height
> RenderPanel
.Height
) then
3076 // Окно, показывающее текущее положение экрана на карте:
3078 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
3079 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
3080 // Левый верхний угол:
3081 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
3082 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
3083 // Правый нижний угол:
3087 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3088 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3093 RenderPanel
.SwapBuffers();
3096 procedure TMainForm
.FormResize(Sender
: TObject
);
3098 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3100 sbHorizontal
.Min
:= Min(gMapInfo
.Width
- RenderPanel
.Width
, -RenderPanel
.Width
div 2);
3101 sbHorizontal
.Max
:= Max(0, gMapInfo
.Width
- RenderPanel
.Width
div 2);
3102 sbVertical
.Min
:= Min(gMapInfo
.Height
- RenderPanel
.Height
, -RenderPanel
.Height
div 2);
3103 sbVertical
.Max
:= Max(0, gMapInfo
.Height
- RenderPanel
.Height
div 2);
3105 MapOffset
.X
:= -sbHorizontal
.Position
;
3106 MapOffset
.Y
:= -sbVertical
.Position
;
3109 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3114 j_max
:= 0; // shut up compiler
3118 res
:= (gPanels
<> nil) and
3119 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3120 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3122 gPanels
[ID
].Height
);
3123 j_max
:= Length(gPanels
) - 1;
3128 res
:= (gItems
<> nil) and
3129 LayerEnabled
[LAYER_ITEMS
] and
3130 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3131 ItemSize
[gItems
[ID
].ItemType
][0],
3132 ItemSize
[gItems
[ID
].ItemType
][1]);
3133 j_max
:= Length(gItems
) - 1;
3138 res
:= (gMonsters
<> nil) and
3139 LayerEnabled
[LAYER_MONSTERS
] and
3140 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3141 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3142 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3143 j_max
:= Length(gMonsters
) - 1;
3148 res
:= (gAreas
<> nil) and
3149 LayerEnabled
[LAYER_AREAS
] and
3150 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3151 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3152 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3153 j_max
:= Length(gAreas
) - 1;
3158 res
:= (gTriggers
<> nil) and
3159 LayerEnabled
[LAYER_TRIGGERS
] and
3160 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3161 gTriggers
[ID
].Width
,
3162 gTriggers
[ID
].Height
);
3163 j_max
:= Length(gTriggers
) - 1;
3173 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3182 if j
= Integer(ID
) then
3187 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3188 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3192 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3193 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3194 ItemSize
[gItems
[j
].ItemType
][0],
3195 ItemSize
[gItems
[j
].ItemType
][1]);
3197 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3198 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3199 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3200 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3202 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3203 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3204 AreaSize
[gAreas
[j
].AreaType
].Width
,
3205 AreaSize
[gAreas
[j
].AreaType
].Height
);
3207 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3208 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3210 gTriggers
[j
].Height
);
3217 SetLength(SelectedObjects
, 1);
3219 SelectedObjects
[0].ObjectType
:= ObjectType
;
3220 SelectedObjects
[0].ID
:= j
;
3221 SelectedObjects
[0].Live
:= True;
3229 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3230 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3234 c1
, c2
, c3
, c4
: Boolean;
3240 MainForm
.ActiveControl
:= RenderPanel
;
3241 RenderPanel
.SetFocus();
3243 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3245 if Button
= mbLeft
then // Left Mouse Button
3247 // Двигаем карту с помощью мыши и мини-карты:
3249 g_CollidePoint(X
, Y
,
3250 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3252 max(gMapInfo
.Width
div (16 div Scale
), 1),
3253 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3256 MouseAction
:= MOUSEACTION_MOVEMAP
;
3258 else // Ставим предмет/монстра/область:
3259 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3260 (not (ssShift
in Shift
)) then
3262 case pcObjects
.ActivePageIndex
of
3264 if lbItemList
.ItemIndex
= -1 then
3265 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3268 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3269 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3270 item
.ItemType
:= item
.ItemType
+ 2;
3271 item
.X
:= MousePos
.X
-MapOffset
.X
;
3272 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3274 if not (ssCtrl
in Shift
) then
3276 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3277 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3280 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3281 item
.Fall
:= cbFall
.Checked
;
3282 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3285 if lbMonsterList
.ItemIndex
= -1 then
3286 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3289 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3290 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3291 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3293 if not (ssCtrl
in Shift
) then
3295 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3296 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3299 if rbMonsterLeft
.Checked
then
3300 monster
.Direction
:= D_LEFT
3302 monster
.Direction
:= D_RIGHT
;
3303 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3306 if lbAreasList
.ItemIndex
= -1 then
3307 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3309 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3311 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3312 area
.X
:= MousePos
.X
-MapOffset
.X
;
3313 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3315 if not (ssCtrl
in Shift
) then
3317 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3318 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3321 if rbAreaLeft
.Checked
then
3322 area
.Direction
:= D_LEFT
3324 area
.Direction
:= D_RIGHT
;
3325 Undo_Add(OBJECT_AREA
, AddArea(area
));
3331 i
:= GetFirstSelected();
3333 // Выбираем объект под текущим:
3334 if (SelectedObjects
<> nil) and
3335 (ssShift
in Shift
) and (i
>= 0) and
3336 (SelectedObjects
[i
].Live
) then
3338 if SelectedObjectCount() = 1 then
3339 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3340 SelectedObjects
[i
].ObjectType
,
3341 SelectedObjects
[i
].ID
);
3345 // Рисуем область триггера "Расширитель":
3346 if DrawPressRect
and (i
>= 0) and
3347 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3348 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3349 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3350 MouseAction
:= MOUSEACTION_DRAWPRESS
3351 else // Рисуем панель:
3352 if pcObjects
.ActivePageIndex
= 0 then
3354 if (lbPanelType
.ItemIndex
>= 0) then
3355 MouseAction
:= MOUSEACTION_DRAWPANEL
3357 else // Рисуем триггер:
3358 if (lbTriggersList
.ItemIndex
>= 0) then
3360 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3364 end; // if Button = mbLeft
3366 if Button
= mbRight
then // Right Mouse Button
3368 // Клик по мини-карте:
3370 g_CollidePoint(X
, Y
,
3371 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3373 max(gMapInfo
.Width
div (16 div Scale
), 1),
3374 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3376 MouseAction
:= MOUSEACTION_NOACTION
;
3378 else // Нужно что-то выбрать мышью:
3379 if SelectFlag
<> SELECTFLAG_NONE
then
3382 SELECTFLAG_TELEPORT
:
3383 // Точку назначения телепортации:
3384 with gTriggers
[SelectedObjects
[
3385 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3387 X
:= MousePos
.X
-MapOffset
.X
;
3388 Y
:= MousePos
.Y
-MapOffset
.Y
;
3391 SELECTFLAG_SPAWNPOINT
:
3392 // Точку создания монстра:
3393 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3394 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3396 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3397 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3399 else if TriggerType
= TRIGGER_SPAWNITEM
then
3400 begin // Точка создания предмета:
3401 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3402 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3404 else if TriggerType
= TRIGGER_SHOT
then
3405 begin // Точка создания выстрела:
3406 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3407 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3413 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3415 2, 2, OBJECT_PANEL
, True);
3416 if IDArray
<> nil then
3418 for i
:= 0 to High(IDArray
) do
3419 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3420 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3422 gTriggers
[SelectedObjects
[
3423 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3428 gTriggers
[SelectedObjects
[
3429 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3433 // Панель с текстурой:
3435 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3437 2, 2, OBJECT_PANEL
, True);
3438 if IDArray
<> nil then
3440 for i
:= 0 to High(IDArray
) do
3441 if ((gPanels
[IDArray
[i
]].PanelType
in
3442 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3443 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3445 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3446 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3447 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3449 gTriggers
[SelectedObjects
[
3450 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3455 gTriggers
[SelectedObjects
[
3456 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3462 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3464 2, 2, OBJECT_PANEL
, True);
3465 if IDArray
<> nil then
3467 for i
:= 0 to High(IDArray
) do
3468 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3469 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3470 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3471 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3473 gTriggers
[SelectedObjects
[
3474 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3479 gTriggers
[SelectedObjects
[
3480 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3486 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3488 2, 2, OBJECT_MONSTER
, False);
3489 if IDArray
<> nil then
3490 gTriggers
[SelectedObjects
[
3491 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3493 gTriggers
[SelectedObjects
[
3494 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3497 SELECTFLAG_SHOTPANEL
:
3498 // Панель индикации выстрела:
3500 if gTriggers
[SelectedObjects
[
3501 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3503 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3505 2, 2, OBJECT_PANEL
, True);
3506 if IDArray
<> nil then
3508 for i
:= 0 to High(IDArray
) do
3509 if ((gPanels
[IDArray
[i
]].PanelType
in
3510 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3511 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3513 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3514 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3515 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3517 gTriggers
[SelectedObjects
[
3518 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3523 gTriggers
[SelectedObjects
[
3524 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3529 SelectFlag
:= SELECTFLAG_SELECTED
;
3531 else // if SelectFlag <> SELECTFLAG_NONE...
3533 // Что уже выбрано и не нажат Ctrl:
3534 if (SelectedObjects
<> nil) and
3535 (not (ssCtrl
in Shift
)) then
3536 for i
:= 0 to High(SelectedObjects
) do
3537 with SelectedObjects
[i
] do
3540 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3541 (SelectedObjectCount() = 1) then
3543 Rect
:= ObjectGetRect(ObjectType
, ID
);
3545 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3546 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3547 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3548 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3549 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3550 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3551 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3552 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3554 // Меняем размер панели или триггера:
3555 if c1
or c2
or c3
or c4
then
3557 MouseAction
:= MOUSEACTION_RESIZE
;
3558 LastMovePoint
:= MousePos
;
3562 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3564 ResizeDirection
:= RESIZEDIR_LEFT
3566 ResizeDirection
:= RESIZEDIR_RIGHT
;
3567 RenderPanel
.Cursor
:= crSizeWE
;
3571 ResizeType
:= RESIZETYPE_VERTICAL
;
3573 ResizeDirection
:= RESIZEDIR_UP
3575 ResizeDirection
:= RESIZEDIR_DOWN
;
3576 RenderPanel
.Cursor
:= crSizeNS
;
3583 // Перемещаем панель или триггер:
3584 if ObjectCollide(ObjectType
, ID
,
3586 Y
-MapOffset
.Y
-1, 2, 2) then
3588 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3589 LastMovePoint
:= MousePos
;
3595 end; // if Button = mbRight
3597 if Button
= mbMiddle
then // Middle Mouse Button
3599 SetCapture(RenderPanel
.Handle
);
3600 RenderPanel
.Cursor
:= crSize
;
3603 MouseMDown
:= Button
= mbMiddle
;
3605 MouseMDownPos
:= Mouse
.CursorPos
;
3607 MouseRDown
:= Button
= mbRight
;
3609 MouseRDownPos
:= MousePos
;
3611 MouseLDown
:= Button
= mbLeft
;
3613 MouseLDownPos
:= MousePos
;
3616 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3617 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3622 rSelectRect
: Boolean;
3623 wWidth
, wHeight
: Word;
3626 procedure SelectObjects(ObjectType
: Byte);
3631 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3632 rRect
.Width
, rRect
.Height
,
3633 ObjectType
, rSelectRect
);
3635 if IDArray
<> nil then
3636 for i
:= 0 to High(IDArray
) do
3637 SelectObject(ObjectType
, IDArray
[i
], (ssCtrl
in Shift
) or rSelectRect
);
3640 if Button
= mbLeft
then
3641 MouseLDown
:= False;
3642 if Button
= mbRight
then
3643 MouseRDown
:= False;
3644 if Button
= mbMiddle
then
3645 MouseMDown
:= False;
3648 ResizeType
:= RESIZETYPE_NONE
;
3651 if Button
= mbLeft
then // Left Mouse Button
3653 if MouseAction
<> MOUSEACTION_NONE
then
3654 begin // Было действие мышью
3655 // Мышь сдвинулась во время удержания клавиши,
3656 // либо активирован режим быстрого рисования:
3657 if ((MousePos
.X
<> MouseLDownPos
.X
) and
3658 (MousePos
.Y
<> MouseLDownPos
.Y
)) or
3659 ((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3660 (ssCtrl
in Shift
)) then
3663 MOUSEACTION_DRAWPANEL
:
3665 // Фон или передний план без текстуры - ошибка:
3666 if (lbPanelType
.ItemIndex
in [1, 2]) and
3667 (lbTextureList
.ItemIndex
= -1) then
3668 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3669 else // Назначаем параметры панели:
3671 case lbPanelType
.ItemIndex
of
3672 0: Panel
.PanelType
:= PANEL_WALL
;
3673 1: Panel
.PanelType
:= PANEL_BACK
;
3674 2: Panel
.PanelType
:= PANEL_FORE
;
3675 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3676 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3677 5: Panel
.PanelType
:= PANEL_STEP
;
3678 6: Panel
.PanelType
:= PANEL_WATER
;
3679 7: Panel
.PanelType
:= PANEL_ACID1
;
3680 8: Panel
.PanelType
:= PANEL_ACID2
;
3681 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3682 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3683 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3684 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3685 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3688 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3689 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3690 if ssCtrl
in Shift
then
3694 if (lbTextureList
.ItemIndex
<> -1) and
3695 (not IsSpecialTextureSel()) then
3697 if not g_GetTexture(SelectedTexture(), TextureID
) then
3698 g_GetTexture('NOTEXTURE', TextureID
);
3699 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
3701 Panel
.Width
:= wWidth
;
3702 Panel
.Height
:= wHeight
;
3706 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3707 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3710 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3711 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3712 (lbTextureList
.ItemIndex
= -1) then
3714 Panel
.TextureHeight
:= 1;
3715 Panel
.TextureWidth
:= 1;
3716 Panel
.TextureName
:= '';
3717 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3719 else // Есть текстура:
3721 Panel
.TextureName
:= SelectedTexture();
3723 // Обычная текстура:
3724 if not IsSpecialTextureSel() then
3726 g_GetTextureSizeByName(Panel
.TextureName
,
3727 Panel
.TextureWidth
, Panel
.TextureHeight
);
3728 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3730 else // Спец.текстура:
3732 Panel
.TextureHeight
:= 1;
3733 Panel
.TextureWidth
:= 1;
3734 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3739 Panel
.Blending
:= False;
3741 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3745 // Рисовали триггер:
3746 MOUSEACTION_DRAWTRIGGER
:
3748 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3749 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3750 if ssCtrl
in Shift
then
3754 trigger
.Width
:= wWidth
;
3755 trigger
.Height
:= wHeight
;
3759 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3760 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3763 trigger
.Enabled
:= True;
3764 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3765 trigger
.TexturePanel
:= -1;
3768 trigger
.ActivateType
:= 0;
3770 if clbActivationType
.Checked
[0] then
3771 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3772 if clbActivationType
.Checked
[1] then
3773 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3774 if clbActivationType
.Checked
[2] then
3775 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3776 if clbActivationType
.Checked
[3] then
3777 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3778 if clbActivationType
.Checked
[4] then
3779 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3780 if clbActivationType
.Checked
[5] then
3781 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3783 // Необходимые для активации ключи:
3786 if clbKeys
.Checked
[0] then
3787 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3788 if clbKeys
.Checked
[1] then
3789 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3790 if clbKeys
.Checked
[2] then
3791 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3792 if clbKeys
.Checked
[3] then
3793 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3794 if clbKeys
.Checked
[4] then
3795 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3797 // Параметры триггера:
3798 FillByte(trigger
.Data
.Default
[0], 128, 0);
3800 case trigger
.TriggerType
of
3801 // Переключаемая панель:
3802 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3803 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3804 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3806 Trigger
.Data
.PanelID
:= -1;
3812 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3813 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3814 trigger
.Data
.d2d_teleport
:= True;
3815 trigger
.Data
.TlpDir
:= 0;
3818 // Изменение других триггеров:
3819 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3822 trigger
.Data
.Count
:= 1;
3828 trigger
.Data
.Volume
:= 255;
3829 trigger
.Data
.Pan
:= 127;
3830 trigger
.Data
.PlayCount
:= 1;
3831 trigger
.Data
.Local
:= True;
3832 trigger
.Data
.SoundSwitch
:= False;
3838 trigger
.Data
.MusicAction
:= 1;
3841 // Создание монстра:
3842 TRIGGER_SPAWNMONSTER
:
3844 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3845 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3846 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3847 trigger
.Data
.MonHealth
:= 0;
3848 trigger
.Data
.MonActive
:= False;
3849 trigger
.Data
.MonCount
:= 1;
3852 // Создание предмета:
3855 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3856 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3857 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3858 trigger
.Data
.ItemOnlyDM
:= False;
3859 trigger
.Data
.ItemFalls
:= False;
3860 trigger
.Data
.ItemCount
:= 1;
3861 trigger
.Data
.ItemMax
:= 0;
3862 trigger
.Data
.ItemDelay
:= 0;
3868 trigger
.Data
.PushAngle
:= 90;
3869 trigger
.Data
.PushForce
:= 10;
3870 trigger
.Data
.ResetVel
:= True;
3875 trigger
.Data
.ScoreCount
:= 1;
3876 trigger
.Data
.ScoreCon
:= True;
3877 trigger
.Data
.ScoreMsg
:= True;
3882 trigger
.Data
.MessageKind
:= 0;
3883 trigger
.Data
.MessageSendTo
:= 0;
3884 trigger
.Data
.MessageText
:= '';
3885 trigger
.Data
.MessageTime
:= 144;
3890 trigger
.Data
.DamageValue
:= 5;
3891 trigger
.Data
.DamageInterval
:= 12;
3896 trigger
.Data
.HealValue
:= 5;
3897 trigger
.Data
.HealInterval
:= 36;
3902 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3903 trigger
.Data
.ShotSound
:= True;
3904 trigger
.Data
.ShotPanelID
:= -1;
3905 trigger
.Data
.ShotTarget
:= 0;
3906 trigger
.Data
.ShotIntSight
:= 0;
3907 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
3908 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3909 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3910 trigger
.Data
.ShotAngle
:= 0;
3911 trigger
.Data
.ShotWait
:= 18;
3912 trigger
.Data
.ShotAccuracy
:= 0;
3913 trigger
.Data
.ShotAmmo
:= 0;
3914 trigger
.Data
.ShotIntReload
:= 0;
3919 trigger
.Data
.FXCount
:= 1;
3920 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3921 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3922 trigger
.Data
.FXColorR
:= 0;
3923 trigger
.Data
.FXColorG
:= 0;
3924 trigger
.Data
.FXColorB
:= 255;
3925 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3926 trigger
.Data
.FXWait
:= 1;
3927 trigger
.Data
.FXVelX
:= 0;
3928 trigger
.Data
.FXVelY
:= -20;
3929 trigger
.Data
.FXSpreadL
:= 5;
3930 trigger
.Data
.FXSpreadR
:= 5;
3931 trigger
.Data
.FXSpreadU
:= 4;
3932 trigger
.Data
.FXSpreadD
:= 0;
3936 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3939 // Рисовали область триггера "Расширитель":
3940 MOUSEACTION_DRAWPRESS
:
3941 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3943 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3944 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3945 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3946 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3948 DrawPressRect
:= False;
3952 MouseAction
:= MOUSEACTION_NONE
;
3954 end // if Button = mbLeft...
3955 else if Button
= mbRight
then // Right Mouse Button:
3957 if MouseAction
= MOUSEACTION_NOACTION
then
3959 MouseAction
:= MOUSEACTION_NONE
;
3963 // Объект передвинут или изменен в размере:
3964 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3966 RenderPanel
.Cursor
:= crDefault
;
3967 MouseAction
:= MOUSEACTION_NONE
;
3972 // Еще не все выбрали:
3973 if SelectFlag
<> SELECTFLAG_NONE
then
3975 if SelectFlag
= SELECTFLAG_SELECTED
then
3976 SelectFlag
:= SELECTFLAG_NONE
;
3981 // Мышь сдвинулась во время удержания клавиши:
3982 if (MousePos
.X
<> MouseRDownPos
.X
) and
3983 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3985 rSelectRect
:= True;
3987 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3988 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3989 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3990 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3992 else // Мышь не сдвинулась - нет прямоугольника:
3994 rSelectRect
:= False;
3996 rRect
.X
:= X
-MapOffset
.X
-1;
3997 rRect
.Y
:= Y
-MapOffset
.Y
-1;
4002 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
4003 if not (ssCtrl
in Shift
) then
4004 RemoveSelectFromObjects();
4006 // Выделяем всё в выбранном прямоугольнике:
4007 if (ssCtrl
in Shift
) and (ssAlt
in Shift
) then
4009 SelectObjects(OBJECT_PANEL
);
4010 SelectObjects(OBJECT_ITEM
);
4011 SelectObjects(OBJECT_MONSTER
);
4012 SelectObjects(OBJECT_AREA
);
4013 SelectObjects(OBJECT_TRIGGER
);
4016 SelectObjects(pcObjects
.ActivePageIndex
+1);
4021 else // Middle Mouse Button
4023 RenderPanel
.Cursor
:= crDefault
;
4028 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
4033 function TMainForm
.RenderMousePos(): Types
.TPoint
;
4035 Result
:= RenderPanel
.ScreenToClient(Mouse
.CursorPos
);
4038 procedure TMainForm
.RecountSelectedObjects();
4040 if SelectedObjectCount() = 0 then
4041 StatusBar
.Panels
[0].Text := ''
4043 StatusBar
.Panels
[0].Text := Format(_lc
[I_CAP_STAT_SELECTED
], [SelectedObjectCount()]);
4046 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
4047 Shift
: TShiftState
; X
, Y
: Integer);
4050 dWidth
, dHeight
: Integer;
4053 wWidth
, wHeight
: Word;
4055 _id
:= GetFirstSelected();
4058 // Рисуем панель с текстурой, сетка - размеры текстуры:
4059 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
4060 (lbPanelType
.ItemIndex
in [0..8]) and
4061 (lbTextureList
.ItemIndex
<> -1) and
4062 (not IsSpecialTextureSel()) then
4064 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
4065 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
4068 // Меняем размер панели с текстурой, сетка - размеры текстуры:
4069 if (MouseAction
= MOUSEACTION_RESIZE
) and
4070 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
4071 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
4072 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
4073 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
4075 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
4076 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
4079 // Выравнивание по сетке:
4085 else // Нет выравнивания по сетке:
4091 // Новая позиция мыши:
4093 begin // Зажата левая кнопка мыши
4094 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
4095 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
4099 begin // Зажата правая кнопка мыши
4100 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
4101 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
4104 begin // Кнопки мыши не зажаты
4105 MousePos
.X
:= Round((-MapOffset
.X
+ X
) / sX
) * sX
+ MapOffset
.X
;
4106 MousePos
.Y
:= Round((-MapOffset
.Y
+ Y
) / sY
) * sY
+ MapOffset
.Y
;
4109 // Зажата только правая кнопка мыши:
4110 if (not MouseLDown
) and (MouseRDown
) and (not MouseMDown
) then
4112 // Рисуем прямоугольник выделения:
4113 if MouseAction
= MOUSEACTION_NONE
then
4115 if DrawRect
= nil then
4117 DrawRect
.Top
:= MouseRDownPos
.y
;
4118 DrawRect
.Left
:= MouseRDownPos
.x
;
4119 DrawRect
.Bottom
:= MousePos
.y
;
4120 DrawRect
.Right
:= MousePos
.x
;
4123 // Двигаем выделенные объекты:
4124 if MouseAction
= MOUSEACTION_MOVEOBJ
then
4126 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
4127 MousePos
.X
-LastMovePoint
.X
,
4128 MousePos
.Y
-LastMovePoint
.Y
);
4131 // Меняем размер выделенного объекта:
4132 if MouseAction
= MOUSEACTION_RESIZE
then
4134 if (SelectedObjectCount
= 1) and
4135 (SelectedObjects
[GetFirstSelected
].Live
) then
4137 dWidth
:= MousePos
.X
-LastMovePoint
.X
;
4138 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
;
4141 RESIZETYPE_VERTICAL
: dWidth
:= 0;
4142 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
4145 case ResizeDirection
of
4146 RESIZEDIR_UP
: dHeight
:= -dHeight
;
4147 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
4150 if ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
4151 SelectedObjects
[GetFirstSelected
].ID
,
4152 dWidth
, dHeight
, ResizeDirection
) then
4153 LastMovePoint
:= MousePos
;
4158 // Зажата только левая кнопка мыши:
4159 if (not MouseRDown
) and (MouseLDown
) and (not MouseMDown
) then
4161 // Рисуем прямоугольник планирования панели:
4162 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4163 MOUSEACTION_DRAWTRIGGER
,
4164 MOUSEACTION_DRAWPRESS
] then
4166 if DrawRect
= nil then
4168 if ssCtrl
in Shift
then
4172 if (lbTextureList
.ItemIndex
<> -1) and (not IsSpecialTextureSel()) and
4173 (MouseAction
= MOUSEACTION_DRAWPANEL
) then
4175 if not g_GetTexture(SelectedTexture(), TextureID
) then
4176 g_GetTexture('NOTEXTURE', TextureID
);
4177 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
4179 DrawRect
.Top
:= MouseLDownPos
.y
;
4180 DrawRect
.Left
:= MouseLDownPos
.x
;
4181 DrawRect
.Bottom
:= DrawRect
.Top
+ wHeight
;
4182 DrawRect
.Right
:= DrawRect
.Left
+ wWidth
;
4186 DrawRect
.Top
:= MouseLDownPos
.y
;
4187 DrawRect
.Left
:= MouseLDownPos
.x
;
4188 DrawRect
.Bottom
:= MousePos
.y
;
4189 DrawRect
.Right
:= MousePos
.x
;
4192 else // Двигаем карту:
4193 if MouseAction
= MOUSEACTION_MOVEMAP
then
4199 // Only Middle Mouse Button is pressed
4200 if (not MouseLDown
) and (not MouseRDown
) and (MouseMDown
) then
4202 MapOffset
.X
:= -EnsureRange(-MapOffset
.X
+ MouseMDownPos
.X
- Mouse
.CursorPos
.X
,
4203 sbHorizontal
.Min
, sbHorizontal
.Max
);
4204 sbHorizontal
.Position
:= -MapOffset
.X
;
4205 MapOffset
.Y
:= -EnsureRange(-MapOffset
.Y
+ MouseMDownPos
.Y
- Mouse
.CursorPos
.Y
,
4206 sbVertical
.Min
, sbVertical
.Max
);
4207 sbVertical
.Position
:= -MapOffset
.Y
;
4208 MouseMDownPos
:= Mouse
.CursorPos
;
4211 // Клавиши мыши не зажаты:
4212 if (not MouseRDown
) and (not MouseLDown
) then
4215 // Строка состояния - координаты мыши:
4216 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4217 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4220 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4222 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
4223 PChar(_lc
[I_MSG_EXIT
]),
4224 MB_ICONQUESTION
or MB_YESNO
or
4225 MB_DEFBUTTON1
) = idYes
;
4228 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4233 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4238 config
:= TConfig
.CreateFile(CfgFileName
);
4240 if WindowState
<> wsMaximized
then
4242 config
.WriteInt('Editor', 'XPos', Left
);
4243 config
.WriteInt('Editor', 'YPos', Top
);
4244 config
.WriteInt('Editor', 'Width', Width
);
4245 config
.WriteInt('Editor', 'Height', Height
);
4249 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4250 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4251 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4252 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4254 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4255 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4256 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4257 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4258 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4259 config
.WriteInt('Editor', 'DotStep', DotStep
);
4260 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4261 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4262 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4263 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4264 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4265 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4266 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4267 config
.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect
);
4268 config
.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect
);
4270 for i
:= 0 to RecentCount
-1 do
4271 if i
< RecentFiles
.Count
then
4272 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4274 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4277 config
.SaveFile(CfgFileName
);
4280 slInvalidTextures
.Free
;
4283 procedure TMainForm
.FormDropFiles(Sender
: TObject
;
4284 const FileNames
: array of String);
4286 if Length(FileNames
) <> 1 then
4289 OpenMapFile(FileNames
[0]);
4292 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4294 if MainForm
.Visible
then
4298 procedure TMainForm
.Splitter1Moved(Sender
: TObject
);
4303 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4307 MapOptionsForm
.ShowModal();
4309 ResName
:= OpenedMap
;
4310 while (Pos(':\', ResName
) > 0) do
4311 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4313 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4316 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4318 AboutForm
.ShowModal();
4321 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
4327 if (not EditingProperties
) then
4329 if ssCtrl
in Shift
then
4332 '1': ContourEnabled
[LAYER_BACK
] := not ContourEnabled
[LAYER_BACK
];
4333 '2': ContourEnabled
[LAYER_WALLS
] := not ContourEnabled
[LAYER_WALLS
];
4334 '3': ContourEnabled
[LAYER_FOREGROUND
] := not ContourEnabled
[LAYER_FOREGROUND
];
4335 '4': ContourEnabled
[LAYER_STEPS
] := not ContourEnabled
[LAYER_STEPS
];
4336 '5': ContourEnabled
[LAYER_WATER
] := not ContourEnabled
[LAYER_WATER
];
4337 '6': ContourEnabled
[LAYER_ITEMS
] := not ContourEnabled
[LAYER_ITEMS
];
4338 '7': ContourEnabled
[LAYER_MONSTERS
] := not ContourEnabled
[LAYER_MONSTERS
];
4339 '8': ContourEnabled
[LAYER_AREAS
] := not ContourEnabled
[LAYER_AREAS
];
4340 '9': ContourEnabled
[LAYER_TRIGGERS
] := not ContourEnabled
[LAYER_TRIGGERS
];
4344 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4345 if ContourEnabled
[i
] then
4347 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4348 ContourEnabled
[i
] := not ok
4355 '1': SwitchLayer(LAYER_BACK
);
4356 '2': SwitchLayer(LAYER_WALLS
);
4357 '3': SwitchLayer(LAYER_FOREGROUND
);
4358 '4': SwitchLayer(LAYER_STEPS
);
4359 '5': SwitchLayer(LAYER_WATER
);
4360 '6': SwitchLayer(LAYER_ITEMS
);
4361 '7': SwitchLayer(LAYER_MONSTERS
);
4362 '8': SwitchLayer(LAYER_AREAS
);
4363 '9': SwitchLayer(LAYER_TRIGGERS
);
4364 '0': tbShowClick(tbShow
);
4368 if Key
= Ord('V') then
4369 begin // Поворот монстров и областей:
4370 if (SelectedObjects
<> nil) then
4372 for i
:= 0 to High(SelectedObjects
) do
4373 if (SelectedObjects
[i
].Live
) then
4375 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4377 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4380 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4382 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4388 if pcObjects
.ActivePage
= tsMonsters
then
4390 if rbMonsterLeft
.Checked
then
4391 rbMonsterRight
.Checked
:= True
4393 rbMonsterLeft
.Checked
:= True;
4395 if pcObjects
.ActivePage
= tsAreas
then
4397 if rbAreaLeft
.Checked
then
4398 rbAreaRight
.Checked
:= True
4400 rbAreaLeft
.Checked
:= True;
4405 if not (ssCtrl
in Shift
) then
4407 // Быстрое превью карты:
4408 if Key
= Ord('E') then
4410 if PreviewMode
= 0 then
4414 // Вертикальный скролл карты:
4417 if Key
= Ord('W') then
4420 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4421 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4422 MapOffset
.Y
:= -Position
;
4425 if (MouseLDown
or MouseRDown
) then
4427 if DrawRect
<> nil then
4429 Inc(MouseLDownPos
.y
, dy
);
4430 Inc(MouseRDownPos
.y
, dy
);
4432 Inc(LastMovePoint
.Y
, dy
);
4433 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4437 if Key
= Ord('S') then
4440 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4441 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4442 MapOffset
.Y
:= -Position
;
4445 if (MouseLDown
or MouseRDown
) then
4447 if DrawRect
<> nil then
4449 Inc(MouseLDownPos
.y
, dy
);
4450 Inc(MouseRDownPos
.y
, dy
);
4452 Inc(LastMovePoint
.Y
, dy
);
4453 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4458 // Горизонтальный скролл карты:
4459 with sbHorizontal
do
4461 if Key
= Ord('A') then
4464 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4465 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4466 MapOffset
.X
:= -Position
;
4469 if (MouseLDown
or MouseRDown
) then
4471 if DrawRect
<> nil then
4473 Inc(MouseLDownPos
.x
, dx
);
4474 Inc(MouseRDownPos
.x
, dx
);
4476 Inc(LastMovePoint
.X
, dx
);
4477 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4481 if Key
= Ord('D') then
4484 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4485 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4486 MapOffset
.X
:= -Position
;
4489 if (MouseLDown
or MouseRDown
) then
4491 if DrawRect
<> nil then
4493 Inc(MouseLDownPos
.x
, dx
);
4494 Inc(MouseRDownPos
.x
, dx
);
4496 Inc(LastMovePoint
.X
, dx
);
4497 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4502 else // ssCtrl in Shift
4504 if ssShift
in Shift
then
4506 // Вставка по абсолютному смещению:
4507 if Key
= Ord('V') then
4508 aPasteObjectExecute(Sender
);
4510 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4514 // Удалить выделенные объекты:
4515 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4516 RenderPanel
.Focused() then
4517 DeleteSelectedObjects();
4520 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4521 RemoveSelectFromObjects();
4523 // Передвинуть объекты:
4524 if MainForm
.ActiveControl
= RenderPanel
then
4529 if Key
= VK_NUMPAD4
then
4530 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4531 if Key
= VK_NUMPAD6
then
4532 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4533 if Key
= VK_NUMPAD8
then
4534 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4535 if Key
= VK_NUMPAD5
then
4536 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4538 if (dx
<> 0) or (dy
<> 0) then
4540 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4545 if ssCtrl
in Shift
then
4547 // Выбор панели с текстурой для триггера
4548 if Key
= Ord('T') then
4550 DrawPressRect
:= False;
4551 if SelectFlag
= SELECTFLAG_TEXTURE
then
4553 SelectFlag
:= SELECTFLAG_NONE
;
4556 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4558 SelectFlag
:= SELECTFLAG_TEXTURE
;
4561 if Key
= Ord('D') then
4563 SelectFlag
:= SELECTFLAG_NONE
;
4564 if DrawPressRect
then
4566 DrawPressRect
:= False;
4571 // Выбор области воздействия, в зависимости от типа триггера
4572 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4575 DrawPressRect
:= True;
4578 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4580 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4583 SelectFlag
:= SELECTFLAG_DOOR
;
4586 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4589 SelectFlag
:= SELECTFLAG_LIFT
;
4592 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4595 SelectFlag
:= SELECTFLAG_TELEPORT
;
4598 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4601 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4605 // Выбор основного параметра, в зависимости от типа триггера
4606 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4609 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4610 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
4611 SelectMapForm
.GetMaps(FileName
);
4613 if SelectMapForm
.ShowModal() = mrOK
then
4615 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4616 bApplyProperty
.Click();
4620 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4622 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4625 AddSoundForm
.OKFunction
:= nil;
4626 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4627 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4629 if (AddSoundForm
.ShowModal() = mrOk
) then
4631 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4632 bApplyProperty
.Click();
4636 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4638 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4641 vleObjectProperty
.Row
:= i
;
4642 vleObjectProperty
.SetFocus();
4649 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4651 RemoveSelectFromObjects();
4652 MapOptimizationForm
.ShowModal();
4655 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4657 MapCheckForm
.ShowModal();
4660 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4662 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4663 AddTextureForm
.ShowModal();
4666 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4669 TextureWidth
, TextureHeight
: Word;
4674 if (lbTextureList
.ItemIndex
<> -1) and
4675 (not IsSpecialTextureSel()) then
4677 if g_GetTexture(SelectedTexture(), TextureID
) then
4679 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4681 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4682 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4685 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4686 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4691 lTextureWidth
.Caption
:= '';
4692 lTextureHeight
.Caption
:= '';
4696 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4697 ARect
: TRect
; State
: TOwnerDrawState
);
4699 with Control
as TListBox
do
4701 if LCLType
.odSelected
in State
then
4703 Canvas
.Brush
.Color
:= clHighlight
;
4704 Canvas
.Font
.Color
:= clHighlightText
;
4706 if (Items
<> nil) and (Index
>= 0) then
4707 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4709 Canvas
.Brush
.Color
:= clRed
;
4710 Canvas
.Font
.Color
:= clWhite
;
4712 Canvas
.FillRect(ARect
);
4713 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4717 procedure TMainForm
.miReopenMapClick(Sender
: TObject
);
4719 FileName
, Resource
: String;
4721 if OpenedMap
= '' then
4724 if MessageBox(0, PChar(_lc
[I_MSG_REOPEN_MAP_PROMT
]),
4725 PChar(_lc
[I_MENU_FILE_REOPEN
]), MB_ICONQUESTION
or MB_YESNO
) <> idYes
then
4728 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, @Resource
);
4729 OpenMap(FileName
, Resource
);
4732 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4733 const KeyName
: String; Values
: TStrings
);
4735 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4737 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4739 Values
.Add(DirNames
[D_LEFT
]);
4740 Values
.Add(DirNames
[D_RIGHT
]);
4742 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4744 Values
.Add(DirNamesAdv
[0]);
4745 Values
.Add(DirNamesAdv
[1]);
4746 Values
.Add(DirNamesAdv
[2]);
4747 Values
.Add(DirNamesAdv
[3]);
4749 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4751 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4752 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4754 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4756 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4757 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4758 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4759 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4760 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4761 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4763 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4765 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4766 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4767 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4768 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4770 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4772 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4773 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4774 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4775 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4777 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4779 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4780 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4782 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4784 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4785 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4786 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4787 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4788 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4789 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4791 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4793 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4794 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4795 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4796 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4797 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4798 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4799 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4801 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
4803 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
4804 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
4805 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
4806 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
4808 else if KeyName
= _lc
[I_PROP_TR_DAMAGE_KIND
] then
4810 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_0
]);
4811 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_3
]);
4812 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_4
]);
4813 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_5
]);
4814 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_6
]);
4815 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_7
]);
4816 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_8
]);
4818 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4819 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4820 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4821 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4822 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4823 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4824 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4825 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4826 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4827 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4828 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4829 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4830 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4831 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4832 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4833 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4834 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4835 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4836 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4838 Values
.Add(BoolNames
[True]);
4839 Values
.Add(BoolNames
[False]);
4844 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4846 _id
, a
, r
, c
: Integer;
4856 if SelectedObjectCount() <> 1 then
4858 if not SelectedObjects
[GetFirstSelected()].Live
then
4862 if not CheckProperty() then
4868 _id
:= GetFirstSelected();
4870 r
:= vleObjectProperty
.Row
;
4871 c
:= vleObjectProperty
.Col
;
4873 case SelectedObjects
[_id
].ObjectType
of
4876 with gPanels
[SelectedObjects
[_id
].ID
] do
4878 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4879 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4880 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4881 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4883 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4885 // Сброс ссылки на триггеры смены текстуры:
4886 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4887 if gTriggers
<> nil then
4888 for a
:= 0 to High(gTriggers
) do
4890 if (gTriggers
[a
].TriggerType
<> 0) and
4891 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4892 gTriggers
[a
].TexturePanel
:= -1;
4893 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4894 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4895 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4898 // Сброс ссылки на триггеры лифта:
4899 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4900 if gTriggers
<> nil then
4901 for a
:= 0 to High(gTriggers
) do
4902 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4903 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4904 gTriggers
[a
].Data
.PanelID
:= -1;
4906 // Сброс ссылки на триггеры двери:
4907 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4908 if gTriggers
<> nil then
4909 for a
:= 0 to High(gTriggers
) do
4910 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4911 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4912 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4913 gTriggers
[a
].Data
.PanelID
:= -1;
4915 if IsTexturedPanel(PanelType
) then
4916 begin // Может быть текстура
4917 if TextureName
<> '' then
4918 begin // Была текстура
4919 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4920 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4929 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4931 if TextureName
<> '' then
4932 begin // Есть текстура
4933 // Обычная текстура:
4934 if not IsSpecialTexture(TextureName
) then
4936 g_GetTextureSizeByName(TextureName
,
4937 TextureWidth
, TextureHeight
);
4939 // Проверка кратности размеров панели:
4941 if TextureWidth
<> 0 then
4942 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4944 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4948 if Res
and (TextureHeight
<> 0) then
4949 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4951 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4958 if not g_GetTexture(TextureName
, TextureID
) then
4959 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4960 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4962 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4963 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4965 TextureHeight
:= NH
;
4968 TextureID
:= TEXTURE_SPECIAL_NONE
;
4978 TextureID
:= TEXTURE_SPECIAL_NONE
;
4981 else // Спец.текстура
4985 TextureID
:= SpecialTextureID(TextureName
);
4988 else // Нет текстуры
4992 TextureID
:= TEXTURE_SPECIAL_NONE
;
4995 else // Не может быть текстуры
5002 TextureID
:= TEXTURE_SPECIAL_NONE
;
5009 with gItems
[SelectedObjects
[_id
].ID
] do
5011 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5012 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5013 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5014 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5020 with gMonsters
[SelectedObjects
[_id
].ID
] do
5022 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5023 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5024 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5030 with gAreas
[SelectedObjects
[_id
].ID
] do
5032 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5033 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5034 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5040 with gTriggers
[SelectedObjects
[_id
].ID
] do
5042 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5043 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5044 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
5045 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
5046 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
5047 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
5048 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
5053 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]]);
5054 FillByte(Data
.MapName
[0], 16, 0);
5056 Move(s
[1], Data
.MapName
[0], Min(Length(s
), 16));
5061 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
5062 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
5065 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5067 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
5068 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
5069 if Data
.Count
< 1 then
5071 if TriggerType
= TRIGGER_PRESS
then
5072 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
5075 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
5076 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
5079 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5080 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5085 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5086 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
5087 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
5092 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]]);
5093 FillByte(Data
.SoundName
[0], 64, 0);
5095 Move(s
[1], Data
.SoundName
[0], Min(Length(s
), 64));
5097 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
5098 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
5099 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
5100 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
5101 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
5104 TRIGGER_SPAWNMONSTER
:
5106 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
5107 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
5108 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
5109 if Data
.MonHealth
< 0 then
5110 Data
.MonHealth
:= 0;
5111 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
5112 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5113 if Data
.MonCount
< 1 then
5115 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5116 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5117 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5119 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
5121 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
5123 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
5125 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
5127 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
5133 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
5134 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5135 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5136 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5137 if Data
.ItemCount
< 1 then
5138 Data
.ItemCount
:= 1;
5139 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5140 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5141 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5146 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]]);
5147 FillByte(Data
.MusicName
[0], 64, 0);
5149 Move(s
[1], Data
.MusicName
[0], Min(Length(s
), 64));
5151 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
5152 Data
.MusicAction
:= 1
5154 Data
.MusicAction
:= 0;
5159 Data
.PushAngle
:= Min(
5160 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
5161 Data
.PushForce
:= Min(
5162 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
5163 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
5168 Data
.ScoreAction
:= 0;
5169 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
5170 Data
.ScoreAction
:= 1
5171 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
5172 Data
.ScoreAction
:= 2
5173 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
5174 Data
.ScoreAction
:= 3;
5175 Data
.ScoreCount
:= Min(Max(
5176 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5177 Data
.ScoreTeam
:= 0;
5178 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
5180 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
5182 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
5183 Data
.ScoreTeam
:= 3;
5184 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
5185 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
5190 Data
.MessageKind
:= 0;
5191 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
5192 Data
.MessageKind
:= 1;
5194 Data
.MessageSendTo
:= 0;
5195 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
5196 Data
.MessageSendTo
:= 1
5197 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
5198 Data
.MessageSendTo
:= 2
5199 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
5200 Data
.MessageSendTo
:= 3
5201 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
5202 Data
.MessageSendTo
:= 4
5203 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
5204 Data
.MessageSendTo
:= 5;
5206 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]]);
5207 FillByte(Data
.MessageText
[0], 100, 0);
5209 Move(s
[1], Data
.MessageText
[0], Min(Length(s
), 100));
5211 Data
.MessageTime
:= Min(Max(
5212 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
5217 Data
.DamageValue
:= Min(Max(
5218 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
5219 Data
.DamageInterval
:= Min(Max(
5220 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5221 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_KIND
]];
5222 if s
= _lc
[I_PROP_TR_DAMAGE_KIND_3
] then
5223 Data
.DamageKind
:= 3
5224 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_4
] then
5225 Data
.DamageKind
:= 4
5226 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_5
] then
5227 Data
.DamageKind
:= 5
5228 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_6
] then
5229 Data
.DamageKind
:= 6
5230 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_7
] then
5231 Data
.DamageKind
:= 7
5232 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_8
] then
5233 Data
.DamageKind
:= 8
5235 Data
.DamageKind
:= 0;
5240 Data
.HealValue
:= Min(Max(
5241 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
5242 Data
.HealInterval
:= Min(Max(
5243 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5244 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
5245 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5250 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
5251 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
5252 Data
.ShotTarget
:= 0;
5253 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
5254 Data
.ShotTarget
:= 1
5255 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
5256 Data
.ShotTarget
:= 2
5257 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
5258 Data
.ShotTarget
:= 3
5259 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
5260 Data
.ShotTarget
:= 4
5261 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
5262 Data
.ShotTarget
:= 5
5263 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
5264 Data
.ShotTarget
:= 6;
5265 Data
.ShotIntSight
:= Min(Max(
5266 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
5268 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
5270 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
5272 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
5274 Data
.ShotAngle
:= Min(
5275 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
5276 Data
.ShotWait
:= Min(Max(
5277 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5278 Data
.ShotAccuracy
:= Min(Max(
5279 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
5280 Data
.ShotAmmo
:= Min(Max(
5281 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
5282 Data
.ShotIntReload
:= Min(Max(
5283 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
5288 Data
.FXCount
:= Min(Max(
5289 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5290 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
5292 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
5293 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
5294 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
5295 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
5296 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5297 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
5298 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5299 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
5300 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5301 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
5302 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5303 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
5304 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5305 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
5308 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
5309 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
5312 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
5313 Data
.FXColorR
:= a
and $FF;
5314 Data
.FXColorG
:= (a
shr 8) and $FF;
5315 Data
.FXColorB
:= (a
shr 16) and $FF;
5316 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
5320 Data
.FXWait
:= Min(Max(
5321 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5322 Data
.FXVelX
:= Min(Max(
5323 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
5324 Data
.FXVelY
:= Min(Max(
5325 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
5326 Data
.FXSpreadL
:= Min(Max(
5327 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
5328 Data
.FXSpreadR
:= Min(Max(
5329 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
5330 Data
.FXSpreadU
:= Min(Max(
5331 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
5332 Data
.FXSpreadD
:= Min(Max(
5333 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
5342 vleObjectProperty
.Row
:= r
;
5343 vleObjectProperty
.Col
:= c
;
5346 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5350 i
:= lbTextureList
.ItemIndex
;
5354 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5355 [SelectedTexture()])),
5356 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5357 MB_ICONQUESTION
or MB_YESNO
or
5358 MB_DEFBUTTON1
) <> idYes
then
5361 if gPanels
<> nil then
5362 for a
:= 0 to High(gPanels
) do
5363 if (gPanels
[a
].PanelType
<> 0) and
5364 (gPanels
[a
].TextureName
= SelectedTexture()) then
5366 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5370 g_DeleteTexture(SelectedTexture());
5371 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5373 slInvalidTextures
.Delete(i
);
5374 if lbTextureList
.ItemIndex
> -1 then
5375 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5378 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5380 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
5381 PChar(_lc
[I_MSG_CLEAR_MAP
]),
5382 MB_ICONQUESTION
or MB_YESNO
or
5383 MB_DEFBUTTON1
) = mrYes
) then
5387 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5391 if UndoBuffer
= nil then
5393 if UndoBuffer
[High(UndoBuffer
)] = nil then
5396 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5397 with UndoBuffer
[High(UndoBuffer
)][a
] do
5405 UNDO_DELETE_ITEM
: AddItem(Item
);
5406 UNDO_DELETE_AREA
: AddArea(Area
);
5407 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5408 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5409 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5410 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5411 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5412 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5413 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5417 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5419 RemoveSelectFromObjects();
5421 miUndo
.Enabled
:= UndoBuffer
<> nil;
5425 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5428 CopyBuffer
: TCopyRecArray
;
5432 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5434 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5436 if Result
= 0 then // Одного типа
5437 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5440 procedure QuickSortCopyBuffer(L
, R
: Integer);
5448 P
:= CopyBuffer
[(L
+ R
) shr 1];
5451 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5453 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5459 CopyBuffer
[I
] := CopyBuffer
[J
];
5467 QuickSortCopyBuffer(L
, J
);
5474 if SelectedObjects
= nil then
5480 // Копируем объекты:
5481 for a
:= 0 to High(SelectedObjects
) do
5482 if SelectedObjects
[a
].Live
then
5483 with SelectedObjects
[a
] do
5485 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5486 b
:= High(CopyBuffer
);
5487 CopyBuffer
[b
].ID
:= ID
;
5488 CopyBuffer
[b
].Panel
:= nil;
5493 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5494 New(CopyBuffer
[b
].Panel
);
5495 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5500 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5501 CopyBuffer
[b
].Item
:= gItems
[ID
];
5506 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5507 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5512 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5513 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5518 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5519 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5524 // Сортировка по ID:
5525 if CopyBuffer
<> nil then
5527 QuickSortCopyBuffer(0, b
);
5530 // Пестановка ссылок триггеров:
5531 for a
:= 0 to Length(CopyBuffer
)-1 do
5532 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5534 case CopyBuffer
[a
].Trigger
.TriggerType
of
5535 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5536 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5537 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5538 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5542 for b
:= 0 to Length(CopyBuffer
)-1 do
5543 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5544 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5546 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5551 // Этих панелей нет среди копируемых:
5553 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5556 TRIGGER_PRESS
, TRIGGER_ON
,
5557 TRIGGER_OFF
, TRIGGER_ONOFF
:
5558 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5562 for b
:= 0 to Length(CopyBuffer
)-1 do
5563 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5564 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5566 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5571 // Этих монстров нет среди копируемых:
5573 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5577 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5581 for b
:= 0 to Length(CopyBuffer
)-1 do
5582 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5583 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5585 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5590 // Этих панелей нет среди копируемых:
5592 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5596 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5600 for b
:= 0 to Length(CopyBuffer
)-1 do
5601 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5602 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5604 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5609 // Этих панелей нет среди копируемых:
5611 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5616 str
:= CopyBufferToString(CopyBuffer
);
5617 ClipBoard
.AsText
:= str
;
5619 for a
:= 0 to Length(CopyBuffer
)-1 do
5620 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5621 (CopyBuffer
[a
].Panel
<> nil) then
5622 Dispose(CopyBuffer
[a
].Panel
);
5627 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5630 CopyBuffer
: TCopyRecArray
;
5632 swad
, ssec
, sres
: String;
5638 pmin
.X
:= High(pmin
.X
);
5639 pmin
.Y
:= High(pmin
.Y
);
5641 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
, pmin
);
5642 rel
:= not(ssShift
in GetKeyShiftState());
5644 if CopyBuffer
= nil then
5647 RemoveSelectFromObjects();
5649 h
:= High(CopyBuffer
);
5651 with CopyBuffer
[a
] do
5655 if Panel
<> nil then
5659 Panel
^.X
:= Panel
^.X
- pmin
.X
- MapOffset
.X
+ 32;
5660 Panel
^.Y
:= Panel
^.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5663 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5664 Panel
^.TextureWidth
:= 1;
5665 Panel
^.TextureHeight
:= 1;
5667 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5668 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5669 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5670 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5671 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5672 (Panel
^.TextureName
= '') then
5673 begin // Нет или не может быть текстуры:
5675 else // Есть текстура:
5677 // Обычная текстура:
5678 if not IsSpecialTexture(Panel
^.TextureName
) then
5680 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5684 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5685 AddTexture(swad
, ssec
, sres
, True);
5686 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5690 g_GetTextureSizeByName(Panel
^.TextureName
,
5691 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5693 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5695 Panel
^.TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5696 g_GetTextureSizeByID(NoTextureID
, Panel
^.TextureWidth
, Panel
^.TextureHeight
);
5699 else // Спец.текстура:
5701 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5702 with MainForm
.lbTextureList
.Items
do
5703 if IndexOf(Panel
^.TextureName
) = -1 then
5704 Add(Panel
^.TextureName
);
5708 ID
:= AddPanel(Panel
^);
5710 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5711 SelectObject(OBJECT_PANEL
, ID
, True);
5718 Item
.X
:= Item
.X
- pmin
.X
- MapOffset
.X
+ 32;
5719 Item
.Y
:= Item
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5722 ID
:= AddItem(Item
);
5723 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5724 SelectObject(OBJECT_ITEM
, ID
, True);
5731 Monster
.X
:= Monster
.X
- pmin
.X
- MapOffset
.X
+ 32;
5732 Monster
.Y
:= Monster
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5735 ID
:= AddMonster(Monster
);
5736 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5737 SelectObject(OBJECT_MONSTER
, ID
, True);
5744 Area
.X
:= Area
.X
- pmin
.X
- MapOffset
.X
+ 32;
5745 Area
.Y
:= Area
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5748 ID
:= AddArea(Area
);
5749 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5750 SelectObject(OBJECT_AREA
, ID
, True);
5758 X
:= X
- pmin
.X
- MapOffset
.X
+ 32;
5759 Y
:= Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5764 Data
.TargetPoint
.X
:=
5765 Data
.TargetPoint
.X
- pmin
.X
- MapOffset
.X
+ 32;
5766 Data
.TargetPoint
.Y
:=
5767 Data
.TargetPoint
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5769 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5771 Data
.tX
:= Data
.tX
- pmin
.X
- MapOffset
.X
+ 32;
5772 Data
.tY
:= Data
.tY
- pmin
.Y
- MapOffset
.Y
+ 32;
5774 TRIGGER_SPAWNMONSTER
:
5777 Data
.MonPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5779 Data
.MonPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5784 Data
.ItemPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5786 Data
.ItemPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5791 Data
.ShotPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5793 Data
.ShotPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5798 ID
:= AddTrigger(Trigger
);
5799 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5800 SelectObject(OBJECT_TRIGGER
, ID
, True);
5805 // Переставляем ссылки триггеров:
5806 for a
:= 0 to High(CopyBuffer
) do
5807 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5809 case CopyBuffer
[a
].Trigger
.TriggerType
of
5810 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5811 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5812 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5813 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5814 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5815 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5817 TRIGGER_PRESS
, TRIGGER_ON
,
5818 TRIGGER_OFF
, TRIGGER_ONOFF
:
5819 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5820 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5821 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5824 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5825 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5826 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5829 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5830 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5831 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5840 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5843 DeleteSelectedObjects();
5846 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5848 Key
, FileName
: String;
5851 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5853 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5855 with ChooseTypeForm
, vleObjectProperty
do
5856 begin // Выбор типа панели:
5857 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5858 lbTypeSelect
.Items
.Clear();
5860 for b
:= 0 to High(PANELNAMES
) do
5862 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5863 if Values
[Key
] = PANELNAMES
[b
] then
5864 lbTypeSelect
.ItemIndex
:= b
;
5867 if ShowModal() = mrOK
then
5869 b
:= lbTypeSelect
.ItemIndex
;
5870 Values
[Key
] := PANELNAMES
[b
];
5871 vleObjectPropertyApply(Sender
);
5875 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5876 SelectFlag
:= SELECTFLAG_TELEPORT
5877 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5878 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5879 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5880 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5881 SelectFlag
:= SELECTFLAG_DOOR
5882 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5884 DrawPressRect
:= False;
5885 SelectFlag
:= SELECTFLAG_TEXTURE
;
5887 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5888 SelectFlag
:= SELECTFLAG_SHOTPANEL
5889 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5890 SelectFlag
:= SELECTFLAG_LIFT
5891 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5892 SelectFlag
:= SELECTFLAG_MONSTER
5893 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5895 SelectFlag
:= SELECTFLAG_NONE
;
5896 DrawPressRect
:= True;
5898 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5899 begin // Выбор следующей карты:
5900 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5901 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
5902 SelectMapForm
.GetMaps(FileName
);
5904 if SelectMapForm
.ShowModal() = mrOK
then
5906 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5907 vleObjectPropertyApply(Sender
);
5910 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5911 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5912 begin // Выбор файла звука/музыки:
5913 AddSoundForm
.OKFunction
:= nil;
5914 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5915 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
5917 if (AddSoundForm
.ShowModal() = mrOk
) then
5919 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
5920 vleObjectPropertyApply(Sender
);
5923 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5924 with ActivationTypeForm
, vleObjectProperty
do
5925 begin // Выбор типов активации:
5926 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5927 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5928 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5929 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5930 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5931 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5933 if ShowModal() = mrOK
then
5936 if cbPlayerCollide
.Checked
then
5937 b
:= ACTIVATE_PLAYERCOLLIDE
;
5938 if cbMonsterCollide
.Checked
then
5939 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5940 if cbPlayerPress
.Checked
then
5941 b
:= b
or ACTIVATE_PLAYERPRESS
;
5942 if cbMonsterPress
.Checked
then
5943 b
:= b
or ACTIVATE_MONSTERPRESS
;
5944 if cbShot
.Checked
then
5945 b
:= b
or ACTIVATE_SHOT
;
5946 if cbNoMonster
.Checked
then
5947 b
:= b
or ACTIVATE_NOMONSTER
;
5949 Values
[Key
] := ActivateToStr(b
);
5950 vleObjectPropertyApply(Sender
);
5953 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5954 with KeysForm
, vleObjectProperty
do
5955 begin // Выбор необходимых ключей:
5956 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5957 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5958 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5959 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5960 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5962 if ShowModal() = mrOK
then
5965 if cbRedKey
.Checked
then
5967 if cbGreenKey
.Checked
then
5968 b
:= b
or KEY_GREEN
;
5969 if cbBlueKey
.Checked
then
5971 if cbRedTeam
.Checked
then
5972 b
:= b
or KEY_REDTEAM
;
5973 if cbBlueTeam
.Checked
then
5974 b
:= b
or KEY_BLUETEAM
;
5976 Values
[Key
] := KeyToStr(b
);
5977 vleObjectPropertyApply(Sender
);
5980 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
5981 with ChooseTypeForm
, vleObjectProperty
do
5982 begin // Выбор типа эффекта:
5983 Caption
:= _lc
[I_CAP_FX_TYPE
];
5984 lbTypeSelect
.Items
.Clear();
5986 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
5987 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5989 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
5991 if ShowModal() = mrOK
then
5993 b
:= lbTypeSelect
.ItemIndex
;
5994 Values
[Key
] := EffectToStr(b
);
5995 vleObjectPropertyApply(Sender
);
5998 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
5999 with ChooseTypeForm
, vleObjectProperty
do
6000 begin // Выбор типа монстра:
6001 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
6002 lbTypeSelect
.Items
.Clear();
6004 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
6005 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
6007 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
6009 if ShowModal() = mrOK
then
6011 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
6012 Values
[Key
] := MonsterToStr(b
);
6013 vleObjectPropertyApply(Sender
);
6016 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
6017 with ChooseTypeForm
, vleObjectProperty
do
6018 begin // Выбор типа предмета:
6019 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
6020 lbTypeSelect
.Items
.Clear();
6022 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
6023 lbTypeSelect
.Items
.Add(ItemToStr(b
));
6024 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
6025 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
6026 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
6027 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
6028 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
6029 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
6031 b
:= StrToItem(Values
[Key
]);
6032 if b
>= ITEM_BOTTLE
then
6034 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
6036 if ShowModal() = mrOK
then
6038 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
6039 if b
>= ITEM_WEAPON_KASTET
then
6041 Values
[Key
] := ItemToStr(b
);
6042 vleObjectPropertyApply(Sender
);
6045 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
6046 with ChooseTypeForm
, vleObjectProperty
do
6047 begin // Выбор типа предмета:
6048 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
6049 lbTypeSelect
.Items
.Clear();
6051 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
6052 lbTypeSelect
.Items
.Add(ShotToStr(b
));
6054 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
6056 if ShowModal() = mrOK
then
6058 b
:= lbTypeSelect
.ItemIndex
;
6059 Values
[Key
] := ShotToStr(b
);
6060 vleObjectPropertyApply(Sender
);
6063 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
6064 with ChooseTypeForm
, vleObjectProperty
do
6065 begin // Выбор типа эффекта:
6066 Caption
:= _lc
[I_CAP_FX_TYPE
];
6067 lbTypeSelect
.Items
.Clear();
6069 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
6070 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
6071 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6072 lbTypeSelect
.ItemIndex
:= 1
6074 lbTypeSelect
.ItemIndex
:= 0;
6076 if ShowModal() = mrOK
then
6078 b
:= lbTypeSelect
.ItemIndex
;
6080 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
6082 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
6083 vleObjectPropertyApply(Sender
);
6086 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
6087 with ChooseTypeForm
, vleObjectProperty
do
6088 begin // Выбор подтипа эффекта:
6089 Caption
:= _lc
[I_CAP_FX_TYPE
];
6090 lbTypeSelect
.Items
.Clear();
6092 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6094 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
6095 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6097 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
6100 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
6101 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
6102 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
6103 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
6104 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
6105 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
6106 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
6107 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
6108 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
6109 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
6110 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
6111 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
6112 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
6113 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
6114 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
6115 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
6116 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
6119 if ShowModal() = mrOK
then
6121 b
:= lbTypeSelect
.ItemIndex
;
6123 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6124 Values
[Key
] := EffectToStr(b
+ 1)
6126 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
6127 if b
= TRIGGER_EFFECT_LLIQUID
then
6128 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
6129 if b
= TRIGGER_EFFECT_DLIQUID
then
6130 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
6131 if b
= TRIGGER_EFFECT_BLOOD
then
6132 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
6133 if b
= TRIGGER_EFFECT_SPARK
then
6134 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
6135 if b
= TRIGGER_EFFECT_BUBBLE
then
6136 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
6139 vleObjectPropertyApply(Sender
);
6142 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
6143 with vleObjectProperty
do
6144 begin // Выбор цвета эффекта:
6145 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
6146 if ColorDialog
.Execute
then
6148 Values
[Key
] := IntToStr(ColorDialog
.Color
);
6149 vleObjectPropertyApply(Sender
);
6152 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
6153 begin // Смена текстуры:
6154 vleObjectProperty
.Values
[Key
] := SelectedTexture();
6155 vleObjectPropertyApply(Sender
);
6159 procedure TMainForm
.vleObjectPropertyApply(Sender
: TObject
);
6161 // hack to prevent empty ID in list
6162 RenderPanel
.SetFocus();
6163 bApplyProperty
.Click();
6164 vleObjectProperty
.SetFocus();
6167 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
6169 FileName
, Section
, Res
: String;
6171 if OpenedMap
= '' then
6173 aSaveMapAsExecute(nil);
6177 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
6179 SaveMap(FileName
+':\'+Res
);
6182 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
6184 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
6186 if OpenDialog
.Execute() then
6188 OpenMapFile(OpenDialog
.FileName
);
6189 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
6193 procedure TMainForm
.OpenMapFile(FileName
: String);
6195 if (Pos('.ini', LowerCase(ExtractFileName(FileName
))) > 0) then
6199 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
6200 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
6201 pLoadProgress
.Show();
6206 LoadMapOld(FileName
);
6208 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(FileName
)]);
6210 pLoadProgress
.Hide();
6211 MainForm
.FormResize(Self
);
6213 else // Карты из WAD:
6215 OpenMap(FileName
, '');
6219 procedure TMainForm
.FormActivate(Sender
: TObject
);
6224 MainForm
.ActiveControl
:= RenderPanel
;
6227 if gLanguage
= '' then
6229 lang
:= SelectLanguageForm
.ShowModal();
6231 1: gLanguage
:= LANGUAGE_ENGLISH
;
6232 else gLanguage
:= LANGUAGE_RUSSIAN
;
6235 config
:= TConfig
.CreateFile(CfgFileName
);
6236 config
.WriteStr('Editor', 'Language', gLanguage
);
6237 config
.SaveFile(CfgFileName
);
6241 //e_WriteLog('Read language file', MSG_NOTIFY);
6242 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
6243 g_Language_Set(gLanguage
);
6246 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
6252 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6254 if not OpenDialog
.Execute() then
6257 FileName
:= OpenDialog
.FileName
;
6258 SelectMapForm
.Caption
:= _lc
[I_CAP_REMOVE
];
6259 SelectMapForm
.lbMapList
.Items
.Clear();
6260 SelectMapForm
.GetMaps(FileName
);
6262 if SelectMapForm
.ShowModal() <> mrOK
then
6265 MapName
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6266 if MessageBox(0, PChar(Format(_lc
[I_MSG_DELETE_MAP_PROMT
], [MapName
, OpenDialog
.FileName
])), PChar(_lc
[I_MSG_DELETE_MAP
]), MB_ICONQUESTION
or MB_YESNO
or MB_DEFBUTTON2
) <> mrYes
then
6269 g_DeleteResource(FileName
, '', MapName
, res
);
6272 MessageBox(0, PChar('Cant delete map res=' + IntToStr(res
)), PChar('Map not deleted!'), MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
6278 PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
], [MapName
])),
6279 PChar(_lc
[I_MSG_MAP_DELETED
]),
6280 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
6283 // Удалили текущую карту - сохранять по старому ее нельзя:
6284 if OpenedMap
= (FileName
+ ':\' + MapName
) then
6288 MainForm
.Caption
:= FormCaption
6292 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
6293 var Key
: Word; Shift
: TShiftState
);
6295 if Key
= VK_RETURN
then
6296 vleObjectPropertyApply(Sender
);
6299 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
6304 if (ID
= 0) and (MoveType
= 0) then
6306 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
6308 if (ID
> DWORD(High(gPanels
))) then
6313 if MoveType
= 0 then // to Back
6315 if gTriggers
<> nil then
6316 for a
:= 0 to High(gTriggers
) do
6317 with gTriggers
[a
] do
6319 if TriggerType
= TRIGGER_NONE
then
6322 if TexturePanel
= _id
then
6325 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
6329 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6330 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6331 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6332 if Data
.PanelID
= _id
then
6335 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
6339 if Data
.ShotPanelID
= _id
then
6340 Data
.ShotPanelID
:= 0
6342 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
6343 Inc(Data
.ShotPanelID
);
6347 tmp
:= gPanels
[_id
];
6349 for a
:= _id
downto 1 do
6350 gPanels
[a
] := gPanels
[a
-1];
6358 if gTriggers
<> nil then
6359 for a
:= 0 to High(gTriggers
) do
6360 with gTriggers
[a
] do
6362 if TriggerType
= TRIGGER_NONE
then
6365 if TexturePanel
= _id
then
6366 TexturePanel
:= High(gPanels
)
6368 if TexturePanel
> _id
then
6372 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6373 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6374 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6375 if Data
.PanelID
= _id
then
6376 Data
.PanelID
:= High(gPanels
)
6378 if Data
.PanelID
> _id
then
6382 if Data
.ShotPanelID
= _id
then
6383 Data
.ShotPanelID
:= High(gPanels
)
6385 if Data
.ShotPanelID
> _id
then
6386 Dec(Data
.ShotPanelID
);
6390 tmp
:= gPanels
[_id
];
6392 for a
:= _id
to High(gPanels
)-1 do
6393 gPanels
[a
] := gPanels
[a
+1];
6395 gPanels
[High(gPanels
)] := tmp
;
6397 ID
:= High(gPanels
);
6401 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6405 if SelectedObjects
= nil then
6408 for a
:= 0 to High(SelectedObjects
) do
6409 with SelectedObjects
[a
] do
6410 if Live
and (ObjectType
= OBJECT_PANEL
) then
6412 SelectedObjects
[0] := SelectedObjects
[a
];
6413 SetLength(SelectedObjects
, 1);
6420 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6424 if SelectedObjects
= nil then
6427 for a
:= 0 to High(SelectedObjects
) do
6428 with SelectedObjects
[a
] do
6429 if Live
and (ObjectType
= OBJECT_PANEL
) then
6431 SelectedObjects
[0] := SelectedObjects
[a
];
6432 SetLength(SelectedObjects
, 1);
6439 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6443 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6445 if not SaveDialog
.Execute() then
6448 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6450 if SaveMapForm
.ShowModal() <> mrOK
then
6453 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6454 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6455 OpenedWAD
:= SaveDialog
.FileName
;
6457 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6458 // Такая карта уже недавно открывалась:
6460 RecentFiles
.Delete(idx
);
6461 RecentFiles
.Insert(0, OpenedMap
);
6466 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6467 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6468 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6471 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6475 RemoveSelectFromObjects();
6477 case pcObjects
.ActivePageIndex
+1 of
6479 if gPanels
<> nil then
6480 for a
:= 0 to High(gPanels
) do
6481 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6482 SelectObject(OBJECT_PANEL
, a
, True);
6484 if gItems
<> nil then
6485 for a
:= 0 to High(gItems
) do
6486 if gItems
[a
].ItemType
<> ITEM_NONE
then
6487 SelectObject(OBJECT_ITEM
, a
, True);
6489 if gMonsters
<> nil then
6490 for a
:= 0 to High(gMonsters
) do
6491 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6492 SelectObject(OBJECT_MONSTER
, a
, True);
6494 if gAreas
<> nil then
6495 for a
:= 0 to High(gAreas
) do
6496 if gAreas
[a
].AreaType
<> AREA_NONE
then
6497 SelectObject(OBJECT_AREA
, a
, True);
6499 if gTriggers
<> nil then
6500 for a
:= 0 to High(gTriggers
) do
6501 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6502 SelectObject(OBJECT_TRIGGER
, a
, True);
6505 RecountSelectedObjects();
6508 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6510 DotEnable
:= not DotEnable
;
6511 (Sender
as TToolButton
).Down
:= DotEnable
;
6514 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6516 // FIXME: this is a shitty hack
6517 if not gDataLoaded
then
6519 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6521 e_WriteLog('Loading data', MSG_NOTIFY
);
6522 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6523 e_WriteLog('Loading more data', MSG_NOTIFY
);
6525 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6526 gDataLoaded
:= True;
6527 MainForm
.FormResize(nil);
6532 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6534 if PreviewMode
= 2 then
6537 if PreviewMode
= 0 then
6539 Splitter2
.Visible
:= False;
6540 Splitter1
.Visible
:= False;
6541 StatusBar
.Visible
:= False;
6542 PanelObjs
.Visible
:= False;
6543 PanelProps
.Visible
:= False;
6544 MainToolBar
.Visible
:= False;
6545 sbHorizontal
.Visible
:= False;
6546 sbVertical
.Visible
:= False;
6550 StatusBar
.Visible
:= True;
6551 PanelObjs
.Visible
:= True;
6552 PanelProps
.Visible
:= True;
6553 Splitter2
.Visible
:= True;
6554 Splitter1
.Visible
:= True;
6555 MainToolBar
.Visible
:= True;
6556 sbHorizontal
.Visible
:= True;
6557 sbVertical
.Visible
:= True;
6560 PreviewMode
:= PreviewMode
xor 1;
6561 (Sender
as TMenuItem
).Checked
:= PreviewMode
> 0;
6566 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6568 SwitchLayer(LAYER_BACK
);
6571 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6573 SwitchLayer(LAYER_WALLS
);
6576 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6578 SwitchLayer(LAYER_FOREGROUND
);
6581 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6583 SwitchLayer(LAYER_STEPS
);
6586 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6588 SwitchLayer(LAYER_WATER
);
6591 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6593 SwitchLayer(LAYER_ITEMS
);
6596 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6598 SwitchLayer(LAYER_MONSTERS
);
6601 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6603 SwitchLayer(LAYER_AREAS
);
6606 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6608 SwitchLayer(LAYER_TRIGGERS
);
6611 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6617 for a
:= 0 to High(LayerEnabled
) do
6618 b
:= b
and LayerEnabled
[a
];
6622 ShowLayer(LAYER_BACK
, b
);
6623 ShowLayer(LAYER_WALLS
, b
);
6624 ShowLayer(LAYER_FOREGROUND
, b
);
6625 ShowLayer(LAYER_STEPS
, b
);
6626 ShowLayer(LAYER_WATER
, b
);
6627 ShowLayer(LAYER_ITEMS
, b
);
6628 ShowLayer(LAYER_MONSTERS
, b
);
6629 ShowLayer(LAYER_AREAS
, b
);
6630 ShowLayer(LAYER_TRIGGERS
, b
);
6633 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6638 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6640 if DotStep
= DotStepOne
then
6641 DotStep
:= DotStepTwo
6643 DotStep
:= DotStepOne
;
6645 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6646 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6649 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6654 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6656 SnapToGrid
:= not SnapToGrid
;
6658 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6659 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6661 miSnapToGrid
.Checked
:= SnapToGrid
;
6664 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6666 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6667 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6669 pcObjects
.ActivePageIndex
:= 0;
6672 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6674 SaveMiniMapForm
.ShowModal();
6677 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6679 lbTextureList
.ItemIndex
:= -1;
6680 lTextureWidth
.Caption
:= '';
6681 lTextureHeight
.Caption
:= '';
6684 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6686 PackMapForm
.ShowModal();
6689 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6691 MapTestForm
.ShowModal();
6694 type SSArray
= array of String;
6696 function ParseString (Str
: AnsiString): SSArray
;
6697 function GetStr (var Str
: AnsiString): AnsiString;
6701 if Str
[1] = '"' then
6702 for b
:= 1 to Length(Str
) do
6703 if (b
= Length(Str
)) or (Str
[b
+ 1] = '"') then
6705 Result
:= Copy(Str
, 2, b
- 1);
6706 Delete(Str
, 1, b
+ 1);
6710 for a
:= 1 to Length(Str
) do
6711 if (a
= Length(Str
)) or (Str
[a
+ 1] = ' ') then
6713 Result
:= Copy(Str
, 1, a
);
6714 Delete(Str
, 1, a
+ 1);
6724 SetLength(Result
, Length(Result
)+1);
6725 Result
[High(Result
)] := GetStr(Str
);
6729 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6731 newWAD
, oldWAD
, tempMap
, ext
: String;
6738 // Сохраняем временную карту:
6741 newWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps/temp%.4d', [time
]);
6743 until not FileExists(newWAD
);
6744 if OpenedMap
<> '' then
6746 oldWad
:= g_ExtractWadName(OpenedMap
);
6747 newWad
:= newWad
+ ExtractFileExt(oldWad
);
6748 if CopyFile(oldWad
, newWad
) = false then
6749 e_WriteLog('MapTest: unable to copy [' + oldWad
+ '] to [' + newWad
+ ']', MSG_WARNING
)
6753 newWad
:= newWad
+ '.wad'
6755 tempMap
:= newWAD
+ ':\' + TEST_MAP_NAME
;
6757 tempMap
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', tempMap
);
6761 if TestOptionsTwoPlayers
then
6763 if TestOptionsTeamDamage
then
6765 if TestOptionsAllowExit
then
6767 if TestOptionsWeaponStay
then
6769 if TestOptionsMonstersDM
then
6773 proc
:= TProcessUTF8
.Create(nil);
6774 proc
.Executable
:= TestD2dExe
;
6775 proc
.Parameters
.Add('-map');
6776 proc
.Parameters
.Add(tempMap
);
6777 proc
.Parameters
.Add('-gm');
6778 proc
.Parameters
.Add(TestGameMode
);
6779 proc
.Parameters
.Add('-limt');
6780 proc
.Parameters
.Add(TestLimTime
);
6781 proc
.Parameters
.Add('-lims');
6782 proc
.Parameters
.Add(TestLimScore
);
6783 proc
.Parameters
.Add('-opt');
6784 proc
.Parameters
.Add(IntToStr(opt
));
6785 proc
.Parameters
.Add('--debug');
6787 proc
.Parameters
.Add('--close');
6789 args
:= ParseString(TestD2DArgs
);
6790 for i
:= 0 to High(args
) do
6791 proc
.Parameters
.Add(args
[i
]);
6801 Application
.Minimize();
6804 if (not res
) or (proc
.ExitCode
< 0) then
6806 MessageBox(0, 'FIXME',
6807 PChar(_lc
[I_MSG_EXEC_ERROR
]),
6808 MB_OK
or MB_ICONERROR
);
6812 SysUtils
.DeleteFile(newWAD
);
6813 Application
.Restore();
6816 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6817 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6819 MapOffset
.Y
:= -sbVertical
.Position
;
6822 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6823 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6825 MapOffset
.X
:= -sbHorizontal
.Position
;
6828 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6830 if OpenedWAD
<> '' then
6832 OpenMap(OpenedWAD
, '');
6836 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6840 RemoveSelectFromObjects();
6842 if gPanels
<> nil then
6843 for a
:= 0 to High(gPanels
) do
6844 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6845 SelectObject(OBJECT_PANEL
, a
, True);
6847 if gItems
<> nil then
6848 for a
:= 0 to High(gItems
) do
6849 if gItems
[a
].ItemType
<> ITEM_NONE
then
6850 SelectObject(OBJECT_ITEM
, a
, True);
6852 if gMonsters
<> nil then
6853 for a
:= 0 to High(gMonsters
) do
6854 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6855 SelectObject(OBJECT_MONSTER
, a
, True);
6857 if gAreas
<> nil then
6858 for a
:= 0 to High(gAreas
) do
6859 if gAreas
[a
].AreaType
<> AREA_NONE
then
6860 SelectObject(OBJECT_AREA
, a
, True);
6862 if gTriggers
<> nil then
6863 for a
:= 0 to High(gTriggers
) do
6864 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6865 SelectObject(OBJECT_TRIGGER
, a
, True);
6867 RecountSelectedObjects();
6870 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6871 var NewSize
: Integer; var Accept
: Boolean);
6873 Accept
:= (NewSize
> 140);
6876 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6877 var NewSize
: Integer; var Accept
: Boolean);
6879 Accept
:= (NewSize
> 110);
6882 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6884 EditingProperties
:= True;
6887 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6889 EditingProperties
:= False;
6892 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
6894 // Объекты передвигались:
6895 if MainForm
.ActiveControl
= RenderPanel
then
6897 if (Key
= VK_NUMPAD4
) or
6898 (Key
= VK_NUMPAD6
) or
6899 (Key
= VK_NUMPAD8
) or
6900 (Key
= VK_NUMPAD5
) or
6901 (Key
= Ord('V')) then
6904 // Быстрое превью карты:
6905 if Key
= Ord('E') then
6907 if PreviewMode
= 2 then
6910 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);