3 {$INCLUDE ../shared/a_modes.inc}
8 LCLIntf
, LCLType
, SysUtils
, Variants
, Classes
, Graphics
,
9 Controls
, Forms
, Dialogs
, StdCtrls
, Buttons
,
10 ComCtrls
, ValEdit
, Types
, Menus
, ExtCtrls
,
11 CheckLst
, Grids
, OpenGLContext
, Utils
, UTF8Process
;
17 TMainForm
= class(TForm
)
22 miMenuFile
: TMenuItem
;
26 miSaveMapAs
: TMenuItem
;
27 miOpenWadMap
: TMenuItem
;
29 miReopenMap
: TMenuItem
;
30 miSaveMiniMap
: TMenuItem
;
31 miDeleteMap
: TMenuItem
;
36 miMenuEdit
: TMenuItem
;
43 miSelectAll
: TMenuItem
;
48 miMenuTools
: TMenuItem
;
49 miSnapToGrid
: TMenuItem
;
51 miSwitchGrid
: TMenuItem
;
52 miShowEdges
: TMenuItem
;
64 miMenuService
: TMenuItem
;
65 miCheckMap
: TMenuItem
;
66 miOptimmization
: TMenuItem
;
67 miMapPreview
: TMenuItem
;
70 miMenuSettings
: TMenuItem
;
71 miMapOptions
: TMenuItem
;
75 miMapTestSettings
: TMenuItem
;
77 miMenuHelp
: TMenuItem
;
79 // Скрытый пункт меню для Ctrl+Tab:
83 // Панель инструментов:
84 MainToolBar
: TToolBar
;
86 pLoadProgress
: TPanel
;
87 RenderPanel
: TOpenGLControl
;
88 tbNewMap
: TToolButton
;
89 tbOpenMap
: TToolButton
;
90 tbSaveMap
: TToolButton
;
91 tbOpenWadMap
: TToolButton
;
93 tbShowMap
: TToolButton
;
97 tbGridOn
: TToolButton
;
100 tbTestMap
: TToolButton
;
101 // Всплывающее меню для кнопки слоев:
103 miLayerP1
: TMenuItem
;
104 miLayerP2
: TMenuItem
;
105 miLayerP3
: TMenuItem
;
106 miLayerP4
: TMenuItem
;
107 miLayerP5
: TMenuItem
;
108 miLayerP6
: TMenuItem
;
109 miLayerP7
: TMenuItem
;
110 miLayerP8
: TMenuItem
;
111 miLayerP9
: TMenuItem
;
112 // Всплывающее меню для кнопки теста карты:
113 pmMapTest
: TPopupMenu
;
114 miMapTestPMSet
: TMenuItem
;
119 sbHorizontal
: TScrollBar
;
120 sbVertical
: TScrollBar
;
124 // Панель применения свойств:
125 PanelPropApply
: TPanel
;
126 bApplyProperty
: TButton
;
127 // Редактор свойств объектов:
128 vleObjectProperty
: TValueListEditor
;
130 // Панель объектов - вкладки:
132 pcObjects
: TPageControl
;
135 lbTextureList
: TListBox
;
136 // Панель настройки текстур:
137 PanelTextures
: TPanel
;
139 lTextureWidth
: TLabel
;
141 lTextureHeight
: TLabel
;
142 cbPreview
: TCheckBox
;
143 bbAddTexture
: TBitBtn
;
144 bbRemoveTexture
: TBitBtn
;
145 bClearTexture
: TButton
;
146 // Панель типов панелей:
147 PanelPanelType
: TPanel
;
148 lbPanelType
: TListBox
;
149 // Вкладка "Предметы":
151 lbItemList
: TListBox
;
154 // Вкладка "Монстры":
155 tsMonsters
: TTabSheet
;
156 lbMonsterList
: TListBox
;
157 rbMonsterLeft
: TRadioButton
;
158 rbMonsterRight
: TRadioButton
;
159 // Вкладка "Области":
161 lbAreasList
: TListBox
;
162 rbAreaLeft
: TRadioButton
;
163 rbAreaRight
: TRadioButton
;
164 // Вкладка "Триггеры":
165 tsTriggers
: TTabSheet
;
166 lbTriggersList
: TListBox
;
167 clbActivationType
: TCheckListBox
;
168 clbKeys
: TCheckListBox
;
171 Splitter1
: TSplitter
;
172 Splitter2
: TSplitter
;
173 StatusBar
: TStatusBar
;
175 // Специальные объекты:
176 ImageList
: TImageList
;
177 ilToolbar
: TImageList
;
178 OpenDialog
: TOpenDialog
;
179 SaveDialog
: TSaveDialog
;
180 selectall1
: TMenuItem
;
181 ColorDialog
: TColorDialog
;
183 procedure aAboutExecute(Sender
: TObject
);
184 procedure aCheckMapExecute(Sender
: TObject
);
185 procedure aMoveToFore(Sender
: TObject
);
186 procedure aMoveToBack(Sender
: TObject
);
187 procedure aCopyObjectExecute(Sender
: TObject
);
188 procedure aCutObjectExecute(Sender
: TObject
);
189 procedure aEditorOptionsExecute(Sender
: TObject
);
190 procedure aExitExecute(Sender
: TObject
);
191 procedure aMapOptionsExecute(Sender
: TObject
);
192 procedure aNewMapExecute(Sender
: TObject
);
193 procedure aOpenMapExecute(Sender
: TObject
);
194 procedure aOptimizeExecute(Sender
: TObject
);
195 procedure aPasteObjectExecute(Sender
: TObject
);
196 procedure aSelectAllExecute(Sender
: TObject
);
197 procedure aSaveMapExecute(Sender
: TObject
);
198 procedure aSaveMapAsExecute(Sender
: TObject
);
199 procedure aUndoExecute(Sender
: TObject
);
200 procedure aDeleteMap(Sender
: TObject
);
201 procedure bApplyPropertyClick(Sender
: TObject
);
202 procedure bbAddTextureClick(Sender
: TObject
);
203 procedure bbRemoveTextureClick(Sender
: TObject
);
204 procedure FormActivate(Sender
: TObject
);
205 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
206 procedure FormCreate(Sender
: TObject
);
207 procedure FormDestroy(Sender
: TObject
);
208 procedure FormDropFiles(Sender
: TObject
; const FileNames
: array of String);
209 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
210 procedure FormResize(Sender
: TObject
);
211 procedure lbTextureListClick(Sender
: TObject
);
212 procedure lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
213 ARect
: TRect
; State
: TOwnerDrawState
);
214 procedure miReopenMapClick(Sender
: TObject
);
215 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
216 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
217 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
218 procedure RenderPanelPaint(Sender
: TObject
);
219 procedure RenderPanelResize(Sender
: TObject
);
220 procedure Splitter1Moved(Sender
: TObject
);
221 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
222 procedure vleObjectPropertyApply(Sender
: TObject
);
223 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
224 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
226 procedure tbGridOnClick(Sender
: TObject
);
227 procedure miMapPreviewClick(Sender
: TObject
);
228 procedure miLayer1Click(Sender
: TObject
);
229 procedure miLayer2Click(Sender
: TObject
);
230 procedure miLayer3Click(Sender
: TObject
);
231 procedure miLayer4Click(Sender
: TObject
);
232 procedure miLayer5Click(Sender
: TObject
);
233 procedure miLayer6Click(Sender
: TObject
);
234 procedure miLayer7Click(Sender
: TObject
);
235 procedure miLayer8Click(Sender
: TObject
);
236 procedure miLayer9Click(Sender
: TObject
);
237 procedure tbShowClick(Sender
: TObject
);
238 procedure miSnapToGridClick(Sender
: TObject
);
239 procedure miMiniMapClick(Sender
: TObject
);
240 procedure miSwitchGridClick(Sender
: TObject
);
241 procedure miShowEdgesClick(Sender
: TObject
);
242 procedure minexttabClick(Sender
: TObject
);
243 procedure miSaveMiniMapClick(Sender
: TObject
);
244 procedure bClearTextureClick(Sender
: TObject
);
245 procedure miPackMapClick(Sender
: TObject
);
246 procedure aRecentFileExecute(Sender
: TObject
);
247 procedure miMapTestSettingsClick(Sender
: TObject
);
248 procedure miTestMapClick(Sender
: TObject
);
249 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
250 var ScrollPos
: Integer);
251 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
252 var ScrollPos
: Integer);
253 procedure miOpenWadMapClick(Sender
: TObject
);
254 procedure selectall1Click(Sender
: TObject
);
255 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
256 var Accept
: Boolean);
257 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
258 var Accept
: Boolean);
259 procedure vleObjectPropertyEnter(Sender
: TObject
);
260 procedure vleObjectPropertyExit(Sender
: TObject
);
261 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
265 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
267 procedure RefreshRecentMenu();
268 procedure OpenMapFile(FileName
: String);
269 function RenderMousePos(): TPoint
;
270 procedure RecountSelectedObjects();
276 LAYER_FOREGROUND
= 2;
284 TEST_MAP_NAME
= '$$$_TEST_$$$';
285 LANGUAGE_FILE_NAME
= '_Editor.txt';
296 DotStepOne
, DotStepTwo
: Word;
298 DrawTexturePanel
: Boolean;
299 DrawPanelSize
: Boolean;
301 PreviewColor
: TColor
;
302 UseCheckerboard
: Boolean;
304 RecentCount
: Integer;
305 RecentFiles
: TStringList
;
306 slInvalidTextures
: TStringList
;
308 TestGameMode
: String;
310 TestLimScore
: String;
311 TestOptionsTwoPlayers
: Boolean;
312 TestOptionsTeamDamage
: Boolean;
313 TestOptionsAllowExit
: Boolean;
314 TestOptionsWeaponStay
: Boolean;
315 TestOptionsMonstersDM
: Boolean;
316 TestD2dExe
, TestD2DArgs
: String;
317 TestMapOnce
: Boolean;
319 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
320 (True, True, True, True, True, True, True, True, True);
321 ContourEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
322 (False, False, False, False, False, False, False, False, False);
323 PreviewMode
: Byte = 0;
329 procedure OpenMap(FileName
: String; mapN
: String);
330 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
331 procedure RemoveSelectFromObjects();
332 procedure ChangeShownProperty(Name
: String; NewValue
: String);
337 f_options
, e_graphics
, e_log
, GL
, Math
,
338 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
339 f_mapcheck
, f_addresource_texture
, g_textures
,
340 f_activationtype
, f_keys
, wadreader
, fileutil
,
341 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, MAPDEF
,
342 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
343 f_addresource_sound
, f_maptest
, f_choosetype
,
344 g_language
, f_selectlang
, ClipBrd
, g_resources
, g_options
;
347 UNDO_DELETE_PANEL
= 1;
348 UNDO_DELETE_ITEM
= 2;
349 UNDO_DELETE_AREA
= 3;
350 UNDO_DELETE_MONSTER
= 4;
351 UNDO_DELETE_TRIGGER
= 5;
355 UNDO_ADD_MONSTER
= 9;
356 UNDO_ADD_TRIGGER
= 10;
357 UNDO_MOVE_PANEL
= 11;
360 UNDO_MOVE_MONSTER
= 14;
361 UNDO_MOVE_TRIGGER
= 15;
362 UNDO_RESIZE_PANEL
= 16;
363 UNDO_RESIZE_TRIGGER
= 17;
365 MOUSEACTION_NONE
= 0;
366 MOUSEACTION_DRAWPANEL
= 1;
367 MOUSEACTION_DRAWTRIGGER
= 2;
368 MOUSEACTION_MOVEOBJ
= 3;
369 MOUSEACTION_RESIZE
= 4;
370 MOUSEACTION_MOVEMAP
= 5;
371 MOUSEACTION_DRAWPRESS
= 6;
372 MOUSEACTION_NOACTION
= 7;
375 RESIZETYPE_VERTICAL
= 1;
376 RESIZETYPE_HORIZONTAL
= 2;
385 SELECTFLAG_TELEPORT
= 1;
387 SELECTFLAG_TEXTURE
= 3;
389 SELECTFLAG_MONSTER
= 5;
390 SELECTFLAG_SPAWNPOINT
= 6;
391 SELECTFLAG_SHOTPANEL
= 7;
392 SELECTFLAG_SELECTED
= 8;
394 RECENT_FILES_MENU_START
= 12;
396 CLIPBOARD_SIG
= 'DF:ED';
402 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
403 UNDO_DELETE_ITEM
: (Item
: TItem
);
404 UNDO_DELETE_AREA
: (Area
: TArea
);
405 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
406 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
411 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
416 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
418 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
425 OBJECT_PANEL
: (Panel
: ^TPanel
);
426 OBJECT_ITEM
: (Item
: TItem
);
427 OBJECT_AREA
: (Area
: TArea
);
428 OBJECT_MONSTER
: (Monster
: TMonster
);
429 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
432 TCopyRecArray
= Array of TCopyRec
;
436 gDataLoaded
: Boolean = False;
437 ShowMap
: Boolean = False;
438 DrawRect
: PRect
= nil;
439 SnapToGrid
: Boolean = True;
441 MousePos
: Types
.TPoint
;
442 LastMovePoint
: Types
.TPoint
;
446 MouseLDownPos
: Types
.TPoint
;
447 MouseRDownPos
: Types
.TPoint
;
448 MouseMDownPos
: Types
.TPoint
;
450 SelectFlag
: Byte = SELECTFLAG_NONE
;
451 MouseAction
: Byte = MOUSEACTION_NONE
;
452 ResizeType
: Byte = RESIZETYPE_NONE
;
453 ResizeDirection
: Byte = RESIZEDIR_NONE
;
455 DrawPressRect
: Boolean = False;
456 EditingProperties
: Boolean = False;
458 UndoBuffer
: Array of Array of TUndoRec
= nil;
463 //----------------------------------------
464 //Далее идут вспомогательные процедуры
465 //----------------------------------------
467 function NameToBool(Name
: String): Boolean;
469 if Name
= BoolNames
[True] then
475 function NameToDir(Name
: String): TDirection
;
477 if Name
= DirNames
[D_LEFT
] then
483 function NameToDirAdv(Name
: String): Byte;
485 if Name
= DirNamesAdv
[1] then
488 if Name
= DirNamesAdv
[2] then
491 if Name
= DirNamesAdv
[3] then
497 function ActivateToStr(ActivateType
: Byte): String;
501 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
502 Result
:= Result
+ '+PC';
503 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
504 Result
:= Result
+ '+MC';
505 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
506 Result
:= Result
+ '+PP';
507 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
508 Result
:= Result
+ '+MP';
509 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
510 Result
:= Result
+ '+SH';
511 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
512 Result
:= Result
+ '+NM';
514 if (Result
<> '') and (Result
[1] = '+') then
515 Delete(Result
, 1, 1);
518 function StrToActivate(Str
: String): Byte;
522 if Pos('PC', Str
) > 0 then
523 Result
:= ACTIVATE_PLAYERCOLLIDE
;
524 if Pos('MC', Str
) > 0 then
525 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
526 if Pos('PP', Str
) > 0 then
527 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
528 if Pos('MP', Str
) > 0 then
529 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
530 if Pos('SH', Str
) > 0 then
531 Result
:= Result
or ACTIVATE_SHOT
;
532 if Pos('NM', Str
) > 0 then
533 Result
:= Result
or ACTIVATE_NOMONSTER
;
536 function KeyToStr(Key
: Byte): String;
540 if ByteBool(KEY_RED
and Key
) then
541 Result
:= Result
+ '+RK';
542 if ByteBool(KEY_GREEN
and Key
) then
543 Result
:= Result
+ '+GK';
544 if ByteBool(KEY_BLUE
and Key
) then
545 Result
:= Result
+ '+BK';
546 if ByteBool(KEY_REDTEAM
and Key
) then
547 Result
:= Result
+ '+RT';
548 if ByteBool(KEY_BLUETEAM
and Key
) then
549 Result
:= Result
+ '+BT';
551 if (Result
<> '') and (Result
[1] = '+') then
552 Delete(Result
, 1, 1);
555 function StrToKey(Str
: String): Byte;
559 if Pos('RK', Str
) > 0 then
561 if Pos('GK', Str
) > 0 then
562 Result
:= Result
or KEY_GREEN
;
563 if Pos('BK', Str
) > 0 then
564 Result
:= Result
or KEY_BLUE
;
565 if Pos('RT', Str
) > 0 then
566 Result
:= Result
or KEY_REDTEAM
;
567 if Pos('BT', Str
) > 0 then
568 Result
:= Result
or KEY_BLUETEAM
;
571 function EffectToStr(Effect
: Byte): String;
573 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
574 Result
:= EffectNames
[Effect
]
576 Result
:= EffectNames
[EFFECT_NONE
];
579 function StrToEffect(Str
: String): Byte;
583 Result
:= EFFECT_NONE
;
584 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
585 if EffectNames
[i
] = Str
then
592 function MonsterToStr(MonType
: Byte): String;
594 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
595 Result
:= MonsterNames
[MonType
]
597 Result
:= MonsterNames
[MONSTER_ZOMBY
];
600 function StrToMonster(Str
: String): Byte;
604 Result
:= MONSTER_ZOMBY
;
605 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
606 if MonsterNames
[i
] = Str
then
613 function ItemToStr(ItemType
: Byte): String;
615 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
616 Result
:= ItemNames
[ItemType
]
618 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
621 function StrToItem(Str
: String): Byte;
625 Result
:= ITEM_AMMO_BULLETS
;
626 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
627 if ItemNames
[i
] = Str
then
634 function ShotToStr(ShotType
: Byte): String;
636 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
637 Result
:= ShotNames
[ShotType
]
639 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
642 function StrToShot(Str
: String): Byte;
646 Result
:= TRIGGER_SHOT_PISTOL
;
647 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
648 if ShotNames
[i
] = Str
then
655 function SelectedObjectCount(): Word;
661 if SelectedObjects
= nil then
664 for a
:= 0 to High(SelectedObjects
) do
665 if SelectedObjects
[a
].Live
then
666 Result
:= Result
+ 1;
669 function GetFirstSelected(): Integer;
675 if SelectedObjects
= nil then
678 for a
:= 0 to High(SelectedObjects
) do
679 if SelectedObjects
[a
].Live
then
686 function Normalize16(x
: Integer): Integer;
688 Result
:= (x
div 16) * 16;
691 procedure MoveMap(X
, Y
: Integer);
693 rx
, ry
, ScaleSz
: Integer;
695 with MainForm
.RenderPanel
do
697 ScaleSz
:= 16 div Scale
;
698 // Размер видимой части карты:
699 rx
:= Min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
700 ry
:= Min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
701 // Место клика на мини-карте:
702 MapOffset
.X
:= X
- (Width
- Max(gMapInfo
.Width
div ScaleSz
, 1) - 1);
703 MapOffset
.Y
:= Y
- 1;
704 // Это же место на "большой" карте:
705 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
706 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
707 // Левый верхний угол новой видимой части карты:
708 MapOffset
.X
:= MapOffset
.X
- rx
;
709 MapOffset
.Y
:= MapOffset
.Y
- ry
;
711 MapOffset
.X
:= EnsureRange(MapOffset
.X
, MainForm
.sbHorizontal
.Min
, MainForm
.sbHorizontal
.Max
);
712 MapOffset
.Y
:= EnsureRange(MapOffset
.Y
, MainForm
.sbVertical
.Min
, MainForm
.sbVertical
.Max
);
714 // MapOffset.X := Normalize16(MapOffset.X);
715 // MapOffset.Y := Normalize16(MapOffset.Y);
718 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
719 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
721 MapOffset
.X
:= -MapOffset
.X
;
722 MapOffset
.Y
:= -MapOffset
.Y
;
727 function IsTexturedPanel(PanelType
: Word): Boolean;
729 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
730 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
731 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
734 procedure FillProperty();
739 MainForm
.vleObjectProperty
.Strings
.Clear();
740 MainForm
.RecountSelectedObjects();
742 // Отображаем свойства если выделен только один объект:
743 if SelectedObjectCount() <> 1 then
746 _id
:= GetFirstSelected();
747 if not SelectedObjects
[_id
].Live
then
750 with MainForm
.vleObjectProperty
do
751 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
753 EditStyle
:= esSimple
;
757 case SelectedObjects
[0].ObjectType
of
760 with MainForm
.vleObjectProperty
,
761 gPanels
[SelectedObjects
[_id
].ID
] do
763 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
765 EditStyle
:= esSimple
;
769 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
771 EditStyle
:= esSimple
;
775 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
777 EditStyle
:= esSimple
;
781 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
783 EditStyle
:= esSimple
;
787 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
789 EditStyle
:= esEllipsis
;
793 if IsTexturedPanel(PanelType
) then
794 begin // Может быть текстура
795 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
797 EditStyle
:= esEllipsis
;
801 if TextureName
<> '' then
802 begin // Есть текстура
803 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
805 EditStyle
:= esSimple
;
809 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
811 EditStyle
:= esPickList
;
821 with MainForm
.vleObjectProperty
,
822 gItems
[SelectedObjects
[_id
].ID
] do
824 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
826 EditStyle
:= esSimple
;
830 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
832 EditStyle
:= esSimple
;
836 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
838 EditStyle
:= esPickList
;
842 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
844 EditStyle
:= esPickList
;
852 with MainForm
.vleObjectProperty
,
853 gMonsters
[SelectedObjects
[_id
].ID
] do
855 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
857 EditStyle
:= esSimple
;
861 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
863 EditStyle
:= esSimple
;
867 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
869 EditStyle
:= esPickList
;
877 with MainForm
.vleObjectProperty
,
878 gAreas
[SelectedObjects
[_id
].ID
] do
880 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
882 EditStyle
:= esSimple
;
886 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
888 EditStyle
:= esSimple
;
892 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
894 EditStyle
:= esPickList
;
902 with MainForm
.vleObjectProperty
,
903 gTriggers
[SelectedObjects
[_id
].ID
] do
905 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
907 EditStyle
:= esSimple
;
911 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
913 EditStyle
:= esSimple
;
917 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
919 EditStyle
:= esSimple
;
923 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
925 EditStyle
:= esSimple
;
929 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
931 EditStyle
:= esSimple
;
935 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
937 EditStyle
:= esPickList
;
941 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
943 EditStyle
:= esEllipsis
;
947 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
949 EditStyle
:= esEllipsis
;
953 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
955 EditStyle
:= esEllipsis
;
962 str
:= win2utf(Data
.MapName
);
963 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], str
, True)] do
965 EditStyle
:= esEllipsis
;
972 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
974 EditStyle
:= esEllipsis
;
978 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
980 EditStyle
:= esPickList
;
984 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
986 EditStyle
:= esPickList
;
990 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
992 EditStyle
:= esPickList
;
997 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
998 TRIGGER_DOOR
, TRIGGER_DOOR5
:
1000 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
1002 EditStyle
:= esEllipsis
;
1006 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1008 EditStyle
:= esPickList
;
1012 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1014 EditStyle
:= esPickList
;
1019 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1021 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1023 EditStyle
:= esEllipsis
;
1027 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1029 EditStyle
:= esPickList
;
1033 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1035 EditStyle
:= esPickList
;
1040 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1043 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1044 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1046 EditStyle
:= esEllipsis
;
1050 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1052 EditStyle
:= esSimple
;
1056 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1058 EditStyle
:= esSimple
;
1062 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1064 EditStyle
:= esEllipsis
;
1068 if TriggerType
= TRIGGER_PRESS
then
1069 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1071 EditStyle
:= esPickList
;
1079 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1081 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1083 EditStyle
:= esEllipsis
;
1087 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1089 EditStyle
:= esPickList
;
1093 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1095 EditStyle
:= esPickList
;
1102 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1104 EditStyle
:= esPickList
;
1108 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1110 EditStyle
:= esPickList
;
1117 str
:= win2utf(Data
.SoundName
);
1118 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], str
, True)] do
1120 EditStyle
:= esEllipsis
;
1124 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1126 EditStyle
:= esSimple
;
1130 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1132 EditStyle
:= esSimple
;
1136 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1138 EditStyle
:= esSimple
;
1142 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1144 EditStyle
:= esPickList
;
1148 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1150 EditStyle
:= esPickList
;
1155 TRIGGER_SPAWNMONSTER
:
1157 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1159 EditStyle
:= esEllipsis
;
1163 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1164 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1166 EditStyle
:= esEllipsis
;
1170 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1172 EditStyle
:= esPickList
;
1176 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1178 EditStyle
:= esSimple
;
1182 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1184 EditStyle
:= esPickList
;
1188 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1190 EditStyle
:= esSimple
;
1194 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1196 EditStyle
:= esEllipsis
;
1200 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1202 EditStyle
:= esSimple
;
1206 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1208 EditStyle
:= esSimple
;
1212 case Data
.MonBehav
of
1213 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1214 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1215 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1216 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1217 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1218 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1220 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1222 EditStyle
:= esPickList
;
1229 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1231 EditStyle
:= esEllipsis
;
1235 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1236 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1238 EditStyle
:= esEllipsis
;
1242 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1244 EditStyle
:= esPickList
;
1248 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1250 EditStyle
:= esPickList
;
1254 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1256 EditStyle
:= esSimple
;
1260 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1262 EditStyle
:= esEllipsis
;
1266 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1268 EditStyle
:= esSimple
;
1272 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1274 EditStyle
:= esSimple
;
1281 str
:= win2utf(Data
.MusicName
);
1282 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], str
, True)] do
1284 EditStyle
:= esEllipsis
;
1288 if Data
.MusicAction
= 1 then
1289 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1291 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1293 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1295 EditStyle
:= esPickList
;
1302 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1304 EditStyle
:= esSimple
;
1307 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1309 EditStyle
:= esSimple
;
1312 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1314 EditStyle
:= esPickList
;
1321 case Data
.ScoreAction
of
1322 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1323 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1324 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1325 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1327 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1329 EditStyle
:= esPickList
;
1332 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1334 EditStyle
:= esSimple
;
1337 case Data
.ScoreTeam
of
1338 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1339 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1340 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1341 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1343 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1345 EditStyle
:= esPickList
;
1348 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1350 EditStyle
:= esPickList
;
1353 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1355 EditStyle
:= esPickList
;
1362 case Data
.MessageKind
of
1363 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1364 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1366 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1368 EditStyle
:= esPickList
;
1371 case Data
.MessageSendTo
of
1372 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1373 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1374 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1375 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1376 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1377 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1379 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1381 EditStyle
:= esPickList
;
1384 str
:= win2utf(Data
.MessageText
);
1385 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], str
, True)] do
1387 EditStyle
:= esSimple
;
1390 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1392 EditStyle
:= esSimple
;
1399 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1401 EditStyle
:= esSimple
;
1404 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1406 EditStyle
:= esSimple
;
1409 case Data
.DamageKind
of
1410 3: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_3
];
1411 4: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_4
];
1412 5: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_5
];
1413 6: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_6
];
1414 7: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_7
];
1415 8: str
:= _lc
[I_PROP_TR_DAMAGE_KIND_8
];
1416 else str
:= _lc
[I_PROP_TR_DAMAGE_KIND_0
];
1418 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_KIND
], str
, True)] do
1420 EditStyle
:= esPickList
;
1427 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1429 EditStyle
:= esSimple
;
1432 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1434 EditStyle
:= esSimple
;
1437 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1439 EditStyle
:= esPickList
;
1442 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1444 EditStyle
:= esPickList
;
1451 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1453 EditStyle
:= esEllipsis
;
1457 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1459 EditStyle
:= esPickList
;
1463 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1465 EditStyle
:= esEllipsis
;
1469 case Data
.ShotTarget
of
1470 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1471 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1472 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1473 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1474 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1475 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1476 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1478 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1480 EditStyle
:= esPickList
;
1484 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1486 EditStyle
:= esSimple
;
1490 case Data
.ShotAim
of
1491 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1492 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1493 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1494 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1496 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)] do
1498 EditStyle
:= esPickList
;
1502 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1503 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1505 EditStyle
:= esEllipsis
;
1509 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1511 EditStyle
:= esSimple
;
1515 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1517 EditStyle
:= esSimple
;
1521 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1523 EditStyle
:= esSimple
;
1527 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1529 EditStyle
:= esSimple
;
1533 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1535 EditStyle
:= esSimple
;
1542 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1544 EditStyle
:= esSimple
;
1548 if Data
.FXType
= 0 then
1549 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1551 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1552 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1554 EditStyle
:= esEllipsis
;
1559 if Data
.FXType
= 0 then
1560 case Data
.FXSubType
of
1561 TRIGGER_EFFECT_SLIQUID
:
1562 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1563 TRIGGER_EFFECT_LLIQUID
:
1564 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1565 TRIGGER_EFFECT_DLIQUID
:
1566 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1567 TRIGGER_EFFECT_BLOOD
:
1568 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1569 TRIGGER_EFFECT_SPARK
:
1570 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1571 TRIGGER_EFFECT_BUBBLE
:
1572 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1574 if Data
.FXType
= 1 then
1576 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1577 Data
.FXSubType
:= EFFECT_TELEPORT
;
1578 str
:= EffectToStr(Data
.FXSubType
);
1580 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1582 EditStyle
:= esEllipsis
;
1586 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1588 EditStyle
:= esEllipsis
;
1592 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1594 EditStyle
:= esPickList
;
1598 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1600 EditStyle
:= esSimple
;
1604 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1606 EditStyle
:= esSimple
;
1610 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1612 EditStyle
:= esSimple
;
1616 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1618 EditStyle
:= esSimple
;
1622 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1624 EditStyle
:= esSimple
;
1628 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1630 EditStyle
:= esSimple
;
1634 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1636 EditStyle
:= esSimple
;
1640 end; //case TriggerType
1642 end; // OBJECT_TRIGGER:
1646 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1650 if SelectedObjectCount() <> 1 then
1652 if not SelectedObjects
[GetFirstSelected()].Live
then
1655 // Есть ли такой ключ:
1656 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1658 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1662 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1671 // Уже выделен - убираем:
1672 if SelectedObjects
<> nil then
1673 for a
:= 0 to High(SelectedObjects
) do
1674 with SelectedObjects
[a
] do
1675 if Live
and (ID
= fID
) and
1676 (ObjectType
= fObjectType
) then
1685 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1687 with SelectedObjects
[High(SelectedObjects
)] do
1689 ObjectType
:= fObjectType
;
1696 SetLength(SelectedObjects
, 1);
1698 with SelectedObjects
[0] do
1700 ObjectType
:= fObjectType
;
1706 MainForm
.miCopy
.Enabled
:= True;
1707 MainForm
.miCut
.Enabled
:= True;
1709 if fObjectType
= OBJECT_PANEL
then
1711 MainForm
.miToFore
.Enabled
:= True;
1712 MainForm
.miToBack
.Enabled
:= True;
1716 procedure RemoveSelectFromObjects();
1718 SelectedObjects
:= nil;
1719 DrawPressRect
:= False;
1720 MouseLDown
:= False;
1721 MouseRDown
:= False;
1722 MouseAction
:= MOUSEACTION_NONE
;
1723 SelectFlag
:= SELECTFLAG_NONE
;
1724 ResizeType
:= RESIZETYPE_NONE
;
1725 ResizeDirection
:= RESIZEDIR_NONE
;
1727 MainForm
.vleObjectProperty
.Strings
.Clear();
1729 MainForm
.miCopy
.Enabled
:= False;
1730 MainForm
.miCut
.Enabled
:= False;
1731 MainForm
.miToFore
.Enabled
:= False;
1732 MainForm
.miToBack
.Enabled
:= False;
1735 procedure DeleteSelectedObjects();
1740 if SelectedObjects
= nil then
1746 for a
:= 0 to High(SelectedObjects
) do
1747 with SelectedObjects
[a
] do
1752 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1753 i
:= High(UndoBuffer
);
1757 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1758 ii
:= High(UndoBuffer
[i
]);
1763 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1764 New(UndoBuffer
[i
, ii
].Panel
);
1765 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1769 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1770 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1774 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1775 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1779 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1780 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1784 RemoveObject(ID
, ObjectType
);
1787 RemoveSelectFromObjects();
1789 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1790 MainForm
.RecountSelectedObjects();
1793 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1797 if (not Group
) or (Length(UndoBuffer
) = 0) then
1798 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1799 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1800 i
:= High(UndoBuffer
);
1801 ii
:= High(UndoBuffer
[i
]);
1805 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1807 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1809 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1811 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1813 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1816 UndoBuffer
[i
, ii
].AddID
:= ID
;
1818 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1821 procedure FullClear();
1823 RemoveSelectFromObjects();
1825 LoadSky(gMapInfo
.SkyName
);
1827 slInvalidTextures
.Clear();
1828 MapCheckForm
.lbErrorList
.Clear();
1829 MapCheckForm
.mErrorDescription
.Clear();
1831 MainForm
.miUndo
.Enabled
:= False;
1832 MainForm
.sbHorizontal
.Position
:= 0;
1833 MainForm
.sbVertical
.Position
:= 0;
1834 MainForm
.FormResize(nil);
1835 MainForm
.Caption
:= FormCaption
;
1840 procedure ErrorMessageBox(str
: String);
1842 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1843 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1846 function CheckProperty(): Boolean;
1852 _id
:= GetFirstSelected();
1854 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1855 with gPanels
[SelectedObjects
[_id
].ID
] do
1857 if TextureWidth
<> 0 then
1858 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1860 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1865 if TextureHeight
<> 0 then
1866 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1868 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1873 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1874 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1876 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1881 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1882 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1883 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1885 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1889 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1890 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1892 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1899 procedure SelectTexture(ID
: Integer);
1901 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1902 MainForm
.lbTextureListClick(nil);
1905 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1907 a
, FrameLen
: Integer;
1910 ResourceName
: String;
1911 FullResourceName
: String;
1912 SectionName
: String;
1914 Width
, Height
: Word;
1922 if aSection
= '..' then
1925 SectionName
:= aSection
;
1928 aWAD
:= _lc
[I_WAD_SPECIAL_MAP
];
1930 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1932 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1933 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1935 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1938 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1939 begin // Спец. текстуры
1941 ResourceName
:= aTex
;
1944 begin // Внешний WAD
1945 FileName
:= EditorDir
+'wads/'+aWAD
;
1946 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1951 // Есть ли уже такая текстура:
1952 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1953 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1956 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1961 // Название ресурса <= 64 символов:
1962 if Length(ResourceName
) > 64 then
1965 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1973 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1975 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1982 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1984 if IsAnim(FullResourceName
) then
1985 begin // Аним. текстура
1986 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
1988 if not g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
1990 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1992 else // Обычная текстура
1994 if not g_CreateTextureWAD(ResourceName
, FullResourceName
) then
1996 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1998 if (not ok
) and (slInvalidTextures
.IndexOf(ResourceName
) = -1) then
2000 slInvalidTextures
.Add(ResourceName
);
2003 if (a
> -1) and (not silent
) then
2010 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
2013 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
2014 Caption
:= FormCaption
2017 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
2019 if (sFile
<> '') and (sRes
<> '') then
2020 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
2022 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
2025 procedure OpenMap(FileName
: String; mapN
: String);
2030 SelectMapForm
.Caption
:= _lc
[I_CAP_OPEN
];
2031 SelectMapForm
.GetMaps(FileName
);
2033 if (FileName
= OpenedWAD
) and
2034 (OpenedMap
<> '') then
2036 MapName
:= OpenedMap
;
2037 while (Pos(':\', MapName
) > 0) do
2038 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
2040 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2041 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2044 if SelectMapForm
.lbMapList
.Count
> 0 then
2045 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2047 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2052 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2056 if (SelectMapForm
.ShowModal() = mrOK
) and
2057 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2058 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2063 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2069 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2070 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2071 pLoadProgress
.Show();
2073 OpenedMap
:= FileName
+':\'+MapName
;
2074 OpenedWAD
:= FileName
;
2076 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2077 // Такая карта уже недавно открывалась:
2079 RecentFiles
.Delete(idx
);
2080 RecentFiles
.Insert(0, OpenedMap
);
2081 RefreshRecentMenu();
2085 pLoadProgress
.Hide();
2088 lbTextureList
.Sorted
:= True;
2089 lbTextureList
.Sorted
:= False;
2091 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2095 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2100 if SelectedObjects
= nil then
2107 for a
:= 0 to High(SelectedObjects
) do
2108 if SelectedObjects
[a
].Live
then
2110 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2113 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2116 if (not okX
) or (not okY
) then
2122 for a
:= 0 to High(SelectedObjects
) do
2123 if SelectedObjects
[a
].Live
then
2126 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2129 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2131 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2133 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2134 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2135 begin // Двигаем зону Расширителя
2137 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2139 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2142 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2143 begin // Двигаем точку назначения Телепорта
2145 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2147 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2150 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2151 begin // Двигаем точку создания монстра
2153 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2155 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2158 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2159 begin // Двигаем точку создания предмета
2161 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2163 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2166 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2167 begin // Двигаем точку создания выстрела
2169 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2171 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2176 LastMovePoint
:= MousePos
;
2180 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2182 LayerEnabled
[Layer
] := show
;
2187 MainForm
.miLayer1
.Checked
:= show
;
2188 MainForm
.miLayerP1
.Checked
:= show
;
2192 MainForm
.miLayer2
.Checked
:= show
;
2193 MainForm
.miLayerP2
.Checked
:= show
;
2197 MainForm
.miLayer3
.Checked
:= show
;
2198 MainForm
.miLayerP3
.Checked
:= show
;
2202 MainForm
.miLayer4
.Checked
:= show
;
2203 MainForm
.miLayerP4
.Checked
:= show
;
2207 MainForm
.miLayer5
.Checked
:= show
;
2208 MainForm
.miLayerP5
.Checked
:= show
;
2212 MainForm
.miLayer6
.Checked
:= show
;
2213 MainForm
.miLayerP6
.Checked
:= show
;
2217 MainForm
.miLayer7
.Checked
:= show
;
2218 MainForm
.miLayerP7
.Checked
:= show
;
2222 MainForm
.miLayer8
.Checked
:= show
;
2223 MainForm
.miLayerP8
.Checked
:= show
;
2227 MainForm
.miLayer9
.Checked
:= show
;
2228 MainForm
.miLayerP9
.Checked
:= show
;
2232 RemoveSelectFromObjects();
2235 procedure SwitchLayer(Layer
: Byte);
2237 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2240 procedure SwitchMap();
2242 ShowMap
:= not ShowMap
;
2243 MainForm
.tbShowMap
.Down
:= ShowMap
;
2246 procedure ShowEdges();
2248 if drEdge
[3] < 255 then
2251 drEdge
[3] := gAlphaEdge
;
2254 function SelectedTexture(): String;
2256 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2257 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2262 function IsSpecialTextureSel(): Boolean;
2264 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2265 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2268 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2273 procedure AddInt(x
: Integer);
2275 Res
:= Res
+ IntToStr(x
) + ' ';
2281 if Length(CopyBuf
) = 0 then
2284 Res
:= CLIPBOARD_SIG
+ ' ';
2286 for i
:= 0 to High(CopyBuf
) do
2288 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2289 (CopyBuf
[i
].Panel
= nil) then
2293 AddInt(CopyBuf
[i
].ObjectType
);
2296 // Свойства объекта:
2297 case CopyBuf
[i
].ObjectType
of
2299 with CopyBuf
[i
].Panel
^ do
2306 Res
:= Res
+ '"' + TextureName
+ '" ';
2308 AddInt(IfThen(Blending
, 1, 0));
2312 with CopyBuf
[i
].Item
do
2317 AddInt(IfThen(OnlyDM
, 1, 0));
2318 AddInt(IfThen(Fall
, 1, 0));
2322 with CopyBuf
[i
].Monster
do
2324 AddInt(MonsterType
);
2327 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2331 with CopyBuf
[i
].Area
do
2336 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2340 with CopyBuf
[i
].Trigger
do
2342 AddInt(TriggerType
);
2347 AddInt(ActivateType
);
2349 AddInt(IfThen(Enabled
, 1, 0));
2350 AddInt(TexturePanel
);
2352 for j
:= 0 to 127 do
2353 AddInt(Data
.Default
[j
]);
2361 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
;
2366 function GetNext(): String;
2371 if Str
[1] = '"' then
2383 Result
:= Copy(Str
, 1, p
-1);
2399 Result
:= Copy(Str
, 1, p
-1);
2409 if GetNext() <> CLIPBOARD_SIG
then
2415 t
:= StrToIntDef(GetNext(), 0);
2417 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2418 (GetNext() <> ';') then
2419 begin // Что-то не то => пропускаем:
2427 i
:= Length(CopyBuf
);
2428 SetLength(CopyBuf
, i
+ 1);
2430 CopyBuf
[i
].ObjectType
:= t
;
2431 CopyBuf
[i
].Panel
:= nil;
2433 // Свойства объекта:
2437 New(CopyBuf
[i
].Panel
);
2439 with CopyBuf
[i
].Panel
^ do
2441 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2442 X
:= StrToIntDef(GetNext(), 0);
2443 Y
:= StrToIntDef(GetNext(), 0);
2444 pmin
.X
:= Min(X
, pmin
.X
);
2445 pmin
.Y
:= Min(Y
, pmin
.Y
);
2446 Width
:= StrToIntDef(GetNext(), 16);
2447 Height
:= StrToIntDef(GetNext(), 16);
2448 TextureName
:= GetNext();
2449 Alpha
:= StrToIntDef(GetNext(), 0);
2450 Blending
:= (GetNext() = '1');
2455 with CopyBuf
[i
].Item
do
2457 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2458 X
:= StrToIntDef(GetNext(), 0);
2459 Y
:= StrToIntDef(GetNext(), 0);
2460 pmin
.X
:= Min(X
, pmin
.X
);
2461 pmin
.Y
:= Min(Y
, pmin
.Y
);
2462 OnlyDM
:= (GetNext() = '1');
2463 Fall
:= (GetNext() = '1');
2467 with CopyBuf
[i
].Monster
do
2469 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2470 X
:= StrToIntDef(GetNext(), 0);
2471 Y
:= StrToIntDef(GetNext(), 0);
2472 pmin
.X
:= Min(X
, pmin
.X
);
2473 pmin
.Y
:= Min(Y
, pmin
.Y
);
2475 if GetNext() = '1' then
2478 Direction
:= D_RIGHT
;
2482 with CopyBuf
[i
].Area
do
2484 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2485 X
:= StrToIntDef(GetNext(), 0);
2486 Y
:= StrToIntDef(GetNext(), 0);
2487 pmin
.X
:= Min(X
, pmin
.X
);
2488 pmin
.Y
:= Min(Y
, pmin
.Y
);
2489 if GetNext() = '1' then
2492 Direction
:= D_RIGHT
;
2496 with CopyBuf
[i
].Trigger
do
2498 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2499 X
:= StrToIntDef(GetNext(), 0);
2500 Y
:= StrToIntDef(GetNext(), 0);
2501 pmin
.X
:= Min(X
, pmin
.X
);
2502 pmin
.Y
:= Min(Y
, pmin
.Y
);
2503 Width
:= StrToIntDef(GetNext(), 16);
2504 Height
:= StrToIntDef(GetNext(), 16);
2505 ActivateType
:= StrToIntDef(GetNext(), 0);
2506 Key
:= StrToIntDef(GetNext(), 0);
2507 Enabled
:= (GetNext() = '1');
2508 TexturePanel
:= StrToIntDef(GetNext(), 0);
2510 for j
:= 0 to 127 do
2511 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2516 pmin
.X
:= Min(Data
.TargetPoint
.X
, pmin
.X
);
2517 pmin
.Y
:= Min(Data
.TargetPoint
.Y
, pmin
.Y
);
2519 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
2521 pmin
.X
:= Min(Data
.tX
, pmin
.X
);
2522 pmin
.Y
:= Min(Data
.tY
, pmin
.Y
);
2524 TRIGGER_SPAWNMONSTER
:
2526 pmin
.X
:= Min(Data
.MonPos
.X
, pmin
.X
);
2527 pmin
.Y
:= Min(Data
.MonPos
.Y
, pmin
.Y
);
2531 pmin
.X
:= Min(Data
.ItemPos
.X
, pmin
.X
);
2532 pmin
.Y
:= Min(Data
.ItemPos
.Y
, pmin
.Y
);
2536 pmin
.X
:= Min(Data
.ShotPos
.X
, pmin
.X
);
2537 pmin
.Y
:= Min(Data
.ShotPos
.Y
, pmin
.Y
);
2545 //----------------------------------------
2546 //Закончились вспомогательные процедуры
2547 //----------------------------------------
2549 procedure TMainForm
.RefreshRecentMenu();
2554 // Лишние запомненные карты:
2555 while RecentFiles
.Count
> RecentCount
do
2556 RecentFiles
.Delete(RecentFiles
.Count
-1);
2558 // Лишние строки меню:
2559 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2560 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2562 // Отделение списка карт от строки "Выход":
2563 if RecentFiles
.Count
> 0 then
2565 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2567 MainMenu
.Items
[0].Add(MI
);
2570 // Добавление в меню списка запомненных карт:
2571 for i
:= 0 to RecentFiles
.Count
-1 do
2573 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2574 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2575 MI
.OnClick
:= aRecentFileExecute
;
2576 MainMenu
.Items
[0].Add(MI
);
2580 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2585 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2586 Delete(s
, Pos('&', s
), 1);
2587 s
:= Trim(Copy(s
, 1, 2));
2588 n
:= StrToIntDef(s
, 0) - 1;
2589 if (n
>= 0) and (n
<= RecentFiles
.Count
) then
2591 fn
:= g_ExtractWadName(RecentFiles
[n
]);
2592 if FileExists(fn
) then
2594 s
:= g_ExtractFilePathName(RecentFiles
[n
]);
2597 else if MessageBox(0, PChar(_lc
[I_MSG_DEL_RECENT_PROMT
]), PChar(_lc
[I_MSG_DEL_RECENT
]), MB_ICONQUESTION
or MB_YESNO
) = idYes
then
2599 RecentFiles
.Delete(n
);
2600 RefreshRecentMenu();
2605 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2607 OptionsForm
.ShowModal();
2610 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2620 g_ReadResource(EditorDir
+ 'data/game.wad', 'FONTS', cfgres
, cfgdata
, cfglen
);
2621 if cfgdata
<> nil then
2623 if not g_CreateTextureWAD('FONT_STD', EditorDir
+ 'data/game.wad:FONTS\' + texture
) then
2624 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2626 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2627 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2628 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2629 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2631 if g_GetTexture('FONT_STD', ID
) then
2632 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
- 2);
2639 e_WriteLog('Could not load FONT_STD', MSG_WARNING
)
2643 procedure TMainForm
.FormCreate(Sender
: TObject
);
2651 EditorDir
:= ExtractFilePath(Application
.ExeName
);
2653 e_WriteLog('Doom 2D: Forever Editor version ' + EDITOR_VERSION
, MSG_NOTIFY
);
2654 e_WriteLog('Build date: ' + EDITOR_BUILDDATE
+ ' ' + EDITOR_BUILDTIME
, MSG_NOTIFY
);
2655 e_WriteLog('Build hash: ' + g_GetBuildHash(), MSG_NOTIFY
);
2656 e_WriteLog('Build by: ' + g_GetBuilderName(), MSG_NOTIFY
);
2658 slInvalidTextures
:= TStringList
.Create
;
2660 ShowLayer(LAYER_BACK
, True);
2661 ShowLayer(LAYER_WALLS
, True);
2662 ShowLayer(LAYER_FOREGROUND
, True);
2663 ShowLayer(LAYER_STEPS
, True);
2664 ShowLayer(LAYER_WATER
, True);
2665 ShowLayer(LAYER_ITEMS
, True);
2666 ShowLayer(LAYER_MONSTERS
, True);
2667 ShowLayer(LAYER_AREAS
, True);
2668 ShowLayer(LAYER_TRIGGERS
, True);
2672 FormCaption
:= MainForm
.Caption
;
2676 config
:= TConfig
.CreateFile(CfgFileName
);
2678 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2679 Position
:= poDesktopCenter
2681 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2682 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2683 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2684 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2686 if config
.ReadBool('Editor', 'Maximize', False) then
2687 WindowState
:= wsMaximized
;
2688 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2689 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2690 Splitter1
.Left
:= PanelProps
.Left
;
2691 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2692 Splitter2
.Top
:= PanelObjs
.Top
;
2693 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2694 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2695 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2696 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2697 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2698 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2699 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2700 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2701 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2702 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2703 UseCheckerboard
:= config
.ReadBool('Editor', 'UseCheckerboard', True);
2704 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2705 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2706 if gAlphaEdge
= 255 then
2707 gAlphaEdge
:= ALPHA_EDGE
;
2708 drEdge
[0] := GetRValue(gColorEdge
);
2709 drEdge
[1] := GetGValue(gColorEdge
);
2710 drEdge
[2] := GetBValue(gColorEdge
);
2711 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2714 drEdge
[3] := gAlphaEdge
;
2715 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2716 if gAlphaTriggerLine
= 255 then
2717 gAlphaTriggerLine
:= ALPHA_LINE
;
2718 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2719 if gAlphaTriggerArea
= 255 then
2720 gAlphaTriggerArea
:= ALPHA_AREA
;
2721 gAlphaMonsterRect
:= config
.ReadInt('Editor', 'MonsterRectAlpha', 0);
2722 gAlphaAreaRect
:= config
.ReadInt('Editor', 'AreaRectAlpha', 0);
2723 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2727 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2731 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2732 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2734 s
:= config
.ReadStr('Editor', 'Language', '');
2737 Compress
:= config
.ReadBool('Editor', 'Compress', True);
2738 Backup
:= config
.ReadBool('Editor', 'Backup', True);
2740 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2741 if RecentCount
> 10 then
2743 if RecentCount
< 2 then
2746 RecentFiles
:= TStringList
.Create();
2747 for i
:= 0 to RecentCount
-1 do
2749 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2753 RefreshRecentMenu();
2757 tbShowMap
.Down
:= ShowMap
;
2758 tbGridOn
.Down
:= DotEnable
;
2759 pcObjects
.ActivePageIndex
:= 0;
2760 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2762 Application
.OnIdle
:= OnIdle
;
2765 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2767 // NOTE: all the font printing routines assume CP1251
2768 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2771 procedure TMainForm
.Draw();
2776 Width
, Height
: Word;
2779 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2788 e_Clear(GL_COLOR_BUFFER_BIT
,
2789 GetRValue(BackColor
)/255,
2790 GetGValue(BackColor
)/255,
2791 GetBValue(BackColor
)/255);
2795 ObjCount
:= SelectedObjectCount();
2797 // Обводим выделенные объекты красной рамкой:
2798 if ObjCount
> 0 then
2800 for a
:= 0 to High(SelectedObjects
) do
2801 if SelectedObjects
[a
].Live
then
2803 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2807 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2808 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2811 // Рисуем точки изменения размеров:
2812 if (ObjCount
= 1) and
2813 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2815 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2816 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2817 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2818 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2820 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2821 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2822 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2823 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2830 if DotEnable
and (PreviewMode
= 0) then
2837 x
:= MapOffset
.X
mod DotStep
;
2838 y
:= MapOffset
.Y
mod DotStep
;
2840 while x
< RenderPanel
.Width
do
2842 while y
< RenderPanel
.Height
do
2844 e_DrawPoint(DotSize
, x
+ a
, y
+ a
,
2845 GetRValue(DotColor
),
2846 GetGValue(DotColor
),
2847 GetBValue(DotColor
));
2851 y
:= MapOffset
.Y
mod DotStep
;
2856 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2857 (not IsSpecialTextureSel()) and (PreviewMode
= 0) then
2859 if not g_GetTexture(SelectedTexture(), ID
) then
2860 g_GetTexture('NOTEXTURE', ID
);
2861 g_GetTextureSizeByID(ID
, Width
, Height
);
2862 if UseCheckerboard
then
2864 if g_GetTexture('PREVIEW', PID
) then
2865 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
2867 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
2868 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
2869 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
2870 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
2873 // Подсказка при выборе точки Телепорта:
2874 if SelectFlag
= SELECTFLAG_TELEPORT
then
2876 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2877 if Data
.d2d_teleport
then
2878 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2879 MousePos
.X
+16, MousePos
.Y
-1,
2882 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2883 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2885 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2886 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2887 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
2890 // Подсказка при выборе точки появления:
2891 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2893 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2894 MousePos
.X
+16, MousePos
.Y
-1,
2896 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2897 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2898 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
2901 // Подсказка при выборе панели двери:
2902 if SelectFlag
= SELECTFLAG_DOOR
then
2904 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2905 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2906 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
2909 // Подсказка при выборе панели с текстурой:
2910 if SelectFlag
= SELECTFLAG_TEXTURE
then
2912 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2913 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2914 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
2917 // Подсказка при выборе панели индикации выстрела:
2918 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2920 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2921 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2922 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
2925 // Подсказка при выборе панели лифта:
2926 if SelectFlag
= SELECTFLAG_LIFT
then
2928 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2929 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2930 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
2933 // Подсказка при выборе монстра:
2934 if SelectFlag
= SELECTFLAG_MONSTER
then
2936 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2937 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2938 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
2941 // Подсказка при выборе области воздействия:
2942 if DrawPressRect
then
2944 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2945 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2946 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
2949 // Рисуем текстуры, если чертим панель:
2950 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2951 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2952 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2954 if not g_GetTexture(SelectedTexture(), ID
) then
2955 g_GetTexture('NOTEXTURE', ID
);
2956 g_GetTextureSizeByID(ID
, Width
, Height
);
2958 if (Abs(Right
-Left
) >= Width
) and (Abs(Bottom
-Top
) >= Height
) then
2959 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2960 Abs(Bottom
-Top
) div Height
, 64, True, False);
2963 // Прямоугольник выделения:
2964 if DrawRect
<> nil then
2966 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2968 // Чертим мышью панель/триггер или меняем мышью их размер:
2969 if (((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
2970 not(ssCtrl
in GetKeyShiftState())) or (MouseAction
= MOUSEACTION_RESIZE
)) and
2971 (DrawPanelSize
) then
2973 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2974 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2976 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2977 begin // Чертим новый
2978 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
2979 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
2980 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
],
2981 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
2983 else // Растягиваем существующий
2984 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2986 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2988 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2989 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2993 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2994 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2997 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
2999 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
3004 // Ближайшая к курсору мыши точка на сетке:
3005 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
3010 // Сколько пикселов карты в 1 пикселе мини-карты:
3011 ScaleSz
:= 16 div Scale
;
3012 // Размеры мини-карты:
3013 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
3014 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
3015 // X-координата на RenderPanel нулевой x-координаты карты:
3016 XX
:= RenderPanel
.Width
- aX
- 1;
3018 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
3019 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
3021 if gPanels
<> nil then
3024 for a
:= 0 to High(gPanels
) do
3026 if PanelType
<> 0 then
3028 // Левый верхний угол:
3029 aX
:= XX
+ (X
div ScaleSz
);
3030 aY
:= 1 + (Y
div ScaleSz
);
3032 aX2
:= max(Width
div ScaleSz
, 1);
3033 aY2
:= max(Height
div ScaleSz
, 1);
3034 // Правый нижний угол:
3035 aX2
:= aX
+ aX2
- 1;
3036 aY2
:= aY
+ aY2
- 1;
3039 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
3040 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
3041 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
3042 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
3043 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
3044 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
3045 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
3046 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
3047 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
3048 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
3049 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
3050 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
3054 // Рисуем красным выделенные панели:
3055 if SelectedObjects
<> nil then
3056 for b
:= 0 to High(SelectedObjects
) do
3057 with SelectedObjects
[b
] do
3058 if Live
and (ObjectType
= OBJECT_PANEL
) then
3059 with gPanels
[SelectedObjects
[b
].ID
] do
3060 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
3062 // Левый верхний угол:
3063 aX
:= XX
+ (X
div ScaleSz
);
3064 aY
:= 1 + (Y
div ScaleSz
);
3066 aX2
:= max(Width
div ScaleSz
, 1);
3067 aY2
:= max(Height
div ScaleSz
, 1);
3068 // Правый нижний угол:
3069 aX2
:= aX
+ aX2
- 1;
3070 aY2
:= aY
+ aY2
- 1;
3072 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
3076 if (gMapInfo
.Width
> RenderPanel
.Width
) or
3077 (gMapInfo
.Height
> RenderPanel
.Height
) then
3079 // Окно, показывающее текущее положение экрана на карте:
3081 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
3082 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
3083 // Левый верхний угол:
3084 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
3085 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
3086 // Правый нижний угол:
3090 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3091 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3096 RenderPanel
.SwapBuffers();
3099 procedure TMainForm
.FormResize(Sender
: TObject
);
3101 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3103 sbHorizontal
.Min
:= Min(gMapInfo
.Width
- RenderPanel
.Width
, -RenderPanel
.Width
div 2);
3104 sbHorizontal
.Max
:= Max(0, gMapInfo
.Width
- RenderPanel
.Width
div 2);
3105 sbVertical
.Min
:= Min(gMapInfo
.Height
- RenderPanel
.Height
, -RenderPanel
.Height
div 2);
3106 sbVertical
.Max
:= Max(0, gMapInfo
.Height
- RenderPanel
.Height
div 2);
3108 MapOffset
.X
:= -sbHorizontal
.Position
;
3109 MapOffset
.Y
:= -sbVertical
.Position
;
3112 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3117 j_max
:= 0; // shut up compiler
3121 res
:= (gPanels
<> nil) and
3122 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3123 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3125 gPanels
[ID
].Height
);
3126 j_max
:= Length(gPanels
) - 1;
3131 res
:= (gItems
<> nil) and
3132 LayerEnabled
[LAYER_ITEMS
] and
3133 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3134 ItemSize
[gItems
[ID
].ItemType
][0],
3135 ItemSize
[gItems
[ID
].ItemType
][1]);
3136 j_max
:= Length(gItems
) - 1;
3141 res
:= (gMonsters
<> nil) and
3142 LayerEnabled
[LAYER_MONSTERS
] and
3143 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3144 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3145 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3146 j_max
:= Length(gMonsters
) - 1;
3151 res
:= (gAreas
<> nil) and
3152 LayerEnabled
[LAYER_AREAS
] and
3153 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3154 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3155 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3156 j_max
:= Length(gAreas
) - 1;
3161 res
:= (gTriggers
<> nil) and
3162 LayerEnabled
[LAYER_TRIGGERS
] and
3163 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3164 gTriggers
[ID
].Width
,
3165 gTriggers
[ID
].Height
);
3166 j_max
:= Length(gTriggers
) - 1;
3176 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3185 if j
= Integer(ID
) then
3190 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3191 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3195 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3196 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3197 ItemSize
[gItems
[j
].ItemType
][0],
3198 ItemSize
[gItems
[j
].ItemType
][1]);
3200 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3201 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3202 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3203 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3205 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3206 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3207 AreaSize
[gAreas
[j
].AreaType
].Width
,
3208 AreaSize
[gAreas
[j
].AreaType
].Height
);
3210 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3211 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3213 gTriggers
[j
].Height
);
3220 SetLength(SelectedObjects
, 1);
3222 SelectedObjects
[0].ObjectType
:= ObjectType
;
3223 SelectedObjects
[0].ID
:= j
;
3224 SelectedObjects
[0].Live
:= True;
3232 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3233 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3237 c1
, c2
, c3
, c4
: Boolean;
3243 MainForm
.ActiveControl
:= RenderPanel
;
3244 RenderPanel
.SetFocus();
3246 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3248 if Button
= mbLeft
then // Left Mouse Button
3250 // Двигаем карту с помощью мыши и мини-карты:
3252 g_CollidePoint(X
, Y
,
3253 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3255 max(gMapInfo
.Width
div (16 div Scale
), 1),
3256 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3259 MouseAction
:= MOUSEACTION_MOVEMAP
;
3261 else // Ставим предмет/монстра/область:
3262 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3263 (not (ssShift
in Shift
)) then
3265 case pcObjects
.ActivePageIndex
of
3267 if lbItemList
.ItemIndex
= -1 then
3268 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3271 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3272 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3273 item
.ItemType
:= item
.ItemType
+ 2;
3274 item
.X
:= MousePos
.X
-MapOffset
.X
;
3275 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3277 if not (ssCtrl
in Shift
) then
3279 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3280 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3283 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3284 item
.Fall
:= cbFall
.Checked
;
3285 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3288 if lbMonsterList
.ItemIndex
= -1 then
3289 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3292 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3293 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3294 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3296 if not (ssCtrl
in Shift
) then
3298 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3299 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3302 if rbMonsterLeft
.Checked
then
3303 monster
.Direction
:= D_LEFT
3305 monster
.Direction
:= D_RIGHT
;
3306 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3309 if lbAreasList
.ItemIndex
= -1 then
3310 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3312 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3314 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3315 area
.X
:= MousePos
.X
-MapOffset
.X
;
3316 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3318 if not (ssCtrl
in Shift
) then
3320 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3321 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3324 if rbAreaLeft
.Checked
then
3325 area
.Direction
:= D_LEFT
3327 area
.Direction
:= D_RIGHT
;
3328 Undo_Add(OBJECT_AREA
, AddArea(area
));
3334 i
:= GetFirstSelected();
3336 // Выбираем объект под текущим:
3337 if (SelectedObjects
<> nil) and
3338 (ssShift
in Shift
) and (i
>= 0) and
3339 (SelectedObjects
[i
].Live
) then
3341 if SelectedObjectCount() = 1 then
3342 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3343 SelectedObjects
[i
].ObjectType
,
3344 SelectedObjects
[i
].ID
);
3348 // Рисуем область триггера "Расширитель":
3349 if DrawPressRect
and (i
>= 0) and
3350 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3351 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3352 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3353 MouseAction
:= MOUSEACTION_DRAWPRESS
3354 else // Рисуем панель:
3355 if pcObjects
.ActivePageIndex
= 0 then
3357 if (lbPanelType
.ItemIndex
>= 0) then
3358 MouseAction
:= MOUSEACTION_DRAWPANEL
3360 else // Рисуем триггер:
3361 if (lbTriggersList
.ItemIndex
>= 0) then
3363 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3367 end; // if Button = mbLeft
3369 if Button
= mbRight
then // Right Mouse Button
3371 // Клик по мини-карте:
3373 g_CollidePoint(X
, Y
,
3374 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3376 max(gMapInfo
.Width
div (16 div Scale
), 1),
3377 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3379 MouseAction
:= MOUSEACTION_NOACTION
;
3381 else // Нужно что-то выбрать мышью:
3382 if SelectFlag
<> SELECTFLAG_NONE
then
3385 SELECTFLAG_TELEPORT
:
3386 // Точку назначения телепортации:
3387 with gTriggers
[SelectedObjects
[
3388 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3390 X
:= MousePos
.X
-MapOffset
.X
;
3391 Y
:= MousePos
.Y
-MapOffset
.Y
;
3394 SELECTFLAG_SPAWNPOINT
:
3395 // Точку создания монстра:
3396 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3397 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3399 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3400 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3402 else if TriggerType
= TRIGGER_SPAWNITEM
then
3403 begin // Точка создания предмета:
3404 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3405 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3407 else if TriggerType
= TRIGGER_SHOT
then
3408 begin // Точка создания выстрела:
3409 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3410 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3416 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3418 2, 2, OBJECT_PANEL
, True);
3419 if IDArray
<> nil then
3421 for i
:= 0 to High(IDArray
) do
3422 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3423 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3425 gTriggers
[SelectedObjects
[
3426 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3431 gTriggers
[SelectedObjects
[
3432 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3436 // Панель с текстурой:
3438 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3440 2, 2, OBJECT_PANEL
, True);
3441 if IDArray
<> nil then
3443 for i
:= 0 to High(IDArray
) do
3444 if ((gPanels
[IDArray
[i
]].PanelType
in
3445 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3446 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3448 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3449 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3450 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3452 gTriggers
[SelectedObjects
[
3453 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3458 gTriggers
[SelectedObjects
[
3459 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3465 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3467 2, 2, OBJECT_PANEL
, True);
3468 if IDArray
<> nil then
3470 for i
:= 0 to High(IDArray
) do
3471 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3472 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3473 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3474 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3476 gTriggers
[SelectedObjects
[
3477 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3482 gTriggers
[SelectedObjects
[
3483 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3489 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3491 2, 2, OBJECT_MONSTER
, False);
3492 if IDArray
<> nil then
3493 gTriggers
[SelectedObjects
[
3494 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3496 gTriggers
[SelectedObjects
[
3497 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3500 SELECTFLAG_SHOTPANEL
:
3501 // Панель индикации выстрела:
3503 if gTriggers
[SelectedObjects
[
3504 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3506 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3508 2, 2, OBJECT_PANEL
, True);
3509 if IDArray
<> nil then
3511 for i
:= 0 to High(IDArray
) do
3512 if ((gPanels
[IDArray
[i
]].PanelType
in
3513 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3514 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3516 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3517 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3518 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3520 gTriggers
[SelectedObjects
[
3521 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3526 gTriggers
[SelectedObjects
[
3527 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3532 SelectFlag
:= SELECTFLAG_SELECTED
;
3534 else // if SelectFlag <> SELECTFLAG_NONE...
3536 // Что уже выбрано и не нажат Ctrl:
3537 if (SelectedObjects
<> nil) and
3538 (not (ssCtrl
in Shift
)) then
3539 for i
:= 0 to High(SelectedObjects
) do
3540 with SelectedObjects
[i
] do
3543 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3544 (SelectedObjectCount() = 1) then
3546 Rect
:= ObjectGetRect(ObjectType
, ID
);
3548 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3549 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3550 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3551 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3552 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3553 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3554 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3555 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3557 // Меняем размер панели или триггера:
3558 if c1
or c2
or c3
or c4
then
3560 MouseAction
:= MOUSEACTION_RESIZE
;
3561 LastMovePoint
:= MousePos
;
3565 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3567 ResizeDirection
:= RESIZEDIR_LEFT
3569 ResizeDirection
:= RESIZEDIR_RIGHT
;
3570 RenderPanel
.Cursor
:= crSizeWE
;
3574 ResizeType
:= RESIZETYPE_VERTICAL
;
3576 ResizeDirection
:= RESIZEDIR_UP
3578 ResizeDirection
:= RESIZEDIR_DOWN
;
3579 RenderPanel
.Cursor
:= crSizeNS
;
3586 // Перемещаем панель или триггер:
3587 if ObjectCollide(ObjectType
, ID
,
3589 Y
-MapOffset
.Y
-1, 2, 2) then
3591 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3592 LastMovePoint
:= MousePos
;
3598 end; // if Button = mbRight
3600 if Button
= mbMiddle
then // Middle Mouse Button
3602 SetCapture(RenderPanel
.Handle
);
3603 RenderPanel
.Cursor
:= crSize
;
3606 MouseMDown
:= Button
= mbMiddle
;
3608 MouseMDownPos
:= Mouse
.CursorPos
;
3610 MouseRDown
:= Button
= mbRight
;
3612 MouseRDownPos
:= MousePos
;
3614 MouseLDown
:= Button
= mbLeft
;
3616 MouseLDownPos
:= MousePos
;
3619 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3620 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3625 rSelectRect
: Boolean;
3626 wWidth
, wHeight
: Word;
3629 procedure SelectObjects(ObjectType
: Byte);
3634 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3635 rRect
.Width
, rRect
.Height
,
3636 ObjectType
, rSelectRect
);
3638 if IDArray
<> nil then
3639 for i
:= 0 to High(IDArray
) do
3640 SelectObject(ObjectType
, IDArray
[i
], (ssCtrl
in Shift
) or rSelectRect
);
3643 if Button
= mbLeft
then
3644 MouseLDown
:= False;
3645 if Button
= mbRight
then
3646 MouseRDown
:= False;
3647 if Button
= mbMiddle
then
3648 MouseMDown
:= False;
3651 ResizeType
:= RESIZETYPE_NONE
;
3654 if Button
= mbLeft
then // Left Mouse Button
3656 if MouseAction
<> MOUSEACTION_NONE
then
3657 begin // Было действие мышью
3658 // Мышь сдвинулась во время удержания клавиши,
3659 // либо активирован режим быстрого рисования:
3660 if ((MousePos
.X
<> MouseLDownPos
.X
) and
3661 (MousePos
.Y
<> MouseLDownPos
.Y
)) or
3662 ((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3663 (ssCtrl
in Shift
)) then
3666 MOUSEACTION_DRAWPANEL
:
3668 // Фон или передний план без текстуры - ошибка:
3669 if (lbPanelType
.ItemIndex
in [1, 2]) and
3670 (lbTextureList
.ItemIndex
= -1) then
3671 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3672 else // Назначаем параметры панели:
3674 case lbPanelType
.ItemIndex
of
3675 0: Panel
.PanelType
:= PANEL_WALL
;
3676 1: Panel
.PanelType
:= PANEL_BACK
;
3677 2: Panel
.PanelType
:= PANEL_FORE
;
3678 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3679 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3680 5: Panel
.PanelType
:= PANEL_STEP
;
3681 6: Panel
.PanelType
:= PANEL_WATER
;
3682 7: Panel
.PanelType
:= PANEL_ACID1
;
3683 8: Panel
.PanelType
:= PANEL_ACID2
;
3684 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3685 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3686 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3687 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3688 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3691 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3692 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3693 if ssCtrl
in Shift
then
3697 if (lbTextureList
.ItemIndex
<> -1) and
3698 (not IsSpecialTextureSel()) then
3700 if not g_GetTexture(SelectedTexture(), TextureID
) then
3701 g_GetTexture('NOTEXTURE', TextureID
);
3702 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
3704 Panel
.Width
:= wWidth
;
3705 Panel
.Height
:= wHeight
;
3709 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3710 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3713 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3714 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3715 (lbTextureList
.ItemIndex
= -1) then
3717 Panel
.TextureHeight
:= 1;
3718 Panel
.TextureWidth
:= 1;
3719 Panel
.TextureName
:= '';
3720 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3722 else // Есть текстура:
3724 Panel
.TextureName
:= SelectedTexture();
3726 // Обычная текстура:
3727 if not IsSpecialTextureSel() then
3729 g_GetTextureSizeByName(Panel
.TextureName
,
3730 Panel
.TextureWidth
, Panel
.TextureHeight
);
3731 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3733 else // Спец.текстура:
3735 Panel
.TextureHeight
:= 1;
3736 Panel
.TextureWidth
:= 1;
3737 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3742 Panel
.Blending
:= False;
3744 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3748 // Рисовали триггер:
3749 MOUSEACTION_DRAWTRIGGER
:
3751 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3752 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3753 if ssCtrl
in Shift
then
3757 trigger
.Width
:= wWidth
;
3758 trigger
.Height
:= wHeight
;
3762 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3763 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3766 trigger
.Enabled
:= True;
3767 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3768 trigger
.TexturePanel
:= -1;
3771 trigger
.ActivateType
:= 0;
3773 if clbActivationType
.Checked
[0] then
3774 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3775 if clbActivationType
.Checked
[1] then
3776 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3777 if clbActivationType
.Checked
[2] then
3778 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3779 if clbActivationType
.Checked
[3] then
3780 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3781 if clbActivationType
.Checked
[4] then
3782 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3783 if clbActivationType
.Checked
[5] then
3784 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3786 // Необходимые для активации ключи:
3789 if clbKeys
.Checked
[0] then
3790 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3791 if clbKeys
.Checked
[1] then
3792 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3793 if clbKeys
.Checked
[2] then
3794 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3795 if clbKeys
.Checked
[3] then
3796 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3797 if clbKeys
.Checked
[4] then
3798 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3800 // Параметры триггера:
3801 FillByte(trigger
.Data
.Default
[0], 128, 0);
3803 case trigger
.TriggerType
of
3804 // Переключаемая панель:
3805 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3806 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3807 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3809 Trigger
.Data
.PanelID
:= -1;
3815 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3816 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3817 trigger
.Data
.d2d_teleport
:= True;
3818 trigger
.Data
.TlpDir
:= 0;
3821 // Изменение других триггеров:
3822 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3825 trigger
.Data
.Count
:= 1;
3831 trigger
.Data
.Volume
:= 255;
3832 trigger
.Data
.Pan
:= 127;
3833 trigger
.Data
.PlayCount
:= 1;
3834 trigger
.Data
.Local
:= True;
3835 trigger
.Data
.SoundSwitch
:= False;
3841 trigger
.Data
.MusicAction
:= 1;
3844 // Создание монстра:
3845 TRIGGER_SPAWNMONSTER
:
3847 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3848 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3849 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3850 trigger
.Data
.MonHealth
:= 0;
3851 trigger
.Data
.MonActive
:= False;
3852 trigger
.Data
.MonCount
:= 1;
3855 // Создание предмета:
3858 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3859 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3860 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3861 trigger
.Data
.ItemOnlyDM
:= False;
3862 trigger
.Data
.ItemFalls
:= False;
3863 trigger
.Data
.ItemCount
:= 1;
3864 trigger
.Data
.ItemMax
:= 0;
3865 trigger
.Data
.ItemDelay
:= 0;
3871 trigger
.Data
.PushAngle
:= 90;
3872 trigger
.Data
.PushForce
:= 10;
3873 trigger
.Data
.ResetVel
:= True;
3878 trigger
.Data
.ScoreCount
:= 1;
3879 trigger
.Data
.ScoreCon
:= True;
3880 trigger
.Data
.ScoreMsg
:= True;
3885 trigger
.Data
.MessageKind
:= 0;
3886 trigger
.Data
.MessageSendTo
:= 0;
3887 trigger
.Data
.MessageText
:= '';
3888 trigger
.Data
.MessageTime
:= 144;
3893 trigger
.Data
.DamageValue
:= 5;
3894 trigger
.Data
.DamageInterval
:= 12;
3899 trigger
.Data
.HealValue
:= 5;
3900 trigger
.Data
.HealInterval
:= 36;
3905 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3906 trigger
.Data
.ShotSound
:= True;
3907 trigger
.Data
.ShotPanelID
:= -1;
3908 trigger
.Data
.ShotTarget
:= 0;
3909 trigger
.Data
.ShotIntSight
:= 0;
3910 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
3911 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3912 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3913 trigger
.Data
.ShotAngle
:= 0;
3914 trigger
.Data
.ShotWait
:= 18;
3915 trigger
.Data
.ShotAccuracy
:= 0;
3916 trigger
.Data
.ShotAmmo
:= 0;
3917 trigger
.Data
.ShotIntReload
:= 0;
3922 trigger
.Data
.FXCount
:= 1;
3923 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3924 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3925 trigger
.Data
.FXColorR
:= 0;
3926 trigger
.Data
.FXColorG
:= 0;
3927 trigger
.Data
.FXColorB
:= 255;
3928 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3929 trigger
.Data
.FXWait
:= 1;
3930 trigger
.Data
.FXVelX
:= 0;
3931 trigger
.Data
.FXVelY
:= -20;
3932 trigger
.Data
.FXSpreadL
:= 5;
3933 trigger
.Data
.FXSpreadR
:= 5;
3934 trigger
.Data
.FXSpreadU
:= 4;
3935 trigger
.Data
.FXSpreadD
:= 0;
3939 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3942 // Рисовали область триггера "Расширитель":
3943 MOUSEACTION_DRAWPRESS
:
3944 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3946 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3947 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3948 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3949 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3951 DrawPressRect
:= False;
3955 MouseAction
:= MOUSEACTION_NONE
;
3957 end // if Button = mbLeft...
3958 else if Button
= mbRight
then // Right Mouse Button:
3960 if MouseAction
= MOUSEACTION_NOACTION
then
3962 MouseAction
:= MOUSEACTION_NONE
;
3966 // Объект передвинут или изменен в размере:
3967 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3969 RenderPanel
.Cursor
:= crDefault
;
3970 MouseAction
:= MOUSEACTION_NONE
;
3975 // Еще не все выбрали:
3976 if SelectFlag
<> SELECTFLAG_NONE
then
3978 if SelectFlag
= SELECTFLAG_SELECTED
then
3979 SelectFlag
:= SELECTFLAG_NONE
;
3984 // Мышь сдвинулась во время удержания клавиши:
3985 if (MousePos
.X
<> MouseRDownPos
.X
) and
3986 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3988 rSelectRect
:= True;
3990 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3991 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3992 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3993 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3995 else // Мышь не сдвинулась - нет прямоугольника:
3997 rSelectRect
:= False;
3999 rRect
.X
:= X
-MapOffset
.X
-1;
4000 rRect
.Y
:= Y
-MapOffset
.Y
-1;
4005 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
4006 if not (ssCtrl
in Shift
) then
4007 RemoveSelectFromObjects();
4009 // Выделяем всё в выбранном прямоугольнике:
4010 if (ssCtrl
in Shift
) and (ssAlt
in Shift
) then
4012 SelectObjects(OBJECT_PANEL
);
4013 SelectObjects(OBJECT_ITEM
);
4014 SelectObjects(OBJECT_MONSTER
);
4015 SelectObjects(OBJECT_AREA
);
4016 SelectObjects(OBJECT_TRIGGER
);
4019 SelectObjects(pcObjects
.ActivePageIndex
+1);
4024 else // Middle Mouse Button
4026 RenderPanel
.Cursor
:= crDefault
;
4031 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
4036 function TMainForm
.RenderMousePos(): Types
.TPoint
;
4038 Result
:= RenderPanel
.ScreenToClient(Mouse
.CursorPos
);
4041 procedure TMainForm
.RecountSelectedObjects();
4043 if SelectedObjectCount() = 0 then
4044 StatusBar
.Panels
[0].Text := ''
4046 StatusBar
.Panels
[0].Text := Format(_lc
[I_CAP_STAT_SELECTED
], [SelectedObjectCount()]);
4049 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
4050 Shift
: TShiftState
; X
, Y
: Integer);
4053 dWidth
, dHeight
: Integer;
4056 wWidth
, wHeight
: Word;
4058 _id
:= GetFirstSelected();
4061 // Рисуем панель с текстурой, сетка - размеры текстуры:
4062 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
4063 (lbPanelType
.ItemIndex
in [0..8]) and
4064 (lbTextureList
.ItemIndex
<> -1) and
4065 (not IsSpecialTextureSel()) then
4067 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
4068 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
4071 // Меняем размер панели с текстурой, сетка - размеры текстуры:
4072 if (MouseAction
= MOUSEACTION_RESIZE
) and
4073 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
4074 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
4075 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
4076 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
4078 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
4079 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
4082 // Выравнивание по сетке:
4088 else // Нет выравнивания по сетке:
4094 // Новая позиция мыши:
4096 begin // Зажата левая кнопка мыши
4097 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
4098 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
4102 begin // Зажата правая кнопка мыши
4103 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
4104 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
4107 begin // Кнопки мыши не зажаты
4108 MousePos
.X
:= Round((-MapOffset
.X
+ X
) / sX
) * sX
+ MapOffset
.X
;
4109 MousePos
.Y
:= Round((-MapOffset
.Y
+ Y
) / sY
) * sY
+ MapOffset
.Y
;
4112 // Зажата только правая кнопка мыши:
4113 if (not MouseLDown
) and (MouseRDown
) and (not MouseMDown
) then
4115 // Рисуем прямоугольник выделения:
4116 if MouseAction
= MOUSEACTION_NONE
then
4118 if DrawRect
= nil then
4120 DrawRect
.Top
:= MouseRDownPos
.y
;
4121 DrawRect
.Left
:= MouseRDownPos
.x
;
4122 DrawRect
.Bottom
:= MousePos
.y
;
4123 DrawRect
.Right
:= MousePos
.x
;
4126 // Двигаем выделенные объекты:
4127 if MouseAction
= MOUSEACTION_MOVEOBJ
then
4129 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
4130 MousePos
.X
-LastMovePoint
.X
,
4131 MousePos
.Y
-LastMovePoint
.Y
);
4134 // Меняем размер выделенного объекта:
4135 if MouseAction
= MOUSEACTION_RESIZE
then
4137 if (SelectedObjectCount
= 1) and
4138 (SelectedObjects
[GetFirstSelected
].Live
) then
4140 dWidth
:= MousePos
.X
-LastMovePoint
.X
;
4141 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
;
4144 RESIZETYPE_VERTICAL
: dWidth
:= 0;
4145 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
4148 case ResizeDirection
of
4149 RESIZEDIR_UP
: dHeight
:= -dHeight
;
4150 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
4153 if ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
4154 SelectedObjects
[GetFirstSelected
].ID
,
4155 dWidth
, dHeight
, ResizeDirection
) then
4156 LastMovePoint
:= MousePos
;
4161 // Зажата только левая кнопка мыши:
4162 if (not MouseRDown
) and (MouseLDown
) and (not MouseMDown
) then
4164 // Рисуем прямоугольник планирования панели:
4165 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4166 MOUSEACTION_DRAWTRIGGER
,
4167 MOUSEACTION_DRAWPRESS
] then
4169 if DrawRect
= nil then
4171 if ssCtrl
in Shift
then
4175 if (lbTextureList
.ItemIndex
<> -1) and (not IsSpecialTextureSel()) and
4176 (MouseAction
= MOUSEACTION_DRAWPANEL
) then
4178 if not g_GetTexture(SelectedTexture(), TextureID
) then
4179 g_GetTexture('NOTEXTURE', TextureID
);
4180 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
4182 DrawRect
.Top
:= MouseLDownPos
.y
;
4183 DrawRect
.Left
:= MouseLDownPos
.x
;
4184 DrawRect
.Bottom
:= DrawRect
.Top
+ wHeight
;
4185 DrawRect
.Right
:= DrawRect
.Left
+ wWidth
;
4189 DrawRect
.Top
:= MouseLDownPos
.y
;
4190 DrawRect
.Left
:= MouseLDownPos
.x
;
4191 DrawRect
.Bottom
:= MousePos
.y
;
4192 DrawRect
.Right
:= MousePos
.x
;
4195 else // Двигаем карту:
4196 if MouseAction
= MOUSEACTION_MOVEMAP
then
4202 // Only Middle Mouse Button is pressed
4203 if (not MouseLDown
) and (not MouseRDown
) and (MouseMDown
) then
4205 MapOffset
.X
:= -EnsureRange(-MapOffset
.X
+ MouseMDownPos
.X
- Mouse
.CursorPos
.X
,
4206 sbHorizontal
.Min
, sbHorizontal
.Max
);
4207 sbHorizontal
.Position
:= -MapOffset
.X
;
4208 MapOffset
.Y
:= -EnsureRange(-MapOffset
.Y
+ MouseMDownPos
.Y
- Mouse
.CursorPos
.Y
,
4209 sbVertical
.Min
, sbVertical
.Max
);
4210 sbVertical
.Position
:= -MapOffset
.Y
;
4211 MouseMDownPos
:= Mouse
.CursorPos
;
4214 // Клавиши мыши не зажаты:
4215 if (not MouseRDown
) and (not MouseLDown
) then
4218 // Строка состояния - координаты мыши:
4219 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4220 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4223 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4225 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
4226 PChar(_lc
[I_MSG_EXIT
]),
4227 MB_ICONQUESTION
or MB_YESNO
or
4228 MB_DEFBUTTON1
) = idYes
;
4231 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4236 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4241 config
:= TConfig
.CreateFile(CfgFileName
);
4243 if WindowState
<> wsMaximized
then
4245 config
.WriteInt('Editor', 'XPos', Left
);
4246 config
.WriteInt('Editor', 'YPos', Top
);
4247 config
.WriteInt('Editor', 'Width', Width
);
4248 config
.WriteInt('Editor', 'Height', Height
);
4252 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4253 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4254 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4255 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4257 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4258 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4259 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4260 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4261 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4262 config
.WriteInt('Editor', 'DotStep', DotStep
);
4263 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4264 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4265 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4266 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4267 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4268 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4269 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4270 config
.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect
);
4271 config
.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect
);
4273 for i
:= 0 to RecentCount
-1 do
4274 if i
< RecentFiles
.Count
then
4275 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4277 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4280 config
.SaveFile(CfgFileName
);
4283 slInvalidTextures
.Free
;
4286 procedure TMainForm
.FormDropFiles(Sender
: TObject
;
4287 const FileNames
: array of String);
4289 if Length(FileNames
) <> 1 then
4292 OpenMapFile(FileNames
[0]);
4295 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4297 if MainForm
.Visible
then
4301 procedure TMainForm
.Splitter1Moved(Sender
: TObject
);
4306 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4310 MapOptionsForm
.ShowModal();
4312 ResName
:= OpenedMap
;
4313 while (Pos(':\', ResName
) > 0) do
4314 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4316 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4319 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4321 AboutForm
.ShowModal();
4324 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
4330 if (not EditingProperties
) then
4332 if ssCtrl
in Shift
then
4335 '1': ContourEnabled
[LAYER_BACK
] := not ContourEnabled
[LAYER_BACK
];
4336 '2': ContourEnabled
[LAYER_WALLS
] := not ContourEnabled
[LAYER_WALLS
];
4337 '3': ContourEnabled
[LAYER_FOREGROUND
] := not ContourEnabled
[LAYER_FOREGROUND
];
4338 '4': ContourEnabled
[LAYER_STEPS
] := not ContourEnabled
[LAYER_STEPS
];
4339 '5': ContourEnabled
[LAYER_WATER
] := not ContourEnabled
[LAYER_WATER
];
4340 '6': ContourEnabled
[LAYER_ITEMS
] := not ContourEnabled
[LAYER_ITEMS
];
4341 '7': ContourEnabled
[LAYER_MONSTERS
] := not ContourEnabled
[LAYER_MONSTERS
];
4342 '8': ContourEnabled
[LAYER_AREAS
] := not ContourEnabled
[LAYER_AREAS
];
4343 '9': ContourEnabled
[LAYER_TRIGGERS
] := not ContourEnabled
[LAYER_TRIGGERS
];
4347 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4348 if ContourEnabled
[i
] then
4350 for i
:= Low(ContourEnabled
) to High(ContourEnabled
) do
4351 ContourEnabled
[i
] := not ok
4358 '1': SwitchLayer(LAYER_BACK
);
4359 '2': SwitchLayer(LAYER_WALLS
);
4360 '3': SwitchLayer(LAYER_FOREGROUND
);
4361 '4': SwitchLayer(LAYER_STEPS
);
4362 '5': SwitchLayer(LAYER_WATER
);
4363 '6': SwitchLayer(LAYER_ITEMS
);
4364 '7': SwitchLayer(LAYER_MONSTERS
);
4365 '8': SwitchLayer(LAYER_AREAS
);
4366 '9': SwitchLayer(LAYER_TRIGGERS
);
4367 '0': tbShowClick(tbShow
);
4371 if Key
= Ord('V') then
4372 begin // Поворот монстров и областей:
4373 if (SelectedObjects
<> nil) then
4375 for i
:= 0 to High(SelectedObjects
) do
4376 if (SelectedObjects
[i
].Live
) then
4378 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4380 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4383 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4385 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4391 if pcObjects
.ActivePage
= tsMonsters
then
4393 if rbMonsterLeft
.Checked
then
4394 rbMonsterRight
.Checked
:= True
4396 rbMonsterLeft
.Checked
:= True;
4398 if pcObjects
.ActivePage
= tsAreas
then
4400 if rbAreaLeft
.Checked
then
4401 rbAreaRight
.Checked
:= True
4403 rbAreaLeft
.Checked
:= True;
4408 if not (ssCtrl
in Shift
) then
4410 // Быстрое превью карты:
4411 if Key
= Ord('E') then
4413 if PreviewMode
= 0 then
4417 // Вертикальный скролл карты:
4420 if Key
= Ord('W') then
4423 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4424 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4425 MapOffset
.Y
:= -Position
;
4428 if (MouseLDown
or MouseRDown
) then
4430 if DrawRect
<> nil then
4432 Inc(MouseLDownPos
.y
, dy
);
4433 Inc(MouseRDownPos
.y
, dy
);
4435 Inc(LastMovePoint
.Y
, dy
);
4436 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4440 if Key
= Ord('S') then
4443 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4444 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4445 MapOffset
.Y
:= -Position
;
4448 if (MouseLDown
or MouseRDown
) then
4450 if DrawRect
<> nil then
4452 Inc(MouseLDownPos
.y
, dy
);
4453 Inc(MouseRDownPos
.y
, dy
);
4455 Inc(LastMovePoint
.Y
, dy
);
4456 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4461 // Горизонтальный скролл карты:
4462 with sbHorizontal
do
4464 if Key
= Ord('A') then
4467 if ssShift
in Shift
then Position
:= EnsureRange(Position
- DotStep
* 4, Min
, Max
)
4468 else Position
:= EnsureRange(Position
- DotStep
, Min
, Max
);
4469 MapOffset
.X
:= -Position
;
4472 if (MouseLDown
or MouseRDown
) then
4474 if DrawRect
<> nil then
4476 Inc(MouseLDownPos
.x
, dx
);
4477 Inc(MouseRDownPos
.x
, dx
);
4479 Inc(LastMovePoint
.X
, dx
);
4480 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4484 if Key
= Ord('D') then
4487 if ssShift
in Shift
then Position
:= EnsureRange(Position
+ DotStep
* 4, Min
, Max
)
4488 else Position
:= EnsureRange(Position
+ DotStep
, Min
, Max
);
4489 MapOffset
.X
:= -Position
;
4492 if (MouseLDown
or MouseRDown
) then
4494 if DrawRect
<> nil then
4496 Inc(MouseLDownPos
.x
, dx
);
4497 Inc(MouseRDownPos
.x
, dx
);
4499 Inc(LastMovePoint
.X
, dx
);
4500 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4505 else // ssCtrl in Shift
4507 if ssShift
in Shift
then
4509 // Вставка по абсолютному смещению:
4510 if Key
= Ord('V') then
4511 aPasteObjectExecute(Sender
);
4513 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4517 // Удалить выделенные объекты:
4518 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4519 RenderPanel
.Focused() then
4520 DeleteSelectedObjects();
4523 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4524 RemoveSelectFromObjects();
4526 // Передвинуть объекты:
4527 if MainForm
.ActiveControl
= RenderPanel
then
4532 if Key
= VK_NUMPAD4
then
4533 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4534 if Key
= VK_NUMPAD6
then
4535 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4536 if Key
= VK_NUMPAD8
then
4537 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4538 if Key
= VK_NUMPAD5
then
4539 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4541 if (dx
<> 0) or (dy
<> 0) then
4543 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4548 if ssCtrl
in Shift
then
4550 // Выбор панели с текстурой для триггера
4551 if Key
= Ord('T') then
4553 DrawPressRect
:= False;
4554 if SelectFlag
= SELECTFLAG_TEXTURE
then
4556 SelectFlag
:= SELECTFLAG_NONE
;
4559 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4561 SelectFlag
:= SELECTFLAG_TEXTURE
;
4564 if Key
= Ord('D') then
4566 SelectFlag
:= SELECTFLAG_NONE
;
4567 if DrawPressRect
then
4569 DrawPressRect
:= False;
4574 // Выбор области воздействия, в зависимости от типа триггера
4575 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4578 DrawPressRect
:= True;
4581 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4583 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4586 SelectFlag
:= SELECTFLAG_DOOR
;
4589 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4592 SelectFlag
:= SELECTFLAG_LIFT
;
4595 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4598 SelectFlag
:= SELECTFLAG_TELEPORT
;
4601 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4604 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4608 // Выбор основного параметра, в зависимости от типа триггера
4609 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4612 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4613 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
4614 SelectMapForm
.GetMaps(FileName
);
4616 if SelectMapForm
.ShowModal() = mrOK
then
4618 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4619 bApplyProperty
.Click();
4623 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4625 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4628 AddSoundForm
.OKFunction
:= nil;
4629 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4630 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4632 if (AddSoundForm
.ShowModal() = mrOk
) then
4634 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4635 bApplyProperty
.Click();
4639 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4641 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4644 vleObjectProperty
.Row
:= i
;
4645 vleObjectProperty
.SetFocus();
4652 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4654 RemoveSelectFromObjects();
4655 MapOptimizationForm
.ShowModal();
4658 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4660 MapCheckForm
.ShowModal();
4663 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4665 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4666 AddTextureForm
.ShowModal();
4669 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4672 TextureWidth
, TextureHeight
: Word;
4677 if (lbTextureList
.ItemIndex
<> -1) and
4678 (not IsSpecialTextureSel()) then
4680 if g_GetTexture(SelectedTexture(), TextureID
) then
4682 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4684 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4685 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4688 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4689 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4694 lTextureWidth
.Caption
:= '';
4695 lTextureHeight
.Caption
:= '';
4699 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4700 ARect
: TRect
; State
: TOwnerDrawState
);
4702 with Control
as TListBox
do
4704 if LCLType
.odSelected
in State
then
4706 Canvas
.Brush
.Color
:= clHighlight
;
4707 Canvas
.Font
.Color
:= clHighlightText
;
4709 if (Items
<> nil) and (Index
>= 0) then
4710 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4712 Canvas
.Brush
.Color
:= clRed
;
4713 Canvas
.Font
.Color
:= clWhite
;
4715 Canvas
.FillRect(ARect
);
4716 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4720 procedure TMainForm
.miReopenMapClick(Sender
: TObject
);
4722 FileName
, Resource
: String;
4724 if OpenedMap
= '' then
4727 if MessageBox(0, PChar(_lc
[I_MSG_REOPEN_MAP_PROMT
]),
4728 PChar(_lc
[I_MENU_FILE_REOPEN
]), MB_ICONQUESTION
or MB_YESNO
) <> idYes
then
4731 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, @Resource
);
4732 OpenMap(FileName
, Resource
);
4735 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4736 const KeyName
: String; Values
: TStrings
);
4738 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4740 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4742 Values
.Add(DirNames
[D_LEFT
]);
4743 Values
.Add(DirNames
[D_RIGHT
]);
4745 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4747 Values
.Add(DirNamesAdv
[0]);
4748 Values
.Add(DirNamesAdv
[1]);
4749 Values
.Add(DirNamesAdv
[2]);
4750 Values
.Add(DirNamesAdv
[3]);
4752 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4754 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4755 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4757 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4759 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4760 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4761 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4762 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4763 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4764 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4766 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4768 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4769 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4770 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4771 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4773 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4775 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4776 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4777 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4778 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4780 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4782 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4783 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4785 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4787 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4788 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4789 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4790 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4791 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4792 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4794 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4796 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4797 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4798 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4799 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4800 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4801 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4802 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4804 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
4806 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
4807 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
4808 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
4809 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
4811 else if KeyName
= _lc
[I_PROP_TR_DAMAGE_KIND
] then
4813 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_0
]);
4814 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_3
]);
4815 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_4
]);
4816 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_5
]);
4817 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_6
]);
4818 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_7
]);
4819 Values
.Add(_lc
[I_PROP_TR_DAMAGE_KIND_8
]);
4821 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4822 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4823 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4824 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4825 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4826 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4827 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4828 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4829 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4830 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4831 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4832 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4833 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4834 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4835 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4836 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4837 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4838 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4839 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4841 Values
.Add(BoolNames
[True]);
4842 Values
.Add(BoolNames
[False]);
4847 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4849 _id
, a
, r
, c
: Integer;
4859 if SelectedObjectCount() <> 1 then
4861 if not SelectedObjects
[GetFirstSelected()].Live
then
4865 if not CheckProperty() then
4871 _id
:= GetFirstSelected();
4873 r
:= vleObjectProperty
.Row
;
4874 c
:= vleObjectProperty
.Col
;
4876 case SelectedObjects
[_id
].ObjectType
of
4879 with gPanels
[SelectedObjects
[_id
].ID
] do
4881 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4882 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4883 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4884 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4886 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4888 // Сброс ссылки на триггеры смены текстуры:
4889 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4890 if gTriggers
<> nil then
4891 for a
:= 0 to High(gTriggers
) do
4893 if (gTriggers
[a
].TriggerType
<> 0) and
4894 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4895 gTriggers
[a
].TexturePanel
:= -1;
4896 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4897 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4898 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4901 // Сброс ссылки на триггеры лифта:
4902 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4903 if gTriggers
<> nil then
4904 for a
:= 0 to High(gTriggers
) do
4905 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4906 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4907 gTriggers
[a
].Data
.PanelID
:= -1;
4909 // Сброс ссылки на триггеры двери:
4910 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4911 if gTriggers
<> nil then
4912 for a
:= 0 to High(gTriggers
) do
4913 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4914 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4915 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4916 gTriggers
[a
].Data
.PanelID
:= -1;
4918 if IsTexturedPanel(PanelType
) then
4919 begin // Может быть текстура
4920 if TextureName
<> '' then
4921 begin // Была текстура
4922 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4923 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4932 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4934 if TextureName
<> '' then
4935 begin // Есть текстура
4936 // Обычная текстура:
4937 if not IsSpecialTexture(TextureName
) then
4939 g_GetTextureSizeByName(TextureName
,
4940 TextureWidth
, TextureHeight
);
4942 // Проверка кратности размеров панели:
4944 if TextureWidth
<> 0 then
4945 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4947 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4951 if Res
and (TextureHeight
<> 0) then
4952 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4954 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4961 if not g_GetTexture(TextureName
, TextureID
) then
4962 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4963 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4965 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4966 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4968 TextureHeight
:= NH
;
4971 TextureID
:= TEXTURE_SPECIAL_NONE
;
4981 TextureID
:= TEXTURE_SPECIAL_NONE
;
4984 else // Спец.текстура
4988 TextureID
:= SpecialTextureID(TextureName
);
4991 else // Нет текстуры
4995 TextureID
:= TEXTURE_SPECIAL_NONE
;
4998 else // Не может быть текстуры
5005 TextureID
:= TEXTURE_SPECIAL_NONE
;
5012 with gItems
[SelectedObjects
[_id
].ID
] do
5014 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5015 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5016 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5017 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5023 with gMonsters
[SelectedObjects
[_id
].ID
] do
5025 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5026 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5027 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5033 with gAreas
[SelectedObjects
[_id
].ID
] do
5035 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5036 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5037 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
5043 with gTriggers
[SelectedObjects
[_id
].ID
] do
5045 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
5046 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
5047 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
5048 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
5049 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
5050 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
5051 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
5056 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]]);
5057 FillByte(Data
.MapName
[0], 16, 0);
5059 Move(s
[1], Data
.MapName
[0], Min(Length(s
), 16));
5064 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
5065 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
5068 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5070 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
5071 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
5072 if Data
.Count
< 1 then
5074 if TriggerType
= TRIGGER_PRESS
then
5075 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
5078 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
5079 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
5082 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5083 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5088 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5089 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
5090 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
5095 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]]);
5096 FillByte(Data
.SoundName
[0], 64, 0);
5098 Move(s
[1], Data
.SoundName
[0], Min(Length(s
), 64));
5100 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
5101 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
5102 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
5103 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
5104 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
5107 TRIGGER_SPAWNMONSTER
:
5109 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
5110 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
5111 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
5112 if Data
.MonHealth
< 0 then
5113 Data
.MonHealth
:= 0;
5114 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
5115 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5116 if Data
.MonCount
< 1 then
5118 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5119 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5120 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5122 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
5124 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
5126 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
5128 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
5130 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
5136 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
5137 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5138 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5139 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5140 if Data
.ItemCount
< 1 then
5141 Data
.ItemCount
:= 1;
5142 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5143 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5144 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5149 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]]);
5150 FillByte(Data
.MusicName
[0], 64, 0);
5152 Move(s
[1], Data
.MusicName
[0], Min(Length(s
), 64));
5154 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
5155 Data
.MusicAction
:= 1
5157 Data
.MusicAction
:= 0;
5162 Data
.PushAngle
:= Min(
5163 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
5164 Data
.PushForce
:= Min(
5165 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
5166 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
5171 Data
.ScoreAction
:= 0;
5172 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
5173 Data
.ScoreAction
:= 1
5174 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
5175 Data
.ScoreAction
:= 2
5176 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
5177 Data
.ScoreAction
:= 3;
5178 Data
.ScoreCount
:= Min(Max(
5179 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5180 Data
.ScoreTeam
:= 0;
5181 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
5183 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
5185 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
5186 Data
.ScoreTeam
:= 3;
5187 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
5188 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
5193 Data
.MessageKind
:= 0;
5194 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
5195 Data
.MessageKind
:= 1;
5197 Data
.MessageSendTo
:= 0;
5198 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
5199 Data
.MessageSendTo
:= 1
5200 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
5201 Data
.MessageSendTo
:= 2
5202 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
5203 Data
.MessageSendTo
:= 3
5204 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
5205 Data
.MessageSendTo
:= 4
5206 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
5207 Data
.MessageSendTo
:= 5;
5209 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]]);
5210 FillByte(Data
.MessageText
[0], 100, 0);
5212 Move(s
[1], Data
.MessageText
[0], Min(Length(s
), 100));
5214 Data
.MessageTime
:= Min(Max(
5215 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
5220 Data
.DamageValue
:= Min(Max(
5221 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
5222 Data
.DamageInterval
:= Min(Max(
5223 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5224 s
:= vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_KIND
]];
5225 if s
= _lc
[I_PROP_TR_DAMAGE_KIND_3
] then
5226 Data
.DamageKind
:= 3
5227 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_4
] then
5228 Data
.DamageKind
:= 4
5229 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_5
] then
5230 Data
.DamageKind
:= 5
5231 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_6
] then
5232 Data
.DamageKind
:= 6
5233 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_7
] then
5234 Data
.DamageKind
:= 7
5235 else if s
= _lc
[I_PROP_TR_DAMAGE_KIND_8
] then
5236 Data
.DamageKind
:= 8
5238 Data
.DamageKind
:= 0;
5243 Data
.HealValue
:= Min(Max(
5244 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
5245 Data
.HealInterval
:= Min(Max(
5246 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5247 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
5248 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5253 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
5254 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
5255 Data
.ShotTarget
:= 0;
5256 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
5257 Data
.ShotTarget
:= 1
5258 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
5259 Data
.ShotTarget
:= 2
5260 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
5261 Data
.ShotTarget
:= 3
5262 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
5263 Data
.ShotTarget
:= 4
5264 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
5265 Data
.ShotTarget
:= 5
5266 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
5267 Data
.ShotTarget
:= 6;
5268 Data
.ShotIntSight
:= Min(Max(
5269 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
5271 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
5273 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
5275 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
5277 Data
.ShotAngle
:= Min(
5278 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
5279 Data
.ShotWait
:= Min(Max(
5280 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5281 Data
.ShotAccuracy
:= Min(Max(
5282 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
5283 Data
.ShotAmmo
:= Min(Max(
5284 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
5285 Data
.ShotIntReload
:= Min(Max(
5286 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
5291 Data
.FXCount
:= Min(Max(
5292 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5293 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
5295 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
5296 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
5297 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
5298 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
5299 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5300 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
5301 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5302 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
5303 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5304 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
5305 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5306 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
5307 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5308 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
5311 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
5312 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
5315 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
5316 Data
.FXColorR
:= a
and $FF;
5317 Data
.FXColorG
:= (a
shr 8) and $FF;
5318 Data
.FXColorB
:= (a
shr 16) and $FF;
5319 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
5323 Data
.FXWait
:= Min(Max(
5324 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5325 Data
.FXVelX
:= Min(Max(
5326 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
5327 Data
.FXVelY
:= Min(Max(
5328 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
5329 Data
.FXSpreadL
:= Min(Max(
5330 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
5331 Data
.FXSpreadR
:= Min(Max(
5332 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
5333 Data
.FXSpreadU
:= Min(Max(
5334 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
5335 Data
.FXSpreadD
:= Min(Max(
5336 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
5345 vleObjectProperty
.Row
:= r
;
5346 vleObjectProperty
.Col
:= c
;
5349 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5353 i
:= lbTextureList
.ItemIndex
;
5357 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5358 [SelectedTexture()])),
5359 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5360 MB_ICONQUESTION
or MB_YESNO
or
5361 MB_DEFBUTTON1
) <> idYes
then
5364 if gPanels
<> nil then
5365 for a
:= 0 to High(gPanels
) do
5366 if (gPanels
[a
].PanelType
<> 0) and
5367 (gPanels
[a
].TextureName
= SelectedTexture()) then
5369 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5373 g_DeleteTexture(SelectedTexture());
5374 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5376 slInvalidTextures
.Delete(i
);
5377 if lbTextureList
.ItemIndex
> -1 then
5378 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5381 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5383 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
5384 PChar(_lc
[I_MSG_CLEAR_MAP
]),
5385 MB_ICONQUESTION
or MB_YESNO
or
5386 MB_DEFBUTTON1
) = mrYes
) then
5390 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5394 if UndoBuffer
= nil then
5396 if UndoBuffer
[High(UndoBuffer
)] = nil then
5399 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5400 with UndoBuffer
[High(UndoBuffer
)][a
] do
5408 UNDO_DELETE_ITEM
: AddItem(Item
);
5409 UNDO_DELETE_AREA
: AddArea(Area
);
5410 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5411 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5412 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5413 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5414 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5415 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5416 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5420 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5422 RemoveSelectFromObjects();
5424 miUndo
.Enabled
:= UndoBuffer
<> nil;
5428 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5431 CopyBuffer
: TCopyRecArray
;
5435 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5437 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5439 if Result
= 0 then // Одного типа
5440 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5443 procedure QuickSortCopyBuffer(L
, R
: Integer);
5451 P
:= CopyBuffer
[(L
+ R
) shr 1];
5454 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5456 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5462 CopyBuffer
[I
] := CopyBuffer
[J
];
5470 QuickSortCopyBuffer(L
, J
);
5477 if SelectedObjects
= nil then
5483 // Копируем объекты:
5484 for a
:= 0 to High(SelectedObjects
) do
5485 if SelectedObjects
[a
].Live
then
5486 with SelectedObjects
[a
] do
5488 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5489 b
:= High(CopyBuffer
);
5490 CopyBuffer
[b
].ID
:= ID
;
5491 CopyBuffer
[b
].Panel
:= nil;
5496 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5497 New(CopyBuffer
[b
].Panel
);
5498 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5503 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5504 CopyBuffer
[b
].Item
:= gItems
[ID
];
5509 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5510 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5515 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5516 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5521 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5522 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5527 // Сортировка по ID:
5528 if CopyBuffer
<> nil then
5530 QuickSortCopyBuffer(0, b
);
5533 // Пестановка ссылок триггеров:
5534 for a
:= 0 to Length(CopyBuffer
)-1 do
5535 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5537 case CopyBuffer
[a
].Trigger
.TriggerType
of
5538 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5539 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5540 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5541 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5545 for b
:= 0 to Length(CopyBuffer
)-1 do
5546 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5547 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5549 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5554 // Этих панелей нет среди копируемых:
5556 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5559 TRIGGER_PRESS
, TRIGGER_ON
,
5560 TRIGGER_OFF
, TRIGGER_ONOFF
:
5561 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5565 for b
:= 0 to Length(CopyBuffer
)-1 do
5566 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5567 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5569 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5574 // Этих монстров нет среди копируемых:
5576 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5580 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5584 for b
:= 0 to Length(CopyBuffer
)-1 do
5585 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5586 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5588 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5593 // Этих панелей нет среди копируемых:
5595 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5599 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5603 for b
:= 0 to Length(CopyBuffer
)-1 do
5604 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5605 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5607 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5612 // Этих панелей нет среди копируемых:
5614 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5619 str
:= CopyBufferToString(CopyBuffer
);
5620 ClipBoard
.AsText
:= str
;
5622 for a
:= 0 to Length(CopyBuffer
)-1 do
5623 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5624 (CopyBuffer
[a
].Panel
<> nil) then
5625 Dispose(CopyBuffer
[a
].Panel
);
5630 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5633 CopyBuffer
: TCopyRecArray
;
5635 swad
, ssec
, sres
: String;
5641 pmin
.X
:= High(pmin
.X
);
5642 pmin
.Y
:= High(pmin
.Y
);
5644 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
, pmin
);
5645 rel
:= not(ssShift
in GetKeyShiftState());
5647 if CopyBuffer
= nil then
5650 RemoveSelectFromObjects();
5652 h
:= High(CopyBuffer
);
5654 with CopyBuffer
[a
] do
5658 if Panel
<> nil then
5662 Panel
^.X
:= Panel
^.X
- pmin
.X
- MapOffset
.X
+ 32;
5663 Panel
^.Y
:= Panel
^.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5666 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5667 Panel
^.TextureWidth
:= 1;
5668 Panel
^.TextureHeight
:= 1;
5670 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5671 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5672 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5673 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5674 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5675 (Panel
^.TextureName
= '') then
5676 begin // Нет или не может быть текстуры:
5678 else // Есть текстура:
5680 // Обычная текстура:
5681 if not IsSpecialTexture(Panel
^.TextureName
) then
5683 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5687 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5688 AddTexture(swad
, ssec
, sres
, True);
5689 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5693 g_GetTextureSizeByName(Panel
^.TextureName
,
5694 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5696 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5698 Panel
^.TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5699 g_GetTextureSizeByID(NoTextureID
, Panel
^.TextureWidth
, Panel
^.TextureHeight
);
5702 else // Спец.текстура:
5704 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5705 with MainForm
.lbTextureList
.Items
do
5706 if IndexOf(Panel
^.TextureName
) = -1 then
5707 Add(Panel
^.TextureName
);
5711 ID
:= AddPanel(Panel
^);
5713 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5714 SelectObject(OBJECT_PANEL
, ID
, True);
5721 Item
.X
:= Item
.X
- pmin
.X
- MapOffset
.X
+ 32;
5722 Item
.Y
:= Item
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5725 ID
:= AddItem(Item
);
5726 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5727 SelectObject(OBJECT_ITEM
, ID
, True);
5734 Monster
.X
:= Monster
.X
- pmin
.X
- MapOffset
.X
+ 32;
5735 Monster
.Y
:= Monster
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5738 ID
:= AddMonster(Monster
);
5739 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5740 SelectObject(OBJECT_MONSTER
, ID
, True);
5747 Area
.X
:= Area
.X
- pmin
.X
- MapOffset
.X
+ 32;
5748 Area
.Y
:= Area
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5751 ID
:= AddArea(Area
);
5752 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5753 SelectObject(OBJECT_AREA
, ID
, True);
5761 X
:= X
- pmin
.X
- MapOffset
.X
+ 32;
5762 Y
:= Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5767 Data
.TargetPoint
.X
:=
5768 Data
.TargetPoint
.X
- pmin
.X
- MapOffset
.X
+ 32;
5769 Data
.TargetPoint
.Y
:=
5770 Data
.TargetPoint
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5772 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5774 Data
.tX
:= Data
.tX
- pmin
.X
- MapOffset
.X
+ 32;
5775 Data
.tY
:= Data
.tY
- pmin
.Y
- MapOffset
.Y
+ 32;
5777 TRIGGER_SPAWNMONSTER
:
5780 Data
.MonPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5782 Data
.MonPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5787 Data
.ItemPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5789 Data
.ItemPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5794 Data
.ShotPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5796 Data
.ShotPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5801 ID
:= AddTrigger(Trigger
);
5802 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5803 SelectObject(OBJECT_TRIGGER
, ID
, True);
5808 // Переставляем ссылки триггеров:
5809 for a
:= 0 to High(CopyBuffer
) do
5810 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5812 case CopyBuffer
[a
].Trigger
.TriggerType
of
5813 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5814 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5815 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5816 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5817 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5818 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5820 TRIGGER_PRESS
, TRIGGER_ON
,
5821 TRIGGER_OFF
, TRIGGER_ONOFF
:
5822 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5823 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5824 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5827 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5828 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5829 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5832 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5833 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5834 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5843 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5846 DeleteSelectedObjects();
5849 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5851 Key
, FileName
: String;
5854 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5856 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5858 with ChooseTypeForm
, vleObjectProperty
do
5859 begin // Выбор типа панели:
5860 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5861 lbTypeSelect
.Items
.Clear();
5863 for b
:= 0 to High(PANELNAMES
) do
5865 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5866 if Values
[Key
] = PANELNAMES
[b
] then
5867 lbTypeSelect
.ItemIndex
:= b
;
5870 if ShowModal() = mrOK
then
5872 b
:= lbTypeSelect
.ItemIndex
;
5873 Values
[Key
] := PANELNAMES
[b
];
5874 vleObjectPropertyApply(Sender
);
5878 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5879 SelectFlag
:= SELECTFLAG_TELEPORT
5880 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5881 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5882 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5883 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5884 SelectFlag
:= SELECTFLAG_DOOR
5885 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5887 DrawPressRect
:= False;
5888 SelectFlag
:= SELECTFLAG_TEXTURE
;
5890 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5891 SelectFlag
:= SELECTFLAG_SHOTPANEL
5892 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5893 SelectFlag
:= SELECTFLAG_LIFT
5894 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5895 SelectFlag
:= SELECTFLAG_MONSTER
5896 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5898 SelectFlag
:= SELECTFLAG_NONE
;
5899 DrawPressRect
:= True;
5901 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5902 begin // Выбор следующей карты:
5903 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5904 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
5905 SelectMapForm
.GetMaps(FileName
);
5907 if SelectMapForm
.ShowModal() = mrOK
then
5909 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5910 vleObjectPropertyApply(Sender
);
5913 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5914 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5915 begin // Выбор файла звука/музыки:
5916 AddSoundForm
.OKFunction
:= nil;
5917 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5918 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
5920 if (AddSoundForm
.ShowModal() = mrOk
) then
5922 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
5923 vleObjectPropertyApply(Sender
);
5926 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5927 with ActivationTypeForm
, vleObjectProperty
do
5928 begin // Выбор типов активации:
5929 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5930 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5931 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5932 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5933 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5934 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5936 if ShowModal() = mrOK
then
5939 if cbPlayerCollide
.Checked
then
5940 b
:= ACTIVATE_PLAYERCOLLIDE
;
5941 if cbMonsterCollide
.Checked
then
5942 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5943 if cbPlayerPress
.Checked
then
5944 b
:= b
or ACTIVATE_PLAYERPRESS
;
5945 if cbMonsterPress
.Checked
then
5946 b
:= b
or ACTIVATE_MONSTERPRESS
;
5947 if cbShot
.Checked
then
5948 b
:= b
or ACTIVATE_SHOT
;
5949 if cbNoMonster
.Checked
then
5950 b
:= b
or ACTIVATE_NOMONSTER
;
5952 Values
[Key
] := ActivateToStr(b
);
5953 vleObjectPropertyApply(Sender
);
5956 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5957 with KeysForm
, vleObjectProperty
do
5958 begin // Выбор необходимых ключей:
5959 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5960 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5961 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5962 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5963 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5965 if ShowModal() = mrOK
then
5968 if cbRedKey
.Checked
then
5970 if cbGreenKey
.Checked
then
5971 b
:= b
or KEY_GREEN
;
5972 if cbBlueKey
.Checked
then
5974 if cbRedTeam
.Checked
then
5975 b
:= b
or KEY_REDTEAM
;
5976 if cbBlueTeam
.Checked
then
5977 b
:= b
or KEY_BLUETEAM
;
5979 Values
[Key
] := KeyToStr(b
);
5980 vleObjectPropertyApply(Sender
);
5983 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
5984 with ChooseTypeForm
, vleObjectProperty
do
5985 begin // Выбор типа эффекта:
5986 Caption
:= _lc
[I_CAP_FX_TYPE
];
5987 lbTypeSelect
.Items
.Clear();
5989 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
5990 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5992 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
5994 if ShowModal() = mrOK
then
5996 b
:= lbTypeSelect
.ItemIndex
;
5997 Values
[Key
] := EffectToStr(b
);
5998 vleObjectPropertyApply(Sender
);
6001 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
6002 with ChooseTypeForm
, vleObjectProperty
do
6003 begin // Выбор типа монстра:
6004 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
6005 lbTypeSelect
.Items
.Clear();
6007 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
6008 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
6010 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
6012 if ShowModal() = mrOK
then
6014 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
6015 Values
[Key
] := MonsterToStr(b
);
6016 vleObjectPropertyApply(Sender
);
6019 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
6020 with ChooseTypeForm
, vleObjectProperty
do
6021 begin // Выбор типа предмета:
6022 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
6023 lbTypeSelect
.Items
.Clear();
6025 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
6026 lbTypeSelect
.Items
.Add(ItemToStr(b
));
6027 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
6028 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
6029 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
6030 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
6031 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
6032 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
6034 b
:= StrToItem(Values
[Key
]);
6035 if b
>= ITEM_BOTTLE
then
6037 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
6039 if ShowModal() = mrOK
then
6041 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
6042 if b
>= ITEM_WEAPON_KASTET
then
6044 Values
[Key
] := ItemToStr(b
);
6045 vleObjectPropertyApply(Sender
);
6048 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
6049 with ChooseTypeForm
, vleObjectProperty
do
6050 begin // Выбор типа предмета:
6051 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
6052 lbTypeSelect
.Items
.Clear();
6054 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
6055 lbTypeSelect
.Items
.Add(ShotToStr(b
));
6057 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
6059 if ShowModal() = mrOK
then
6061 b
:= lbTypeSelect
.ItemIndex
;
6062 Values
[Key
] := ShotToStr(b
);
6063 vleObjectPropertyApply(Sender
);
6066 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
6067 with ChooseTypeForm
, vleObjectProperty
do
6068 begin // Выбор типа эффекта:
6069 Caption
:= _lc
[I_CAP_FX_TYPE
];
6070 lbTypeSelect
.Items
.Clear();
6072 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
6073 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
6074 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6075 lbTypeSelect
.ItemIndex
:= 1
6077 lbTypeSelect
.ItemIndex
:= 0;
6079 if ShowModal() = mrOK
then
6081 b
:= lbTypeSelect
.ItemIndex
;
6083 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
6085 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
6086 vleObjectPropertyApply(Sender
);
6089 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
6090 with ChooseTypeForm
, vleObjectProperty
do
6091 begin // Выбор подтипа эффекта:
6092 Caption
:= _lc
[I_CAP_FX_TYPE
];
6093 lbTypeSelect
.Items
.Clear();
6095 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6097 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
6098 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6100 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
6103 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
6104 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
6105 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
6106 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
6107 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
6108 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
6109 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
6110 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
6111 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
6112 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
6113 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
6114 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
6115 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
6116 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
6117 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
6118 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
6119 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
6122 if ShowModal() = mrOK
then
6124 b
:= lbTypeSelect
.ItemIndex
;
6126 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6127 Values
[Key
] := EffectToStr(b
+ 1)
6129 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
6130 if b
= TRIGGER_EFFECT_LLIQUID
then
6131 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
6132 if b
= TRIGGER_EFFECT_DLIQUID
then
6133 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
6134 if b
= TRIGGER_EFFECT_BLOOD
then
6135 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
6136 if b
= TRIGGER_EFFECT_SPARK
then
6137 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
6138 if b
= TRIGGER_EFFECT_BUBBLE
then
6139 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
6142 vleObjectPropertyApply(Sender
);
6145 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
6146 with vleObjectProperty
do
6147 begin // Выбор цвета эффекта:
6148 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
6149 if ColorDialog
.Execute
then
6151 Values
[Key
] := IntToStr(ColorDialog
.Color
);
6152 vleObjectPropertyApply(Sender
);
6155 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
6156 begin // Смена текстуры:
6157 vleObjectProperty
.Values
[Key
] := SelectedTexture();
6158 vleObjectPropertyApply(Sender
);
6162 procedure TMainForm
.vleObjectPropertyApply(Sender
: TObject
);
6164 // hack to prevent empty ID in list
6165 RenderPanel
.SetFocus();
6166 bApplyProperty
.Click();
6167 vleObjectProperty
.SetFocus();
6170 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
6172 FileName
, Section
, Res
: String;
6174 if OpenedMap
= '' then
6176 aSaveMapAsExecute(nil);
6180 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
6182 SaveMap(FileName
+':\'+Res
);
6185 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
6187 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
6189 if OpenDialog
.Execute() then
6191 OpenMapFile(OpenDialog
.FileName
);
6192 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
6196 procedure TMainForm
.OpenMapFile(FileName
: String);
6198 if (Pos('.ini', LowerCase(ExtractFileName(FileName
))) > 0) then
6202 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
6203 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
6204 pLoadProgress
.Show();
6209 LoadMapOld(FileName
);
6211 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(FileName
)]);
6213 pLoadProgress
.Hide();
6214 MainForm
.FormResize(Self
);
6216 else // Карты из WAD:
6218 OpenMap(FileName
, '');
6222 procedure TMainForm
.FormActivate(Sender
: TObject
);
6227 MainForm
.ActiveControl
:= RenderPanel
;
6230 if gLanguage
= '' then
6232 lang
:= SelectLanguageForm
.ShowModal();
6234 1: gLanguage
:= LANGUAGE_ENGLISH
;
6235 else gLanguage
:= LANGUAGE_RUSSIAN
;
6238 config
:= TConfig
.CreateFile(CfgFileName
);
6239 config
.WriteStr('Editor', 'Language', gLanguage
);
6240 config
.SaveFile(CfgFileName
);
6244 //e_WriteLog('Read language file', MSG_NOTIFY);
6245 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
6246 g_Language_Set(gLanguage
);
6249 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
6255 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6257 if not OpenDialog
.Execute() then
6260 FileName
:= OpenDialog
.FileName
;
6261 SelectMapForm
.Caption
:= _lc
[I_CAP_REMOVE
];
6262 SelectMapForm
.lbMapList
.Items
.Clear();
6263 SelectMapForm
.GetMaps(FileName
);
6265 if SelectMapForm
.ShowModal() <> mrOK
then
6268 MapName
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6269 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
6272 g_DeleteResource(FileName
, '', MapName
, res
);
6275 MessageBox(0, PChar('Cant delete map res=' + IntToStr(res
)), PChar('Map not deleted!'), MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
6281 PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
], [MapName
])),
6282 PChar(_lc
[I_MSG_MAP_DELETED
]),
6283 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
6286 // Удалили текущую карту - сохранять по старому ее нельзя:
6287 if OpenedMap
= (FileName
+ ':\' + MapName
) then
6291 MainForm
.Caption
:= FormCaption
6295 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
6296 var Key
: Word; Shift
: TShiftState
);
6298 if Key
= VK_RETURN
then
6299 vleObjectPropertyApply(Sender
);
6302 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
6307 if (ID
= 0) and (MoveType
= 0) then
6309 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
6311 if (ID
> DWORD(High(gPanels
))) then
6316 if MoveType
= 0 then // to Back
6318 if gTriggers
<> nil then
6319 for a
:= 0 to High(gTriggers
) do
6320 with gTriggers
[a
] do
6322 if TriggerType
= TRIGGER_NONE
then
6325 if TexturePanel
= _id
then
6328 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
6332 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6333 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6334 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6335 if Data
.PanelID
= _id
then
6338 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
6342 if Data
.ShotPanelID
= _id
then
6343 Data
.ShotPanelID
:= 0
6345 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
6346 Inc(Data
.ShotPanelID
);
6350 tmp
:= gPanels
[_id
];
6352 for a
:= _id
downto 1 do
6353 gPanels
[a
] := gPanels
[a
-1];
6361 if gTriggers
<> nil then
6362 for a
:= 0 to High(gTriggers
) do
6363 with gTriggers
[a
] do
6365 if TriggerType
= TRIGGER_NONE
then
6368 if TexturePanel
= _id
then
6369 TexturePanel
:= High(gPanels
)
6371 if TexturePanel
> _id
then
6375 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6376 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6377 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6378 if Data
.PanelID
= _id
then
6379 Data
.PanelID
:= High(gPanels
)
6381 if Data
.PanelID
> _id
then
6385 if Data
.ShotPanelID
= _id
then
6386 Data
.ShotPanelID
:= High(gPanels
)
6388 if Data
.ShotPanelID
> _id
then
6389 Dec(Data
.ShotPanelID
);
6393 tmp
:= gPanels
[_id
];
6395 for a
:= _id
to High(gPanels
)-1 do
6396 gPanels
[a
] := gPanels
[a
+1];
6398 gPanels
[High(gPanels
)] := tmp
;
6400 ID
:= High(gPanels
);
6404 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6408 if SelectedObjects
= nil then
6411 for a
:= 0 to High(SelectedObjects
) do
6412 with SelectedObjects
[a
] do
6413 if Live
and (ObjectType
= OBJECT_PANEL
) then
6415 SelectedObjects
[0] := SelectedObjects
[a
];
6416 SetLength(SelectedObjects
, 1);
6423 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6427 if SelectedObjects
= nil then
6430 for a
:= 0 to High(SelectedObjects
) do
6431 with SelectedObjects
[a
] do
6432 if Live
and (ObjectType
= OBJECT_PANEL
) then
6434 SelectedObjects
[0] := SelectedObjects
[a
];
6435 SetLength(SelectedObjects
, 1);
6442 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6446 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6448 if not SaveDialog
.Execute() then
6451 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6453 if SaveMapForm
.ShowModal() <> mrOK
then
6456 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6457 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6458 OpenedWAD
:= SaveDialog
.FileName
;
6460 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6461 // Такая карта уже недавно открывалась:
6463 RecentFiles
.Delete(idx
);
6464 RecentFiles
.Insert(0, OpenedMap
);
6469 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6470 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6471 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6474 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6478 RemoveSelectFromObjects();
6480 case pcObjects
.ActivePageIndex
+1 of
6482 if gPanels
<> nil then
6483 for a
:= 0 to High(gPanels
) do
6484 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6485 SelectObject(OBJECT_PANEL
, a
, True);
6487 if gItems
<> nil then
6488 for a
:= 0 to High(gItems
) do
6489 if gItems
[a
].ItemType
<> ITEM_NONE
then
6490 SelectObject(OBJECT_ITEM
, a
, True);
6492 if gMonsters
<> nil then
6493 for a
:= 0 to High(gMonsters
) do
6494 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6495 SelectObject(OBJECT_MONSTER
, a
, True);
6497 if gAreas
<> nil then
6498 for a
:= 0 to High(gAreas
) do
6499 if gAreas
[a
].AreaType
<> AREA_NONE
then
6500 SelectObject(OBJECT_AREA
, a
, True);
6502 if gTriggers
<> nil then
6503 for a
:= 0 to High(gTriggers
) do
6504 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6505 SelectObject(OBJECT_TRIGGER
, a
, True);
6508 RecountSelectedObjects();
6511 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6513 DotEnable
:= not DotEnable
;
6514 (Sender
as TToolButton
).Down
:= DotEnable
;
6517 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6519 // FIXME: this is a shitty hack
6520 if not gDataLoaded
then
6522 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6524 e_WriteLog('Loading data', MSG_NOTIFY
);
6525 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6526 e_WriteLog('Loading more data', MSG_NOTIFY
);
6528 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6529 gDataLoaded
:= True;
6530 MainForm
.FormResize(nil);
6535 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6537 if PreviewMode
= 2 then
6540 if PreviewMode
= 0 then
6542 Splitter2
.Visible
:= False;
6543 Splitter1
.Visible
:= False;
6544 StatusBar
.Visible
:= False;
6545 PanelObjs
.Visible
:= False;
6546 PanelProps
.Visible
:= False;
6547 MainToolBar
.Visible
:= False;
6548 sbHorizontal
.Visible
:= False;
6549 sbVertical
.Visible
:= False;
6553 StatusBar
.Visible
:= True;
6554 PanelObjs
.Visible
:= True;
6555 PanelProps
.Visible
:= True;
6556 Splitter2
.Visible
:= True;
6557 Splitter1
.Visible
:= True;
6558 MainToolBar
.Visible
:= True;
6559 sbHorizontal
.Visible
:= True;
6560 sbVertical
.Visible
:= True;
6563 PreviewMode
:= PreviewMode
xor 1;
6564 (Sender
as TMenuItem
).Checked
:= PreviewMode
> 0;
6569 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6571 SwitchLayer(LAYER_BACK
);
6574 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6576 SwitchLayer(LAYER_WALLS
);
6579 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6581 SwitchLayer(LAYER_FOREGROUND
);
6584 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6586 SwitchLayer(LAYER_STEPS
);
6589 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6591 SwitchLayer(LAYER_WATER
);
6594 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6596 SwitchLayer(LAYER_ITEMS
);
6599 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6601 SwitchLayer(LAYER_MONSTERS
);
6604 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6606 SwitchLayer(LAYER_AREAS
);
6609 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6611 SwitchLayer(LAYER_TRIGGERS
);
6614 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6620 for a
:= 0 to High(LayerEnabled
) do
6621 b
:= b
and LayerEnabled
[a
];
6625 ShowLayer(LAYER_BACK
, b
);
6626 ShowLayer(LAYER_WALLS
, b
);
6627 ShowLayer(LAYER_FOREGROUND
, b
);
6628 ShowLayer(LAYER_STEPS
, b
);
6629 ShowLayer(LAYER_WATER
, b
);
6630 ShowLayer(LAYER_ITEMS
, b
);
6631 ShowLayer(LAYER_MONSTERS
, b
);
6632 ShowLayer(LAYER_AREAS
, b
);
6633 ShowLayer(LAYER_TRIGGERS
, b
);
6636 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6641 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6643 if DotStep
= DotStepOne
then
6644 DotStep
:= DotStepTwo
6646 DotStep
:= DotStepOne
;
6648 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6649 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6652 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6657 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6659 SnapToGrid
:= not SnapToGrid
;
6661 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6662 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6664 miSnapToGrid
.Checked
:= SnapToGrid
;
6667 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6669 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6670 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6672 pcObjects
.ActivePageIndex
:= 0;
6675 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6677 SaveMiniMapForm
.ShowModal();
6680 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6682 lbTextureList
.ItemIndex
:= -1;
6683 lTextureWidth
.Caption
:= '';
6684 lTextureHeight
.Caption
:= '';
6687 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6689 PackMapForm
.ShowModal();
6692 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6694 MapTestForm
.ShowModal();
6697 type SSArray
= array of String;
6699 function ParseString (Str
: AnsiString
): SSArray
;
6700 function GetStr (var Str
: AnsiString
): AnsiString
;
6704 if Str
[1] = '"' then
6705 for b
:= 1 to Length(Str
) do
6706 if (b
= Length(Str
)) or (Str
[b
+ 1] = '"') then
6708 Result
:= Copy(Str
, 2, b
- 1);
6709 Delete(Str
, 1, b
+ 1);
6713 for a
:= 1 to Length(Str
) do
6714 if (a
= Length(Str
)) or (Str
[a
+ 1] = ' ') then
6716 Result
:= Copy(Str
, 1, a
);
6717 Delete(Str
, 1, a
+ 1);
6727 SetLength(Result
, Length(Result
)+1);
6728 Result
[High(Result
)] := GetStr(Str
);
6732 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6734 newWAD
, oldWAD
, tempMap
, ext
: String;
6741 // Сохраняем временную карту:
6744 newWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps/temp%.4d', [time
]);
6746 until not FileExists(newWAD
);
6747 if OpenedMap
<> '' then
6749 oldWad
:= g_ExtractWadName(OpenedMap
);
6750 newWad
:= newWad
+ ExtractFileExt(oldWad
);
6751 if CopyFile(oldWad
, newWad
) = false then
6752 e_WriteLog('MapTest: unable to copy [' + oldWad
+ '] to [' + newWad
+ ']', MSG_WARNING
)
6756 newWad
:= newWad
+ '.wad'
6758 tempMap
:= newWAD
+ ':\' + TEST_MAP_NAME
;
6760 tempMap
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', tempMap
);
6764 if TestOptionsTwoPlayers
then
6766 if TestOptionsTeamDamage
then
6768 if TestOptionsAllowExit
then
6770 if TestOptionsWeaponStay
then
6772 if TestOptionsMonstersDM
then
6776 proc
:= TProcessUTF8
.Create(nil);
6777 proc
.Executable
:= TestD2dExe
;
6778 proc
.Parameters
.Add('-map');
6779 proc
.Parameters
.Add(tempMap
);
6780 proc
.Parameters
.Add('-gm');
6781 proc
.Parameters
.Add(TestGameMode
);
6782 proc
.Parameters
.Add('-limt');
6783 proc
.Parameters
.Add(TestLimTime
);
6784 proc
.Parameters
.Add('-lims');
6785 proc
.Parameters
.Add(TestLimScore
);
6786 proc
.Parameters
.Add('-opt');
6787 proc
.Parameters
.Add(IntToStr(opt
));
6788 proc
.Parameters
.Add('--debug');
6790 proc
.Parameters
.Add('--close');
6792 args
:= ParseString(TestD2DArgs
);
6793 for i
:= 0 to High(args
) do
6794 proc
.Parameters
.Add(args
[i
]);
6804 Application
.Minimize();
6807 if (not res
) or (proc
.ExitCode
< 0) then
6809 MessageBox(0, 'FIXME',
6810 PChar(_lc
[I_MSG_EXEC_ERROR
]),
6811 MB_OK
or MB_ICONERROR
);
6815 SysUtils
.DeleteFile(newWAD
);
6816 Application
.Restore();
6819 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6820 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6822 MapOffset
.Y
:= -sbVertical
.Position
;
6825 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6826 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6828 MapOffset
.X
:= -sbHorizontal
.Position
;
6831 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6833 if OpenedWAD
<> '' then
6835 OpenMap(OpenedWAD
, '');
6839 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6843 RemoveSelectFromObjects();
6845 if gPanels
<> nil then
6846 for a
:= 0 to High(gPanels
) do
6847 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6848 SelectObject(OBJECT_PANEL
, a
, True);
6850 if gItems
<> nil then
6851 for a
:= 0 to High(gItems
) do
6852 if gItems
[a
].ItemType
<> ITEM_NONE
then
6853 SelectObject(OBJECT_ITEM
, a
, True);
6855 if gMonsters
<> nil then
6856 for a
:= 0 to High(gMonsters
) do
6857 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6858 SelectObject(OBJECT_MONSTER
, a
, True);
6860 if gAreas
<> nil then
6861 for a
:= 0 to High(gAreas
) do
6862 if gAreas
[a
].AreaType
<> AREA_NONE
then
6863 SelectObject(OBJECT_AREA
, a
, True);
6865 if gTriggers
<> nil then
6866 for a
:= 0 to High(gTriggers
) do
6867 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6868 SelectObject(OBJECT_TRIGGER
, a
, True);
6870 RecountSelectedObjects();
6873 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6874 var NewSize
: Integer; var Accept
: Boolean);
6876 Accept
:= (NewSize
> 140);
6879 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6880 var NewSize
: Integer; var Accept
: Boolean);
6882 Accept
:= (NewSize
> 110);
6885 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6887 EditingProperties
:= True;
6890 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6892 EditingProperties
:= False;
6895 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
6897 // Объекты передвигались:
6898 if MainForm
.ActiveControl
= RenderPanel
then
6900 if (Key
= VK_NUMPAD4
) or
6901 (Key
= VK_NUMPAD6
) or
6902 (Key
= VK_NUMPAD8
) or
6903 (Key
= VK_NUMPAD5
) or
6904 (Key
= Ord('V')) then
6907 // Быстрое превью карты:
6908 if Key
= Ord('E') then
6910 if PreviewMode
= 2 then
6913 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);