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 MapTestTimer
: TTimer
;
128 // Редактор свойств объектов:
129 vleObjectProperty
: TValueListEditor
;
131 // Панель объектов - вкладки:
133 pcObjects
: TPageControl
;
136 lbTextureList
: TListBox
;
137 // Панель настройки текстур:
138 PanelTextures
: TPanel
;
140 lTextureWidth
: TLabel
;
142 lTextureHeight
: TLabel
;
143 cbPreview
: TCheckBox
;
144 bbAddTexture
: TBitBtn
;
145 bbRemoveTexture
: TBitBtn
;
146 bClearTexture
: TButton
;
147 // Панель типов панелей:
148 PanelPanelType
: TPanel
;
149 lbPanelType
: TListBox
;
150 // Вкладка "Предметы":
152 lbItemList
: TListBox
;
155 // Вкладка "Монстры":
156 tsMonsters
: TTabSheet
;
157 lbMonsterList
: TListBox
;
158 rbMonsterLeft
: TRadioButton
;
159 rbMonsterRight
: TRadioButton
;
160 // Вкладка "Области":
162 lbAreasList
: TListBox
;
163 rbAreaLeft
: TRadioButton
;
164 rbAreaRight
: TRadioButton
;
165 // Вкладка "Триггеры":
166 tsTriggers
: TTabSheet
;
167 lbTriggersList
: TListBox
;
168 clbActivationType
: TCheckListBox
;
169 clbKeys
: TCheckListBox
;
172 Splitter1
: TSplitter
;
173 Splitter2
: TSplitter
;
174 StatusBar
: TStatusBar
;
176 // Специальные объекты:
177 ImageList
: TImageList
;
178 ilToolbar
: TImageList
;
179 OpenDialog
: TOpenDialog
;
180 SaveDialog
: TSaveDialog
;
181 selectall1
: TMenuItem
;
182 ColorDialog
: TColorDialog
;
184 procedure aAboutExecute(Sender
: TObject
);
185 procedure aCheckMapExecute(Sender
: TObject
);
186 procedure aMoveToFore(Sender
: TObject
);
187 procedure aMoveToBack(Sender
: TObject
);
188 procedure aCopyObjectExecute(Sender
: TObject
);
189 procedure aCutObjectExecute(Sender
: TObject
);
190 procedure aEditorOptionsExecute(Sender
: TObject
);
191 procedure aExitExecute(Sender
: TObject
);
192 procedure aMapOptionsExecute(Sender
: TObject
);
193 procedure aNewMapExecute(Sender
: TObject
);
194 procedure aOpenMapExecute(Sender
: TObject
);
195 procedure aOptimizeExecute(Sender
: TObject
);
196 procedure aPasteObjectExecute(Sender
: TObject
);
197 procedure aSelectAllExecute(Sender
: TObject
);
198 procedure aSaveMapExecute(Sender
: TObject
);
199 procedure aSaveMapAsExecute(Sender
: TObject
);
200 procedure aUndoExecute(Sender
: TObject
);
201 procedure aDeleteMap(Sender
: TObject
);
202 procedure bApplyPropertyClick(Sender
: TObject
);
203 procedure bbAddTextureClick(Sender
: TObject
);
204 procedure bbRemoveTextureClick(Sender
: TObject
);
205 procedure FormActivate(Sender
: TObject
);
206 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
207 procedure FormCreate(Sender
: TObject
);
208 procedure FormDestroy(Sender
: TObject
);
209 procedure FormDropFiles(Sender
: TObject
; const FileNames
: array of String);
210 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
211 procedure FormResize(Sender
: TObject
);
212 procedure lbTextureListClick(Sender
: TObject
);
213 procedure lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
214 ARect
: TRect
; State
: TOwnerDrawState
);
215 procedure miReopenMapClick(Sender
: TObject
);
216 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
217 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
218 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
219 procedure RenderPanelPaint(Sender
: TObject
);
220 procedure RenderPanelResize(Sender
: TObject
);
221 procedure Splitter1Moved(Sender
: TObject
);
222 procedure MapTestCheck(Sender
: TObject
);
223 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
224 procedure vleObjectPropertyApply(Sender
: TObject
);
225 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
226 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
228 procedure tbGridOnClick(Sender
: TObject
);
229 procedure miMapPreviewClick(Sender
: TObject
);
230 procedure miLayer1Click(Sender
: TObject
);
231 procedure miLayer2Click(Sender
: TObject
);
232 procedure miLayer3Click(Sender
: TObject
);
233 procedure miLayer4Click(Sender
: TObject
);
234 procedure miLayer5Click(Sender
: TObject
);
235 procedure miLayer6Click(Sender
: TObject
);
236 procedure miLayer7Click(Sender
: TObject
);
237 procedure miLayer8Click(Sender
: TObject
);
238 procedure miLayer9Click(Sender
: TObject
);
239 procedure tbShowClick(Sender
: TObject
);
240 procedure miSnapToGridClick(Sender
: TObject
);
241 procedure miMiniMapClick(Sender
: TObject
);
242 procedure miSwitchGridClick(Sender
: TObject
);
243 procedure miShowEdgesClick(Sender
: TObject
);
244 procedure minexttabClick(Sender
: TObject
);
245 procedure miSaveMiniMapClick(Sender
: TObject
);
246 procedure bClearTextureClick(Sender
: TObject
);
247 procedure miPackMapClick(Sender
: TObject
);
248 procedure aRecentFileExecute(Sender
: TObject
);
249 procedure miMapTestSettingsClick(Sender
: TObject
);
250 procedure miTestMapClick(Sender
: TObject
);
251 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
252 var ScrollPos
: Integer);
253 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
254 var ScrollPos
: Integer);
255 procedure miOpenWadMapClick(Sender
: TObject
);
256 procedure selectall1Click(Sender
: TObject
);
257 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
258 var Accept
: Boolean);
259 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
260 var Accept
: Boolean);
261 procedure vleObjectPropertyEnter(Sender
: TObject
);
262 procedure vleObjectPropertyExit(Sender
: TObject
);
263 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
267 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
269 procedure RefreshRecentMenu();
270 procedure OpenMapFile(FileName
: String);
271 function RenderMousePos(): TPoint
;
272 procedure RecountSelectedObjects();
278 LAYER_FOREGROUND
= 2;
286 TEST_MAP_NAME
= '$$$_TEST_$$$';
287 LANGUAGE_FILE_NAME
= '_Editor.txt';
298 DotStepOne
, DotStepTwo
: Word;
300 DrawTexturePanel
: Boolean;
301 DrawPanelSize
: Boolean;
303 PreviewColor
: TColor
;
304 UseCheckerboard
: Boolean;
306 RecentCount
: Integer;
307 RecentFiles
: TStringList
;
308 slInvalidTextures
: TStringList
;
310 TestGameMode
: String;
312 TestLimScore
: String;
313 TestOptionsTwoPlayers
: Boolean;
314 TestOptionsTeamDamage
: Boolean;
315 TestOptionsAllowExit
: Boolean;
316 TestOptionsWeaponStay
: Boolean;
317 TestOptionsMonstersDM
: Boolean;
318 TestD2dExe
, TestD2DArgs
: String;
319 TestMapOnce
: Boolean;
321 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
322 (True, True, True, True, True, True, True, True, True);
323 ContourEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
324 (False, False, False, False, False, False, False, False, False);
325 PreviewMode
: Byte = 0;
331 procedure OpenMap(FileName
: String; mapN
: String);
332 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
333 procedure RemoveSelectFromObjects();
334 procedure ChangeShownProperty(Name
: String; NewValue
: String);
339 f_options
, e_graphics
, e_log
, GL
, Math
,
340 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
341 f_mapcheck
, f_addresource_texture
, g_textures
,
342 f_activationtype
, f_keys
, wadreader
, fileutil
,
343 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, MAPDEF
,
344 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
345 f_addresource_sound
, f_maptest
, f_choosetype
,
346 g_language
, f_selectlang
, ClipBrd
, g_resources
, g_options
;
349 UNDO_DELETE_PANEL
= 1;
350 UNDO_DELETE_ITEM
= 2;
351 UNDO_DELETE_AREA
= 3;
352 UNDO_DELETE_MONSTER
= 4;
353 UNDO_DELETE_TRIGGER
= 5;
357 UNDO_ADD_MONSTER
= 9;
358 UNDO_ADD_TRIGGER
= 10;
359 UNDO_MOVE_PANEL
= 11;
362 UNDO_MOVE_MONSTER
= 14;
363 UNDO_MOVE_TRIGGER
= 15;
364 UNDO_RESIZE_PANEL
= 16;
365 UNDO_RESIZE_TRIGGER
= 17;
367 MOUSEACTION_NONE
= 0;
368 MOUSEACTION_DRAWPANEL
= 1;
369 MOUSEACTION_DRAWTRIGGER
= 2;
370 MOUSEACTION_MOVEOBJ
= 3;
371 MOUSEACTION_RESIZE
= 4;
372 MOUSEACTION_MOVEMAP
= 5;
373 MOUSEACTION_DRAWPRESS
= 6;
374 MOUSEACTION_NOACTION
= 7;
377 RESIZETYPE_VERTICAL
= 1;
378 RESIZETYPE_HORIZONTAL
= 2;
387 SELECTFLAG_TELEPORT
= 1;
389 SELECTFLAG_TEXTURE
= 3;
391 SELECTFLAG_MONSTER
= 5;
392 SELECTFLAG_SPAWNPOINT
= 6;
393 SELECTFLAG_SHOTPANEL
= 7;
394 SELECTFLAG_SELECTED
= 8;
396 RECENT_FILES_MENU_START
= 12;
398 CLIPBOARD_SIG
= 'DF:ED';
404 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
405 UNDO_DELETE_ITEM
: (Item
: TItem
);
406 UNDO_DELETE_AREA
: (Area
: TArea
);
407 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
408 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
413 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
418 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
420 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
427 OBJECT_PANEL
: (Panel
: ^TPanel
);
428 OBJECT_ITEM
: (Item
: TItem
);
429 OBJECT_AREA
: (Area
: TArea
);
430 OBJECT_MONSTER
: (Monster
: TMonster
);
431 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
434 TCopyRecArray
= Array of TCopyRec
;
438 gDataLoaded
: Boolean = False;
439 ShowMap
: Boolean = False;
440 DrawRect
: PRect
= nil;
441 SnapToGrid
: Boolean = True;
443 MousePos
: Types
.TPoint
;
444 LastMovePoint
: Types
.TPoint
;
448 MouseLDownPos
: Types
.TPoint
;
449 MouseRDownPos
: Types
.TPoint
;
450 MouseMDownPos
: Types
.TPoint
;
452 SelectFlag
: Byte = SELECTFLAG_NONE
;
453 MouseAction
: Byte = MOUSEACTION_NONE
;
454 ResizeType
: Byte = RESIZETYPE_NONE
;
455 ResizeDirection
: Byte = RESIZEDIR_NONE
;
457 DrawPressRect
: Boolean = False;
458 EditingProperties
: Boolean = False;
460 UndoBuffer
: Array of Array of TUndoRec
= nil;
462 MapTestProcess
: TProcessUTF8
;
467 //----------------------------------------
468 //Далее идут вспомогательные процедуры
469 //----------------------------------------
471 function NameToBool(Name
: String): Boolean;
473 if Name
= BoolNames
[True] then
479 function NameToDir(Name
: String): TDirection
;
481 if Name
= DirNames
[D_LEFT
] then
487 function NameToDirAdv(Name
: String): Byte;
489 if Name
= DirNamesAdv
[1] then
492 if Name
= DirNamesAdv
[2] then
495 if Name
= DirNamesAdv
[3] then
501 function ActivateToStr(ActivateType
: Byte): String;
505 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
506 Result
:= Result
+ '+PC';
507 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
508 Result
:= Result
+ '+MC';
509 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
510 Result
:= Result
+ '+PP';
511 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
512 Result
:= Result
+ '+MP';
513 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
514 Result
:= Result
+ '+SH';
515 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
516 Result
:= Result
+ '+NM';
518 if (Result
<> '') and (Result
[1] = '+') then
519 Delete(Result
, 1, 1);
522 function StrToActivate(Str
: String): Byte;
526 if Pos('PC', Str
) > 0 then
527 Result
:= ACTIVATE_PLAYERCOLLIDE
;
528 if Pos('MC', Str
) > 0 then
529 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
530 if Pos('PP', Str
) > 0 then
531 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
532 if Pos('MP', Str
) > 0 then
533 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
534 if Pos('SH', Str
) > 0 then
535 Result
:= Result
or ACTIVATE_SHOT
;
536 if Pos('NM', Str
) > 0 then
537 Result
:= Result
or ACTIVATE_NOMONSTER
;
540 function KeyToStr(Key
: Byte): String;
544 if ByteBool(KEY_RED
and Key
) then
545 Result
:= Result
+ '+RK';
546 if ByteBool(KEY_GREEN
and Key
) then
547 Result
:= Result
+ '+GK';
548 if ByteBool(KEY_BLUE
and Key
) then
549 Result
:= Result
+ '+BK';
550 if ByteBool(KEY_REDTEAM
and Key
) then
551 Result
:= Result
+ '+RT';
552 if ByteBool(KEY_BLUETEAM
and Key
) then
553 Result
:= Result
+ '+BT';
555 if (Result
<> '') and (Result
[1] = '+') then
556 Delete(Result
, 1, 1);
559 function StrToKey(Str
: String): Byte;
563 if Pos('RK', Str
) > 0 then
565 if Pos('GK', Str
) > 0 then
566 Result
:= Result
or KEY_GREEN
;
567 if Pos('BK', Str
) > 0 then
568 Result
:= Result
or KEY_BLUE
;
569 if Pos('RT', Str
) > 0 then
570 Result
:= Result
or KEY_REDTEAM
;
571 if Pos('BT', Str
) > 0 then
572 Result
:= Result
or KEY_BLUETEAM
;
575 function EffectToStr(Effect
: Byte): String;
577 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
578 Result
:= EffectNames
[Effect
]
580 Result
:= EffectNames
[EFFECT_NONE
];
583 function StrToEffect(Str
: String): Byte;
587 Result
:= EFFECT_NONE
;
588 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
589 if EffectNames
[i
] = Str
then
596 function MonsterToStr(MonType
: Byte): String;
598 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
599 Result
:= MonsterNames
[MonType
]
601 Result
:= MonsterNames
[MONSTER_ZOMBY
];
604 function StrToMonster(Str
: String): Byte;
608 Result
:= MONSTER_ZOMBY
;
609 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
610 if MonsterNames
[i
] = Str
then
617 function ItemToStr(ItemType
: Byte): String;
619 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
620 Result
:= ItemNames
[ItemType
]
622 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
625 function StrToItem(Str
: String): Byte;
629 Result
:= ITEM_AMMO_BULLETS
;
630 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
631 if ItemNames
[i
] = Str
then
638 function ShotToStr(ShotType
: Byte): String;
640 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
641 Result
:= ShotNames
[ShotType
]
643 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
646 function StrToShot(Str
: String): Byte;
650 Result
:= TRIGGER_SHOT_PISTOL
;
651 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
652 if ShotNames
[i
] = Str
then
659 function SelectedObjectCount(): Word;
665 if SelectedObjects
= nil then
668 for a
:= 0 to High(SelectedObjects
) do
669 if SelectedObjects
[a
].Live
then
670 Result
:= Result
+ 1;
673 function GetFirstSelected(): Integer;
679 if SelectedObjects
= nil then
682 for a
:= 0 to High(SelectedObjects
) do
683 if SelectedObjects
[a
].Live
then
690 function Normalize16(x
: Integer): Integer;
692 Result
:= (x
div 16) * 16;
695 procedure MoveMap(X
, Y
: Integer);
697 rx
, ry
, ScaleSz
: Integer;
699 with MainForm
.RenderPanel
do
701 ScaleSz
:= 16 div Scale
;
702 // Размер видимой части карты:
703 rx
:= Min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
704 ry
:= Min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
705 // Место клика на мини-карте:
706 MapOffset
.X
:= X
- (Width
- Max(gMapInfo
.Width
div ScaleSz
, 1) - 1);
707 MapOffset
.Y
:= Y
- 1;
708 // Это же место на "большой" карте:
709 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
710 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
711 // Левый верхний угол новой видимой части карты:
712 MapOffset
.X
:= MapOffset
.X
- rx
;
713 MapOffset
.Y
:= MapOffset
.Y
- ry
;
715 MapOffset
.X
:= EnsureRange(MapOffset
.X
, MainForm
.sbHorizontal
.Min
, MainForm
.sbHorizontal
.Max
);
716 MapOffset
.Y
:= EnsureRange(MapOffset
.Y
, MainForm
.sbVertical
.Min
, MainForm
.sbVertical
.Max
);
718 // MapOffset.X := Normalize16(MapOffset.X);
719 // MapOffset.Y := Normalize16(MapOffset.Y);
722 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
723 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
725 MapOffset
.X
:= -MapOffset
.X
;
726 MapOffset
.Y
:= -MapOffset
.Y
;
731 function IsTexturedPanel(PanelType
: Word): Boolean;
733 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
734 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
735 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
738 procedure FillProperty();
743 MainForm
.vleObjectProperty
.Strings
.Clear();
744 MainForm
.RecountSelectedObjects();
746 // Отображаем свойства если выделен только один объект:
747 if SelectedObjectCount() <> 1 then
750 _id
:= GetFirstSelected();
751 if not SelectedObjects
[_id
].Live
then
754 with MainForm
.vleObjectProperty
do
755 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
757 EditStyle
:= esSimple
;
761 case SelectedObjects
[0].ObjectType
of
764 with MainForm
.vleObjectProperty
,
765 gPanels
[SelectedObjects
[_id
].ID
] do
767 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
769 EditStyle
:= esSimple
;
773 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
775 EditStyle
:= esSimple
;
779 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
781 EditStyle
:= esSimple
;
785 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
787 EditStyle
:= esSimple
;
791 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
793 EditStyle
:= esEllipsis
;
797 if IsTexturedPanel(PanelType
) then
798 begin // Может быть текстура
799 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
801 EditStyle
:= esEllipsis
;
805 if TextureName
<> '' then
806 begin // Есть текстура
807 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
809 EditStyle
:= esSimple
;
813 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
815 EditStyle
:= esPickList
;
825 with MainForm
.vleObjectProperty
,
826 gItems
[SelectedObjects
[_id
].ID
] do
828 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
830 EditStyle
:= esSimple
;
834 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
836 EditStyle
:= esSimple
;
840 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
842 EditStyle
:= esPickList
;
846 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
848 EditStyle
:= esPickList
;
856 with MainForm
.vleObjectProperty
,
857 gMonsters
[SelectedObjects
[_id
].ID
] do
859 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
861 EditStyle
:= esSimple
;
865 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
867 EditStyle
:= esSimple
;
871 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
873 EditStyle
:= esPickList
;
881 with MainForm
.vleObjectProperty
,
882 gAreas
[SelectedObjects
[_id
].ID
] do
884 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
886 EditStyle
:= esSimple
;
890 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
892 EditStyle
:= esSimple
;
896 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
898 EditStyle
:= esPickList
;
906 with MainForm
.vleObjectProperty
,
907 gTriggers
[SelectedObjects
[_id
].ID
] do
909 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
911 EditStyle
:= esSimple
;
915 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
917 EditStyle
:= esSimple
;
921 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
923 EditStyle
:= esSimple
;
927 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
929 EditStyle
:= esSimple
;
933 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
935 EditStyle
:= esSimple
;
939 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
941 EditStyle
:= esPickList
;
945 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
947 EditStyle
:= esEllipsis
;
951 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
953 EditStyle
:= esEllipsis
;
957 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
959 EditStyle
:= esEllipsis
;
966 str
:= win2utf(Data
.MapName
);
967 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], str
, True)] do
969 EditStyle
:= esEllipsis
;
976 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
978 EditStyle
:= esEllipsis
;
982 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
984 EditStyle
:= esPickList
;
988 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
990 EditStyle
:= esPickList
;
994 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
996 EditStyle
:= esPickList
;
1001 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
1002 TRIGGER_DOOR
, TRIGGER_DOOR5
:
1004 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
1006 EditStyle
:= esEllipsis
;
1010 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1012 EditStyle
:= esPickList
;
1016 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1018 EditStyle
:= esPickList
;
1023 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1025 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1027 EditStyle
:= esEllipsis
;
1031 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1033 EditStyle
:= esPickList
;
1037 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1039 EditStyle
:= esPickList
;
1044 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1047 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1048 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1050 EditStyle
:= esEllipsis
;
1054 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1056 EditStyle
:= esSimple
;
1060 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1062 EditStyle
:= esSimple
;
1066 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1068 EditStyle
:= esEllipsis
;
1072 if TriggerType
= TRIGGER_PRESS
then
1073 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1075 EditStyle
:= esPickList
;
1083 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1085 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1087 EditStyle
:= esEllipsis
;
1091 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1093 EditStyle
:= esPickList
;
1097 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1099 EditStyle
:= esPickList
;
1106 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1108 EditStyle
:= esPickList
;
1112 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1114 EditStyle
:= esPickList
;
1121 str
:= win2utf(Data
.SoundName
);
1122 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], str
, True)] do
1124 EditStyle
:= esEllipsis
;
1128 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1130 EditStyle
:= esSimple
;
1134 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1136 EditStyle
:= esSimple
;
1140 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1142 EditStyle
:= esSimple
;
1146 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1148 EditStyle
:= esPickList
;
1152 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1154 EditStyle
:= esPickList
;
1159 TRIGGER_SPAWNMONSTER
:
1161 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1163 EditStyle
:= esEllipsis
;
1167 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1168 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1170 EditStyle
:= esEllipsis
;
1174 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1176 EditStyle
:= esPickList
;
1180 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1182 EditStyle
:= esSimple
;
1186 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1188 EditStyle
:= esPickList
;
1192 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1194 EditStyle
:= esSimple
;
1198 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1200 EditStyle
:= esEllipsis
;
1204 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1206 EditStyle
:= esSimple
;
1210 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1212 EditStyle
:= esSimple
;
1216 case Data
.MonBehav
of
1217 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1218 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1219 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1220 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1221 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1222 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1224 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1226 EditStyle
:= esPickList
;
1233 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1235 EditStyle
:= esEllipsis
;
1239 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1240 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1242 EditStyle
:= esEllipsis
;
1246 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1248 EditStyle
:= esPickList
;
1252 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1254 EditStyle
:= esPickList
;
1258 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1260 EditStyle
:= esSimple
;
1264 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1266 EditStyle
:= esEllipsis
;
1270 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1272 EditStyle
:= esSimple
;
1276 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1278 EditStyle
:= esSimple
;
1285 str
:= win2utf(Data
.MusicName
);
1286 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], str
, True)] do
1288 EditStyle
:= esEllipsis
;
1292 if Data
.MusicAction
= 1 then
1293 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1295 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1297 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1299 EditStyle
:= esPickList
;
1306 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1308 EditStyle
:= esSimple
;
1311 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1313 EditStyle
:= esSimple
;
1316 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1318 EditStyle
:= esPickList
;
1325 case Data
.ScoreAction
of
1326 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1327 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1328 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1329 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1331 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1333 EditStyle
:= esPickList
;
1336 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1338 EditStyle
:= esSimple
;
1341 case Data
.ScoreTeam
of
1342 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1343 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1344 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1345 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1347 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1349 EditStyle
:= esPickList
;
1352 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1354 EditStyle
:= esPickList
;
1357 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1359 EditStyle
:= esPickList
;
1366 case Data
.MessageKind
of
1367 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1368 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1370 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1372 EditStyle
:= esPickList
;
1375 case Data
.MessageSendTo
of
1376 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1377 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1378 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1379 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1380 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1381 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1383 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1385 EditStyle
:= esPickList
;
1388 str
:= win2utf(Data
.MessageText
);
1389 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], str
, True)] do
1391 EditStyle
:= esSimple
;
1394 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1396 EditStyle
:= esSimple
;
1403 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1405 EditStyle
:= esSimple
;
1408 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1410 EditStyle
:= esSimple
;
1413 case Data
.DamageKind
of
1414 3: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_3
];
1415 4: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_4
];
1416 5: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_5
];
1417 6: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_6
];
1418 7: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_7
];
1419 8: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_8
];
1420 else str
:= _lc
[I_PROP_TR_DAMAGE_KIND_0
];
1422 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_KIND
], str
, True)] do
1424 EditStyle
:= esPickList
;
1431 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1433 EditStyle
:= esSimple
;
1436 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1438 EditStyle
:= esSimple
;
1441 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1443 EditStyle
:= esPickList
;
1446 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1448 EditStyle
:= esPickList
;
1455 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1457 EditStyle
:= esEllipsis
;
1461 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1463 EditStyle
:= esPickList
;
1467 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1469 EditStyle
:= esEllipsis
;
1473 case Data
.ShotTarget
of
1474 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1475 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1476 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1477 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1478 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1479 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1480 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1482 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1484 EditStyle
:= esPickList
;
1488 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1490 EditStyle
:= esSimple
;
1494 case Data
.ShotAim
of
1495 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1496 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1497 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1498 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1500 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)] do
1502 EditStyle
:= esPickList
;
1506 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1507 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1509 EditStyle
:= esEllipsis
;
1513 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1515 EditStyle
:= esSimple
;
1519 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1521 EditStyle
:= esSimple
;
1525 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1527 EditStyle
:= esSimple
;
1531 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1533 EditStyle
:= esSimple
;
1537 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1539 EditStyle
:= esSimple
;
1546 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1548 EditStyle
:= esSimple
;
1552 if Data
.FXType
= 0 then
1553 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1555 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1556 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1558 EditStyle
:= esEllipsis
;
1563 if Data
.FXType
= 0 then
1564 case Data
.FXSubType
of
1565 TRIGGER_EFFECT_SLIQUID
:
1566 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1567 TRIGGER_EFFECT_LLIQUID
:
1568 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1569 TRIGGER_EFFECT_DLIQUID
:
1570 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1571 TRIGGER_EFFECT_BLOOD
:
1572 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1573 TRIGGER_EFFECT_SPARK
:
1574 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1575 TRIGGER_EFFECT_BUBBLE
:
1576 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1578 if Data
.FXType
= 1 then
1580 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1581 Data
.FXSubType
:= EFFECT_TELEPORT
;
1582 str
:= EffectToStr(Data
.FXSubType
);
1584 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1586 EditStyle
:= esEllipsis
;
1590 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1592 EditStyle
:= esEllipsis
;
1596 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1598 EditStyle
:= esPickList
;
1602 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1604 EditStyle
:= esSimple
;
1608 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1610 EditStyle
:= esSimple
;
1614 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1616 EditStyle
:= esSimple
;
1620 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1622 EditStyle
:= esSimple
;
1626 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1628 EditStyle
:= esSimple
;
1632 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1634 EditStyle
:= esSimple
;
1638 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1640 EditStyle
:= esSimple
;
1644 end; //case TriggerType
1646 end; // OBJECT_TRIGGER:
1650 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1654 if SelectedObjectCount() <> 1 then
1656 if not SelectedObjects
[GetFirstSelected()].Live
then
1659 // Есть ли такой ключ:
1660 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1662 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1666 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1675 // Уже выделен - убираем:
1676 if SelectedObjects
<> nil then
1677 for a
:= 0 to High(SelectedObjects
) do
1678 with SelectedObjects
[a
] do
1679 if Live
and (ID
= fID
) and
1680 (ObjectType
= fObjectType
) then
1689 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1691 with SelectedObjects
[High(SelectedObjects
)] do
1693 ObjectType
:= fObjectType
;
1700 SetLength(SelectedObjects
, 1);
1702 with SelectedObjects
[0] do
1704 ObjectType
:= fObjectType
;
1710 MainForm
.miCopy
.Enabled
:= True;
1711 MainForm
.miCut
.Enabled
:= True;
1713 if fObjectType
= OBJECT_PANEL
then
1715 MainForm
.miToFore
.Enabled
:= True;
1716 MainForm
.miToBack
.Enabled
:= True;
1720 procedure RemoveSelectFromObjects();
1722 SelectedObjects
:= nil;
1723 DrawPressRect
:= False;
1724 MouseLDown
:= False;
1725 MouseRDown
:= False;
1726 MouseAction
:= MOUSEACTION_NONE
;
1727 SelectFlag
:= SELECTFLAG_NONE
;
1728 ResizeType
:= RESIZETYPE_NONE
;
1729 ResizeDirection
:= RESIZEDIR_NONE
;
1731 MainForm
.vleObjectProperty
.Strings
.Clear();
1733 MainForm
.miCopy
.Enabled
:= False;
1734 MainForm
.miCut
.Enabled
:= False;
1735 MainForm
.miToFore
.Enabled
:= False;
1736 MainForm
.miToBack
.Enabled
:= False;
1739 procedure DeleteSelectedObjects();
1744 if SelectedObjects
= nil then
1750 for a
:= 0 to High(SelectedObjects
) do
1751 with SelectedObjects
[a
] do
1756 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1757 i
:= High(UndoBuffer
);
1761 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1762 ii
:= High(UndoBuffer
[i
]);
1767 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1768 New(UndoBuffer
[i
, ii
].Panel
);
1769 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1773 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1774 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1778 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1779 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1783 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1784 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1788 RemoveObject(ID
, ObjectType
);
1791 RemoveSelectFromObjects();
1793 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1794 MainForm
.RecountSelectedObjects();
1797 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1801 if (not Group
) or (Length(UndoBuffer
) = 0) then
1802 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1803 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1804 i
:= High(UndoBuffer
);
1805 ii
:= High(UndoBuffer
[i
]);
1809 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1811 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1813 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1815 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1817 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1820 UndoBuffer
[i
, ii
].AddID
:= ID
;
1822 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1825 procedure FullClear();
1827 RemoveSelectFromObjects();
1829 LoadSky(gMapInfo
.SkyName
);
1831 slInvalidTextures
.Clear();
1832 MapCheckForm
.lbErrorList
.Clear();
1833 MapCheckForm
.mErrorDescription
.Clear();
1835 MainForm
.miUndo
.Enabled
:= False;
1836 MainForm
.sbHorizontal
.Position
:= 0;
1837 MainForm
.sbVertical
.Position
:= 0;
1838 MainForm
.FormResize(nil);
1839 MainForm
.Caption
:= FormCaption
;
1844 procedure ErrorMessageBox(str
: String);
1846 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1847 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1850 function CheckProperty(): Boolean;
1856 _id
:= GetFirstSelected();
1858 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1859 with gPanels
[SelectedObjects
[_id
].ID
] do
1861 if TextureWidth
<> 0 then
1862 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1864 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1869 if TextureHeight
<> 0 then
1870 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1872 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1877 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1878 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1880 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1885 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1886 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1887 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1889 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1893 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1894 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1896 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1903 procedure SelectTexture(ID
: Integer);
1905 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1906 MainForm
.lbTextureListClick(nil);
1909 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1911 a
, FrameLen
: Integer;
1914 ResourceName
: String;
1915 FullResourceName
: String;
1916 SectionName
: String;
1918 Width
, Height
: Word;
1926 if aSection
= '..' then
1929 SectionName
:= aSection
;
1932 aWAD
:= _lc
[I_WAD_SPECIAL_MAP
];
1934 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1936 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1937 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1939 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1942 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1943 begin // Спец. текстуры
1945 ResourceName
:= aTex
;
1948 begin // Внешний WAD
1949 FileName
:= WadsDir
+ DirectorySeparator
+ aWAD
;
1950 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1955 // Есть ли уже такая текстура:
1956 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1957 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1960 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1965 // Название ресурса <= 64 символов:
1966 if Length(ResourceName
) > 64 then
1969 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1977 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1979 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1986 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1988 if IsAnim(FullResourceName
) then
1989 begin // Аним. текстура
1990 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
1992 if not g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
1994 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1996 else // Обычная текстура
1998 if not g_CreateTextureWAD(ResourceName
, FullResourceName
) then
2000 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
2002 if (not ok
) and (slInvalidTextures
.IndexOf(ResourceName
) = -1) then
2004 slInvalidTextures
.Add(ResourceName
);
2007 if (a
> -1) and (not silent
) then
2014 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
2017 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
2018 Caption
:= FormCaption
2021 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
2023 if (sFile
<> '') and (sRes
<> '') then
2024 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
2026 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
2029 procedure OpenMap(FileName
: String; mapN
: String);
2034 SelectMapForm
.Caption
:= _lc
[I_CAP_OPEN
];
2035 SelectMapForm
.GetMaps(FileName
);
2037 if (FileName
= OpenedWAD
) and
2038 (OpenedMap
<> '') then
2040 MapName
:= OpenedMap
;
2041 while (Pos(':\', MapName
) > 0) do
2042 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
2044 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2045 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2048 if SelectMapForm
.lbMapList
.Count
> 0 then
2049 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2051 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2056 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2060 if (SelectMapForm
.ShowModal() = mrOK
) and
2061 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2062 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2067 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2073 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2074 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2075 pLoadProgress
.Show();
2077 OpenedMap
:= FileName
+':\'+MapName
;
2078 OpenedWAD
:= FileName
;
2080 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2081 // Такая карта уже недавно открывалась:
2083 RecentFiles
.Delete(idx
);
2084 RecentFiles
.Insert(0, OpenedMap
);
2085 RefreshRecentMenu();
2089 pLoadProgress
.Hide();
2092 lbTextureList
.Sorted
:= True;
2093 lbTextureList
.Sorted
:= False;
2095 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2099 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2104 if SelectedObjects
= nil then
2111 for a
:= 0 to High(SelectedObjects
) do
2112 if SelectedObjects
[a
].Live
then
2114 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2117 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2120 if (not okX
) or (not okY
) then
2126 for a
:= 0 to High(SelectedObjects
) do
2127 if SelectedObjects
[a
].Live
then
2130 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2133 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2135 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2137 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2138 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2139 begin // Двигаем зону Расширителя
2141 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2143 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2146 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2147 begin // Двигаем точку назначения Телепорта
2149 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2151 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2154 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2155 begin // Двигаем точку создания монстра
2157 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2159 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2162 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2163 begin // Двигаем точку создания предмета
2165 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2167 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2170 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2171 begin // Двигаем точку создания выстрела
2173 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2175 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2180 LastMovePoint
:= MousePos
;
2184 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2186 LayerEnabled
[Layer
] := show
;
2191 MainForm
.miLayer1
.Checked
:= show
;
2192 MainForm
.miLayerP1
.Checked
:= show
;
2196 MainForm
.miLayer2
.Checked
:= show
;
2197 MainForm
.miLayerP2
.Checked
:= show
;
2201 MainForm
.miLayer3
.Checked
:= show
;
2202 MainForm
.miLayerP3
.Checked
:= show
;
2206 MainForm
.miLayer4
.Checked
:= show
;
2207 MainForm
.miLayerP4
.Checked
:= show
;
2211 MainForm
.miLayer5
.Checked
:= show
;
2212 MainForm
.miLayerP5
.Checked
:= show
;
2216 MainForm
.miLayer6
.Checked
:= show
;
2217 MainForm
.miLayerP6
.Checked
:= show
;
2221 MainForm
.miLayer7
.Checked
:= show
;
2222 MainForm
.miLayerP7
.Checked
:= show
;
2226 MainForm
.miLayer8
.Checked
:= show
;
2227 MainForm
.miLayerP8
.Checked
:= show
;
2231 MainForm
.miLayer9
.Checked
:= show
;
2232 MainForm
.miLayerP9
.Checked
:= show
;
2236 RemoveSelectFromObjects();
2239 procedure SwitchLayer(Layer
: Byte);
2241 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2244 procedure SwitchMap();
2246 ShowMap
:= not ShowMap
;
2247 MainForm
.tbShowMap
.Down
:= ShowMap
;
2250 procedure ShowEdges();
2252 if drEdge
[3] < 255 then
2255 drEdge
[3] := gAlphaEdge
;
2258 function SelectedTexture(): String;
2260 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2261 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2266 function IsSpecialTextureSel(): Boolean;
2268 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2269 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2272 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2277 procedure AddInt(x
: Integer);
2279 Res
:= Res
+ IntToStr(x
) + ' ';
2285 if Length(CopyBuf
) = 0 then
2288 Res
:= CLIPBOARD_SIG
+ ' ';
2290 for i
:= 0 to High(CopyBuf
) do
2292 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2293 (CopyBuf
[i
].Panel
= nil) then
2297 AddInt(CopyBuf
[i
].ObjectType
);
2300 // Свойства объекта:
2301 case CopyBuf
[i
].ObjectType
of
2303 with CopyBuf
[i
].Panel
^ do
2310 Res
:= Res
+ '"' + TextureName
+ '" ';
2312 AddInt(IfThen(Blending
, 1, 0));
2316 with CopyBuf
[i
].Item
do
2321 AddInt(IfThen(OnlyDM
, 1, 0));
2322 AddInt(IfThen(Fall
, 1, 0));
2326 with CopyBuf
[i
].Monster
do
2328 AddInt(MonsterType
);
2331 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2335 with CopyBuf
[i
].Area
do
2340 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2344 with CopyBuf
[i
].Trigger
do
2346 AddInt(TriggerType
);
2351 AddInt(ActivateType
);
2353 AddInt(IfThen(Enabled
, 1, 0));
2354 AddInt(TexturePanel
);
2356 for j
:= 0 to 127 do
2357 AddInt(Data
.Default
[j
]);
2365 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
;
2370 function GetNext(): String;
2375 if Str
[1] = '"' then
2387 Result
:= Copy(Str
, 1, p
-1);
2403 Result
:= Copy(Str
, 1, p
-1);
2413 if GetNext() <> CLIPBOARD_SIG
then
2419 t
:= StrToIntDef(GetNext(), 0);
2421 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2422 (GetNext() <> ';') then
2423 begin // Что-то не то => пропускаем:
2431 i
:= Length(CopyBuf
);
2432 SetLength(CopyBuf
, i
+ 1);
2434 CopyBuf
[i
].ObjectType
:= t
;
2435 CopyBuf
[i
].Panel
:= nil;
2437 // Свойства объекта:
2441 New(CopyBuf
[i
].Panel
);
2443 with CopyBuf
[i
].Panel
^ do
2445 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2446 X
:= StrToIntDef(GetNext(), 0);
2447 Y
:= StrToIntDef(GetNext(), 0);
2448 pmin
.X
:= Min(X
, pmin
.X
);
2449 pmin
.Y
:= Min(Y
, pmin
.Y
);
2450 Width
:= StrToIntDef(GetNext(), 16);
2451 Height
:= StrToIntDef(GetNext(), 16);
2452 TextureName
:= GetNext();
2453 Alpha
:= StrToIntDef(GetNext(), 0);
2454 Blending
:= (GetNext() = '1');
2459 with CopyBuf
[i
].Item
do
2461 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2462 X
:= StrToIntDef(GetNext(), 0);
2463 Y
:= StrToIntDef(GetNext(), 0);
2464 pmin
.X
:= Min(X
, pmin
.X
);
2465 pmin
.Y
:= Min(Y
, pmin
.Y
);
2466 OnlyDM
:= (GetNext() = '1');
2467 Fall
:= (GetNext() = '1');
2471 with CopyBuf
[i
].Monster
do
2473 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2474 X
:= StrToIntDef(GetNext(), 0);
2475 Y
:= StrToIntDef(GetNext(), 0);
2476 pmin
.X
:= Min(X
, pmin
.X
);
2477 pmin
.Y
:= Min(Y
, pmin
.Y
);
2479 if GetNext() = '1' then
2482 Direction
:= D_RIGHT
;
2486 with CopyBuf
[i
].Area
do
2488 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2489 X
:= StrToIntDef(GetNext(), 0);
2490 Y
:= StrToIntDef(GetNext(), 0);
2491 pmin
.X
:= Min(X
, pmin
.X
);
2492 pmin
.Y
:= Min(Y
, pmin
.Y
);
2493 if GetNext() = '1' then
2496 Direction
:= D_RIGHT
;
2500 with CopyBuf
[i
].Trigger
do
2502 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2503 X
:= StrToIntDef(GetNext(), 0);
2504 Y
:= StrToIntDef(GetNext(), 0);
2505 pmin
.X
:= Min(X
, pmin
.X
);
2506 pmin
.Y
:= Min(Y
, pmin
.Y
);
2507 Width
:= StrToIntDef(GetNext(), 16);
2508 Height
:= StrToIntDef(GetNext(), 16);
2509 ActivateType
:= StrToIntDef(GetNext(), 0);
2510 Key
:= StrToIntDef(GetNext(), 0);
2511 Enabled
:= (GetNext() = '1');
2512 TexturePanel
:= StrToIntDef(GetNext(), 0);
2514 for j
:= 0 to 127 do
2515 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2520 pmin
.X
:= Min(Data
.TargetPoint
.X
, pmin
.X
);
2521 pmin
.Y
:= Min(Data
.TargetPoint
.Y
, pmin
.Y
);
2523 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
2525 pmin
.X
:= Min(Data
.tX
, pmin
.X
);
2526 pmin
.Y
:= Min(Data
.tY
, pmin
.Y
);
2528 TRIGGER_SPAWNMONSTER
:
2530 pmin
.X
:= Min(Data
.MonPos
.X
, pmin
.X
);
2531 pmin
.Y
:= Min(Data
.MonPos
.Y
, pmin
.Y
);
2535 pmin
.X
:= Min(Data
.ItemPos
.X
, pmin
.X
);
2536 pmin
.Y
:= Min(Data
.ItemPos
.Y
, pmin
.Y
);
2540 pmin
.X
:= Min(Data
.ShotPos
.X
, pmin
.X
);
2541 pmin
.Y
:= Min(Data
.ShotPos
.Y
, pmin
.Y
);
2549 //----------------------------------------
2550 //Закончились вспомогательные процедуры
2551 //----------------------------------------
2553 procedure TMainForm
.RefreshRecentMenu();
2558 // Лишние запомненные карты:
2559 while RecentFiles
.Count
> RecentCount
do
2560 RecentFiles
.Delete(RecentFiles
.Count
-1);
2562 // Лишние строки меню:
2563 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2564 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2566 // Отделение списка карт от строки "Выход":
2567 if RecentFiles
.Count
> 0 then
2569 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2571 MainMenu
.Items
[0].Add(MI
);
2574 // Добавление в меню списка запомненных карт:
2575 for i
:= 0 to RecentFiles
.Count
-1 do
2577 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2578 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2579 MI
.OnClick
:= aRecentFileExecute
;
2580 MainMenu
.Items
[0].Add(MI
);
2584 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2589 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2590 Delete(s
, Pos('&', s
), 1);
2591 s
:= Trim(Copy(s
, 1, 2));
2592 n
:= StrToIntDef(s
, 0) - 1;
2593 if (n
>= 0) and (n
<= RecentFiles
.Count
) then
2595 fn
:= g_ExtractWadName(RecentFiles
[n
]);
2596 if FileExists(fn
) then
2598 s
:= g_ExtractFilePathName(RecentFiles
[n
]);
2601 else if MessageBox(0, PChar(_lc
[I_MSG_DEL_RECENT_PROMT
]), PChar(_lc
[I_MSG_DEL_RECENT
]), MB_ICONQUESTION
or MB_YESNO
) = idYes
then
2603 RecentFiles
.Delete(n
);
2604 RefreshRecentMenu();
2609 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2611 OptionsForm
.ShowModal();
2614 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2624 g_ReadResource(GameWad
, 'FONTS', cfgres
, cfgdata
, cfglen
);
2625 if cfgdata
<> nil then
2627 if not g_CreateTextureWAD('FONT_STD', GameWad
+ ':FONTS\' + texture
) then
2628 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2630 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2631 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2632 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2633 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2635 if g_GetTexture('FONT_STD', ID
) then
2636 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
- 2);
2643 e_WriteLog('Could not load FONT_STD', MSG_WARNING
)
2647 procedure TMainForm
.FormCreate(Sender
: TObject
);
2655 e_WriteLog('Doom 2D: Forever Editor version ' + EDITOR_VERSION
, MSG_NOTIFY
);
2656 e_WriteLog('Build date: ' + EDITOR_BUILDDATE
+ ' ' + EDITOR_BUILDTIME
, MSG_NOTIFY
);
2657 e_WriteLog('Build hash: ' + g_GetBuildHash(), MSG_NOTIFY
);
2658 e_WriteLog('Build by: ' + g_GetBuilderName(), MSG_NOTIFY
);
2660 slInvalidTextures
:= TStringList
.Create
;
2662 ShowLayer(LAYER_BACK
, True);
2663 ShowLayer(LAYER_WALLS
, True);
2664 ShowLayer(LAYER_FOREGROUND
, True);
2665 ShowLayer(LAYER_STEPS
, True);
2666 ShowLayer(LAYER_WATER
, True);
2667 ShowLayer(LAYER_ITEMS
, True);
2668 ShowLayer(LAYER_MONSTERS
, True);
2669 ShowLayer(LAYER_AREAS
, True);
2670 ShowLayer(LAYER_TRIGGERS
, True);
2674 FormCaption
:= MainForm
.Caption
;
2678 config
:= TConfig
.CreateFile(CfgFileName
);
2680 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2681 Position
:= poDesktopCenter
2683 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2684 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2685 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2686 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2688 if config
.ReadBool('Editor', 'Maximize', False) then
2689 WindowState
:= wsMaximized
;
2690 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2691 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2692 Splitter1
.Left
:= PanelProps
.Left
;
2693 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2694 Splitter2
.Top
:= PanelObjs
.Top
;
2695 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2696 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2697 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2698 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2699 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2700 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2701 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2702 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2703 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2704 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2705 UseCheckerboard
:= config
.ReadBool('Editor', 'UseCheckerboard', True);
2706 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2707 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2708 if gAlphaEdge
= 255 then
2709 gAlphaEdge
:= ALPHA_EDGE
;
2710 drEdge
[0] := GetRValue(gColorEdge
);
2711 drEdge
[1] := GetGValue(gColorEdge
);
2712 drEdge
[2] := GetBValue(gColorEdge
);
2713 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2716 drEdge
[3] := gAlphaEdge
;
2717 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2718 if gAlphaTriggerLine
= 255 then
2719 gAlphaTriggerLine
:= ALPHA_LINE
;
2720 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2721 if gAlphaTriggerArea
= 255 then
2722 gAlphaTriggerArea
:= ALPHA_AREA
;
2723 gAlphaMonsterRect
:= config
.ReadInt('Editor', 'MonsterRectAlpha', 0);
2724 gAlphaAreaRect
:= config
.ReadInt('Editor', 'AreaRectAlpha', 0);
2725 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2729 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2733 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2734 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2736 s
:= config
.ReadStr('Editor', 'Language', '');
2739 Compress
:= config
.ReadBool('Editor', 'Compress', True);
2740 Backup
:= config
.ReadBool('Editor', 'Backup', True);
2742 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2743 if RecentCount
> 10 then
2745 if RecentCount
< 2 then
2748 RecentFiles
:= TStringList
.Create();
2749 for i
:= 0 to RecentCount
-1 do
2751 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2755 RefreshRecentMenu();
2759 tbShowMap
.Down
:= ShowMap
;
2760 tbGridOn
.Down
:= DotEnable
;
2761 pcObjects
.ActivePageIndex
:= 0;
2762 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2764 Application
.OnIdle
:= OnIdle
;
2767 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2769 // NOTE: all the font printing routines assume CP1251
2770 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2773 procedure TMainForm
.Draw();
2778 Width
, Height
: Word;
2781 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2790 e_Clear(GL_COLOR_BUFFER_BIT
,
2791 GetRValue(BackColor
)/255,
2792 GetGValue(BackColor
)/255,
2793 GetBValue(BackColor
)/255);
2797 ObjCount
:= SelectedObjectCount();
2799 // Обводим выделенные объекты красной рамкой:
2800 if ObjCount
> 0 then
2802 for a
:= 0 to High(SelectedObjects
) do
2803 if SelectedObjects
[a
].Live
then
2805 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2809 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2810 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2813 // Рисуем точки изменения размеров:
2814 if (ObjCount
= 1) and
2815 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2817 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2818 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2819 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2820 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2822 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2823 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2824 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2825 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2832 if DotEnable
and (PreviewMode
= 0) then
2839 x
:= MapOffset
.X
mod DotStep
;
2840 y
:= MapOffset
.Y
mod DotStep
;
2842 while x
< RenderPanel
.Width
do
2844 while y
< RenderPanel
.Height
do
2846 e_DrawPoint(DotSize
, x
+ a
, y
+ a
,
2847 GetRValue(DotColor
),
2848 GetGValue(DotColor
),
2849 GetBValue(DotColor
));
2853 y
:= MapOffset
.Y
mod DotStep
;
2858 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2859 (not IsSpecialTextureSel()) and (PreviewMode
= 0) then
2861 if not g_GetTexture(SelectedTexture(), ID
) then
2862 g_GetTexture('NOTEXTURE', ID
);
2863 g_GetTextureSizeByID(ID
, Width
, Height
);
2864 if UseCheckerboard
then
2866 if g_GetTexture('PREVIEW', PID
) then
2867 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
2869 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
2870 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
2871 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
2872 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
2875 // Подсказка при выборе точки Телепорта:
2876 if SelectFlag
= SELECTFLAG_TELEPORT
then
2878 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2879 if Data
.d2d_teleport
then
2880 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2881 MousePos
.X
+16, MousePos
.Y
-1,
2884 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2885 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2887 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2888 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2889 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
2892 // Подсказка при выборе точки появления:
2893 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2895 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2896 MousePos
.X
+16, MousePos
.Y
-1,
2898 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2899 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2900 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
2903 // Подсказка при выборе панели двери:
2904 if SelectFlag
= SELECTFLAG_DOOR
then
2906 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2907 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2908 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
2911 // Подсказка при выборе панели с текстурой:
2912 if SelectFlag
= SELECTFLAG_TEXTURE
then
2914 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2915 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2916 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
2919 // Подсказка при выборе панели индикации выстрела:
2920 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2922 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2923 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2924 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
2927 // Подсказка при выборе панели лифта:
2928 if SelectFlag
= SELECTFLAG_LIFT
then
2930 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2931 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2932 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
2935 // Подсказка при выборе монстра:
2936 if SelectFlag
= SELECTFLAG_MONSTER
then
2938 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2939 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2940 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
2943 // Подсказка при выборе области воздействия:
2944 if DrawPressRect
then
2946 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2947 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2948 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
2951 // Рисуем текстуры, если чертим панель:
2952 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2953 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2954 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2956 if not g_GetTexture(SelectedTexture(), ID
) then
2957 g_GetTexture('NOTEXTURE', ID
);
2958 g_GetTextureSizeByID(ID
, Width
, Height
);
2960 if (Abs(Right
-Left
) >= Width
) and (Abs(Bottom
-Top
) >= Height
) then
2961 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2962 Abs(Bottom
-Top
) div Height
, 64, True, False);
2965 // Прямоугольник выделения:
2966 if DrawRect
<> nil then
2968 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2970 // Чертим мышью панель/триггер или меняем мышью их размер:
2971 if (((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
2972 not(ssCtrl
in GetKeyShiftState())) or (MouseAction
= MOUSEACTION_RESIZE
)) and
2973 (DrawPanelSize
) then
2975 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2976 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2978 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2979 begin // Чертим новый
2980 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
2981 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
2982 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
],
2983 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
2985 else // Растягиваем существующий
2986 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2988 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2990 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2991 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2995 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2996 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2999 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
3001 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
3006 // Ближайшая к курсору мыши точка на сетке:
3007 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
3012 // Сколько пикселов карты в 1 пикселе мини-карты:
3013 ScaleSz
:= 16 div Scale
;
3014 // Размеры мини-карты:
3015 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
3016 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
3017 // X-координата на RenderPanel нулевой x-координаты карты:
3018 XX
:= RenderPanel
.Width
- aX
- 1;
3020 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
3021 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
3023 if gPanels
<> nil then
3026 for a
:= 0 to High(gPanels
) do
3028 if PanelType
<> 0 then
3030 // Левый верхний угол:
3031 aX
:= XX
+ (X
div ScaleSz
);
3032 aY
:= 1 + (Y
div ScaleSz
);
3034 aX2
:= max(Width
div ScaleSz
, 1);
3035 aY2
:= max(Height
div ScaleSz
, 1);
3036 // Правый нижний угол:
3037 aX2
:= aX
+ aX2
- 1;
3038 aY2
:= aY
+ aY2
- 1;
3041 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
3042 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
3043 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
3044 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
3045 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
3046 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
3047 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
3048 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
3049 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
3050 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
3051 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
3052 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
3056 // Рисуем красным выделенные панели:
3057 if SelectedObjects
<> nil then
3058 for b
:= 0 to High(SelectedObjects
) do
3059 with SelectedObjects
[b
] do
3060 if Live
and (ObjectType
= OBJECT_PANEL
) then
3061 with gPanels
[SelectedObjects
[b
].ID
] do
3062 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
3064 // Левый верхний угол:
3065 aX
:= XX
+ (X
div ScaleSz
);
3066 aY
:= 1 + (Y
div ScaleSz
);
3068 aX2
:= max(Width
div ScaleSz
, 1);
3069 aY2
:= max(Height
div ScaleSz
, 1);
3070 // Правый нижний угол:
3071 aX2
:= aX
+ aX2
- 1;
3072 aY2
:= aY
+ aY2
- 1;
3074 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
3078 if (gMapInfo
.Width
> RenderPanel
.Width
) or
3079 (gMapInfo
.Height
> RenderPanel
.Height
) then
3081 // Окно, показывающее текущее положение экрана на карте:
3083 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
3084 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
3085 // Левый верхний угол:
3086 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
3087 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
3088 // Правый нижний угол:
3092 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3093 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3098 RenderPanel
.SwapBuffers();
3101 procedure TMainForm
.FormResize(Sender
: TObject
);
3103 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3105 sbHorizontal
.Min
:= Min(gMapInfo
.Width
- RenderPanel
.Width
, -RenderPanel
.Width
div 2);
3106 sbHorizontal
.Max
:= Max(0, gMapInfo
.Width
- RenderPanel
.Width
div 2);
3107 sbVertical
.Min
:= Min(gMapInfo
.Height
- RenderPanel
.Height
, -RenderPanel
.Height
div 2);
3108 sbVertical
.Max
:= Max(0, gMapInfo
.Height
- RenderPanel
.Height
div 2);
3110 MapOffset
.X
:= -sbHorizontal
.Position
;
3111 MapOffset
.Y
:= -sbVertical
.Position
;
3114 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3119 j_max
:= 0; // shut up compiler
3123 res
:= (gPanels
<> nil) and
3124 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3125 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3127 gPanels
[ID
].Height
);
3128 j_max
:= Length(gPanels
) - 1;
3133 res
:= (gItems
<> nil) and
3134 LayerEnabled
[LAYER_ITEMS
] and
3135 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3136 ItemSize
[gItems
[ID
].ItemType
][0],
3137 ItemSize
[gItems
[ID
].ItemType
][1]);
3138 j_max
:= Length(gItems
) - 1;
3143 res
:= (gMonsters
<> nil) and
3144 LayerEnabled
[LAYER_MONSTERS
] and
3145 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3146 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3147 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3148 j_max
:= Length(gMonsters
) - 1;
3153 res
:= (gAreas
<> nil) and
3154 LayerEnabled
[LAYER_AREAS
] and
3155 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3156 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3157 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3158 j_max
:= Length(gAreas
) - 1;
3163 res
:= (gTriggers
<> nil) and
3164 LayerEnabled
[LAYER_TRIGGERS
] and
3165 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3166 gTriggers
[ID
].Width
,
3167 gTriggers
[ID
].Height
);
3168 j_max
:= Length(gTriggers
) - 1;
3178 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3187 if j
= Integer(ID
) then
3192 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3193 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3197 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3198 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3199 ItemSize
[gItems
[j
].ItemType
][0],
3200 ItemSize
[gItems
[j
].ItemType
][1]);
3202 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3203 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3204 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3205 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3207 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3208 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3209 AreaSize
[gAreas
[j
].AreaType
].Width
,
3210 AreaSize
[gAreas
[j
].AreaType
].Height
);
3212 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3213 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3215 gTriggers
[j
].Height
);
3222 SetLength(SelectedObjects
, 1);
3224 SelectedObjects
[0].ObjectType
:= ObjectType
;
3225 SelectedObjects
[0].ID
:= j
;
3226 SelectedObjects
[0].Live
:= True;
3234 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3235 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3239 c1
, c2
, c3
, c4
: Boolean;
3245 MainForm
.ActiveControl
:= RenderPanel
;
3246 RenderPanel
.SetFocus();
3248 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3250 if Button
= mbLeft
then // Left Mouse Button
3252 // Двигаем карту с помощью мыши и мини-карты:
3254 g_CollidePoint(X
, Y
,
3255 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3257 max(gMapInfo
.Width
div (16 div Scale
), 1),
3258 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3261 MouseAction
:= MOUSEACTION_MOVEMAP
;
3263 else // Ставим предмет/монстра/область:
3264 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3265 (not (ssShift
in Shift
)) then
3267 case pcObjects
.ActivePageIndex
of
3269 if lbItemList
.ItemIndex
= -1 then
3270 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3273 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3274 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3275 item
.ItemType
:= item
.ItemType
+ 2;
3276 item
.X
:= MousePos
.X
-MapOffset
.X
;
3277 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3279 if not (ssCtrl
in Shift
) then
3281 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3282 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3285 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3286 item
.Fall
:= cbFall
.Checked
;
3287 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3290 if lbMonsterList
.ItemIndex
= -1 then
3291 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3294 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3295 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3296 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3298 if not (ssCtrl
in Shift
) then
3300 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3301 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3304 if rbMonsterLeft
.Checked
then
3305 monster
.Direction
:= D_LEFT
3307 monster
.Direction
:= D_RIGHT
;
3308 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3311 if lbAreasList
.ItemIndex
= -1 then
3312 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3314 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3316 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3317 area
.X
:= MousePos
.X
-MapOffset
.X
;
3318 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3320 if not (ssCtrl
in Shift
) then
3322 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3323 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3326 if rbAreaLeft
.Checked
then
3327 area
.Direction
:= D_LEFT
3329 area
.Direction
:= D_RIGHT
;
3330 Undo_Add(OBJECT_AREA
, AddArea(area
));
3336 i
:= GetFirstSelected();
3338 // Выбираем объект под текущим:
3339 if (SelectedObjects
<> nil) and
3340 (ssShift
in Shift
) and (i
>= 0) and
3341 (SelectedObjects
[i
].Live
) then
3343 if SelectedObjectCount() = 1 then
3344 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3345 SelectedObjects
[i
].ObjectType
,
3346 SelectedObjects
[i
].ID
);
3350 // Рисуем область триггера "Расширитель":
3351 if DrawPressRect
and (i
>= 0) and
3352 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3353 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3354 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3355 MouseAction
:= MOUSEACTION_DRAWPRESS
3356 else // Рисуем панель:
3357 if pcObjects
.ActivePageIndex
= 0 then
3359 if (lbPanelType
.ItemIndex
>= 0) then
3360 MouseAction
:= MOUSEACTION_DRAWPANEL
3362 else // Рисуем триггер:
3363 if (lbTriggersList
.ItemIndex
>= 0) then
3365 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3369 end; // if Button = mbLeft
3371 if Button
= mbRight
then // Right Mouse Button
3373 // Клик по мини-карте:
3375 g_CollidePoint(X
, Y
,
3376 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3378 max(gMapInfo
.Width
div (16 div Scale
), 1),
3379 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3381 MouseAction
:= MOUSEACTION_NOACTION
;
3383 else // Нужно что-то выбрать мышью:
3384 if SelectFlag
<> SELECTFLAG_NONE
then
3387 SELECTFLAG_TELEPORT
:
3388 // Точку назначения телепортации:
3389 with gTriggers
[SelectedObjects
[
3390 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3392 X
:= MousePos
.X
-MapOffset
.X
;
3393 Y
:= MousePos
.Y
-MapOffset
.Y
;
3396 SELECTFLAG_SPAWNPOINT
:
3397 // Точку создания монстра:
3398 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3399 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3401 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3402 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3404 else if TriggerType
= TRIGGER_SPAWNITEM
then
3405 begin // Точка создания предмета:
3406 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3407 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3409 else if TriggerType
= TRIGGER_SHOT
then
3410 begin // Точка создания выстрела:
3411 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3412 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3418 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3420 2, 2, OBJECT_PANEL
, True);
3421 if IDArray
<> nil then
3423 for i
:= 0 to High(IDArray
) do
3424 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3425 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3427 gTriggers
[SelectedObjects
[
3428 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3433 gTriggers
[SelectedObjects
[
3434 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3438 // Панель с текстурой:
3440 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3442 2, 2, OBJECT_PANEL
, True);
3443 if IDArray
<> nil then
3445 for i
:= 0 to High(IDArray
) do
3446 if ((gPanels
[IDArray
[i
]].PanelType
in
3447 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3448 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3450 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3451 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3452 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3454 gTriggers
[SelectedObjects
[
3455 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3460 gTriggers
[SelectedObjects
[
3461 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3467 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3469 2, 2, OBJECT_PANEL
, True);
3470 if IDArray
<> nil then
3472 for i
:= 0 to High(IDArray
) do
3473 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3474 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3475 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3476 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3478 gTriggers
[SelectedObjects
[
3479 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3484 gTriggers
[SelectedObjects
[
3485 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3491 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3493 2, 2, OBJECT_MONSTER
, False);
3494 if IDArray
<> nil then
3495 gTriggers
[SelectedObjects
[
3496 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3498 gTriggers
[SelectedObjects
[
3499 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3502 SELECTFLAG_SHOTPANEL
:
3503 // Панель индикации выстрела:
3505 if gTriggers
[SelectedObjects
[
3506 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3508 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3510 2, 2, OBJECT_PANEL
, True);
3511 if IDArray
<> nil then
3513 for i
:= 0 to High(IDArray
) do
3514 if ((gPanels
[IDArray
[i
]].PanelType
in
3515 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3516 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3518 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3519 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3520 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3522 gTriggers
[SelectedObjects
[
3523 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3528 gTriggers
[SelectedObjects
[
3529 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3534 SelectFlag
:= SELECTFLAG_SELECTED
;
3536 else // if SelectFlag <> SELECTFLAG_NONE...
3538 // Что уже выбрано и не нажат Ctrl:
3539 if (SelectedObjects
<> nil) and
3540 (not (ssCtrl
in Shift
)) then
3541 for i
:= 0 to High(SelectedObjects
) do
3542 with SelectedObjects
[i
] do
3545 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3546 (SelectedObjectCount() = 1) then
3548 Rect
:= ObjectGetRect(ObjectType
, ID
);
3550 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3551 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3552 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3553 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3554 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3555 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3556 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3557 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3559 // Меняем размер панели или триггера:
3560 if c1
or c2
or c3
or c4
then
3562 MouseAction
:= MOUSEACTION_RESIZE
;
3563 LastMovePoint
:= MousePos
;
3567 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3569 ResizeDirection
:= RESIZEDIR_LEFT
3571 ResizeDirection
:= RESIZEDIR_RIGHT
;
3572 RenderPanel
.Cursor
:= crSizeWE
;
3576 ResizeType
:= RESIZETYPE_VERTICAL
;
3578 ResizeDirection
:= RESIZEDIR_UP
3580 ResizeDirection
:= RESIZEDIR_DOWN
;
3581 RenderPanel
.Cursor
:= crSizeNS
;
3588 // Перемещаем панель или триггер:
3589 if ObjectCollide(ObjectType
, ID
,
3591 Y
-MapOffset
.Y
-1, 2, 2) then
3593 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3594 LastMovePoint
:= MousePos
;
3600 end; // if Button = mbRight
3602 if Button
= mbMiddle
then // Middle Mouse Button
3604 SetCapture(RenderPanel
.Handle
);
3605 RenderPanel
.Cursor
:= crSize
;
3608 MouseMDown
:= Button
= mbMiddle
;
3610 MouseMDownPos
:= Mouse
.CursorPos
;
3612 MouseRDown
:= Button
= mbRight
;
3614 MouseRDownPos
:= MousePos
;
3616 MouseLDown
:= Button
= mbLeft
;
3618 MouseLDownPos
:= MousePos
;
3621 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3622 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3627 rSelectRect
: Boolean;
3628 wWidth
, wHeight
: Word;
3631 procedure SelectObjects(ObjectType
: Byte);
3636 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3637 rRect
.Width
, rRect
.Height
,
3638 ObjectType
, rSelectRect
);
3640 if IDArray
<> nil then
3641 for i
:= 0 to High(IDArray
) do
3642 SelectObject(ObjectType
, IDArray
[i
], (ssCtrl
in Shift
) or rSelectRect
);
3645 if Button
= mbLeft
then
3646 MouseLDown
:= False;
3647 if Button
= mbRight
then
3648 MouseRDown
:= False;
3649 if Button
= mbMiddle
then
3650 MouseMDown
:= False;
3653 ResizeType
:= RESIZETYPE_NONE
;
3656 if Button
= mbLeft
then // Left Mouse Button
3658 if MouseAction
<> MOUSEACTION_NONE
then
3659 begin // Было действие мышью
3660 // Мышь сдвинулась во время удержания клавиши,
3661 // либо активирован режим быстрого рисования:
3662 if ((MousePos
.X
<> MouseLDownPos
.X
) and
3663 (MousePos
.Y
<> MouseLDownPos
.Y
)) or
3664 ((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3665 (ssCtrl
in Shift
)) then
3668 MOUSEACTION_DRAWPANEL
:
3670 // Фон или передний план без текстуры - ошибка:
3671 if (lbPanelType
.ItemIndex
in [1, 2]) and
3672 (lbTextureList
.ItemIndex
= -1) then
3673 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3674 else // Назначаем параметры панели:
3676 case lbPanelType
.ItemIndex
of
3677 0: Panel
.PanelType
:= PANEL_WALL
;
3678 1: Panel
.PanelType
:= PANEL_BACK
;
3679 2: Panel
.PanelType
:= PANEL_FORE
;
3680 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3681 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3682 5: Panel
.PanelType
:= PANEL_STEP
;
3683 6: Panel
.PanelType
:= PANEL_WATER
;
3684 7: Panel
.PanelType
:= PANEL_ACID1
;
3685 8: Panel
.PanelType
:= PANEL_ACID2
;
3686 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3687 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3688 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3689 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3690 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3693 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3694 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3695 if ssCtrl
in Shift
then
3699 if (lbTextureList
.ItemIndex
<> -1) and
3700 (not IsSpecialTextureSel()) then
3702 if not g_GetTexture(SelectedTexture(), TextureID
) then
3703 g_GetTexture('NOTEXTURE', TextureID
);
3704 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
3706 Panel
.Width
:= wWidth
;
3707 Panel
.Height
:= wHeight
;
3711 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3712 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3715 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3716 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3717 (lbTextureList
.ItemIndex
= -1) then
3719 Panel
.TextureHeight
:= 1;
3720 Panel
.TextureWidth
:= 1;
3721 Panel
.TextureName
:= '';
3722 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3724 else // Есть текстура:
3726 Panel
.TextureName
:= SelectedTexture();
3728 // Обычная текстура:
3729 if not IsSpecialTextureSel() then
3731 g_GetTextureSizeByName(Panel
.TextureName
,
3732 Panel
.TextureWidth
, Panel
.TextureHeight
);
3733 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3735 else // Спец.текстура:
3737 Panel
.TextureHeight
:= 1;
3738 Panel
.TextureWidth
:= 1;
3739 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3744 Panel
.Blending
:= False;
3746 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3750 // Рисовали триггер:
3751 MOUSEACTION_DRAWTRIGGER
:
3753 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3754 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3755 if ssCtrl
in Shift
then
3759 trigger
.Width
:= wWidth
;
3760 trigger
.Height
:= wHeight
;
3764 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3765 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3768 trigger
.Enabled
:= True;
3769 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3770 trigger
.TexturePanel
:= -1;
3773 trigger
.ActivateType
:= 0;
3775 if clbActivationType
.Checked
[0] then
3776 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3777 if clbActivationType
.Checked
[1] then
3778 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3779 if clbActivationType
.Checked
[2] then
3780 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3781 if clbActivationType
.Checked
[3] then
3782 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3783 if clbActivationType
.Checked
[4] then
3784 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3785 if clbActivationType
.Checked
[5] then
3786 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3788 // Необходимые для активации ключи:
3791 if clbKeys
.Checked
[0] then
3792 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3793 if clbKeys
.Checked
[1] then
3794 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3795 if clbKeys
.Checked
[2] then
3796 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3797 if clbKeys
.Checked
[3] then
3798 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3799 if clbKeys
.Checked
[4] then
3800 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3802 // Параметры триггера:
3803 FillByte(trigger
.Data
.Default
[0], 128, 0);
3805 case trigger
.TriggerType
of
3806 // Переключаемая панель:
3807 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3808 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3809 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3811 Trigger
.Data
.PanelID
:= -1;
3817 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3818 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3819 trigger
.Data
.d2d_teleport
:= True;
3820 trigger
.Data
.TlpDir
:= 0;
3823 // Изменение других триггеров:
3824 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3827 trigger
.Data
.Count
:= 1;
3833 trigger
.Data
.Volume
:= 255;
3834 trigger
.Data
.Pan
:= 127;
3835 trigger
.Data
.PlayCount
:= 1;
3836 trigger
.Data
.Local
:= True;
3837 trigger
.Data
.SoundSwitch
:= False;
3843 trigger
.Data
.MusicAction
:= 1;
3846 // Создание монстра:
3847 TRIGGER_SPAWNMONSTER
:
3849 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3850 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3851 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3852 trigger
.Data
.MonHealth
:= 0;
3853 trigger
.Data
.MonActive
:= False;
3854 trigger
.Data
.MonCount
:= 1;
3857 // Создание предмета:
3860 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3861 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3862 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3863 trigger
.Data
.ItemOnlyDM
:= False;
3864 trigger
.Data
.ItemFalls
:= False;
3865 trigger
.Data
.ItemCount
:= 1;
3866 trigger
.Data
.ItemMax
:= 0;
3867 trigger
.Data
.ItemDelay
:= 0;
3873 trigger
.Data
.PushAngle
:= 90;
3874 trigger
.Data
.PushForce
:= 10;
3875 trigger
.Data
.ResetVel
:= True;
3880 trigger
.Data
.ScoreCount
:= 1;
3881 trigger
.Data
.ScoreCon
:= True;
3882 trigger
.Data
.ScoreMsg
:= True;
3887 trigger
.Data
.MessageKind
:= 0;
3888 trigger
.Data
.MessageSendTo
:= 0;
3889 trigger
.Data
.MessageText
:= '';
3890 trigger
.Data
.MessageTime
:= 144;
3895 trigger
.Data
.DamageValue
:= 5;
3896 trigger
.Data
.DamageInterval
:= 12;
3901 trigger
.Data
.HealValue
:= 5;
3902 trigger
.Data
.HealInterval
:= 36;
3907 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3908 trigger
.Data
.ShotSound
:= True;
3909 trigger
.Data
.ShotPanelID
:= -1;
3910 trigger
.Data
.ShotTarget
:= 0;
3911 trigger
.Data
.ShotIntSight
:= 0;
3912 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
3913 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3914 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3915 trigger
.Data
.ShotAngle
:= 0;
3916 trigger
.Data
.ShotWait
:= 18;
3917 trigger
.Data
.ShotAccuracy
:= 0;
3918 trigger
.Data
.ShotAmmo
:= 0;
3919 trigger
.Data
.ShotIntReload
:= 0;
3924 trigger
.Data
.FXCount
:= 1;
3925 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3926 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3927 trigger
.Data
.FXColorR
:= 0;
3928 trigger
.Data
.FXColorG
:= 0;
3929 trigger
.Data
.FXColorB
:= 255;
3930 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3931 trigger
.Data
.FXWait
:= 1;
3932 trigger
.Data
.FXVelX
:= 0;
3933 trigger
.Data
.FXVelY
:= -20;
3934 trigger
.Data
.FXSpreadL
:= 5;
3935 trigger
.Data
.FXSpreadR
:= 5;
3936 trigger
.Data
.FXSpreadU
:= 4;
3937 trigger
.Data
.FXSpreadD
:= 0;
3941 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3944 // Рисовали область триггера "Расширитель":
3945 MOUSEACTION_DRAWPRESS
:
3946 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3948 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3949 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3950 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3951 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3953 DrawPressRect
:= False;
3957 MouseAction
:= MOUSEACTION_NONE
;
3959 end // if Button = mbLeft...
3960 else if Button
= mbRight
then // Right Mouse Button:
3962 if MouseAction
= MOUSEACTION_NOACTION
then
3964 MouseAction
:= MOUSEACTION_NONE
;
3968 // Объект передвинут или изменен в размере:
3969 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3971 RenderPanel
.Cursor
:= crDefault
;
3972 MouseAction
:= MOUSEACTION_NONE
;
3977 // Еще не все выбрали:
3978 if SelectFlag
<> SELECTFLAG_NONE
then
3980 if SelectFlag
= SELECTFLAG_SELECTED
then
3981 SelectFlag
:= SELECTFLAG_NONE
;
3986 // Мышь сдвинулась во время удержания клавиши:
3987 if (MousePos
.X
<> MouseRDownPos
.X
) and
3988 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3990 rSelectRect
:= True;
3992 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3993 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3994 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3995 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3997 else // Мышь не сдвинулась - нет прямоугольника:
3999 rSelectRect
:= False;
4001 rRect
.X
:= X
-MapOffset
.X
-1;
4002 rRect
.Y
:= Y
-MapOffset
.Y
-1;
4007 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
4008 if not (ssCtrl
in Shift
) then
4009 RemoveSelectFromObjects();
4011 // Выделяем всё в выбранном прямоугольнике:
4012 if (ssCtrl
in Shift
) and (ssAlt
in Shift
) then
4014 SelectObjects(OBJECT_PANEL
);
4015 SelectObjects(OBJECT_ITEM
);
4016 SelectObjects(OBJECT_MONSTER
);
4017 SelectObjects(OBJECT_AREA
);
4018 SelectObjects(OBJECT_TRIGGER
);
4021 SelectObjects(pcObjects
.ActivePageIndex
+1);
4026 else // Middle Mouse Button
4028 RenderPanel
.Cursor
:= crDefault
;
4033 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
4038 function TMainForm
.RenderMousePos(): Types
.TPoint
;
4040 Result
:= RenderPanel
.ScreenToClient(Mouse
.CursorPos
);
4043 procedure TMainForm
.RecountSelectedObjects();
4045 if SelectedObjectCount() = 0 then
4046 StatusBar
.Panels
[0].Text := ''
4048 StatusBar
.Panels
[0].Text := Format(_lc
[I_CAP_STAT_SELECTED
], [SelectedObjectCount()]);
4051 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
4052 Shift
: TShiftState
; X
, Y
: Integer);
4055 dWidth
, dHeight
: Integer;
4058 wWidth
, wHeight
: Word;
4060 _id
:= GetFirstSelected();
4063 // Рисуем панель с текстурой, сетка - размеры текстуры:
4064 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
4065 (lbPanelType
.ItemIndex
in [0..8]) and
4066 (lbTextureList
.ItemIndex
<> -1) and
4067 (not IsSpecialTextureSel()) then
4069 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
4070 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
4073 // Меняем размер панели с текстурой, сетка - размеры текстуры:
4074 if (MouseAction
= MOUSEACTION_RESIZE
) and
4075 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
4076 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
4077 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
4078 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
4080 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
4081 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
4084 // Выравнивание по сетке:
4090 else // Нет выравнивания по сетке:
4096 // Новая позиция мыши:
4098 begin // Зажата левая кнопка мыши
4099 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
4100 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
4104 begin // Зажата правая кнопка мыши
4105 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
4106 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
4109 begin // Кнопки мыши не зажаты
4110 MousePos
.X
:= Round((-MapOffset
.X
+ X
) / sX
) * sX
+ MapOffset
.X
;
4111 MousePos
.Y
:= Round((-MapOffset
.Y
+ Y
) / sY
) * sY
+ MapOffset
.Y
;
4114 // Зажата только правая кнопка мыши:
4115 if (not MouseLDown
) and (MouseRDown
) and (not MouseMDown
) then
4117 // Рисуем прямоугольник выделения:
4118 if MouseAction
= MOUSEACTION_NONE
then
4120 if DrawRect
= nil then
4122 DrawRect
.Top
:= MouseRDownPos
.y
;
4123 DrawRect
.Left
:= MouseRDownPos
.x
;
4124 DrawRect
.Bottom
:= MousePos
.y
;
4125 DrawRect
.Right
:= MousePos
.x
;
4128 // Двигаем выделенные объекты:
4129 if MouseAction
= MOUSEACTION_MOVEOBJ
then
4131 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
4132 MousePos
.X
-LastMovePoint
.X
,
4133 MousePos
.Y
-LastMovePoint
.Y
);
4136 // Меняем размер выделенного объекта:
4137 if MouseAction
= MOUSEACTION_RESIZE
then
4139 if (SelectedObjectCount
= 1) and
4140 (SelectedObjects
[GetFirstSelected
].Live
) then
4142 dWidth
:= MousePos
.X
-LastMovePoint
.X
;
4143 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
;
4146 RESIZETYPE_VERTICAL
: dWidth
:= 0;
4147 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
4150 case ResizeDirection
of
4151 RESIZEDIR_UP
: dHeight
:= -dHeight
;
4152 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
4155 if ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
4156 SelectedObjects
[GetFirstSelected
].ID
,
4157 dWidth
, dHeight
, ResizeDirection
) then
4158 LastMovePoint
:= MousePos
;
4163 // Зажата только левая кнопка мыши:
4164 if (not MouseRDown
) and (MouseLDown
) and (not MouseMDown
) then
4166 // Рисуем прямоугольник планирования панели:
4167 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4168 MOUSEACTION_DRAWTRIGGER
,
4169 MOUSEACTION_DRAWPRESS
] then
4171 if DrawRect
= nil then
4173 if ssCtrl
in Shift
then
4177 if (lbTextureList
.ItemIndex
<> -1) and (not IsSpecialTextureSel()) and
4178 (MouseAction
= MOUSEACTION_DRAWPANEL
) then
4180 if not g_GetTexture(SelectedTexture(), TextureID
) then
4181 g_GetTexture('NOTEXTURE', TextureID
);
4182 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
4184 DrawRect
.Top
:= MouseLDownPos
.y
;
4185 DrawRect
.Left
:= MouseLDownPos
.x
;
4186 DrawRect
.Bottom
:= DrawRect
.Top
+ wHeight
;
4187 DrawRect
.Right
:= DrawRect
.Left
+ wWidth
;
4191 DrawRect
.Top
:= MouseLDownPos
.y
;
4192 DrawRect
.Left
:= MouseLDownPos
.x
;
4193 DrawRect
.Bottom
:= MousePos
.y
;
4194 DrawRect
.Right
:= MousePos
.x
;
4197 else // Двигаем карту:
4198 if MouseAction
= MOUSEACTION_MOVEMAP
then
4204 // Only Middle Mouse Button is pressed
4205 if (not MouseLDown
) and (not MouseRDown
) and (MouseMDown
) then
4207 MapOffset
.X
:= -EnsureRange(-MapOffset
.X
+ MouseMDownPos
.X
- Mouse
.CursorPos
.X
,
4208 sbHorizontal
.Min
, sbHorizontal
.Max
);
4209 sbHorizontal
.Position
:= -MapOffset
.X
;
4210 MapOffset
.Y
:= -EnsureRange(-MapOffset
.Y
+ MouseMDownPos
.Y
- Mouse
.CursorPos
.Y
,
4211 sbVertical
.Min
, sbVertical
.Max
);
4212 sbVertical
.Position
:= -MapOffset
.Y
;
4213 MouseMDownPos
:= Mouse
.CursorPos
;
4216 // Клавиши мыши не зажаты:
4217 if (not MouseRDown
) and (not MouseLDown
) then
4220 // Строка состояния - координаты мыши:
4221 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4222 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4225 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4227 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
4228 PChar(_lc
[I_MSG_EXIT
]),
4229 MB_ICONQUESTION
or MB_YESNO
or
4230 MB_DEFBUTTON1
) = idYes
;
4233 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4238 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4243 config
:= TConfig
.CreateFile(CfgFileName
);
4245 if WindowState
<> wsMaximized
then
4247 config
.WriteInt('Editor', 'XPos', Left
);
4248 config
.WriteInt('Editor', 'YPos', Top
);
4249 config
.WriteInt('Editor', 'Width', Width
);
4250 config
.WriteInt('Editor', 'Height', Height
);
4254 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4255 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4256 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4257 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4259 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4260 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4261 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4262 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4263 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4264 config
.WriteInt('Editor', 'DotStep', DotStep
);
4265 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4266 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4267 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4268 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4269 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4270 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4271 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4272 config
.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect
);
4273 config
.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect
);
4275 for i
:= 0 to RecentCount
-1 do
4276 if i
< RecentFiles
.Count
then
4277 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4279 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4282 config
.SaveFile(CfgFileName
);
4285 slInvalidTextures
.Free
;
4288 procedure TMainForm
.FormDropFiles(Sender
: TObject
;
4289 const FileNames
: array of String);
4291 if Length(FileNames
) <> 1 then
4294 OpenMapFile(FileNames
[0]);
4297 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4299 if MainForm
.Visible
then
4303 procedure TMainForm
.Splitter1Moved(Sender
: TObject
);
4308 procedure TMainForm
.MapTestCheck(Sender
: TObject
);
4310 if MapTestProcess
<> nil then
4312 if MapTestProcess
.Running
= false then
4314 if MapTestProcess
.ExitCode
<> 0 then
4315 Application
.MessageBox(PChar(_lc
[I_MSG_EXEC_ERROR
]), 'FIXME', MB_OK
or MB_ICONERROR
);
4316 SysUtils
.DeleteFile(MapTestFile
);
4318 FreeAndNil(MapTestProcess
);
4319 tbTestMap
.Enabled
:= True;
4324 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4328 MapOptionsForm
.ShowModal();
4330 ResName
:= OpenedMap
;
4331 while (Pos(':\', ResName
) > 0) do
4332 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4334 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4337 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4339 AboutForm
.ShowModal();
4342 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
4348 if (not EditingProperties
) then
4350 if ssCtrl
in Shift
then
4353 '1': ContourEnabled
[LAYER_BACK
] := not ContourEnabled
[LAYER_BACK
];
4354 '2': ContourEnabled
[LAYER_WALLS
] := not ContourEnabled
[LAYER_WALLS
];
4355 '3': ContourEnabled
[LAYER_FOREGROUND
] := not ContourEnabled
[LAYER_FOREGROUND
];
4356 '4': ContourEnabled
[LAYER_STEPS
] := not ContourEnabled
[LAYER_STEPS
];
4357 '5': ContourEnabled
[LAYER_WATER
] := not ContourEnabled
[LAYER_WATER
];
4358 '6': ContourEnabled
[LAYER_ITEMS
] := not ContourEnabled
[LAYER_ITEMS
];
4359 '7': ContourEnabled
[LAYER_MONSTERS
] := not ContourEnabled
[LAYER_MONSTERS
];
4360 '8': ContourEnabled
[LAYER_AREAS
] := not ContourEnabled
[LAYER_AREAS
];
4361 '9': ContourEnabled
[LAYER_TRIGGERS
] := not ContourEnabled
[LAYER_TRIGGERS
];
4365 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4366 if ContourEnabled
[i
] then
4368 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4369 ContourEnabled
[i
] := not ok
4376 '1': SwitchLayer(LAYER_BACK
);
4377 '2': SwitchLayer(LAYER_WALLS
);
4378 '3': SwitchLayer(LAYER_FOREGROUND
);
4379 '4': SwitchLayer(LAYER_STEPS
);
4380 '5': SwitchLayer(LAYER_WATER
);
4381 '6': SwitchLayer(LAYER_ITEMS
);
4382 '7': SwitchLayer(LAYER_MONSTERS
);
4383 '8': SwitchLayer(LAYER_AREAS
);
4384 '9': SwitchLayer(LAYER_TRIGGERS
);
4385 '0': tbShowClick(tbShow
);
4389 if Key
= Ord('V') then
4390 begin // Поворот монстров и областей:
4391 if (SelectedObjects
<> nil) then
4393 for i
:= 0 to High(SelectedObjects
) do
4394 if (SelectedObjects
[i
].Live
) then
4396 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4398 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4401 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4403 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4409 if pcObjects
.ActivePage
= tsMonsters
then
4411 if rbMonsterLeft
.Checked
then
4412 rbMonsterRight
.Checked
:= True
4414 rbMonsterLeft
.Checked
:= True;
4416 if pcObjects
.ActivePage
= tsAreas
then
4418 if rbAreaLeft
.Checked
then
4419 rbAreaRight
.Checked
:= True
4421 rbAreaLeft
.Checked
:= True;
4426 if not (ssCtrl
in Shift
) then
4428 // Быстрое превью карты:
4429 if Key
= Ord('E') then
4431 if PreviewMode
= 0 then
4435 // Вертикальный скролл карты:
4438 if Key
= Ord('W') then
4441 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4442 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4443 MapOffset
.Y
:= -Position
;
4446 if (MouseLDown
or MouseRDown
) then
4448 if DrawRect
<> nil then
4450 Inc(MouseLDownPos
.y
, dy
);
4451 Inc(MouseRDownPos
.y
, dy
);
4453 Inc(LastMovePoint
.Y
, dy
);
4454 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4458 if Key
= Ord('S') then
4461 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4462 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4463 MapOffset
.Y
:= -Position
;
4466 if (MouseLDown
or MouseRDown
) then
4468 if DrawRect
<> nil then
4470 Inc(MouseLDownPos
.y
, dy
);
4471 Inc(MouseRDownPos
.y
, dy
);
4473 Inc(LastMovePoint
.Y
, dy
);
4474 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4479 // Горизонтальный скролл карты:
4480 with sbHorizontal
do
4482 if Key
= Ord('A') then
4485 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4486 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4487 MapOffset
.X
:= -Position
;
4490 if (MouseLDown
or MouseRDown
) then
4492 if DrawRect
<> nil then
4494 Inc(MouseLDownPos
.x
, dx
);
4495 Inc(MouseRDownPos
.x
, dx
);
4497 Inc(LastMovePoint
.X
, dx
);
4498 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4502 if Key
= Ord('D') then
4505 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4506 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4507 MapOffset
.X
:= -Position
;
4510 if (MouseLDown
or MouseRDown
) then
4512 if DrawRect
<> nil then
4514 Inc(MouseLDownPos
.x
, dx
);
4515 Inc(MouseRDownPos
.x
, dx
);
4517 Inc(LastMovePoint
.X
, dx
);
4518 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4523 else // ssCtrl in Shift
4525 if ssShift
in Shift
then
4527 // Вставка по абсолютному смещению:
4528 if Key
= Ord('V') then
4529 aPasteObjectExecute(Sender
);
4531 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4535 // Удалить выделенные объекты:
4536 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4537 RenderPanel
.Focused() then
4538 DeleteSelectedObjects();
4541 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4542 RemoveSelectFromObjects();
4544 // Передвинуть объекты:
4545 if MainForm
.ActiveControl
= RenderPanel
then
4550 if Key
= VK_NUMPAD4
then
4551 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4552 if Key
= VK_NUMPAD6
then
4553 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4554 if Key
= VK_NUMPAD8
then
4555 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4556 if Key
= VK_NUMPAD5
then
4557 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4559 if (dx
<> 0) or (dy
<> 0) then
4561 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4566 if ssCtrl
in Shift
then
4568 // Выбор панели с текстурой для триггера
4569 if Key
= Ord('T') then
4571 DrawPressRect
:= False;
4572 if SelectFlag
= SELECTFLAG_TEXTURE
then
4574 SelectFlag
:= SELECTFLAG_NONE
;
4577 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4579 SelectFlag
:= SELECTFLAG_TEXTURE
;
4582 if Key
= Ord('D') then
4584 SelectFlag
:= SELECTFLAG_NONE
;
4585 if DrawPressRect
then
4587 DrawPressRect
:= False;
4592 // Выбор области воздействия, в зависимости от типа триггера
4593 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4596 DrawPressRect
:= True;
4599 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4601 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4604 SelectFlag
:= SELECTFLAG_DOOR
;
4607 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4610 SelectFlag
:= SELECTFLAG_LIFT
;
4613 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4616 SelectFlag
:= SELECTFLAG_TELEPORT
;
4619 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4622 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4626 // Выбор основного параметра, в зависимости от типа триггера
4627 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4630 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4631 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
4632 SelectMapForm
.GetMaps(FileName
);
4634 if SelectMapForm
.ShowModal() = mrOK
then
4636 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4637 bApplyProperty
.Click();
4641 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4643 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4646 AddSoundForm
.OKFunction
:= nil;
4647 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4648 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4650 if (AddSoundForm
.ShowModal() = mrOk
) then
4652 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4653 bApplyProperty
.Click();
4657 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4659 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4662 vleObjectProperty
.Row
:= i
;
4663 vleObjectProperty
.SetFocus();
4670 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4672 RemoveSelectFromObjects();
4673 MapOptimizationForm
.ShowModal();
4676 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4678 MapCheckForm
.ShowModal();
4681 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4683 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4684 AddTextureForm
.ShowModal();
4687 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4690 TextureWidth
, TextureHeight
: Word;
4695 if (lbTextureList
.ItemIndex
<> -1) and
4696 (not IsSpecialTextureSel()) then
4698 if g_GetTexture(SelectedTexture(), TextureID
) then
4700 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4702 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4703 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4706 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4707 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4712 lTextureWidth
.Caption
:= '';
4713 lTextureHeight
.Caption
:= '';
4717 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4718 ARect
: TRect
; State
: TOwnerDrawState
);
4720 with Control
as TListBox
do
4722 if LCLType
.odSelected
in State
then
4724 Canvas
.Brush
.Color
:= clHighlight
;
4725 Canvas
.Font
.Color
:= clHighlightText
;
4727 if (Items
<> nil) and (Index
>= 0) then
4728 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4730 Canvas
.Brush
.Color
:= clRed
;
4731 Canvas
.Font
.Color
:= clWhite
;
4733 Canvas
.FillRect(ARect
);
4734 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4738 procedure TMainForm
.miReopenMapClick(Sender
: TObject
);
4740 FileName
, Resource
: String;
4742 if OpenedMap
= '' then
4745 if MessageBox(0, PChar(_lc
[I_MSG_REOPEN_MAP_PROMT
]),
4746 PChar(_lc
[I_MENU_FILE_REOPEN
]), MB_ICONQUESTION
or MB_YESNO
) <> idYes
then
4749 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, @Resource
);
4750 OpenMap(FileName
, Resource
);
4753 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4754 const KeyName
: String; Values
: TStrings
);
4756 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4758 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4760 Values
.Add(DirNames
[D_LEFT
]);
4761 Values
.Add(DirNames
[D_RIGHT
]);
4763 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4765 Values
.Add(DirNamesAdv
[0]);
4766 Values
.Add(DirNamesAdv
[1]);
4767 Values
.Add(DirNamesAdv
[2]);
4768 Values
.Add(DirNamesAdv
[3]);
4770 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4772 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4773 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4775 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4777 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4778 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4779 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4780 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4781 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4782 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4784 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4786 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4787 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4788 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4789 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4791 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4793 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4794 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4795 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4796 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4798 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4800 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4801 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4803 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4805 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4806 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4807 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4808 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4809 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4810 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4812 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4814 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4815 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4816 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4817 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4818 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4819 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4820 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4822 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
4824 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
4825 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
4826 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
4827 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
4829 else if KeyName
= _lc
[I_PROP_TR_DAMAGE_KIND
] then
4831 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_0
]);
4832 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_3
]);
4833 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_4
]);
4834 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_5
]);
4835 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_6
]);
4836 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_7
]);
4837 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_8
]);
4839 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4840 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4841 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4842 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4843 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4844 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4845 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4846 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4847 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4848 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4849 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4850 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4851 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4852 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4853 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4854 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4855 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4856 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4857 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4859 Values
.Add(BoolNames
[True]);
4860 Values
.Add(BoolNames
[False]);
4865 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4867 _id
, a
, r
, c
: Integer;
4877 if SelectedObjectCount() <> 1 then
4879 if not SelectedObjects
[GetFirstSelected()].Live
then
4883 if not CheckProperty() then
4889 _id
:= GetFirstSelected();
4891 r
:= vleObjectProperty
.Row
;
4892 c
:= vleObjectProperty
.Col
;
4894 case SelectedObjects
[_id
].ObjectType
of
4897 with gPanels
[SelectedObjects
[_id
].ID
] do
4899 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4900 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4901 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4902 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4904 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4906 // Сброс ссылки на триггеры смены текстуры:
4907 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4908 if gTriggers
<> nil then
4909 for a
:= 0 to High(gTriggers
) do
4911 if (gTriggers
[a
].TriggerType
<> 0) and
4912 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4913 gTriggers
[a
].TexturePanel
:= -1;
4914 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4915 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4916 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4919 // Сброс ссылки на триггеры лифта:
4920 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4921 if gTriggers
<> nil then
4922 for a
:= 0 to High(gTriggers
) do
4923 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4924 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4925 gTriggers
[a
].Data
.PanelID
:= -1;
4927 // Сброс ссылки на триггеры двери:
4928 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4929 if gTriggers
<> nil then
4930 for a
:= 0 to High(gTriggers
) do
4931 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4932 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4933 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4934 gTriggers
[a
].Data
.PanelID
:= -1;
4936 if IsTexturedPanel(PanelType
) then
4937 begin // Может быть текстура
4938 if TextureName
<> '' then
4939 begin // Была текстура
4940 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4941 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4950 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4952 if TextureName
<> '' then
4953 begin // Есть текстура
4954 // Обычная текстура:
4955 if not IsSpecialTexture(TextureName
) then
4957 g_GetTextureSizeByName(TextureName
,
4958 TextureWidth
, TextureHeight
);
4960 // Проверка кратности размеров панели:
4962 if TextureWidth
<> 0 then
4963 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4965 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4969 if Res
and (TextureHeight
<> 0) then
4970 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4972 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4979 if not g_GetTexture(TextureName
, TextureID
) then
4980 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4981 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4983 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4984 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4986 TextureHeight
:= NH
;
4989 TextureID
:= TEXTURE_SPECIAL_NONE
;
4999 TextureID
:= TEXTURE_SPECIAL_NONE
;
5002 else // Спец.текстура
5006 TextureID
:= SpecialTextureID(TextureName
);
5009 else // Нет текстуры
5013 TextureID
:= TEXTURE_SPECIAL_NONE
;
5016 else // Не может быть текстуры
5023 TextureID
:= TEXTURE_SPECIAL_NONE
;
5030 with gItems
[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 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5035 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5041 with gMonsters
[SelectedObjects
[_id
].ID
] do
5043 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5044 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5045 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5051 with gAreas
[SelectedObjects
[_id
].ID
] do
5053 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5054 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5055 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5061 with gTriggers
[SelectedObjects
[_id
].ID
] do
5063 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5064 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5065 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
5066 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
5067 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
5068 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
5069 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
5074 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]]);
5075 FillByte(Data
.MapName
[0], 16, 0);
5077 Move(s
[1], Data
.MapName
[0], Min(Length(s
), 16));
5082 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
5083 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
5086 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5088 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
5089 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
5090 if Data
.Count
< 1 then
5092 if TriggerType
= TRIGGER_PRESS
then
5093 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
5096 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
5097 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
5100 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5101 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5106 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5107 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
5108 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
5113 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]]);
5114 FillByte(Data
.SoundName
[0], 64, 0);
5116 Move(s
[1], Data
.SoundName
[0], Min(Length(s
), 64));
5118 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
5119 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
5120 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
5121 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
5122 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
5125 TRIGGER_SPAWNMONSTER
:
5127 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
5128 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
5129 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
5130 if Data
.MonHealth
< 0 then
5131 Data
.MonHealth
:= 0;
5132 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
5133 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5134 if Data
.MonCount
< 1 then
5136 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5137 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5138 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5140 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
5142 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
5144 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
5146 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
5148 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
5154 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
5155 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5156 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5157 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5158 if Data
.ItemCount
< 1 then
5159 Data
.ItemCount
:= 1;
5160 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5161 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5162 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5167 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]]);
5168 FillByte(Data
.MusicName
[0], 64, 0);
5170 Move(s
[1], Data
.MusicName
[0], Min(Length(s
), 64));
5172 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
5173 Data
.MusicAction
:= 1
5175 Data
.MusicAction
:= 0;
5180 Data
.PushAngle
:= Min(
5181 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
5182 Data
.PushForce
:= Min(
5183 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
5184 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
5189 Data
.ScoreAction
:= 0;
5190 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
5191 Data
.ScoreAction
:= 1
5192 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
5193 Data
.ScoreAction
:= 2
5194 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
5195 Data
.ScoreAction
:= 3;
5196 Data
.ScoreCount
:= Min(Max(
5197 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5198 Data
.ScoreTeam
:= 0;
5199 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
5201 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
5203 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
5204 Data
.ScoreTeam
:= 3;
5205 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
5206 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
5211 Data
.MessageKind
:= 0;
5212 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
5213 Data
.MessageKind
:= 1;
5215 Data
.MessageSendTo
:= 0;
5216 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
5217 Data
.MessageSendTo
:= 1
5218 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
5219 Data
.MessageSendTo
:= 2
5220 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
5221 Data
.MessageSendTo
:= 3
5222 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
5223 Data
.MessageSendTo
:= 4
5224 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
5225 Data
.MessageSendTo
:= 5;
5227 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]]);
5228 FillByte(Data
.MessageText
[0], 100, 0);
5230 Move(s
[1], Data
.MessageText
[0], Min(Length(s
), 100));
5232 Data
.MessageTime
:= Min(Max(
5233 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
5238 Data
.DamageValue
:= Min(Max(
5239 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
5240 Data
.DamageInterval
:= Min(Max(
5241 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5242 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_KIND
]];
5243 if s
= _lc
[I_PROP_TR_DAMAGE_KIND_3
] then
5244 Data
.DamageKind
:= 3
5245 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_4
] then
5246 Data
.DamageKind
:= 4
5247 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_5
] then
5248 Data
.DamageKind
:= 5
5249 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_6
] then
5250 Data
.DamageKind
:= 6
5251 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_7
] then
5252 Data
.DamageKind
:= 7
5253 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_8
] then
5254 Data
.DamageKind
:= 8
5256 Data
.DamageKind
:= 0;
5261 Data
.HealValue
:= Min(Max(
5262 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
5263 Data
.HealInterval
:= Min(Max(
5264 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5265 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
5266 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5271 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
5272 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
5273 Data
.ShotTarget
:= 0;
5274 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
5275 Data
.ShotTarget
:= 1
5276 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
5277 Data
.ShotTarget
:= 2
5278 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
5279 Data
.ShotTarget
:= 3
5280 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
5281 Data
.ShotTarget
:= 4
5282 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
5283 Data
.ShotTarget
:= 5
5284 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
5285 Data
.ShotTarget
:= 6;
5286 Data
.ShotIntSight
:= Min(Max(
5287 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
5289 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
5291 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
5293 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
5295 Data
.ShotAngle
:= Min(
5296 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
5297 Data
.ShotWait
:= Min(Max(
5298 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5299 Data
.ShotAccuracy
:= Min(Max(
5300 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
5301 Data
.ShotAmmo
:= Min(Max(
5302 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
5303 Data
.ShotIntReload
:= Min(Max(
5304 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
5309 Data
.FXCount
:= Min(Max(
5310 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5311 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
5313 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
5314 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
5315 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
5316 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
5317 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5318 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
5319 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5320 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
5321 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5322 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
5323 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5324 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
5325 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5326 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
5329 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
5330 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
5333 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
5334 Data
.FXColorR
:= a
and $FF;
5335 Data
.FXColorG
:= (a
shr 8) and $FF;
5336 Data
.FXColorB
:= (a
shr 16) and $FF;
5337 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
5341 Data
.FXWait
:= Min(Max(
5342 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5343 Data
.FXVelX
:= Min(Max(
5344 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
5345 Data
.FXVelY
:= Min(Max(
5346 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
5347 Data
.FXSpreadL
:= Min(Max(
5348 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
5349 Data
.FXSpreadR
:= Min(Max(
5350 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
5351 Data
.FXSpreadU
:= Min(Max(
5352 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
5353 Data
.FXSpreadD
:= Min(Max(
5354 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
5363 vleObjectProperty
.Row
:= r
;
5364 vleObjectProperty
.Col
:= c
;
5367 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5371 i
:= lbTextureList
.ItemIndex
;
5375 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5376 [SelectedTexture()])),
5377 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5378 MB_ICONQUESTION
or MB_YESNO
or
5379 MB_DEFBUTTON1
) <> idYes
then
5382 if gPanels
<> nil then
5383 for a
:= 0 to High(gPanels
) do
5384 if (gPanels
[a
].PanelType
<> 0) and
5385 (gPanels
[a
].TextureName
= SelectedTexture()) then
5387 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5391 g_DeleteTexture(SelectedTexture());
5392 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5394 slInvalidTextures
.Delete(i
);
5395 if lbTextureList
.ItemIndex
> -1 then
5396 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5399 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5401 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
5402 PChar(_lc
[I_MSG_CLEAR_MAP
]),
5403 MB_ICONQUESTION
or MB_YESNO
or
5404 MB_DEFBUTTON1
) = mrYes
) then
5408 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5412 if UndoBuffer
= nil then
5414 if UndoBuffer
[High(UndoBuffer
)] = nil then
5417 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5418 with UndoBuffer
[High(UndoBuffer
)][a
] do
5426 UNDO_DELETE_ITEM
: AddItem(Item
);
5427 UNDO_DELETE_AREA
: AddArea(Area
);
5428 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5429 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5430 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5431 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5432 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5433 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5434 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5438 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5440 RemoveSelectFromObjects();
5442 miUndo
.Enabled
:= UndoBuffer
<> nil;
5446 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5449 CopyBuffer
: TCopyRecArray
;
5453 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5455 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5457 if Result
= 0 then // Одного типа
5458 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5461 procedure QuickSortCopyBuffer(L
, R
: Integer);
5469 P
:= CopyBuffer
[(L
+ R
) shr 1];
5472 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5474 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5480 CopyBuffer
[I
] := CopyBuffer
[J
];
5488 QuickSortCopyBuffer(L
, J
);
5495 if SelectedObjects
= nil then
5501 // Копируем объекты:
5502 for a
:= 0 to High(SelectedObjects
) do
5503 if SelectedObjects
[a
].Live
then
5504 with SelectedObjects
[a
] do
5506 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5507 b
:= High(CopyBuffer
);
5508 CopyBuffer
[b
].ID
:= ID
;
5509 CopyBuffer
[b
].Panel
:= nil;
5514 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5515 New(CopyBuffer
[b
].Panel
);
5516 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5521 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5522 CopyBuffer
[b
].Item
:= gItems
[ID
];
5527 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5528 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5533 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5534 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5539 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5540 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5545 // Сортировка по ID:
5546 if CopyBuffer
<> nil then
5548 QuickSortCopyBuffer(0, b
);
5551 // Пестановка ссылок триггеров:
5552 for a
:= 0 to Length(CopyBuffer
)-1 do
5553 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5555 case CopyBuffer
[a
].Trigger
.TriggerType
of
5556 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5557 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5558 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5559 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5563 for b
:= 0 to Length(CopyBuffer
)-1 do
5564 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5565 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5567 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5572 // Этих панелей нет среди копируемых:
5574 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5577 TRIGGER_PRESS
, TRIGGER_ON
,
5578 TRIGGER_OFF
, TRIGGER_ONOFF
:
5579 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5583 for b
:= 0 to Length(CopyBuffer
)-1 do
5584 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5585 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5587 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5592 // Этих монстров нет среди копируемых:
5594 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5598 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5602 for b
:= 0 to Length(CopyBuffer
)-1 do
5603 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5604 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5606 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5611 // Этих панелей нет среди копируемых:
5613 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5617 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5621 for b
:= 0 to Length(CopyBuffer
)-1 do
5622 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5623 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5625 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5630 // Этих панелей нет среди копируемых:
5632 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5637 str
:= CopyBufferToString(CopyBuffer
);
5638 ClipBoard
.AsText
:= str
;
5640 for a
:= 0 to Length(CopyBuffer
)-1 do
5641 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5642 (CopyBuffer
[a
].Panel
<> nil) then
5643 Dispose(CopyBuffer
[a
].Panel
);
5648 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5651 CopyBuffer
: TCopyRecArray
;
5653 swad
, ssec
, sres
: String;
5659 pmin
.X
:= High(pmin
.X
);
5660 pmin
.Y
:= High(pmin
.Y
);
5662 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
, pmin
);
5663 rel
:= not(ssShift
in GetKeyShiftState());
5665 if CopyBuffer
= nil then
5668 RemoveSelectFromObjects();
5670 h
:= High(CopyBuffer
);
5672 with CopyBuffer
[a
] do
5676 if Panel
<> nil then
5680 Panel
^.X
:= Panel
^.X
- pmin
.X
- MapOffset
.X
+ 32;
5681 Panel
^.Y
:= Panel
^.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5684 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5685 Panel
^.TextureWidth
:= 1;
5686 Panel
^.TextureHeight
:= 1;
5688 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5689 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5690 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5691 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5692 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5693 (Panel
^.TextureName
= '') then
5694 begin // Нет или не может быть текстуры:
5696 else // Есть текстура:
5698 // Обычная текстура:
5699 if not IsSpecialTexture(Panel
^.TextureName
) then
5701 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5705 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5706 AddTexture(swad
, ssec
, sres
, True);
5707 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5711 g_GetTextureSizeByName(Panel
^.TextureName
,
5712 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5714 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5716 Panel
^.TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5717 g_GetTextureSizeByID(NoTextureID
, Panel
^.TextureWidth
, Panel
^.TextureHeight
);
5720 else // Спец.текстура:
5722 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5723 with MainForm
.lbTextureList
.Items
do
5724 if IndexOf(Panel
^.TextureName
) = -1 then
5725 Add(Panel
^.TextureName
);
5729 ID
:= AddPanel(Panel
^);
5731 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5732 SelectObject(OBJECT_PANEL
, ID
, True);
5739 Item
.X
:= Item
.X
- pmin
.X
- MapOffset
.X
+ 32;
5740 Item
.Y
:= Item
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5743 ID
:= AddItem(Item
);
5744 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5745 SelectObject(OBJECT_ITEM
, ID
, True);
5752 Monster
.X
:= Monster
.X
- pmin
.X
- MapOffset
.X
+ 32;
5753 Monster
.Y
:= Monster
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5756 ID
:= AddMonster(Monster
);
5757 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5758 SelectObject(OBJECT_MONSTER
, ID
, True);
5765 Area
.X
:= Area
.X
- pmin
.X
- MapOffset
.X
+ 32;
5766 Area
.Y
:= Area
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5769 ID
:= AddArea(Area
);
5770 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5771 SelectObject(OBJECT_AREA
, ID
, True);
5779 X
:= X
- pmin
.X
- MapOffset
.X
+ 32;
5780 Y
:= Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5785 Data
.TargetPoint
.X
:=
5786 Data
.TargetPoint
.X
- pmin
.X
- MapOffset
.X
+ 32;
5787 Data
.TargetPoint
.Y
:=
5788 Data
.TargetPoint
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5790 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5792 Data
.tX
:= Data
.tX
- pmin
.X
- MapOffset
.X
+ 32;
5793 Data
.tY
:= Data
.tY
- pmin
.Y
- MapOffset
.Y
+ 32;
5795 TRIGGER_SPAWNMONSTER
:
5798 Data
.MonPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5800 Data
.MonPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5805 Data
.ItemPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5807 Data
.ItemPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5812 Data
.ShotPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5814 Data
.ShotPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5819 ID
:= AddTrigger(Trigger
);
5820 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5821 SelectObject(OBJECT_TRIGGER
, ID
, True);
5826 // Переставляем ссылки триггеров:
5827 for a
:= 0 to High(CopyBuffer
) do
5828 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5830 case CopyBuffer
[a
].Trigger
.TriggerType
of
5831 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5832 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5833 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5834 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5835 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5836 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5838 TRIGGER_PRESS
, TRIGGER_ON
,
5839 TRIGGER_OFF
, TRIGGER_ONOFF
:
5840 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5841 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5842 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5845 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5846 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5847 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5850 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5851 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5852 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5861 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5864 DeleteSelectedObjects();
5867 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5869 Key
, FileName
: String;
5872 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5874 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5876 with ChooseTypeForm
, vleObjectProperty
do
5877 begin // Выбор типа панели:
5878 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5879 lbTypeSelect
.Items
.Clear();
5881 for b
:= 0 to High(PANELNAMES
) do
5883 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5884 if Values
[Key
] = PANELNAMES
[b
] then
5885 lbTypeSelect
.ItemIndex
:= b
;
5888 if ShowModal() = mrOK
then
5890 b
:= lbTypeSelect
.ItemIndex
;
5891 Values
[Key
] := PANELNAMES
[b
];
5892 vleObjectPropertyApply(Sender
);
5896 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5897 SelectFlag
:= SELECTFLAG_TELEPORT
5898 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5899 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5900 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5901 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5902 SelectFlag
:= SELECTFLAG_DOOR
5903 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5905 DrawPressRect
:= False;
5906 SelectFlag
:= SELECTFLAG_TEXTURE
;
5908 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5909 SelectFlag
:= SELECTFLAG_SHOTPANEL
5910 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5911 SelectFlag
:= SELECTFLAG_LIFT
5912 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5913 SelectFlag
:= SELECTFLAG_MONSTER
5914 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5916 SelectFlag
:= SELECTFLAG_NONE
;
5917 DrawPressRect
:= True;
5919 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5920 begin // Выбор следующей карты:
5921 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5922 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
5923 SelectMapForm
.GetMaps(FileName
);
5925 if SelectMapForm
.ShowModal() = mrOK
then
5927 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5928 vleObjectPropertyApply(Sender
);
5931 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5932 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5933 begin // Выбор файла звука/музыки:
5934 AddSoundForm
.OKFunction
:= nil;
5935 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5936 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
5938 if (AddSoundForm
.ShowModal() = mrOk
) then
5940 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
5941 vleObjectPropertyApply(Sender
);
5944 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5945 with ActivationTypeForm
, vleObjectProperty
do
5946 begin // Выбор типов активации:
5947 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5948 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5949 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5950 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5951 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5952 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5954 if ShowModal() = mrOK
then
5957 if cbPlayerCollide
.Checked
then
5958 b
:= ACTIVATE_PLAYERCOLLIDE
;
5959 if cbMonsterCollide
.Checked
then
5960 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5961 if cbPlayerPress
.Checked
then
5962 b
:= b
or ACTIVATE_PLAYERPRESS
;
5963 if cbMonsterPress
.Checked
then
5964 b
:= b
or ACTIVATE_MONSTERPRESS
;
5965 if cbShot
.Checked
then
5966 b
:= b
or ACTIVATE_SHOT
;
5967 if cbNoMonster
.Checked
then
5968 b
:= b
or ACTIVATE_NOMONSTER
;
5970 Values
[Key
] := ActivateToStr(b
);
5971 vleObjectPropertyApply(Sender
);
5974 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5975 with KeysForm
, vleObjectProperty
do
5976 begin // Выбор необходимых ключей:
5977 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5978 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5979 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5980 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5981 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5983 if ShowModal() = mrOK
then
5986 if cbRedKey
.Checked
then
5988 if cbGreenKey
.Checked
then
5989 b
:= b
or KEY_GREEN
;
5990 if cbBlueKey
.Checked
then
5992 if cbRedTeam
.Checked
then
5993 b
:= b
or KEY_REDTEAM
;
5994 if cbBlueTeam
.Checked
then
5995 b
:= b
or KEY_BLUETEAM
;
5997 Values
[Key
] := KeyToStr(b
);
5998 vleObjectPropertyApply(Sender
);
6001 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
6002 with ChooseTypeForm
, vleObjectProperty
do
6003 begin // Выбор типа эффекта:
6004 Caption
:= _lc
[I_CAP_FX_TYPE
];
6005 lbTypeSelect
.Items
.Clear();
6007 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
6008 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6010 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
6012 if ShowModal() = mrOK
then
6014 b
:= lbTypeSelect
.ItemIndex
;
6015 Values
[Key
] := EffectToStr(b
);
6016 vleObjectPropertyApply(Sender
);
6019 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
6020 with ChooseTypeForm
, vleObjectProperty
do
6021 begin // Выбор типа монстра:
6022 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
6023 lbTypeSelect
.Items
.Clear();
6025 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
6026 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
6028 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
6030 if ShowModal() = mrOK
then
6032 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
6033 Values
[Key
] := MonsterToStr(b
);
6034 vleObjectPropertyApply(Sender
);
6037 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
6038 with ChooseTypeForm
, vleObjectProperty
do
6039 begin // Выбор типа предмета:
6040 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
6041 lbTypeSelect
.Items
.Clear();
6043 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
6044 lbTypeSelect
.Items
.Add(ItemToStr(b
));
6045 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
6046 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
6047 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
6048 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
6049 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
6050 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
6052 b
:= StrToItem(Values
[Key
]);
6053 if b
>= ITEM_BOTTLE
then
6055 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
6057 if ShowModal() = mrOK
then
6059 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
6060 if b
>= ITEM_WEAPON_KASTET
then
6062 Values
[Key
] := ItemToStr(b
);
6063 vleObjectPropertyApply(Sender
);
6066 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
6067 with ChooseTypeForm
, vleObjectProperty
do
6068 begin // Выбор типа предмета:
6069 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
6070 lbTypeSelect
.Items
.Clear();
6072 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
6073 lbTypeSelect
.Items
.Add(ShotToStr(b
));
6075 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
6077 if ShowModal() = mrOK
then
6079 b
:= lbTypeSelect
.ItemIndex
;
6080 Values
[Key
] := ShotToStr(b
);
6081 vleObjectPropertyApply(Sender
);
6084 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
6085 with ChooseTypeForm
, vleObjectProperty
do
6086 begin // Выбор типа эффекта:
6087 Caption
:= _lc
[I_CAP_FX_TYPE
];
6088 lbTypeSelect
.Items
.Clear();
6090 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
6091 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
6092 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6093 lbTypeSelect
.ItemIndex
:= 1
6095 lbTypeSelect
.ItemIndex
:= 0;
6097 if ShowModal() = mrOK
then
6099 b
:= lbTypeSelect
.ItemIndex
;
6101 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
6103 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
6104 vleObjectPropertyApply(Sender
);
6107 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
6108 with ChooseTypeForm
, vleObjectProperty
do
6109 begin // Выбор подтипа эффекта:
6110 Caption
:= _lc
[I_CAP_FX_TYPE
];
6111 lbTypeSelect
.Items
.Clear();
6113 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6115 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
6116 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6118 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
6121 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
6122 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
6123 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
6124 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
6125 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
6126 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
6127 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
6128 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
6129 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
6130 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
6131 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
6132 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
6133 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
6134 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
6135 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
6136 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
6137 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
6140 if ShowModal() = mrOK
then
6142 b
:= lbTypeSelect
.ItemIndex
;
6144 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6145 Values
[Key
] := EffectToStr(b
+ 1)
6147 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
6148 if b
= TRIGGER_EFFECT_LLIQUID
then
6149 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
6150 if b
= TRIGGER_EFFECT_DLIQUID
then
6151 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
6152 if b
= TRIGGER_EFFECT_BLOOD
then
6153 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
6154 if b
= TRIGGER_EFFECT_SPARK
then
6155 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
6156 if b
= TRIGGER_EFFECT_BUBBLE
then
6157 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
6160 vleObjectPropertyApply(Sender
);
6163 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
6164 with vleObjectProperty
do
6165 begin // Выбор цвета эффекта:
6166 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
6167 if ColorDialog
.Execute
then
6169 Values
[Key
] := IntToStr(ColorDialog
.Color
);
6170 vleObjectPropertyApply(Sender
);
6173 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
6174 begin // Смена текстуры:
6175 vleObjectProperty
.Values
[Key
] := SelectedTexture();
6176 vleObjectPropertyApply(Sender
);
6180 procedure TMainForm
.vleObjectPropertyApply(Sender
: TObject
);
6182 // hack to prevent empty ID in list
6183 RenderPanel
.SetFocus();
6184 bApplyProperty
.Click();
6185 vleObjectProperty
.SetFocus();
6188 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
6190 FileName
, Section
, Res
: String;
6192 if OpenedMap
= '' then
6194 aSaveMapAsExecute(nil);
6198 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
6200 SaveMap(FileName
+':\'+Res
);
6203 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
6205 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
6207 if OpenDialog
.Execute() then
6209 OpenMapFile(OpenDialog
.FileName
);
6210 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
6214 procedure TMainForm
.OpenMapFile(FileName
: String);
6216 if (Pos('.ini', LowerCase(ExtractFileName(FileName
))) > 0) then
6220 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
6221 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
6222 pLoadProgress
.Show();
6227 LoadMapOld(FileName
);
6229 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(FileName
)]);
6231 pLoadProgress
.Hide();
6232 MainForm
.FormResize(Self
);
6234 else // Карты из WAD:
6236 OpenMap(FileName
, '');
6240 procedure TMainForm
.FormActivate(Sender
: TObject
);
6245 MainForm
.ActiveControl
:= RenderPanel
;
6248 if gLanguage
= '' then
6250 lang
:= SelectLanguageForm
.ShowModal();
6252 1: gLanguage
:= LANGUAGE_ENGLISH
;
6253 else gLanguage
:= LANGUAGE_RUSSIAN
;
6256 config
:= TConfig
.CreateFile(CfgFileName
);
6257 config
.WriteStr('Editor', 'Language', gLanguage
);
6258 config
.SaveFile(CfgFileName
);
6262 //e_WriteLog('Read language file', MSG_NOTIFY);
6263 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
6264 g_Language_Set(gLanguage
);
6267 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
6273 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6275 if not OpenDialog
.Execute() then
6278 FileName
:= OpenDialog
.FileName
;
6279 SelectMapForm
.Caption
:= _lc
[I_CAP_REMOVE
];
6280 SelectMapForm
.lbMapList
.Items
.Clear();
6281 SelectMapForm
.GetMaps(FileName
);
6283 if SelectMapForm
.ShowModal() <> mrOK
then
6286 MapName
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6287 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
6290 g_DeleteResource(FileName
, '', MapName
, res
);
6293 MessageBox(0, PChar('Cant delete map res=' + IntToStr(res
)), PChar('Map not deleted!'), MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
6299 PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
], [MapName
])),
6300 PChar(_lc
[I_MSG_MAP_DELETED
]),
6301 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
6304 // Удалили текущую карту - сохранять по старому ее нельзя:
6305 if OpenedMap
= (FileName
+ ':\' + MapName
) then
6309 MainForm
.Caption
:= FormCaption
6313 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
6314 var Key
: Word; Shift
: TShiftState
);
6316 if Key
= VK_RETURN
then
6317 vleObjectPropertyApply(Sender
);
6320 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
6325 if (ID
= 0) and (MoveType
= 0) then
6327 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
6329 if (ID
> DWORD(High(gPanels
))) then
6334 if MoveType
= 0 then // to Back
6336 if gTriggers
<> nil then
6337 for a
:= 0 to High(gTriggers
) do
6338 with gTriggers
[a
] do
6340 if TriggerType
= TRIGGER_NONE
then
6343 if TexturePanel
= _id
then
6346 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
6350 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6351 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6352 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6353 if Data
.PanelID
= _id
then
6356 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
6360 if Data
.ShotPanelID
= _id
then
6361 Data
.ShotPanelID
:= 0
6363 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
6364 Inc(Data
.ShotPanelID
);
6368 tmp
:= gPanels
[_id
];
6370 for a
:= _id
downto 1 do
6371 gPanels
[a
] := gPanels
[a
-1];
6379 if gTriggers
<> nil then
6380 for a
:= 0 to High(gTriggers
) do
6381 with gTriggers
[a
] do
6383 if TriggerType
= TRIGGER_NONE
then
6386 if TexturePanel
= _id
then
6387 TexturePanel
:= High(gPanels
)
6389 if TexturePanel
> _id
then
6393 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6394 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6395 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6396 if Data
.PanelID
= _id
then
6397 Data
.PanelID
:= High(gPanels
)
6399 if Data
.PanelID
> _id
then
6403 if Data
.ShotPanelID
= _id
then
6404 Data
.ShotPanelID
:= High(gPanels
)
6406 if Data
.ShotPanelID
> _id
then
6407 Dec(Data
.ShotPanelID
);
6411 tmp
:= gPanels
[_id
];
6413 for a
:= _id
to High(gPanels
)-1 do
6414 gPanels
[a
] := gPanels
[a
+1];
6416 gPanels
[High(gPanels
)] := tmp
;
6418 ID
:= High(gPanels
);
6422 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6426 if SelectedObjects
= nil then
6429 for a
:= 0 to High(SelectedObjects
) do
6430 with SelectedObjects
[a
] do
6431 if Live
and (ObjectType
= OBJECT_PANEL
) then
6433 SelectedObjects
[0] := SelectedObjects
[a
];
6434 SetLength(SelectedObjects
, 1);
6441 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6445 if SelectedObjects
= nil then
6448 for a
:= 0 to High(SelectedObjects
) do
6449 with SelectedObjects
[a
] do
6450 if Live
and (ObjectType
= OBJECT_PANEL
) then
6452 SelectedObjects
[0] := SelectedObjects
[a
];
6453 SetLength(SelectedObjects
, 1);
6460 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6464 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6466 if not SaveDialog
.Execute() then
6469 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6471 if SaveMapForm
.ShowModal() <> mrOK
then
6474 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6475 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6476 OpenedWAD
:= SaveDialog
.FileName
;
6478 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6479 // Такая карта уже недавно открывалась:
6481 RecentFiles
.Delete(idx
);
6482 RecentFiles
.Insert(0, OpenedMap
);
6487 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6488 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6489 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6492 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6496 RemoveSelectFromObjects();
6498 case pcObjects
.ActivePageIndex
+1 of
6500 if gPanels
<> nil then
6501 for a
:= 0 to High(gPanels
) do
6502 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6503 SelectObject(OBJECT_PANEL
, a
, True);
6505 if gItems
<> nil then
6506 for a
:= 0 to High(gItems
) do
6507 if gItems
[a
].ItemType
<> ITEM_NONE
then
6508 SelectObject(OBJECT_ITEM
, a
, True);
6510 if gMonsters
<> nil then
6511 for a
:= 0 to High(gMonsters
) do
6512 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6513 SelectObject(OBJECT_MONSTER
, a
, True);
6515 if gAreas
<> nil then
6516 for a
:= 0 to High(gAreas
) do
6517 if gAreas
[a
].AreaType
<> AREA_NONE
then
6518 SelectObject(OBJECT_AREA
, a
, True);
6520 if gTriggers
<> nil then
6521 for a
:= 0 to High(gTriggers
) do
6522 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6523 SelectObject(OBJECT_TRIGGER
, a
, True);
6526 RecountSelectedObjects();
6529 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6531 DotEnable
:= not DotEnable
;
6532 (Sender
as TToolButton
).Down
:= DotEnable
;
6535 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6538 // FIXME: this is a shitty hack
6539 if not gDataLoaded
then
6541 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6543 e_WriteLog('Loading data', MSG_NOTIFY
);
6544 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6545 e_WriteLog('Loading more data', MSG_NOTIFY
);
6547 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6548 gDataLoaded
:= True;
6549 MainForm
.FormResize(nil);
6552 if StartMap
<> '' then
6560 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6562 if PreviewMode
= 2 then
6565 if PreviewMode
= 0 then
6567 Splitter2
.Visible
:= False;
6568 Splitter1
.Visible
:= False;
6569 StatusBar
.Visible
:= False;
6570 PanelObjs
.Visible
:= False;
6571 PanelProps
.Visible
:= False;
6572 MainToolBar
.Visible
:= False;
6573 sbHorizontal
.Visible
:= False;
6574 sbVertical
.Visible
:= False;
6578 StatusBar
.Visible
:= True;
6579 PanelObjs
.Visible
:= True;
6580 PanelProps
.Visible
:= True;
6581 Splitter2
.Visible
:= True;
6582 Splitter1
.Visible
:= True;
6583 MainToolBar
.Visible
:= True;
6584 sbHorizontal
.Visible
:= True;
6585 sbVertical
.Visible
:= True;
6588 PreviewMode
:= PreviewMode
xor 1;
6589 (Sender
as TMenuItem
).Checked
:= PreviewMode
> 0;
6594 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6596 SwitchLayer(LAYER_BACK
);
6599 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6601 SwitchLayer(LAYER_WALLS
);
6604 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6606 SwitchLayer(LAYER_FOREGROUND
);
6609 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6611 SwitchLayer(LAYER_STEPS
);
6614 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6616 SwitchLayer(LAYER_WATER
);
6619 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6621 SwitchLayer(LAYER_ITEMS
);
6624 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6626 SwitchLayer(LAYER_MONSTERS
);
6629 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6631 SwitchLayer(LAYER_AREAS
);
6634 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6636 SwitchLayer(LAYER_TRIGGERS
);
6639 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6645 for a
:= 0 to High(LayerEnabled
) do
6646 b
:= b
and LayerEnabled
[a
];
6650 ShowLayer(LAYER_BACK
, b
);
6651 ShowLayer(LAYER_WALLS
, b
);
6652 ShowLayer(LAYER_FOREGROUND
, b
);
6653 ShowLayer(LAYER_STEPS
, b
);
6654 ShowLayer(LAYER_WATER
, b
);
6655 ShowLayer(LAYER_ITEMS
, b
);
6656 ShowLayer(LAYER_MONSTERS
, b
);
6657 ShowLayer(LAYER_AREAS
, b
);
6658 ShowLayer(LAYER_TRIGGERS
, b
);
6661 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6666 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6668 if DotStep
= DotStepOne
then
6669 DotStep
:= DotStepTwo
6671 DotStep
:= DotStepOne
;
6673 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6674 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6677 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6682 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6684 SnapToGrid
:= not SnapToGrid
;
6686 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6687 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6689 miSnapToGrid
.Checked
:= SnapToGrid
;
6692 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6694 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6695 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6697 pcObjects
.ActivePageIndex
:= 0;
6700 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6702 SaveMiniMapForm
.ShowModal();
6705 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6707 lbTextureList
.ItemIndex
:= -1;
6708 lTextureWidth
.Caption
:= '';
6709 lTextureHeight
.Caption
:= '';
6712 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6714 PackMapForm
.ShowModal();
6717 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6719 MapTestForm
.ShowModal();
6722 type SSArray
= array of String;
6724 function ParseString (Str
: AnsiString
): SSArray
;
6725 function GetStr (var Str
: AnsiString
): AnsiString
;
6729 if Str
[1] = '"' then
6730 for b
:= 1 to Length(Str
) do
6731 if (b
= Length(Str
)) or (Str
[b
+ 1] = '"') then
6733 Result
:= Copy(Str
, 2, b
- 1);
6734 Delete(Str
, 1, b
+ 1);
6738 for a
:= 1 to Length(Str
) do
6739 if (a
= Length(Str
)) or (Str
[a
+ 1] = ' ') then
6741 Result
:= Copy(Str
, 1, a
);
6742 Delete(Str
, 1, a
+ 1);
6752 SetLength(Result
, Length(Result
)+1);
6753 Result
[High(Result
)] := GetStr(Str
);
6757 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6759 newWAD
, oldWAD
, tempMap
, ext
: String;
6766 // Ignore while map testing in progress
6767 if MapTestProcess
<> nil then
6770 // Сохраняем временную карту:
6773 newWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps/temp%.4d', [time
]);
6775 until not FileExists(newWAD
);
6776 if OpenedMap
<> '' then
6778 oldWad
:= g_ExtractWadName(OpenedMap
);
6779 newWad
:= newWad
+ ExtractFileExt(oldWad
);
6780 if CopyFile(oldWad
, newWad
) = false then
6781 e_WriteLog('MapTest: unable to copy [' + oldWad
+ '] to [' + newWad
+ ']', MSG_WARNING
)
6785 newWad
:= newWad
+ '.wad'
6787 tempMap
:= newWAD
+ ':\' + TEST_MAP_NAME
;
6789 tempMap
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', tempMap
);
6793 if TestOptionsTwoPlayers
then
6795 if TestOptionsTeamDamage
then
6797 if TestOptionsAllowExit
then
6799 if TestOptionsWeaponStay
then
6801 if TestOptionsMonstersDM
then
6805 proc
:= TProcessUTF8
.Create(nil);
6806 proc
.Executable
:= TestD2dExe
;
6807 proc
.Parameters
.Add('-map');
6808 proc
.Parameters
.Add(tempMap
);
6809 proc
.Parameters
.Add('-gm');
6810 proc
.Parameters
.Add(TestGameMode
);
6811 proc
.Parameters
.Add('-limt');
6812 proc
.Parameters
.Add(TestLimTime
);
6813 proc
.Parameters
.Add('-lims');
6814 proc
.Parameters
.Add(TestLimScore
);
6815 proc
.Parameters
.Add('-opt');
6816 proc
.Parameters
.Add(IntToStr(opt
));
6817 proc
.Parameters
.Add('--debug');
6819 proc
.Parameters
.Add('--close');
6821 args
:= ParseString(TestD2DArgs
);
6822 for i
:= 0 to High(args
) do
6823 proc
.Parameters
.Add(args
[i
]);
6833 tbTestMap
.Enabled
:= False;
6834 MapTestFile
:= newWAD
;
6835 MapTestProcess
:= proc
;
6839 Application
.MessageBox(PChar(_lc
[I_MSG_EXEC_ERROR
]), 'FIXME', MB_OK
or MB_ICONERROR
);
6840 SysUtils
.DeleteFile(newWAD
);
6845 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6846 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6848 MapOffset
.Y
:= -sbVertical
.Position
;
6851 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6852 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6854 MapOffset
.X
:= -sbHorizontal
.Position
;
6857 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6859 if OpenedWAD
<> '' then
6861 OpenMap(OpenedWAD
, '');
6865 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6869 RemoveSelectFromObjects();
6871 if gPanels
<> nil then
6872 for a
:= 0 to High(gPanels
) do
6873 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6874 SelectObject(OBJECT_PANEL
, a
, True);
6876 if gItems
<> nil then
6877 for a
:= 0 to High(gItems
) do
6878 if gItems
[a
].ItemType
<> ITEM_NONE
then
6879 SelectObject(OBJECT_ITEM
, a
, True);
6881 if gMonsters
<> nil then
6882 for a
:= 0 to High(gMonsters
) do
6883 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6884 SelectObject(OBJECT_MONSTER
, a
, True);
6886 if gAreas
<> nil then
6887 for a
:= 0 to High(gAreas
) do
6888 if gAreas
[a
].AreaType
<> AREA_NONE
then
6889 SelectObject(OBJECT_AREA
, a
, True);
6891 if gTriggers
<> nil then
6892 for a
:= 0 to High(gTriggers
) do
6893 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6894 SelectObject(OBJECT_TRIGGER
, a
, True);
6896 RecountSelectedObjects();
6899 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6900 var NewSize
: Integer; var Accept
: Boolean);
6902 Accept
:= (NewSize
> 140);
6905 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6906 var NewSize
: Integer; var Accept
: Boolean);
6908 Accept
:= (NewSize
> 110);
6911 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6913 EditingProperties
:= True;
6916 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6918 EditingProperties
:= False;
6921 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
6923 // Объекты передвигались:
6924 if MainForm
.ActiveControl
= RenderPanel
then
6926 if (Key
= VK_NUMPAD4
) or
6927 (Key
= VK_NUMPAD6
) or
6928 (Key
= VK_NUMPAD8
) or
6929 (Key
= VK_NUMPAD5
) or
6930 (Key
= Ord('V')) then
6933 // Быстрое превью карты:
6934 if Key
= Ord('E') then
6936 if PreviewMode
= 2 then
6939 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);