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
;
275 LAYER_FOREGROUND
= 2;
283 TEST_MAP_NAME
= '$$$_TEST_$$$';
284 LANGUAGE_FILE_NAME
= '_Editor.txt';
295 DotStepOne
, DotStepTwo
: Byte;
297 DrawTexturePanel
: Boolean;
298 DrawPanelSize
: Boolean;
300 PreviewColor
: TColor
;
301 UseCheckerboard
: Boolean;
303 RecentCount
: Integer;
304 RecentFiles
: TStringList
;
305 slInvalidTextures
: TStringList
;
307 TestGameMode
: String;
309 TestLimScore
: String;
310 TestOptionsTwoPlayers
: Boolean;
311 TestOptionsTeamDamage
: Boolean;
312 TestOptionsAllowExit
: Boolean;
313 TestOptionsWeaponStay
: Boolean;
314 TestOptionsMonstersDM
: Boolean;
316 TestMapOnce
: Boolean;
318 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
319 (True, True, True, True, True, True, True, True, True);
320 PreviewMode
: Byte = 0;
326 procedure OpenMap(FileName
: String; mapN
: String);
327 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
328 procedure RemoveSelectFromObjects();
329 procedure ChangeShownProperty(Name
: String; NewValue
: String);
334 f_options
, e_graphics
, e_log
, GL
, Math
,
335 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
336 f_mapcheck
, f_addresource_texture
, g_textures
,
337 f_activationtype
, f_keys
,
338 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, WADSTRUCT
, MAPDEF
,
339 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
340 f_addresource_sound
, f_maptest
, f_choosetype
,
341 g_language
, f_selectlang
, ClipBrd
;
344 UNDO_DELETE_PANEL
= 1;
345 UNDO_DELETE_ITEM
= 2;
346 UNDO_DELETE_AREA
= 3;
347 UNDO_DELETE_MONSTER
= 4;
348 UNDO_DELETE_TRIGGER
= 5;
352 UNDO_ADD_MONSTER
= 9;
353 UNDO_ADD_TRIGGER
= 10;
354 UNDO_MOVE_PANEL
= 11;
357 UNDO_MOVE_MONSTER
= 14;
358 UNDO_MOVE_TRIGGER
= 15;
359 UNDO_RESIZE_PANEL
= 16;
360 UNDO_RESIZE_TRIGGER
= 17;
362 MOUSEACTION_NONE
= 0;
363 MOUSEACTION_DRAWPANEL
= 1;
364 MOUSEACTION_DRAWTRIGGER
= 2;
365 MOUSEACTION_MOVEOBJ
= 3;
366 MOUSEACTION_RESIZE
= 4;
367 MOUSEACTION_MOVEMAP
= 5;
368 MOUSEACTION_DRAWPRESS
= 6;
369 MOUSEACTION_NOACTION
= 7;
372 RESIZETYPE_VERTICAL
= 1;
373 RESIZETYPE_HORIZONTAL
= 2;
382 SELECTFLAG_TELEPORT
= 1;
384 SELECTFLAG_TEXTURE
= 3;
386 SELECTFLAG_MONSTER
= 5;
387 SELECTFLAG_SPAWNPOINT
= 6;
388 SELECTFLAG_SHOTPANEL
= 7;
389 SELECTFLAG_SELECTED
= 8;
391 RECENT_FILES_MENU_START
= 12;
393 CLIPBOARD_SIG
= 'DF:ED';
399 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
400 UNDO_DELETE_ITEM
: (Item
: TItem
);
401 UNDO_DELETE_AREA
: (Area
: TArea
);
402 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
403 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
408 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
413 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
415 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
422 OBJECT_PANEL
: (Panel
: ^TPanel
);
423 OBJECT_ITEM
: (Item
: TItem
);
424 OBJECT_AREA
: (Area
: TArea
);
425 OBJECT_MONSTER
: (Monster
: TMonster
);
426 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
429 TCopyRecArray
= Array of TCopyRec
;
433 gDataLoaded
: Boolean = False;
434 ShowMap
: Boolean = False;
435 DrawRect
: PRect
= nil;
436 SnapToGrid
: Boolean = True;
438 MousePos
: Types
.TPoint
;
439 LastMovePoint
: Types
.TPoint
;
442 MouseLDownPos
: Types
.TPoint
;
443 MouseRDownPos
: Types
.TPoint
;
446 SelectFlag
: Byte = SELECTFLAG_NONE
;
447 MouseAction
: Byte = MOUSEACTION_NONE
;
448 ResizeType
: Byte = RESIZETYPE_NONE
;
449 ResizeDirection
: Byte = RESIZEDIR_NONE
;
451 DrawPressRect
: Boolean = False;
452 EditingProperties
: Boolean = False;
454 UndoBuffer
: Array of Array of TUndoRec
= nil;
459 //----------------------------------------
460 //Далее идут вспомогательные процедуры
461 //----------------------------------------
463 function NameToBool(Name
: String): Boolean;
465 if Name
= BoolNames
[True] then
471 function NameToDir(Name
: String): TDirection
;
473 if Name
= DirNames
[D_LEFT
] then
479 function NameToDirAdv(Name
: String): Byte;
481 if Name
= DirNamesAdv
[1] then
484 if Name
= DirNamesAdv
[2] then
487 if Name
= DirNamesAdv
[3] then
493 function ActivateToStr(ActivateType
: Byte): String;
497 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
498 Result
:= Result
+ '+PC';
499 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
500 Result
:= Result
+ '+MC';
501 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
502 Result
:= Result
+ '+PP';
503 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
504 Result
:= Result
+ '+MP';
505 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
506 Result
:= Result
+ '+SH';
507 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
508 Result
:= Result
+ '+NM';
510 if (Result
<> '') and (Result
[1] = '+') then
511 Delete(Result
, 1, 1);
514 function StrToActivate(Str
: String): Byte;
518 if Pos('PC', Str
) > 0 then
519 Result
:= ACTIVATE_PLAYERCOLLIDE
;
520 if Pos('MC', Str
) > 0 then
521 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
522 if Pos('PP', Str
) > 0 then
523 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
524 if Pos('MP', Str
) > 0 then
525 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
526 if Pos('SH', Str
) > 0 then
527 Result
:= Result
or ACTIVATE_SHOT
;
528 if Pos('NM', Str
) > 0 then
529 Result
:= Result
or ACTIVATE_NOMONSTER
;
532 function KeyToStr(Key
: Byte): String;
536 if ByteBool(KEY_RED
and Key
) then
537 Result
:= Result
+ '+RK';
538 if ByteBool(KEY_GREEN
and Key
) then
539 Result
:= Result
+ '+GK';
540 if ByteBool(KEY_BLUE
and Key
) then
541 Result
:= Result
+ '+BK';
542 if ByteBool(KEY_REDTEAM
and Key
) then
543 Result
:= Result
+ '+RT';
544 if ByteBool(KEY_BLUETEAM
and Key
) then
545 Result
:= Result
+ '+BT';
547 if (Result
<> '') and (Result
[1] = '+') then
548 Delete(Result
, 1, 1);
551 function StrToKey(Str
: String): Byte;
555 if Pos('RK', Str
) > 0 then
557 if Pos('GK', Str
) > 0 then
558 Result
:= Result
or KEY_GREEN
;
559 if Pos('BK', Str
) > 0 then
560 Result
:= Result
or KEY_BLUE
;
561 if Pos('RT', Str
) > 0 then
562 Result
:= Result
or KEY_REDTEAM
;
563 if Pos('BT', Str
) > 0 then
564 Result
:= Result
or KEY_BLUETEAM
;
567 function EffectToStr(Effect
: Byte): String;
569 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
570 Result
:= EffectNames
[Effect
]
572 Result
:= EffectNames
[EFFECT_NONE
];
575 function StrToEffect(Str
: String): Byte;
579 Result
:= EFFECT_NONE
;
580 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
581 if EffectNames
[i
] = Str
then
588 function MonsterToStr(MonType
: Byte): String;
590 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
591 Result
:= MonsterNames
[MonType
]
593 Result
:= MonsterNames
[MONSTER_ZOMBY
];
596 function StrToMonster(Str
: String): Byte;
600 Result
:= MONSTER_ZOMBY
;
601 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
602 if MonsterNames
[i
] = Str
then
609 function ItemToStr(ItemType
: Byte): String;
611 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
612 Result
:= ItemNames
[ItemType
]
614 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
617 function StrToItem(Str
: String): Byte;
621 Result
:= ITEM_AMMO_BULLETS
;
622 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
623 if ItemNames
[i
] = Str
then
630 function ShotToStr(ShotType
: Byte): String;
632 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
633 Result
:= ShotNames
[ShotType
]
635 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
638 function StrToShot(Str
: String): Byte;
642 Result
:= TRIGGER_SHOT_PISTOL
;
643 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
644 if ShotNames
[i
] = Str
then
651 function SelectedObjectCount(): Word;
657 if SelectedObjects
= nil then
660 for a
:= 0 to High(SelectedObjects
) do
661 if SelectedObjects
[a
].Live
then
662 Result
:= Result
+ 1;
665 function GetFirstSelected(): Integer;
671 if SelectedObjects
= nil then
674 for a
:= 0 to High(SelectedObjects
) do
675 if SelectedObjects
[a
].Live
then
682 function Normalize16(x
: Integer): Integer;
684 Result
:= (x
div 16) * 16;
687 procedure MoveMap(X
, Y
: Integer);
689 rx
, ry
, ScaleSz
: Integer;
691 with MainForm
.RenderPanel
do
693 ScaleSz
:= 16 div Scale
;
694 // Размер видимой части карты:
695 rx
:= min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
696 ry
:= min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
697 // Место клика на мини-карте:
698 MapOffset
.X
:= X
- (Width
-max(gMapInfo
.Width
div ScaleSz
, 1)-1);
699 MapOffset
.Y
:= Y
- 1;
700 // Это же место на "большой" карте:
701 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
702 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
703 // Левый верхний угол новой видимой части карты:
704 MapOffset
.X
:= MapOffset
.X
- rx
;
705 MapOffset
.Y
:= MapOffset
.Y
- ry
;
707 if MapOffset
.X
< 0 then
709 if MapOffset
.Y
< 0 then
711 if MapOffset
.X
> MainForm
.sbHorizontal
.Max
then
712 MapOffset
.X
:= MainForm
.sbHorizontal
.Max
;
713 if MapOffset
.Y
> MainForm
.sbVertical
.Max
then
714 MapOffset
.Y
:= MainForm
.sbVertical
.Max
;
716 MapOffset
.X
:= Normalize16(MapOffset
.X
);
717 MapOffset
.Y
:= Normalize16(MapOffset
.Y
);
720 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
721 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
723 MapOffset
.X
:= -MapOffset
.X
;
724 MapOffset
.Y
:= -MapOffset
.Y
;
729 function IsTexturedPanel(PanelType
: Word): Boolean;
731 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
732 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
733 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
736 procedure FillProperty();
741 MainForm
.vleObjectProperty
.Strings
.Clear();
743 // Отображаем свойства если выделен только один объект:
744 if SelectedObjectCount() <> 1 then
747 _id
:= GetFirstSelected();
748 if not SelectedObjects
[_id
].Live
then
751 with MainForm
.vleObjectProperty
do
752 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
754 EditStyle
:= esSimple
;
758 case SelectedObjects
[0].ObjectType
of
761 with MainForm
.vleObjectProperty
,
762 gPanels
[SelectedObjects
[_id
].ID
] do
764 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
766 EditStyle
:= esSimple
;
770 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
772 EditStyle
:= esSimple
;
776 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
778 EditStyle
:= esSimple
;
782 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
784 EditStyle
:= esSimple
;
788 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
790 EditStyle
:= esEllipsis
;
794 if IsTexturedPanel(PanelType
) then
795 begin // Может быть текстура
796 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
798 EditStyle
:= esEllipsis
;
802 if TextureName
<> '' then
803 begin // Есть текстура
804 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
806 EditStyle
:= esSimple
;
810 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
812 EditStyle
:= esPickList
;
822 with MainForm
.vleObjectProperty
,
823 gItems
[SelectedObjects
[_id
].ID
] do
825 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
827 EditStyle
:= esSimple
;
831 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
833 EditStyle
:= esSimple
;
837 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
839 EditStyle
:= esPickList
;
843 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
845 EditStyle
:= esPickList
;
853 with MainForm
.vleObjectProperty
,
854 gMonsters
[SelectedObjects
[_id
].ID
] do
856 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
858 EditStyle
:= esSimple
;
862 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
864 EditStyle
:= esSimple
;
868 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
870 EditStyle
:= esPickList
;
878 with MainForm
.vleObjectProperty
,
879 gAreas
[SelectedObjects
[_id
].ID
] do
881 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
883 EditStyle
:= esSimple
;
887 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
889 EditStyle
:= esSimple
;
893 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
895 EditStyle
:= esPickList
;
903 with MainForm
.vleObjectProperty
,
904 gTriggers
[SelectedObjects
[_id
].ID
] do
906 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
908 EditStyle
:= esSimple
;
912 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
914 EditStyle
:= esSimple
;
918 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
920 EditStyle
:= esSimple
;
924 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
926 EditStyle
:= esSimple
;
930 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
932 EditStyle
:= esSimple
;
936 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
938 EditStyle
:= esPickList
;
942 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
944 EditStyle
:= esEllipsis
;
948 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
950 EditStyle
:= esEllipsis
;
954 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
956 EditStyle
:= esEllipsis
;
963 str
:= win2utf(Data
.MapName
);
964 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], str
, True)] do
966 EditStyle
:= esEllipsis
;
973 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
975 EditStyle
:= esEllipsis
;
979 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
981 EditStyle
:= esPickList
;
985 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
987 EditStyle
:= esPickList
;
991 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
993 EditStyle
:= esPickList
;
998 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
999 TRIGGER_DOOR
, TRIGGER_DOOR5
:
1001 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
1003 EditStyle
:= esEllipsis
;
1007 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1009 EditStyle
:= esPickList
;
1013 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1015 EditStyle
:= esPickList
;
1020 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1022 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1024 EditStyle
:= esEllipsis
;
1028 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1030 EditStyle
:= esPickList
;
1034 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1036 EditStyle
:= esPickList
;
1041 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1044 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1045 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1047 EditStyle
:= esEllipsis
;
1051 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1053 EditStyle
:= esSimple
;
1057 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1059 EditStyle
:= esSimple
;
1063 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1065 EditStyle
:= esEllipsis
;
1069 if TriggerType
= TRIGGER_PRESS
then
1070 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1072 EditStyle
:= esPickList
;
1080 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1082 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1084 EditStyle
:= esEllipsis
;
1088 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1090 EditStyle
:= esPickList
;
1094 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1096 EditStyle
:= esPickList
;
1103 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1105 EditStyle
:= esPickList
;
1109 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1111 EditStyle
:= esPickList
;
1118 str
:= win2utf(Data
.SoundName
);
1119 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], str
, True)] do
1121 EditStyle
:= esEllipsis
;
1125 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1127 EditStyle
:= esSimple
;
1131 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1133 EditStyle
:= esSimple
;
1137 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1139 EditStyle
:= esSimple
;
1143 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1145 EditStyle
:= esPickList
;
1149 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1151 EditStyle
:= esPickList
;
1156 TRIGGER_SPAWNMONSTER
:
1158 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1160 EditStyle
:= esEllipsis
;
1164 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1165 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1167 EditStyle
:= esEllipsis
;
1171 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1173 EditStyle
:= esPickList
;
1177 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1179 EditStyle
:= esSimple
;
1183 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1185 EditStyle
:= esPickList
;
1189 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1191 EditStyle
:= esSimple
;
1195 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1197 EditStyle
:= esEllipsis
;
1201 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1203 EditStyle
:= esSimple
;
1207 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1209 EditStyle
:= esSimple
;
1213 case Data
.MonBehav
of
1214 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1215 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1216 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1217 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1218 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1219 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1221 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1223 EditStyle
:= esPickList
;
1230 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1232 EditStyle
:= esEllipsis
;
1236 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1237 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1239 EditStyle
:= esEllipsis
;
1243 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1245 EditStyle
:= esPickList
;
1249 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1251 EditStyle
:= esPickList
;
1255 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1257 EditStyle
:= esSimple
;
1261 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1263 EditStyle
:= esEllipsis
;
1267 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1269 EditStyle
:= esSimple
;
1273 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1275 EditStyle
:= esSimple
;
1282 str
:= win2utf(Data
.MusicName
);
1283 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], str
, True)] do
1285 EditStyle
:= esEllipsis
;
1289 if Data
.MusicAction
= 1 then
1290 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1292 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1294 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1296 EditStyle
:= esPickList
;
1303 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1305 EditStyle
:= esSimple
;
1308 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1310 EditStyle
:= esSimple
;
1313 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1315 EditStyle
:= esPickList
;
1322 case Data
.ScoreAction
of
1323 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1324 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1325 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1326 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1328 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1330 EditStyle
:= esPickList
;
1333 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1335 EditStyle
:= esSimple
;
1338 case Data
.ScoreTeam
of
1339 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1340 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1341 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1342 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1344 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1346 EditStyle
:= esPickList
;
1349 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1351 EditStyle
:= esPickList
;
1354 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1356 EditStyle
:= esPickList
;
1363 case Data
.MessageKind
of
1364 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1365 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1367 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1369 EditStyle
:= esPickList
;
1372 case Data
.MessageSendTo
of
1373 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1374 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1375 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1376 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1377 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1378 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1380 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1382 EditStyle
:= esPickList
;
1385 str
:= win2utf(Data
.MessageText
);
1386 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], str
, True)] do
1388 EditStyle
:= esSimple
;
1391 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1393 EditStyle
:= esSimple
;
1400 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1402 EditStyle
:= esSimple
;
1405 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1407 EditStyle
:= esSimple
;
1414 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1416 EditStyle
:= esSimple
;
1419 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1421 EditStyle
:= esSimple
;
1424 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1426 EditStyle
:= esPickList
;
1429 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1431 EditStyle
:= esPickList
;
1438 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1440 EditStyle
:= esEllipsis
;
1444 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1446 EditStyle
:= esPickList
;
1450 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1452 EditStyle
:= esEllipsis
;
1456 case Data
.ShotTarget
of
1457 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1458 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1459 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1460 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1461 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1462 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1463 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1465 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1467 EditStyle
:= esPickList
;
1471 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1473 EditStyle
:= esSimple
;
1477 case Data
.ShotAim
of
1478 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1479 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1480 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1481 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1483 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)-1] do
1485 EditStyle
:= esPickList
;
1489 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1490 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1492 EditStyle
:= esEllipsis
;
1496 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1498 EditStyle
:= esSimple
;
1502 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1504 EditStyle
:= esSimple
;
1508 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1510 EditStyle
:= esSimple
;
1514 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1516 EditStyle
:= esSimple
;
1520 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1522 EditStyle
:= esSimple
;
1529 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1531 EditStyle
:= esSimple
;
1535 if Data
.FXType
= 0 then
1536 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1538 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1539 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1541 EditStyle
:= esEllipsis
;
1546 if Data
.FXType
= 0 then
1547 case Data
.FXSubType
of
1548 TRIGGER_EFFECT_SLIQUID
:
1549 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1550 TRIGGER_EFFECT_LLIQUID
:
1551 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1552 TRIGGER_EFFECT_DLIQUID
:
1553 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1554 TRIGGER_EFFECT_BLOOD
:
1555 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1556 TRIGGER_EFFECT_SPARK
:
1557 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1558 TRIGGER_EFFECT_BUBBLE
:
1559 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1561 if Data
.FXType
= 1 then
1563 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1564 Data
.FXSubType
:= EFFECT_TELEPORT
;
1565 str
:= EffectToStr(Data
.FXSubType
);
1567 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1569 EditStyle
:= esEllipsis
;
1573 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1575 EditStyle
:= esEllipsis
;
1579 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1581 EditStyle
:= esPickList
;
1585 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1587 EditStyle
:= esSimple
;
1591 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1593 EditStyle
:= esSimple
;
1597 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1599 EditStyle
:= esSimple
;
1603 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1605 EditStyle
:= esSimple
;
1609 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1611 EditStyle
:= esSimple
;
1615 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1617 EditStyle
:= esSimple
;
1621 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1623 EditStyle
:= esSimple
;
1627 end; //case TriggerType
1629 end; // OBJECT_TRIGGER:
1633 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1637 if SelectedObjectCount() <> 1 then
1639 if not SelectedObjects
[GetFirstSelected()].Live
then
1642 // Есть ли такой ключ:
1643 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1645 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1649 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1658 // Уже выделен - убираем:
1659 if SelectedObjects
<> nil then
1660 for a
:= 0 to High(SelectedObjects
) do
1661 with SelectedObjects
[a
] do
1662 if Live
and (ID
= fID
) and
1663 (ObjectType
= fObjectType
) then
1672 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1674 with SelectedObjects
[High(SelectedObjects
)] do
1676 ObjectType
:= fObjectType
;
1683 SetLength(SelectedObjects
, 1);
1685 with SelectedObjects
[0] do
1687 ObjectType
:= fObjectType
;
1693 MainForm
.miCopy
.Enabled
:= True;
1694 MainForm
.miCut
.Enabled
:= True;
1696 if fObjectType
= OBJECT_PANEL
then
1698 MainForm
.miToFore
.Enabled
:= True;
1699 MainForm
.miToBack
.Enabled
:= True;
1703 procedure RemoveSelectFromObjects();
1705 SelectedObjects
:= nil;
1706 DrawPressRect
:= False;
1707 MouseLDown
:= False;
1708 MouseRDown
:= False;
1709 MouseAction
:= MOUSEACTION_NONE
;
1710 SelectFlag
:= SELECTFLAG_NONE
;
1711 ResizeType
:= RESIZETYPE_NONE
;
1712 ResizeDirection
:= RESIZEDIR_NONE
;
1714 MainForm
.vleObjectProperty
.Strings
.Clear();
1716 MainForm
.miCopy
.Enabled
:= False;
1717 MainForm
.miCut
.Enabled
:= False;
1718 MainForm
.miToFore
.Enabled
:= False;
1719 MainForm
.miToBack
.Enabled
:= False;
1722 procedure DeleteSelectedObjects();
1727 if SelectedObjects
= nil then
1733 for a
:= 0 to High(SelectedObjects
) do
1734 with SelectedObjects
[a
] do
1739 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1740 i
:= High(UndoBuffer
);
1744 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1745 ii
:= High(UndoBuffer
[i
]);
1750 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1751 New(UndoBuffer
[i
, ii
].Panel
);
1752 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1756 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1757 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1761 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1762 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1766 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1767 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1771 RemoveObject(ID
, ObjectType
);
1774 RemoveSelectFromObjects();
1776 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1779 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1783 if (not Group
) or (Length(UndoBuffer
) = 0) then
1784 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1785 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1786 i
:= High(UndoBuffer
);
1787 ii
:= High(UndoBuffer
[i
]);
1791 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1793 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1795 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1797 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1799 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1802 UndoBuffer
[i
, ii
].AddID
:= ID
;
1804 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1807 procedure FullClear();
1809 RemoveSelectFromObjects();
1811 LoadSky(gMapInfo
.SkyName
);
1813 slInvalidTextures
.Clear();
1814 MapCheckForm
.lbErrorList
.Clear();
1815 MapCheckForm
.mErrorDescription
.Clear();
1817 MainForm
.miUndo
.Enabled
:= False;
1818 MainForm
.sbHorizontal
.Position
:= 0;
1819 MainForm
.sbVertical
.Position
:= 0;
1820 MainForm
.FormResize(nil);
1821 MainForm
.Caption
:= FormCaption
;
1826 procedure ErrorMessageBox(str
: String);
1828 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1829 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1832 function CheckProperty(): Boolean;
1838 _id
:= GetFirstSelected();
1840 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1841 with gPanels
[SelectedObjects
[_id
].ID
] do
1843 if TextureWidth
<> 0 then
1844 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1846 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1851 if TextureHeight
<> 0 then
1852 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1854 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1859 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1860 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1862 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1867 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1868 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1869 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1871 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1875 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1876 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1878 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1885 procedure SelectTexture(ID
: Integer);
1887 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1888 MainForm
.lbTextureListClick(nil);
1891 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1893 a
, FrameLen
: Integer;
1896 ResourceName
: String;
1897 FullResourceName
: String;
1898 SectionName
: String;
1900 Width
, Height
: Word;
1908 if aSection
= '..' then
1911 SectionName
:= aSection
;
1914 aWAD
:= _lc
[I_WAD_SPECIAL_MAP
];
1916 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1918 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1919 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1921 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1924 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1925 begin // Спец. текстуры
1927 ResourceName
:= aTex
;
1930 begin // Внешний WAD
1931 FileName
:= EditorDir
+'wads/'+aWAD
;
1932 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1937 // Есть ли уже такая текстура:
1938 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1939 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1942 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1947 // Название ресурса <= 64 символов:
1948 if Length(ResourceName
) > 64 then
1951 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1959 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1961 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1968 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1970 if IsAnim(FullResourceName
) then
1971 begin // Аним. текстура
1972 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
1974 if not g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
1976 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1978 else // Обычная текстура
1980 if not g_CreateTextureWAD(ResourceName
, FullResourceName
) then
1982 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1984 if (not ok
) and (slInvalidTextures
.IndexOf(ResourceName
) = -1) then
1986 slInvalidTextures
.Add(ResourceName
);
1989 if (a
> -1) and (not silent
) then
1996 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
1999 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
2000 Caption
:= FormCaption
2003 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
2005 if (sFile
<> '') and (sRes
<> '') then
2006 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
2008 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
2011 procedure OpenMap(FileName
: String; mapN
: String);
2016 SelectMapForm
.Caption
:= _lc
[I_CAP_OPEN
];
2017 SelectMapForm
.GetMaps(FileName
);
2019 if (FileName
= OpenedWAD
) and
2020 (OpenedMap
<> '') then
2022 MapName
:= OpenedMap
;
2023 while (Pos(':\', MapName
) > 0) do
2024 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
2026 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2027 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2030 if SelectMapForm
.lbMapList
.Count
> 0 then
2031 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2033 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2038 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2042 if (SelectMapForm
.ShowModal() = mrOK
) and
2043 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2044 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2049 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2055 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2056 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2057 pLoadProgress
.Show();
2059 OpenedMap
:= FileName
+':\'+MapName
;
2060 OpenedWAD
:= FileName
;
2062 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2063 // Такая карта уже недавно открывалась:
2065 RecentFiles
.Delete(idx
);
2066 RecentFiles
.Insert(0, OpenedMap
);
2067 RefreshRecentMenu();
2071 pLoadProgress
.Hide();
2074 lbTextureList
.Sorted
:= True;
2075 lbTextureList
.Sorted
:= False;
2077 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2081 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2086 if SelectedObjects
= nil then
2093 for a
:= 0 to High(SelectedObjects
) do
2094 if SelectedObjects
[a
].Live
then
2096 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2099 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2102 if (not okX
) or (not okY
) then
2108 for a
:= 0 to High(SelectedObjects
) do
2109 if SelectedObjects
[a
].Live
then
2112 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2115 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2117 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2119 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2120 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2121 begin // Двигаем зону Расширителя
2123 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2125 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2128 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2129 begin // Двигаем точку назначения Телепорта
2131 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2133 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2136 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2137 begin // Двигаем точку создания монстра
2139 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2141 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2144 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2145 begin // Двигаем точку создания предмета
2147 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2149 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2152 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2153 begin // Двигаем точку создания выстрела
2155 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2157 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2162 LastMovePoint
:= MousePos
;
2166 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2168 LayerEnabled
[Layer
] := show
;
2173 MainForm
.miLayer1
.Checked
:= show
;
2174 MainForm
.miLayerP1
.Checked
:= show
;
2178 MainForm
.miLayer2
.Checked
:= show
;
2179 MainForm
.miLayerP2
.Checked
:= show
;
2183 MainForm
.miLayer3
.Checked
:= show
;
2184 MainForm
.miLayerP3
.Checked
:= show
;
2188 MainForm
.miLayer4
.Checked
:= show
;
2189 MainForm
.miLayerP4
.Checked
:= show
;
2193 MainForm
.miLayer5
.Checked
:= show
;
2194 MainForm
.miLayerP5
.Checked
:= show
;
2198 MainForm
.miLayer6
.Checked
:= show
;
2199 MainForm
.miLayerP6
.Checked
:= show
;
2203 MainForm
.miLayer7
.Checked
:= show
;
2204 MainForm
.miLayerP7
.Checked
:= show
;
2208 MainForm
.miLayer8
.Checked
:= show
;
2209 MainForm
.miLayerP8
.Checked
:= show
;
2213 MainForm
.miLayer9
.Checked
:= show
;
2214 MainForm
.miLayerP9
.Checked
:= show
;
2218 RemoveSelectFromObjects();
2221 procedure SwitchLayer(Layer
: Byte);
2223 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2226 procedure SwitchMap();
2228 ShowMap
:= not ShowMap
;
2229 MainForm
.tbShowMap
.Down
:= ShowMap
;
2232 procedure ShowEdges();
2234 if drEdge
[3] < 255 then
2237 drEdge
[3] := gAlphaEdge
;
2240 function SelectedTexture(): String;
2242 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2243 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2248 function IsSpecialTextureSel(): Boolean;
2250 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2251 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2254 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2259 procedure AddInt(x
: Integer);
2261 Res
:= Res
+ IntToStr(x
) + ' ';
2267 if Length(CopyBuf
) = 0 then
2270 Res
:= CLIPBOARD_SIG
+ ' ';
2272 for i
:= 0 to High(CopyBuf
) do
2274 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2275 (CopyBuf
[i
].Panel
= nil) then
2279 AddInt(CopyBuf
[i
].ObjectType
);
2282 // Свойства объекта:
2283 case CopyBuf
[i
].ObjectType
of
2285 with CopyBuf
[i
].Panel
^ do
2292 Res
:= Res
+ '"' + TextureName
+ '" ';
2294 AddInt(IfThen(Blending
, 1, 0));
2298 with CopyBuf
[i
].Item
do
2303 AddInt(IfThen(OnlyDM
, 1, 0));
2304 AddInt(IfThen(Fall
, 1, 0));
2308 with CopyBuf
[i
].Monster
do
2310 AddInt(MonsterType
);
2313 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2317 with CopyBuf
[i
].Area
do
2322 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2326 with CopyBuf
[i
].Trigger
do
2328 AddInt(TriggerType
);
2333 AddInt(ActivateType
);
2335 AddInt(IfThen(Enabled
, 1, 0));
2336 AddInt(TexturePanel
);
2338 for j
:= 0 to 127 do
2339 AddInt(Data
.Default
[j
]);
2347 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
;
2352 function GetNext(): String;
2357 if Str
[1] = '"' then
2369 Result
:= Copy(Str
, 1, p
-1);
2385 Result
:= Copy(Str
, 1, p
-1);
2395 if GetNext() <> CLIPBOARD_SIG
then
2401 t
:= StrToIntDef(GetNext(), 0);
2403 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2404 (GetNext() <> ';') then
2405 begin // Что-то не то => пропускаем:
2413 i
:= Length(CopyBuf
);
2414 SetLength(CopyBuf
, i
+ 1);
2416 CopyBuf
[i
].ObjectType
:= t
;
2417 CopyBuf
[i
].Panel
:= nil;
2419 // Свойства объекта:
2423 New(CopyBuf
[i
].Panel
);
2425 with CopyBuf
[i
].Panel
^ do
2427 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2428 X
:= StrToIntDef(GetNext(), 0);
2429 Y
:= StrToIntDef(GetNext(), 0);
2430 pmin
.X
:= Min(X
, pmin
.X
);
2431 pmin
.Y
:= Min(Y
, pmin
.Y
);
2432 Width
:= StrToIntDef(GetNext(), 16);
2433 Height
:= StrToIntDef(GetNext(), 16);
2434 TextureName
:= GetNext();
2435 Alpha
:= StrToIntDef(GetNext(), 0);
2436 Blending
:= (GetNext() = '1');
2441 with CopyBuf
[i
].Item
do
2443 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2444 X
:= StrToIntDef(GetNext(), 0);
2445 Y
:= StrToIntDef(GetNext(), 0);
2446 pmin
.X
:= Min(X
, pmin
.X
);
2447 pmin
.Y
:= Min(Y
, pmin
.Y
);
2448 OnlyDM
:= (GetNext() = '1');
2449 Fall
:= (GetNext() = '1');
2453 with CopyBuf
[i
].Monster
do
2455 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2456 X
:= StrToIntDef(GetNext(), 0);
2457 Y
:= StrToIntDef(GetNext(), 0);
2458 pmin
.X
:= Min(X
, pmin
.X
);
2459 pmin
.Y
:= Min(Y
, pmin
.Y
);
2461 if GetNext() = '1' then
2464 Direction
:= D_RIGHT
;
2468 with CopyBuf
[i
].Area
do
2470 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2471 X
:= StrToIntDef(GetNext(), 0);
2472 Y
:= StrToIntDef(GetNext(), 0);
2473 pmin
.X
:= Min(X
, pmin
.X
);
2474 pmin
.Y
:= Min(Y
, pmin
.Y
);
2475 if GetNext() = '1' then
2478 Direction
:= D_RIGHT
;
2482 with CopyBuf
[i
].Trigger
do
2484 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
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 Width
:= StrToIntDef(GetNext(), 16);
2490 Height
:= StrToIntDef(GetNext(), 16);
2491 ActivateType
:= StrToIntDef(GetNext(), 0);
2492 Key
:= StrToIntDef(GetNext(), 0);
2493 Enabled
:= (GetNext() = '1');
2494 TexturePanel
:= StrToIntDef(GetNext(), 0);
2496 for j
:= 0 to 127 do
2497 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2502 pmin
.X
:= Min(Data
.TargetPoint
.X
, pmin
.X
);
2503 pmin
.Y
:= Min(Data
.TargetPoint
.Y
, pmin
.Y
);
2505 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
2507 pmin
.X
:= Min(Data
.tX
, pmin
.X
);
2508 pmin
.Y
:= Min(Data
.tY
, pmin
.Y
);
2510 TRIGGER_SPAWNMONSTER
:
2512 pmin
.X
:= Min(Data
.MonPos
.X
, pmin
.X
);
2513 pmin
.Y
:= Min(Data
.MonPos
.Y
, pmin
.Y
);
2517 pmin
.X
:= Min(Data
.ItemPos
.X
, pmin
.X
);
2518 pmin
.Y
:= Min(Data
.ItemPos
.Y
, pmin
.Y
);
2522 pmin
.X
:= Min(Data
.ShotPos
.X
, pmin
.X
);
2523 pmin
.Y
:= Min(Data
.ShotPos
.Y
, pmin
.Y
);
2531 //----------------------------------------
2532 //Закончились вспомогательные процедуры
2533 //----------------------------------------
2535 procedure TMainForm
.RefreshRecentMenu();
2540 // Лишние запомненные карты:
2541 while RecentFiles
.Count
> RecentCount
do
2542 RecentFiles
.Delete(RecentFiles
.Count
-1);
2544 // Лишние строки меню:
2545 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2546 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2548 // Отделение списка карт от строки "Выход":
2549 if RecentFiles
.Count
> 0 then
2551 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2553 MainMenu
.Items
[0].Add(MI
);
2556 // Добавление в меню списка запомненных карт:
2557 for i
:= 0 to RecentFiles
.Count
-1 do
2559 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2560 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2561 MI
.OnClick
:= aRecentFileExecute
;
2562 MainMenu
.Items
[0].Add(MI
);
2566 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2572 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2573 Delete(s
, Pos('&', s
), 1);
2574 s
:= Trim(Copy(s
, 1, 2));
2575 n
:= StrToIntDef(s
, 0) - 1;
2577 if (n
< 0) or (n
>= RecentFiles
.Count
) then
2580 s
:= RecentFiles
[n
];
2581 pw
:= Pos('.wad:\', LowerCase(s
));
2585 begin // Map name included
2586 fn
:= Copy(s
, 1, pw
+ 3);
2587 Delete(s
, 1, pw
+ 5);
2588 if (FileExists(fn
)) then
2594 else // Only wad name
2595 if (FileExists(s
)) then
2601 if (not b
) and (MessageBox(0, PChar(_lc
[I_MSG_DEL_RECENT_PROMT
]),
2602 PChar(_lc
[I_MSG_DEL_RECENT
]), MB_ICONQUESTION
or MB_YESNO
) = idYes
) then
2604 RecentFiles
.Delete(n
);
2605 RefreshRecentMenu();
2609 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2611 OptionsForm
.ShowModal();
2614 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2628 wad
:= TWADEditor_1
.Create
;
2629 if wad
.ReadFile(EditorDir
+'data/Game.wad') then
2630 wad
.GetResource('FONTS', cfgres
, cfgdata
, cfglen
);
2635 if not g_CreateTextureWAD('FONT_STD', EditorDir
+'data/Game.wad:FONTS\'+texture
) then
2636 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2638 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2639 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2640 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2641 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2643 if g_GetTexture('FONT_STD', ID
) then
2644 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
-2);
2649 e_WriteLog('Could not load FONT_STD', MSG_WARNING
);
2651 if cfglen
<> 0 then FreeMem(cfgdata
);
2654 procedure TMainForm
.FormCreate(Sender
: TObject
);
2662 EditorDir
:= ExtractFilePath(Application
.ExeName
);
2664 e_InitLog(EditorDir
+'Editor.log', WM_NEWFILE
);
2666 slInvalidTextures
:= TStringList
.Create
;
2668 ShowLayer(LAYER_BACK
, True);
2669 ShowLayer(LAYER_WALLS
, True);
2670 ShowLayer(LAYER_FOREGROUND
, True);
2671 ShowLayer(LAYER_STEPS
, True);
2672 ShowLayer(LAYER_WATER
, True);
2673 ShowLayer(LAYER_ITEMS
, True);
2674 ShowLayer(LAYER_MONSTERS
, True);
2675 ShowLayer(LAYER_AREAS
, True);
2676 ShowLayer(LAYER_TRIGGERS
, True);
2680 FormCaption
:= MainForm
.Caption
;
2684 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
2686 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2687 Position
:= poDesktopCenter
2689 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2690 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2691 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2692 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2694 if config
.ReadBool('Editor', 'Maximize', False) then
2695 WindowState
:= wsMaximized
;
2696 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2697 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2698 Splitter1
.Left
:= PanelProps
.Left
;
2699 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2700 Splitter2
.Top
:= PanelObjs
.Top
;
2701 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2702 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2703 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2704 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2705 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2706 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2707 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2708 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2709 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2710 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2711 UseCheckerboard
:= config
.ReadBool('Editor', 'UseCheckerboard', True);
2712 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2713 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2714 if gAlphaEdge
= 255 then
2715 gAlphaEdge
:= ALPHA_EDGE
;
2716 drEdge
[0] := GetRValue(gColorEdge
);
2717 drEdge
[1] := GetGValue(gColorEdge
);
2718 drEdge
[2] := GetBValue(gColorEdge
);
2719 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2722 drEdge
[3] := gAlphaEdge
;
2723 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2724 if gAlphaTriggerLine
= 255 then
2725 gAlphaTriggerLine
:= ALPHA_LINE
;
2726 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2727 if gAlphaTriggerArea
= 255 then
2728 gAlphaTriggerArea
:= ALPHA_AREA
;
2729 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2733 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2737 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2738 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2740 s
:= config
.ReadStr('Editor', 'Language', '');
2743 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2744 if RecentCount
> 10 then
2746 if RecentCount
< 2 then
2749 RecentFiles
:= TStringList
.Create();
2750 for i
:= 0 to RecentCount
-1 do
2752 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2756 RefreshRecentMenu();
2760 tbShowMap
.Down
:= ShowMap
;
2761 tbGridOn
.Down
:= DotEnable
;
2762 pcObjects
.ActivePageIndex
:= 0;
2763 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2765 Application
.OnIdle
:= OnIdle
;
2768 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2770 // NOTE: all the font printing routines assume CP1251
2771 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2774 procedure TMainForm
.Draw();
2779 Width
, Height
: Word;
2782 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2791 e_Clear(GL_COLOR_BUFFER_BIT
,
2792 GetRValue(BackColor
)/255,
2793 GetGValue(BackColor
)/255,
2794 GetBValue(BackColor
)/255);
2798 ObjCount
:= SelectedObjectCount();
2800 // Обводим выделенные объекты красной рамкой:
2801 if ObjCount
> 0 then
2803 for a
:= 0 to High(SelectedObjects
) do
2804 if SelectedObjects
[a
].Live
then
2806 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2810 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2811 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2814 // Рисуем точки изменения размеров:
2815 if (ObjCount
= 1) and
2816 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2818 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2819 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2820 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2821 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2823 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2824 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2825 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2826 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2833 if DotEnable
and (PreviewMode
= 0) then
2840 for x
:= 0 to (RenderPanel
.Width
div DotStep
) do
2841 for y
:= 0 to (RenderPanel
.Height
div DotStep
) do
2842 e_DrawPoint(DotSize
, x
*DotStep
+ a
, y
*DotStep
+ a
,
2843 GetRValue(DotColor
),
2844 GetGValue(DotColor
),
2845 GetBValue(DotColor
));
2849 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2850 (not IsSpecialTextureSel()) and (PreviewMode
= 0) then
2852 if not g_GetTexture(SelectedTexture(), ID
) then
2853 g_GetTexture('NOTEXTURE', ID
);
2854 g_GetTextureSizeByID(ID
, Width
, Height
);
2855 if UseCheckerboard
then
2857 if g_GetTexture('PREVIEW', PID
) then
2858 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
2860 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
2861 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
2862 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
2863 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
2866 // Подсказка при выборе точки Телепорта:
2867 if SelectFlag
= SELECTFLAG_TELEPORT
then
2869 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2870 if Data
.d2d_teleport
then
2871 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2872 MousePos
.X
+16, MousePos
.Y
-1,
2875 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2876 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2878 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2879 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2880 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
2883 // Подсказка при выборе точки появления:
2884 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2886 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2887 MousePos
.X
+16, MousePos
.Y
-1,
2889 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2890 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2891 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
2894 // Подсказка при выборе панели двери:
2895 if SelectFlag
= SELECTFLAG_DOOR
then
2897 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2898 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2899 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
2902 // Подсказка при выборе панели с текстурой:
2903 if SelectFlag
= SELECTFLAG_TEXTURE
then
2905 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2906 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2907 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
2910 // Подсказка при выборе панели индикации выстрела:
2911 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2913 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2914 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2915 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
2918 // Подсказка при выборе панели лифта:
2919 if SelectFlag
= SELECTFLAG_LIFT
then
2921 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2922 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2923 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
2926 // Подсказка при выборе монстра:
2927 if SelectFlag
= SELECTFLAG_MONSTER
then
2929 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2930 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2931 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
2934 // Подсказка при выборе области воздействия:
2935 if DrawPressRect
then
2937 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2938 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2939 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
2942 // Рисуем текстуры, если чертим панель:
2943 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2944 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2945 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2947 if not g_GetTexture(SelectedTexture(), ID
) then
2948 g_GetTexture('NOTEXTURE', ID
);
2949 g_GetTextureSizeByID(ID
, Width
, Height
);
2951 if (Abs(Right
-Left
) >= Width
) and (Abs(Bottom
-Top
) >= Height
) then
2952 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2953 Abs(Bottom
-Top
) div Height
, 64, True, False);
2956 // Прямоугольник выделения:
2957 if DrawRect
<> nil then
2959 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2961 // Чертим мышью панель/триггер или меняем мышью их размер:
2962 if (((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
2963 not(ssCtrl
in GetKeyShiftState())) or (MouseAction
= MOUSEACTION_RESIZE
)) and
2964 (DrawPanelSize
) then
2966 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2967 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2969 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2970 begin // Чертим новый
2971 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
2972 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
2973 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
],
2974 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
2976 else // Растягиваем существующий
2977 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2979 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2981 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2982 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2986 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2987 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2990 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
2992 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
2997 // Ближайшая к курсору мыши точка на сетке:
2998 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
3003 // Сколько пикселов карты в 1 пикселе мини-карты:
3004 ScaleSz
:= 16 div Scale
;
3005 // Размеры мини-карты:
3006 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
3007 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
3008 // X-координата на RenderPanel нулевой x-координаты карты:
3009 XX
:= RenderPanel
.Width
- aX
- 1;
3011 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
3012 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
3014 if gPanels
<> nil then
3017 for a
:= 0 to High(gPanels
) do
3019 if PanelType
<> 0 then
3021 // Левый верхний угол:
3022 aX
:= XX
+ (X
div ScaleSz
);
3023 aY
:= 1 + (Y
div ScaleSz
);
3025 aX2
:= max(Width
div ScaleSz
, 1);
3026 aY2
:= max(Height
div ScaleSz
, 1);
3027 // Правый нижний угол:
3028 aX2
:= aX
+ aX2
- 1;
3029 aY2
:= aY
+ aY2
- 1;
3032 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
3033 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
3034 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
3035 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
3036 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
3037 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
3038 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
3039 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
3040 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
3041 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
3042 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
3043 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
3047 // Рисуем красным выделенные панели:
3048 if SelectedObjects
<> nil then
3049 for b
:= 0 to High(SelectedObjects
) do
3050 with SelectedObjects
[b
] do
3051 if Live
and (ObjectType
= OBJECT_PANEL
) then
3052 with gPanels
[SelectedObjects
[b
].ID
] do
3053 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
3055 // Левый верхний угол:
3056 aX
:= XX
+ (X
div ScaleSz
);
3057 aY
:= 1 + (Y
div ScaleSz
);
3059 aX2
:= max(Width
div ScaleSz
, 1);
3060 aY2
:= max(Height
div ScaleSz
, 1);
3061 // Правый нижний угол:
3062 aX2
:= aX
+ aX2
- 1;
3063 aY2
:= aY
+ aY2
- 1;
3065 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
3069 if (gMapInfo
.Width
> RenderPanel
.Width
) or
3070 (gMapInfo
.Height
> RenderPanel
.Height
) then
3072 // Окно, показывающее текущее положение экрана на карте:
3074 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
3075 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
3076 // Левый верхний угол:
3077 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
3078 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
3079 // Правый нижний угол:
3083 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3084 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3089 RenderPanel
.SwapBuffers();
3092 procedure TMainForm
.FormResize(Sender
: TObject
);
3094 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3096 if gMapInfo
.Width
>= RenderPanel
.Width
then
3097 sbHorizontal
.Max
:= Normalize16(gMapInfo
.Width
-RenderPanel
.Width
+16)
3099 sbHorizontal
.Max
:= 0;
3101 if gMapInfo
.Height
>= RenderPanel
.Height
then
3102 sbVertical
.Max
:= Normalize16(gMapInfo
.Height
-RenderPanel
.Height
+16)
3104 sbVertical
.Max
:= 0;
3106 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
3107 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
3110 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3115 j_max
:= 0; // shut up compiler
3119 res
:= (gPanels
<> nil) and
3120 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3121 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3123 gPanels
[ID
].Height
);
3124 j_max
:= Length(gPanels
) - 1;
3129 res
:= (gItems
<> nil) and
3130 LayerEnabled
[LAYER_ITEMS
] and
3131 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3132 ItemSize
[gItems
[ID
].ItemType
][0],
3133 ItemSize
[gItems
[ID
].ItemType
][1]);
3134 j_max
:= Length(gItems
) - 1;
3139 res
:= (gMonsters
<> nil) and
3140 LayerEnabled
[LAYER_MONSTERS
] and
3141 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3142 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3143 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3144 j_max
:= Length(gMonsters
) - 1;
3149 res
:= (gAreas
<> nil) and
3150 LayerEnabled
[LAYER_AREAS
] and
3151 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3152 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3153 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3154 j_max
:= Length(gAreas
) - 1;
3159 res
:= (gTriggers
<> nil) and
3160 LayerEnabled
[LAYER_TRIGGERS
] and
3161 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3162 gTriggers
[ID
].Width
,
3163 gTriggers
[ID
].Height
);
3164 j_max
:= Length(gTriggers
) - 1;
3174 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3183 if j
= Integer(ID
) then
3188 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3189 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3193 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3194 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3195 ItemSize
[gItems
[j
].ItemType
][0],
3196 ItemSize
[gItems
[j
].ItemType
][1]);
3198 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3199 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3200 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3201 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3203 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3204 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3205 AreaSize
[gAreas
[j
].AreaType
].Width
,
3206 AreaSize
[gAreas
[j
].AreaType
].Height
);
3208 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3209 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3211 gTriggers
[j
].Height
);
3218 SetLength(SelectedObjects
, 1);
3220 SelectedObjects
[0].ObjectType
:= ObjectType
;
3221 SelectedObjects
[0].ID
:= j
;
3222 SelectedObjects
[0].Live
:= True;
3230 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3231 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3235 c1
, c2
, c3
, c4
: Boolean;
3241 MainForm
.ActiveControl
:= RenderPanel
;
3242 RenderPanel
.SetFocus();
3244 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3246 if Button
= mbLeft
then // Left Mouse Button
3248 // Двигаем карту с помощью мыши и мини-карты:
3250 g_CollidePoint(X
, Y
,
3251 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3253 max(gMapInfo
.Width
div (16 div Scale
), 1),
3254 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3257 MouseAction
:= MOUSEACTION_MOVEMAP
;
3259 else // Ставим предмет/монстра/область:
3260 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3261 (not (ssShift
in Shift
)) then
3263 case pcObjects
.ActivePageIndex
of
3265 if lbItemList
.ItemIndex
= -1 then
3266 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3269 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3270 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3271 item
.ItemType
:= item
.ItemType
+ 2;
3272 item
.X
:= MousePos
.X
-MapOffset
.X
;
3273 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3275 if not (ssCtrl
in Shift
) then
3277 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3278 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3281 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3282 item
.Fall
:= cbFall
.Checked
;
3283 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3286 if lbMonsterList
.ItemIndex
= -1 then
3287 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3290 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3291 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3292 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3294 if not (ssCtrl
in Shift
) then
3296 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3297 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3300 if rbMonsterLeft
.Checked
then
3301 monster
.Direction
:= D_LEFT
3303 monster
.Direction
:= D_RIGHT
;
3304 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3307 if lbAreasList
.ItemIndex
= -1 then
3308 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3310 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3312 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3313 area
.X
:= MousePos
.X
-MapOffset
.X
;
3314 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3316 if not (ssCtrl
in Shift
) then
3318 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3319 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3322 if rbAreaLeft
.Checked
then
3323 area
.Direction
:= D_LEFT
3325 area
.Direction
:= D_RIGHT
;
3326 Undo_Add(OBJECT_AREA
, AddArea(area
));
3332 i
:= GetFirstSelected();
3334 // Выбираем объект под текущим:
3335 if (SelectedObjects
<> nil) and
3336 (ssShift
in Shift
) and (i
>= 0) and
3337 (SelectedObjects
[i
].Live
) then
3339 if SelectedObjectCount() = 1 then
3340 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3341 SelectedObjects
[i
].ObjectType
,
3342 SelectedObjects
[i
].ID
);
3346 // Рисуем область триггера "Расширитель":
3347 if DrawPressRect
and (i
>= 0) and
3348 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3349 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3350 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3351 MouseAction
:= MOUSEACTION_DRAWPRESS
3352 else // Рисуем панель:
3353 if pcObjects
.ActivePageIndex
= 0 then
3355 if (lbPanelType
.ItemIndex
>= 0) then
3356 MouseAction
:= MOUSEACTION_DRAWPANEL
3358 else // Рисуем триггер:
3359 if (lbTriggersList
.ItemIndex
>= 0) then
3361 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3365 end; // if Button = mbLeft
3367 if Button
= mbRight
then // Right Mouse Button
3369 // Клик по мини-карте:
3371 g_CollidePoint(X
, Y
,
3372 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3374 max(gMapInfo
.Width
div (16 div Scale
), 1),
3375 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3377 MouseAction
:= MOUSEACTION_NOACTION
;
3379 else // Нужно что-то выбрать мышью:
3380 if SelectFlag
<> SELECTFLAG_NONE
then
3383 SELECTFLAG_TELEPORT
:
3384 // Точку назначения телепортации:
3385 with gTriggers
[SelectedObjects
[
3386 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3388 X
:= MousePos
.X
-MapOffset
.X
;
3389 Y
:= MousePos
.Y
-MapOffset
.Y
;
3392 SELECTFLAG_SPAWNPOINT
:
3393 // Точку создания монстра:
3394 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3395 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3397 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3398 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3400 else if TriggerType
= TRIGGER_SPAWNITEM
then
3401 begin // Точка создания предмета:
3402 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3403 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3405 else if TriggerType
= TRIGGER_SHOT
then
3406 begin // Точка создания выстрела:
3407 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3408 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3414 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3416 2, 2, OBJECT_PANEL
, True);
3417 if IDArray
<> nil then
3419 for i
:= 0 to High(IDArray
) do
3420 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3421 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3423 gTriggers
[SelectedObjects
[
3424 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3429 gTriggers
[SelectedObjects
[
3430 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3434 // Панель с текстурой:
3436 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3438 2, 2, OBJECT_PANEL
, True);
3439 if IDArray
<> nil then
3441 for i
:= 0 to High(IDArray
) do
3442 if ((gPanels
[IDArray
[i
]].PanelType
in
3443 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3444 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3446 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3447 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3448 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3450 gTriggers
[SelectedObjects
[
3451 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3456 gTriggers
[SelectedObjects
[
3457 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3463 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3465 2, 2, OBJECT_PANEL
, True);
3466 if IDArray
<> nil then
3468 for i
:= 0 to High(IDArray
) do
3469 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3470 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3471 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3472 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3474 gTriggers
[SelectedObjects
[
3475 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3480 gTriggers
[SelectedObjects
[
3481 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3487 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3489 2, 2, OBJECT_MONSTER
, False);
3490 if IDArray
<> nil then
3491 gTriggers
[SelectedObjects
[
3492 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3494 gTriggers
[SelectedObjects
[
3495 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3498 SELECTFLAG_SHOTPANEL
:
3499 // Панель индикации выстрела:
3501 if gTriggers
[SelectedObjects
[
3502 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3504 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3506 2, 2, OBJECT_PANEL
, True);
3507 if IDArray
<> nil then
3509 for i
:= 0 to High(IDArray
) do
3510 if ((gPanels
[IDArray
[i
]].PanelType
in
3511 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3512 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3514 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3515 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3516 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3518 gTriggers
[SelectedObjects
[
3519 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3524 gTriggers
[SelectedObjects
[
3525 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3530 SelectFlag
:= SELECTFLAG_SELECTED
;
3532 else // if SelectFlag <> SELECTFLAG_NONE...
3534 // Что уже выбрано и не нажат Ctrl:
3535 if (SelectedObjects
<> nil) and
3536 (not (ssCtrl
in Shift
)) then
3537 for i
:= 0 to High(SelectedObjects
) do
3538 with SelectedObjects
[i
] do
3541 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3542 (SelectedObjectCount() = 1) then
3544 Rect
:= ObjectGetRect(ObjectType
, ID
);
3546 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3547 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3548 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3549 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3550 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3551 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3552 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3553 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3555 // Меняем размер панели или триггера:
3556 if c1
or c2
or c3
or c4
then
3558 MouseAction
:= MOUSEACTION_RESIZE
;
3559 LastMovePoint
:= MousePos
;
3563 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3565 ResizeDirection
:= RESIZEDIR_LEFT
3567 ResizeDirection
:= RESIZEDIR_RIGHT
;
3568 RenderPanel
.Cursor
:= crSizeWE
;
3572 ResizeType
:= RESIZETYPE_VERTICAL
;
3574 ResizeDirection
:= RESIZEDIR_UP
3576 ResizeDirection
:= RESIZEDIR_DOWN
;
3577 RenderPanel
.Cursor
:= crSizeNS
;
3584 // Перемещаем панель или триггер:
3585 if ObjectCollide(ObjectType
, ID
,
3587 Y
-MapOffset
.Y
-1, 2, 2) then
3589 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3590 LastMovePoint
:= MousePos
;
3596 end; // if Button = mbRight
3598 MouseRDown
:= Button
= mbRight
;
3600 MouseRDownPos
:= MousePos
;
3602 MouseLDown
:= Button
= mbLeft
;
3604 MouseLDownPos
:= MousePos
;
3607 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3608 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3615 rSelectRect
: Boolean;
3616 wWidth
, wHeight
: Word;
3619 if Button
= mbLeft
then
3620 MouseLDown
:= False;
3621 if Button
= mbRight
then
3622 MouseRDown
:= False;
3625 ResizeType
:= RESIZETYPE_NONE
;
3628 if Button
= mbLeft
then // Left Mouse Button
3630 if MouseAction
<> MOUSEACTION_NONE
then
3631 begin // Было действие мышью
3632 // Мышь сдвинулась во время удержания клавиши,
3633 // либо активирован режим быстрого рисования:
3634 if ((MousePos
.X
<> MouseLDownPos
.X
) and
3635 (MousePos
.Y
<> MouseLDownPos
.Y
)) or
3636 ((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3637 (ssCtrl
in Shift
)) then
3640 MOUSEACTION_DRAWPANEL
:
3642 // Фон или передний план без текстуры - ошибка:
3643 if (lbPanelType
.ItemIndex
in [1, 2]) and
3644 (lbTextureList
.ItemIndex
= -1) then
3645 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3646 else // Назначаем параметры панели:
3648 case lbPanelType
.ItemIndex
of
3649 0: Panel
.PanelType
:= PANEL_WALL
;
3650 1: Panel
.PanelType
:= PANEL_BACK
;
3651 2: Panel
.PanelType
:= PANEL_FORE
;
3652 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3653 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3654 5: Panel
.PanelType
:= PANEL_STEP
;
3655 6: Panel
.PanelType
:= PANEL_WATER
;
3656 7: Panel
.PanelType
:= PANEL_ACID1
;
3657 8: Panel
.PanelType
:= PANEL_ACID2
;
3658 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3659 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3660 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3661 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3662 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3665 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3666 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3667 if ssCtrl
in Shift
then
3671 if (lbTextureList
.ItemIndex
<> -1) and
3672 (not IsSpecialTextureSel()) then
3674 if not g_GetTexture(SelectedTexture(), TextureID
) then
3675 g_GetTexture('NOTEXTURE', TextureID
);
3676 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
3678 Panel
.Width
:= wWidth
;
3679 Panel
.Height
:= wHeight
;
3683 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3684 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3687 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3688 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3689 (lbTextureList
.ItemIndex
= -1) then
3691 Panel
.TextureHeight
:= 1;
3692 Panel
.TextureWidth
:= 1;
3693 Panel
.TextureName
:= '';
3694 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3696 else // Есть текстура:
3698 Panel
.TextureName
:= SelectedTexture();
3700 // Обычная текстура:
3701 if not IsSpecialTextureSel() then
3703 g_GetTextureSizeByName(Panel
.TextureName
,
3704 Panel
.TextureWidth
, Panel
.TextureHeight
);
3705 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3707 else // Спец.текстура:
3709 Panel
.TextureHeight
:= 1;
3710 Panel
.TextureWidth
:= 1;
3711 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3716 Panel
.Blending
:= False;
3718 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3722 // Рисовали триггер:
3723 MOUSEACTION_DRAWTRIGGER
:
3725 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3726 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3727 if ssCtrl
in Shift
then
3731 trigger
.Width
:= wWidth
;
3732 trigger
.Height
:= wHeight
;
3736 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3737 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3740 trigger
.Enabled
:= True;
3741 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3742 trigger
.TexturePanel
:= -1;
3745 trigger
.ActivateType
:= 0;
3747 if clbActivationType
.Checked
[0] then
3748 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3749 if clbActivationType
.Checked
[1] then
3750 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3751 if clbActivationType
.Checked
[2] then
3752 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3753 if clbActivationType
.Checked
[3] then
3754 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3755 if clbActivationType
.Checked
[4] then
3756 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3757 if clbActivationType
.Checked
[5] then
3758 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3760 // Необходимые для активации ключи:
3763 if clbKeys
.Checked
[0] then
3764 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3765 if clbKeys
.Checked
[1] then
3766 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3767 if clbKeys
.Checked
[2] then
3768 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3769 if clbKeys
.Checked
[3] then
3770 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3771 if clbKeys
.Checked
[4] then
3772 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3774 // Параметры триггера:
3775 FillByte(trigger
.Data
.Default
[0], 128, 0);
3777 case trigger
.TriggerType
of
3778 // Переключаемая панель:
3779 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3780 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3781 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3783 Trigger
.Data
.PanelID
:= -1;
3789 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3790 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3791 trigger
.Data
.d2d_teleport
:= True;
3792 trigger
.Data
.TlpDir
:= 0;
3795 // Изменение других триггеров:
3796 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3799 trigger
.Data
.Count
:= 1;
3805 trigger
.Data
.Volume
:= 255;
3806 trigger
.Data
.Pan
:= 127;
3807 trigger
.Data
.PlayCount
:= 1;
3808 trigger
.Data
.Local
:= True;
3809 trigger
.Data
.SoundSwitch
:= False;
3815 trigger
.Data
.MusicAction
:= 1;
3818 // Создание монстра:
3819 TRIGGER_SPAWNMONSTER
:
3821 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3822 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3823 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3824 trigger
.Data
.MonHealth
:= 0;
3825 trigger
.Data
.MonActive
:= False;
3826 trigger
.Data
.MonCount
:= 1;
3829 // Создание предмета:
3832 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3833 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3834 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3835 trigger
.Data
.ItemOnlyDM
:= False;
3836 trigger
.Data
.ItemFalls
:= False;
3837 trigger
.Data
.ItemCount
:= 1;
3838 trigger
.Data
.ItemMax
:= 0;
3839 trigger
.Data
.ItemDelay
:= 0;
3845 trigger
.Data
.PushAngle
:= 90;
3846 trigger
.Data
.PushForce
:= 10;
3847 trigger
.Data
.ResetVel
:= True;
3852 trigger
.Data
.ScoreCount
:= 1;
3853 trigger
.Data
.ScoreCon
:= True;
3854 trigger
.Data
.ScoreMsg
:= True;
3859 trigger
.Data
.MessageKind
:= 0;
3860 trigger
.Data
.MessageSendTo
:= 0;
3861 trigger
.Data
.MessageText
:= '';
3862 trigger
.Data
.MessageTime
:= 144;
3867 trigger
.Data
.DamageValue
:= 5;
3868 trigger
.Data
.DamageInterval
:= 12;
3873 trigger
.Data
.HealValue
:= 5;
3874 trigger
.Data
.HealInterval
:= 36;
3879 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3880 trigger
.Data
.ShotSound
:= True;
3881 trigger
.Data
.ShotPanelID
:= -1;
3882 trigger
.Data
.ShotTarget
:= 0;
3883 trigger
.Data
.ShotIntSight
:= 0;
3884 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
3885 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3886 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3887 trigger
.Data
.ShotAngle
:= 0;
3888 trigger
.Data
.ShotWait
:= 18;
3889 trigger
.Data
.ShotAccuracy
:= 0;
3890 trigger
.Data
.ShotAmmo
:= 0;
3891 trigger
.Data
.ShotIntReload
:= 0;
3896 trigger
.Data
.FXCount
:= 1;
3897 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3898 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3899 trigger
.Data
.FXColorR
:= 0;
3900 trigger
.Data
.FXColorG
:= 0;
3901 trigger
.Data
.FXColorB
:= 255;
3902 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3903 trigger
.Data
.FXWait
:= 1;
3904 trigger
.Data
.FXVelX
:= 0;
3905 trigger
.Data
.FXVelY
:= -20;
3906 trigger
.Data
.FXSpreadL
:= 5;
3907 trigger
.Data
.FXSpreadR
:= 5;
3908 trigger
.Data
.FXSpreadU
:= 4;
3909 trigger
.Data
.FXSpreadD
:= 0;
3913 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3916 // Рисовали область триггера "Расширитель":
3917 MOUSEACTION_DRAWPRESS
:
3918 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3920 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3921 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3922 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3923 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3925 DrawPressRect
:= False;
3929 MouseAction
:= MOUSEACTION_NONE
;
3931 end // if Button = mbLeft...
3932 else // Right Mouse Button:
3934 if MouseAction
= MOUSEACTION_NOACTION
then
3936 MouseAction
:= MOUSEACTION_NONE
;
3940 // Объект передвинут или изменен в размере:
3941 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3943 MouseAction
:= MOUSEACTION_NONE
;
3948 // Еще не все выбрали:
3949 if SelectFlag
<> SELECTFLAG_NONE
then
3951 if SelectFlag
= SELECTFLAG_SELECTED
then
3952 SelectFlag
:= SELECTFLAG_NONE
;
3957 // Мышь сдвинулась во время удержания клавиши:
3958 if (MousePos
.X
<> MouseRDownPos
.X
) and
3959 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3961 rSelectRect
:= True;
3963 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3964 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3965 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3966 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3968 else // Мышь не сдвинулась - нет прямоугольника:
3970 rSelectRect
:= False;
3972 rRect
.X
:= X
-MapOffset
.X
-1;
3973 rRect
.Y
:= Y
-MapOffset
.Y
-1;
3978 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
3979 if not (ssCtrl
in Shift
) then
3980 RemoveSelectFromObjects();
3982 // Выделяем всё в выбранном прямоугольнике:
3983 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3984 rRect
.Width
, rRect
.Height
,
3985 pcObjects
.ActivePageIndex
+1, rSelectRect
);
3987 if IDArray
<> nil then
3988 for i
:= 0 to High(IDArray
) do
3989 SelectObject(pcObjects
.ActivePageIndex
+1, IDArray
[i
],
3990 (ssCtrl
in Shift
) or rSelectRect
);
3996 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
4001 function TMainForm
.RenderMousePos(): Types
.TPoint
;
4003 Result
:= RenderPanel
.ScreenToClient(Mouse
.CursorPos
);
4006 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
4007 Shift
: TShiftState
; X
, Y
: Integer);
4010 dWidth
, dHeight
: Integer;
4013 wWidth
, wHeight
: Word;
4015 _id
:= GetFirstSelected();
4018 // Рисуем панель с текстурой, сетка - размеры текстуры:
4019 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
4020 (lbPanelType
.ItemIndex
in [0..8]) and
4021 (lbTextureList
.ItemIndex
<> -1) and
4022 (not IsSpecialTextureSel()) then
4024 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
4025 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
4028 // Меняем размер панели с текстурой, сетка - размеры текстуры:
4029 if (MouseAction
= MOUSEACTION_RESIZE
) and
4030 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
4031 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
4032 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
4033 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
4035 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
4036 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
4039 // Выравнивание по сетке:
4045 else // Нет выравнивания по сетке:
4051 // Новая позиция мыши:
4053 begin // Зажата левая кнопка мыши
4054 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
4055 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
4059 begin // Зажата правая кнопка мыши
4060 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
4061 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
4064 begin // Кнопки мыши не зажаты
4065 MousePos
.X
:= (Round(X
/sX
)*sX
);
4066 MousePos
.Y
:= (Round(Y
/sY
)*sY
);
4069 // Изменение размера закончилось - ставим обычный курсор:
4070 if ResizeType
= RESIZETYPE_NONE
then
4071 RenderPanel
.Cursor
:= crDefault
;
4073 // Зажата только правая кнопка мыши:
4074 if (not MouseLDown
) and (MouseRDown
) then
4076 // Рисуем прямоугольник выделения:
4077 if MouseAction
= MOUSEACTION_NONE
then
4079 if DrawRect
= nil then
4081 DrawRect
.Top
:= MouseRDownPos
.y
;
4082 DrawRect
.Left
:= MouseRDownPos
.x
;
4083 DrawRect
.Bottom
:= MousePos
.y
;
4084 DrawRect
.Right
:= MousePos
.x
;
4087 // Двигаем выделенные объекты:
4088 if MouseAction
= MOUSEACTION_MOVEOBJ
then
4090 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
4091 MousePos
.X
-LastMovePoint
.X
+WASDOffset
.X
,
4092 MousePos
.Y
-LastMovePoint
.Y
+WASDOffset
.Y
);
4097 // Меняем размер выделенного объекта:
4098 if MouseAction
= MOUSEACTION_RESIZE
then
4100 if (SelectedObjectCount
= 1) and
4101 (SelectedObjects
[GetFirstSelected
].Live
) then
4103 dWidth
:= MousePos
.X
-LastMovePoint
.X
+WASDOffset
.X
;
4104 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
+WASDOffset
.Y
;
4109 RESIZETYPE_VERTICAL
: dWidth
:= 0;
4110 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
4113 case ResizeDirection
of
4114 RESIZEDIR_UP
: dHeight
:= -dHeight
;
4115 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
4118 ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
4119 SelectedObjects
[GetFirstSelected
].ID
,
4120 dWidth
, dHeight
, ResizeDirection
);
4122 LastMovePoint
:= MousePos
;
4127 // Зажата только левая кнопка мыши:
4128 if (not MouseRDown
) and (MouseLDown
) then
4130 // Рисуем прямоугольник планирования панели:
4131 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4132 MOUSEACTION_DRAWTRIGGER
,
4133 MOUSEACTION_DRAWPRESS
] then
4135 if DrawRect
= nil then
4137 if ssCtrl
in Shift
then
4141 if (lbTextureList
.ItemIndex
<> -1) and (not IsSpecialTextureSel()) and
4142 (MouseAction
= MOUSEACTION_DRAWPANEL
) then
4144 if not g_GetTexture(SelectedTexture(), TextureID
) then
4145 g_GetTexture('NOTEXTURE', TextureID
);
4146 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
4148 DrawRect
.Top
:= MouseLDownPos
.y
;
4149 DrawRect
.Left
:= MouseLDownPos
.x
;
4150 DrawRect
.Bottom
:= DrawRect
.Top
+ wHeight
;
4151 DrawRect
.Right
:= DrawRect
.Left
+ wWidth
;
4155 DrawRect
.Top
:= MouseLDownPos
.y
;
4156 DrawRect
.Left
:= MouseLDownPos
.x
;
4157 DrawRect
.Bottom
:= MousePos
.y
;
4158 DrawRect
.Right
:= MousePos
.x
;
4161 else // Двигаем карту:
4162 if MouseAction
= MOUSEACTION_MOVEMAP
then
4168 // Клавиши мыши не зажаты:
4169 if (not MouseRDown
) and (not MouseLDown
) then
4172 // Строка состояния - координаты мыши:
4173 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4174 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4177 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4179 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
4180 PChar(_lc
[I_MSG_EXIT
]),
4181 MB_ICONQUESTION
or MB_YESNO
or
4182 MB_DEFBUTTON1
) = idYes
;
4185 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4190 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4195 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
4197 if WindowState
<> wsMaximized
then
4199 config
.WriteInt('Editor', 'XPos', Left
);
4200 config
.WriteInt('Editor', 'YPos', Top
);
4201 config
.WriteInt('Editor', 'Width', Width
);
4202 config
.WriteInt('Editor', 'Height', Height
);
4206 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4207 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4208 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4209 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4211 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4212 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4213 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4214 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4215 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4216 config
.WriteInt('Editor', 'DotStep', DotStep
);
4217 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4218 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4219 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4220 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4221 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4222 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4223 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4225 for i
:= 0 to RecentCount
-1 do
4226 if i
< RecentFiles
.Count
then
4227 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4229 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4232 config
.SaveFile(EditorDir
+'Editor.cfg');
4235 slInvalidTextures
.Free
;
4238 procedure TMainForm
.FormDropFiles(Sender
: TObject
;
4239 const FileNames
: array of String);
4241 if Length(FileNames
) <> 1 then
4244 OpenMapFile(FileNames
[0]);
4247 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4249 if MainForm
.Visible
then
4253 procedure TMainForm
.Splitter1Moved(Sender
: TObject
);
4258 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4262 MapOptionsForm
.ShowModal();
4264 ResName
:= OpenedMap
;
4265 while (Pos(':\', ResName
) > 0) do
4266 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4268 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4271 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4273 AboutForm
.ShowModal();
4276 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word;
4277 Shift
: TShiftState
);
4282 if (not EditingProperties
) then
4284 if Key
= Ord('1') then
4285 SwitchLayer(LAYER_BACK
);
4286 if Key
= Ord('2') then
4287 SwitchLayer(LAYER_WALLS
);
4288 if Key
= Ord('3') then
4289 SwitchLayer(LAYER_FOREGROUND
);
4290 if Key
= Ord('4') then
4291 SwitchLayer(LAYER_STEPS
);
4292 if Key
= Ord('5') then
4293 SwitchLayer(LAYER_WATER
);
4294 if Key
= Ord('6') then
4295 SwitchLayer(LAYER_ITEMS
);
4296 if Key
= Ord('7') then
4297 SwitchLayer(LAYER_MONSTERS
);
4298 if Key
= Ord('8') then
4299 SwitchLayer(LAYER_AREAS
);
4300 if Key
= Ord('9') then
4301 SwitchLayer(LAYER_TRIGGERS
);
4302 if Key
= Ord('0') then
4303 tbShowClick(tbShow
);
4305 if Key
= Ord('V') then
4306 begin // Поворот монстров и областей:
4307 if (SelectedObjects
<> nil) then
4309 for i
:= 0 to High(SelectedObjects
) do
4310 if (SelectedObjects
[i
].Live
) then
4312 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4314 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4317 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4319 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4325 if pcObjects
.ActivePage
= tsMonsters
then
4327 if rbMonsterLeft
.Checked
then
4328 rbMonsterRight
.Checked
:= True
4330 rbMonsterLeft
.Checked
:= True;
4332 if pcObjects
.ActivePage
= tsAreas
then
4334 if rbAreaLeft
.Checked
then
4335 rbAreaRight
.Checked
:= True
4337 rbAreaLeft
.Checked
:= True;
4342 if not (ssCtrl
in Shift
) then
4344 // Быстрое превью карты:
4345 if Key
= Ord('E') then
4347 if PreviewMode
= 0 then
4351 // Вертикальный скролл карты:
4354 if Key
= Ord('W') then
4356 if (MouseLDown
or MouseRDown
) and (Position
>= DotStep
) then
4358 Dec(WASDOffset
.Y
, DotStep
);
4359 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4361 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4362 MapOffset
.Y
:= -Round(Position
/16) * 16;
4365 if Key
= Ord('S') then
4367 if (MouseLDown
or MouseRDown
) and (Position
+DotStep
<= Max
) then
4369 Inc(WASDOffset
.Y
, DotStep
);
4370 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4372 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4373 MapOffset
.Y
:= -Round(Position
/16) * 16;
4377 // Горизонтальный скролл карты:
4378 with sbHorizontal
do
4380 if Key
= Ord('A') then
4382 if (MouseLDown
or MouseRDown
) and (Position
>= DotStep
) then
4384 Dec(WASDOffset
.X
, DotStep
);
4385 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4387 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4388 MapOffset
.X
:= -Round(Position
/16) * 16;
4391 if Key
= Ord('D') then
4393 if (MouseLDown
or MouseRDown
) and (Position
+DotStep
<= Max
) then
4395 Inc(WASDOffset
.X
, DotStep
);
4396 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4398 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4399 MapOffset
.X
:= -Round(Position
/16) * 16;
4403 else // ssCtrl in Shift
4405 if ssShift
in Shift
then
4407 // Вставка по абсолютному смещению:
4408 if Key
= Ord('V') then
4409 aPasteObjectExecute(Sender
);
4411 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4415 // Удалить выделенные объекты:
4416 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4417 RenderPanel
.Focused() then
4418 DeleteSelectedObjects();
4421 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4422 RemoveSelectFromObjects();
4424 // Передвинуть объекты:
4425 if MainForm
.ActiveControl
= RenderPanel
then
4430 if Key
= VK_NUMPAD4
then
4431 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4432 if Key
= VK_NUMPAD6
then
4433 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4434 if Key
= VK_NUMPAD8
then
4435 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4436 if Key
= VK_NUMPAD5
then
4437 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4439 if (dx
<> 0) or (dy
<> 0) then
4441 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4446 if ssCtrl
in Shift
then
4448 // Выбор панели с текстурой для триггера
4449 if Key
= Ord('T') then
4451 DrawPressRect
:= False;
4452 if SelectFlag
= SELECTFLAG_TEXTURE
then
4454 SelectFlag
:= SELECTFLAG_NONE
;
4457 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4459 SelectFlag
:= SELECTFLAG_TEXTURE
;
4462 if Key
= Ord('D') then
4464 SelectFlag
:= SELECTFLAG_NONE
;
4465 if DrawPressRect
then
4467 DrawPressRect
:= False;
4472 // Выбор области воздействия, в зависимости от типа триггера
4473 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4476 DrawPressRect
:= True;
4479 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4481 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4484 SelectFlag
:= SELECTFLAG_DOOR
;
4487 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4490 SelectFlag
:= SELECTFLAG_LIFT
;
4493 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4496 SelectFlag
:= SELECTFLAG_TELEPORT
;
4499 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4502 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4506 // Выбор основного параметра, в зависимости от типа триггера
4507 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4510 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4511 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
4512 SelectMapForm
.GetMaps(FileName
);
4514 if SelectMapForm
.ShowModal() = mrOK
then
4516 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4517 bApplyProperty
.Click();
4521 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4523 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4526 AddSoundForm
.OKFunction
:= nil;
4527 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4528 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4530 if (AddSoundForm
.ShowModal() = mrOk
) then
4532 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4533 bApplyProperty
.Click();
4537 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4539 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4542 vleObjectProperty
.Row
:= i
;
4543 vleObjectProperty
.SetFocus();
4550 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4552 RemoveSelectFromObjects();
4553 MapOptimizationForm
.ShowModal();
4556 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4558 MapCheckForm
.ShowModal();
4561 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4563 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4564 AddTextureForm
.ShowModal();
4567 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4570 TextureWidth
, TextureHeight
: Word;
4575 if (lbTextureList
.ItemIndex
<> -1) and
4576 (not IsSpecialTextureSel()) then
4578 if g_GetTexture(SelectedTexture(), TextureID
) then
4580 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4582 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4583 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4586 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4587 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4592 lTextureWidth
.Caption
:= '';
4593 lTextureHeight
.Caption
:= '';
4597 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4598 ARect
: TRect
; State
: TOwnerDrawState
);
4600 with Control
as TListBox
do
4602 if LCLType
.odSelected
in State
then
4604 Canvas
.Brush
.Color
:= clHighlight
;
4605 Canvas
.Font
.Color
:= clHighlightText
;
4607 if (Items
<> nil) and (Index
>= 0) then
4608 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4610 Canvas
.Brush
.Color
:= clRed
;
4611 Canvas
.Font
.Color
:= clWhite
;
4613 Canvas
.FillRect(ARect
);
4614 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4618 procedure TMainForm
.miReopenMapClick(Sender
: TObject
);
4620 FileName
, Resource
: String;
4622 if OpenedMap
= '' then
4625 if MessageBox(0, PChar(_lc
[I_MSG_REOPEN_MAP_PROMT
]),
4626 PChar(_lc
[I_MENU_FILE_REOPEN
]), MB_ICONQUESTION
or MB_YESNO
) <> idYes
then
4629 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, @Resource
);
4630 OpenMap(FileName
, Resource
);
4633 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4634 const KeyName
: String; Values
: TStrings
);
4636 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4638 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4640 Values
.Add(DirNames
[D_LEFT
]);
4641 Values
.Add(DirNames
[D_RIGHT
]);
4643 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4645 Values
.Add(DirNamesAdv
[0]);
4646 Values
.Add(DirNamesAdv
[1]);
4647 Values
.Add(DirNamesAdv
[2]);
4648 Values
.Add(DirNamesAdv
[3]);
4650 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4652 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4653 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4655 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4657 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4658 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4659 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4660 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4661 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4662 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4664 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4666 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4667 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4668 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4669 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4671 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4673 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4674 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4675 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4676 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4678 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4680 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4681 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4683 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4685 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4686 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4687 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4688 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4689 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4690 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4692 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4694 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4695 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4696 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4697 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4698 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4699 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4700 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4702 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
4704 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
4705 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
4706 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
4707 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
4709 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4710 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4711 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4712 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4713 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4714 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4715 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4716 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4717 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4718 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4719 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4720 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4721 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4722 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4723 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4724 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4725 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4726 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4727 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4729 Values
.Add(BoolNames
[True]);
4730 Values
.Add(BoolNames
[False]);
4735 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4737 _id
, a
, r
, c
: Integer;
4747 if SelectedObjectCount() <> 1 then
4749 if not SelectedObjects
[GetFirstSelected()].Live
then
4753 if not CheckProperty() then
4759 _id
:= GetFirstSelected();
4761 r
:= vleObjectProperty
.Row
;
4762 c
:= vleObjectProperty
.Col
;
4764 case SelectedObjects
[_id
].ObjectType
of
4767 with gPanels
[SelectedObjects
[_id
].ID
] do
4769 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4770 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4771 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4772 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4774 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4776 // Сброс ссылки на триггеры смены текстуры:
4777 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4778 if gTriggers
<> nil then
4779 for a
:= 0 to High(gTriggers
) do
4781 if (gTriggers
[a
].TriggerType
<> 0) and
4782 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4783 gTriggers
[a
].TexturePanel
:= -1;
4784 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4785 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4786 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4789 // Сброс ссылки на триггеры лифта:
4790 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4791 if gTriggers
<> nil then
4792 for a
:= 0 to High(gTriggers
) do
4793 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4794 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4795 gTriggers
[a
].Data
.PanelID
:= -1;
4797 // Сброс ссылки на триггеры двери:
4798 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4799 if gTriggers
<> nil then
4800 for a
:= 0 to High(gTriggers
) do
4801 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4802 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4803 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4804 gTriggers
[a
].Data
.PanelID
:= -1;
4806 if IsTexturedPanel(PanelType
) then
4807 begin // Может быть текстура
4808 if TextureName
<> '' then
4809 begin // Была текстура
4810 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4811 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4820 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4822 if TextureName
<> '' then
4823 begin // Есть текстура
4824 // Обычная текстура:
4825 if not IsSpecialTexture(TextureName
) then
4827 g_GetTextureSizeByName(TextureName
,
4828 TextureWidth
, TextureHeight
);
4830 // Проверка кратности размеров панели:
4832 if TextureWidth
<> 0 then
4833 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4835 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4839 if Res
and (TextureHeight
<> 0) then
4840 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4842 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4849 if not g_GetTexture(TextureName
, TextureID
) then
4850 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4851 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4853 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4854 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4856 TextureHeight
:= NH
;
4859 TextureID
:= TEXTURE_SPECIAL_NONE
;
4869 TextureID
:= TEXTURE_SPECIAL_NONE
;
4872 else // Спец.текстура
4876 TextureID
:= SpecialTextureID(TextureName
);
4879 else // Нет текстуры
4883 TextureID
:= TEXTURE_SPECIAL_NONE
;
4886 else // Не может быть текстуры
4893 TextureID
:= TEXTURE_SPECIAL_NONE
;
4900 with gItems
[SelectedObjects
[_id
].ID
] do
4902 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4903 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4904 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
4905 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
4911 with gMonsters
[SelectedObjects
[_id
].ID
] do
4913 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4914 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4915 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4921 with gAreas
[SelectedObjects
[_id
].ID
] do
4923 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4924 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4925 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4931 with gTriggers
[SelectedObjects
[_id
].ID
] do
4933 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4934 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4935 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4936 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4937 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
4938 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
4939 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
4944 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]]);
4945 FillByte(Data
.MapName
[0], 16, 0);
4947 Move(s
[1], Data
.MapName
[0], Min(Length(s
), 16));
4952 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
4953 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
4956 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
4958 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
4959 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
4960 if Data
.Count
< 1 then
4962 if TriggerType
= TRIGGER_PRESS
then
4963 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
4966 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
4967 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
4970 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
4971 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
4976 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
4977 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
4978 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
4983 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]]);
4984 FillByte(Data
.SoundName
[0], 64, 0);
4986 Move(s
[1], Data
.SoundName
[0], Min(Length(s
), 64));
4988 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
4989 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
4990 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
4991 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
4992 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
4995 TRIGGER_SPAWNMONSTER
:
4997 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
4998 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
4999 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
5000 if Data
.MonHealth
< 0 then
5001 Data
.MonHealth
:= 0;
5002 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
5003 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5004 if Data
.MonCount
< 1 then
5006 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5007 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5008 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5010 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
5012 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
5014 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
5016 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
5018 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
5024 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
5025 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5026 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5027 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5028 if Data
.ItemCount
< 1 then
5029 Data
.ItemCount
:= 1;
5030 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5031 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5032 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5037 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]]);
5038 FillByte(Data
.MusicName
[0], 64, 0);
5040 Move(s
[1], Data
.MusicName
[0], Min(Length(s
), 64));
5042 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
5043 Data
.MusicAction
:= 1
5045 Data
.MusicAction
:= 2;
5050 Data
.PushAngle
:= Min(
5051 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
5052 Data
.PushForce
:= Min(
5053 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
5054 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
5059 Data
.ScoreAction
:= 0;
5060 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
5061 Data
.ScoreAction
:= 1
5062 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
5063 Data
.ScoreAction
:= 2
5064 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
5065 Data
.ScoreAction
:= 3;
5066 Data
.ScoreCount
:= Min(Max(
5067 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5068 Data
.ScoreTeam
:= 0;
5069 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
5071 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
5073 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
5074 Data
.ScoreTeam
:= 3;
5075 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
5076 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
5081 Data
.MessageKind
:= 0;
5082 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
5083 Data
.MessageKind
:= 1;
5085 Data
.MessageSendTo
:= 0;
5086 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
5087 Data
.MessageSendTo
:= 1
5088 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
5089 Data
.MessageSendTo
:= 2
5090 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
5091 Data
.MessageSendTo
:= 3
5092 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
5093 Data
.MessageSendTo
:= 4
5094 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
5095 Data
.MessageSendTo
:= 5;
5097 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]]);
5098 FillByte(Data
.MessageText
[0], 100, 0);
5100 Move(s
[1], Data
.MessageText
[0], Min(Length(s
), 100));
5102 Data
.MessageTime
:= Min(Max(
5103 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
5108 Data
.DamageValue
:= Min(Max(
5109 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
5110 Data
.DamageInterval
:= Min(Max(
5111 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5116 Data
.HealValue
:= Min(Max(
5117 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
5118 Data
.HealInterval
:= Min(Max(
5119 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5120 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
5121 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5126 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
5127 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
5128 Data
.ShotTarget
:= 0;
5129 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
5130 Data
.ShotTarget
:= 1
5131 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
5132 Data
.ShotTarget
:= 2
5133 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
5134 Data
.ShotTarget
:= 3
5135 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
5136 Data
.ShotTarget
:= 4
5137 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
5138 Data
.ShotTarget
:= 5
5139 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
5140 Data
.ShotTarget
:= 6;
5141 Data
.ShotIntSight
:= Min(Max(
5142 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
5144 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
5146 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
5148 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
5150 Data
.ShotAngle
:= Min(
5151 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
5152 Data
.ShotWait
:= Min(Max(
5153 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5154 Data
.ShotAccuracy
:= Min(Max(
5155 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
5156 Data
.ShotAmmo
:= Min(Max(
5157 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
5158 Data
.ShotIntReload
:= Min(Max(
5159 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
5164 Data
.FXCount
:= Min(Max(
5165 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5166 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
5168 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
5169 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
5170 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
5171 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
5172 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5173 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
5174 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5175 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
5176 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5177 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
5178 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5179 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
5180 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5181 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
5184 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
5185 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
5188 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
5189 Data
.FXColorR
:= a
and $FF;
5190 Data
.FXColorG
:= (a
shr 8) and $FF;
5191 Data
.FXColorB
:= (a
shr 16) and $FF;
5192 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
5196 Data
.FXWait
:= Min(Max(
5197 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5198 Data
.FXVelX
:= Min(Max(
5199 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
5200 Data
.FXVelY
:= Min(Max(
5201 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
5202 Data
.FXSpreadL
:= Min(Max(
5203 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
5204 Data
.FXSpreadR
:= Min(Max(
5205 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
5206 Data
.FXSpreadU
:= Min(Max(
5207 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
5208 Data
.FXSpreadD
:= Min(Max(
5209 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
5218 vleObjectProperty
.Row
:= r
;
5219 vleObjectProperty
.Col
:= c
;
5222 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5226 i
:= lbTextureList
.ItemIndex
;
5230 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5231 [SelectedTexture()])),
5232 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5233 MB_ICONQUESTION
or MB_YESNO
or
5234 MB_DEFBUTTON1
) <> idYes
then
5237 if gPanels
<> nil then
5238 for a
:= 0 to High(gPanels
) do
5239 if (gPanels
[a
].PanelType
<> 0) and
5240 (gPanels
[a
].TextureName
= SelectedTexture()) then
5242 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5246 g_DeleteTexture(SelectedTexture());
5247 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5249 slInvalidTextures
.Delete(i
);
5250 if lbTextureList
.ItemIndex
> -1 then
5251 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5254 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5256 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
5257 PChar(_lc
[I_MSG_CLEAR_MAP
]),
5258 MB_ICONQUESTION
or MB_YESNO
or
5259 MB_DEFBUTTON1
) = mrYes
) then
5263 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5267 if UndoBuffer
= nil then
5269 if UndoBuffer
[High(UndoBuffer
)] = nil then
5272 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5273 with UndoBuffer
[High(UndoBuffer
)][a
] do
5281 UNDO_DELETE_ITEM
: AddItem(Item
);
5282 UNDO_DELETE_AREA
: AddArea(Area
);
5283 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5284 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5285 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5286 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5287 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5288 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5289 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5293 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5295 RemoveSelectFromObjects();
5297 miUndo
.Enabled
:= UndoBuffer
<> nil;
5301 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5304 CopyBuffer
: TCopyRecArray
;
5308 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5310 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5312 if Result
= 0 then // Одного типа
5313 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5316 procedure QuickSortCopyBuffer(L
, R
: Integer);
5324 P
:= CopyBuffer
[(L
+ R
) shr 1];
5327 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5329 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5335 CopyBuffer
[I
] := CopyBuffer
[J
];
5343 QuickSortCopyBuffer(L
, J
);
5350 if SelectedObjects
= nil then
5356 // Копируем объекты:
5357 for a
:= 0 to High(SelectedObjects
) do
5358 if SelectedObjects
[a
].Live
then
5359 with SelectedObjects
[a
] do
5361 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5362 b
:= High(CopyBuffer
);
5363 CopyBuffer
[b
].ID
:= ID
;
5364 CopyBuffer
[b
].Panel
:= nil;
5369 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5370 New(CopyBuffer
[b
].Panel
);
5371 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5376 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5377 CopyBuffer
[b
].Item
:= gItems
[ID
];
5382 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5383 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5388 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5389 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5394 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5395 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5400 // Сортировка по ID:
5401 if CopyBuffer
<> nil then
5403 QuickSortCopyBuffer(0, b
);
5406 // Пестановка ссылок триггеров:
5407 for a
:= 0 to Length(CopyBuffer
)-1 do
5408 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5410 case CopyBuffer
[a
].Trigger
.TriggerType
of
5411 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5412 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5413 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5414 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5418 for b
:= 0 to Length(CopyBuffer
)-1 do
5419 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5420 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5422 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5427 // Этих панелей нет среди копируемых:
5429 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5432 TRIGGER_PRESS
, TRIGGER_ON
,
5433 TRIGGER_OFF
, TRIGGER_ONOFF
:
5434 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5438 for b
:= 0 to Length(CopyBuffer
)-1 do
5439 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5440 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5442 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5447 // Этих монстров нет среди копируемых:
5449 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5453 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5457 for b
:= 0 to Length(CopyBuffer
)-1 do
5458 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5459 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5461 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5466 // Этих панелей нет среди копируемых:
5468 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5472 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5476 for b
:= 0 to Length(CopyBuffer
)-1 do
5477 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5478 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5480 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5485 // Этих панелей нет среди копируемых:
5487 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5492 str
:= CopyBufferToString(CopyBuffer
);
5493 ClipBoard
.AsText
:= str
;
5495 for a
:= 0 to Length(CopyBuffer
)-1 do
5496 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5497 (CopyBuffer
[a
].Panel
<> nil) then
5498 Dispose(CopyBuffer
[a
].Panel
);
5503 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5506 CopyBuffer
: TCopyRecArray
;
5508 swad
, ssec
, sres
: String;
5514 pmin
.X
:= High(pmin
.X
);
5515 pmin
.Y
:= High(pmin
.Y
);
5517 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
, pmin
);
5518 rel
:= not(ssShift
in GetKeyShiftState());
5520 if CopyBuffer
= nil then
5523 RemoveSelectFromObjects();
5525 h
:= High(CopyBuffer
);
5527 with CopyBuffer
[a
] do
5531 if Panel
<> nil then
5535 Panel
^.X
:= Panel
^.X
- pmin
.X
- MapOffset
.X
+ 32;
5536 Panel
^.Y
:= Panel
^.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5539 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5540 Panel
^.TextureWidth
:= 1;
5541 Panel
^.TextureHeight
:= 1;
5543 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5544 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5545 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5546 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5547 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5548 (Panel
^.TextureName
= '') then
5549 begin // Нет или не может быть текстуры:
5551 else // Есть текстура:
5553 // Обычная текстура:
5554 if not IsSpecialTexture(Panel
^.TextureName
) then
5556 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5560 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5561 AddTexture(swad
, ssec
, sres
, True);
5562 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5566 g_GetTextureSizeByName(Panel
^.TextureName
,
5567 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5569 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5571 Panel
^.TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5572 g_GetTextureSizeByID(NoTextureID
, Panel
^.TextureWidth
, Panel
^.TextureHeight
);
5575 else // Спец.текстура:
5577 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5578 with MainForm
.lbTextureList
.Items
do
5579 if IndexOf(Panel
^.TextureName
) = -1 then
5580 Add(Panel
^.TextureName
);
5584 ID
:= AddPanel(Panel
^);
5586 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5587 SelectObject(OBJECT_PANEL
, ID
, True);
5594 Item
.X
:= Item
.X
- pmin
.X
- MapOffset
.X
+ 32;
5595 Item
.Y
:= Item
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5598 ID
:= AddItem(Item
);
5599 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5600 SelectObject(OBJECT_ITEM
, ID
, True);
5607 Monster
.X
:= Monster
.X
- pmin
.X
- MapOffset
.X
+ 32;
5608 Monster
.Y
:= Monster
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5611 ID
:= AddMonster(Monster
);
5612 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5613 SelectObject(OBJECT_MONSTER
, ID
, True);
5620 Area
.X
:= Area
.X
- pmin
.X
- MapOffset
.X
+ 32;
5621 Area
.Y
:= Area
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5624 ID
:= AddArea(Area
);
5625 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5626 SelectObject(OBJECT_AREA
, ID
, True);
5634 X
:= X
- pmin
.X
- MapOffset
.X
+ 32;
5635 Y
:= Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5640 Data
.TargetPoint
.X
:=
5641 Data
.TargetPoint
.X
- pmin
.X
- MapOffset
.X
+ 32;
5642 Data
.TargetPoint
.Y
:=
5643 Data
.TargetPoint
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5645 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5647 Data
.tX
:= Data
.tX
- pmin
.X
- MapOffset
.X
+ 32;
5648 Data
.tY
:= Data
.tY
- pmin
.Y
- MapOffset
.Y
+ 32;
5650 TRIGGER_SPAWNMONSTER
:
5653 Data
.MonPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5655 Data
.MonPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5660 Data
.ItemPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5662 Data
.ItemPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5667 Data
.ShotPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5669 Data
.ShotPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5674 ID
:= AddTrigger(Trigger
);
5675 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5676 SelectObject(OBJECT_TRIGGER
, ID
, True);
5681 // Переставляем ссылки триггеров:
5682 for a
:= 0 to High(CopyBuffer
) do
5683 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5685 case CopyBuffer
[a
].Trigger
.TriggerType
of
5686 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5687 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5688 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5689 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5690 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5691 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5693 TRIGGER_PRESS
, TRIGGER_ON
,
5694 TRIGGER_OFF
, TRIGGER_ONOFF
:
5695 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5696 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5697 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5700 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5701 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5702 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5705 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5706 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5707 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5716 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5719 DeleteSelectedObjects();
5722 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5724 Key
, FileName
: String;
5727 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5729 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5731 with ChooseTypeForm
, vleObjectProperty
do
5732 begin // Выбор типа панели:
5733 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5734 lbTypeSelect
.Items
.Clear();
5736 for b
:= 0 to High(PANELNAMES
) do
5738 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5739 if Values
[Key
] = PANELNAMES
[b
] then
5740 lbTypeSelect
.ItemIndex
:= b
;
5743 if ShowModal() = mrOK
then
5745 b
:= lbTypeSelect
.ItemIndex
;
5746 Values
[Key
] := PANELNAMES
[b
];
5747 vleObjectPropertyApply(Sender
);
5751 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5752 SelectFlag
:= SELECTFLAG_TELEPORT
5753 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5754 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5755 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5756 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5757 SelectFlag
:= SELECTFLAG_DOOR
5758 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5760 DrawPressRect
:= False;
5761 SelectFlag
:= SELECTFLAG_TEXTURE
;
5763 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5764 SelectFlag
:= SELECTFLAG_SHOTPANEL
5765 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5766 SelectFlag
:= SELECTFLAG_LIFT
5767 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5768 SelectFlag
:= SELECTFLAG_MONSTER
5769 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5771 SelectFlag
:= SELECTFLAG_NONE
;
5772 DrawPressRect
:= True;
5774 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5775 begin // Выбор следующей карты:
5776 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5777 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
5778 SelectMapForm
.GetMaps(FileName
);
5780 if SelectMapForm
.ShowModal() = mrOK
then
5782 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5783 vleObjectPropertyApply(Sender
);
5786 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5787 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5788 begin // Выбор файла звука/музыки:
5789 AddSoundForm
.OKFunction
:= nil;
5790 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5791 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
5793 if (AddSoundForm
.ShowModal() = mrOk
) then
5795 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
5796 vleObjectPropertyApply(Sender
);
5799 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5800 with ActivationTypeForm
, vleObjectProperty
do
5801 begin // Выбор типов активации:
5802 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5803 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5804 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5805 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5806 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5807 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5809 if ShowModal() = mrOK
then
5812 if cbPlayerCollide
.Checked
then
5813 b
:= ACTIVATE_PLAYERCOLLIDE
;
5814 if cbMonsterCollide
.Checked
then
5815 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5816 if cbPlayerPress
.Checked
then
5817 b
:= b
or ACTIVATE_PLAYERPRESS
;
5818 if cbMonsterPress
.Checked
then
5819 b
:= b
or ACTIVATE_MONSTERPRESS
;
5820 if cbShot
.Checked
then
5821 b
:= b
or ACTIVATE_SHOT
;
5822 if cbNoMonster
.Checked
then
5823 b
:= b
or ACTIVATE_NOMONSTER
;
5825 Values
[Key
] := ActivateToStr(b
);
5826 vleObjectPropertyApply(Sender
);
5829 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5830 with KeysForm
, vleObjectProperty
do
5831 begin // Выбор необходимых ключей:
5832 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5833 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5834 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5835 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5836 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5838 if ShowModal() = mrOK
then
5841 if cbRedKey
.Checked
then
5843 if cbGreenKey
.Checked
then
5844 b
:= b
or KEY_GREEN
;
5845 if cbBlueKey
.Checked
then
5847 if cbRedTeam
.Checked
then
5848 b
:= b
or KEY_REDTEAM
;
5849 if cbBlueTeam
.Checked
then
5850 b
:= b
or KEY_BLUETEAM
;
5852 Values
[Key
] := KeyToStr(b
);
5853 vleObjectPropertyApply(Sender
);
5856 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
5857 with ChooseTypeForm
, vleObjectProperty
do
5858 begin // Выбор типа эффекта:
5859 Caption
:= _lc
[I_CAP_FX_TYPE
];
5860 lbTypeSelect
.Items
.Clear();
5862 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
5863 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5865 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
5867 if ShowModal() = mrOK
then
5869 b
:= lbTypeSelect
.ItemIndex
;
5870 Values
[Key
] := EffectToStr(b
);
5871 vleObjectPropertyApply(Sender
);
5874 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
5875 with ChooseTypeForm
, vleObjectProperty
do
5876 begin // Выбор типа монстра:
5877 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
5878 lbTypeSelect
.Items
.Clear();
5880 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
5881 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
5883 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
5885 if ShowModal() = mrOK
then
5887 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
5888 Values
[Key
] := MonsterToStr(b
);
5889 vleObjectPropertyApply(Sender
);
5892 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
5893 with ChooseTypeForm
, vleObjectProperty
do
5894 begin // Выбор типа предмета:
5895 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
5896 lbTypeSelect
.Items
.Clear();
5898 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
5899 lbTypeSelect
.Items
.Add(ItemToStr(b
));
5900 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
5901 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
5902 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
5903 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
5904 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
5905 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
5907 b
:= StrToItem(Values
[Key
]);
5908 if b
>= ITEM_BOTTLE
then
5910 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
5912 if ShowModal() = mrOK
then
5914 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
5915 if b
>= ITEM_WEAPON_KASTET
then
5917 Values
[Key
] := ItemToStr(b
);
5918 vleObjectPropertyApply(Sender
);
5921 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
5922 with ChooseTypeForm
, vleObjectProperty
do
5923 begin // Выбор типа предмета:
5924 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
5925 lbTypeSelect
.Items
.Clear();
5927 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
5928 lbTypeSelect
.Items
.Add(ShotToStr(b
));
5930 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
5932 if ShowModal() = mrOK
then
5934 b
:= lbTypeSelect
.ItemIndex
;
5935 Values
[Key
] := ShotToStr(b
);
5936 vleObjectPropertyApply(Sender
);
5939 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
5940 with ChooseTypeForm
, vleObjectProperty
do
5941 begin // Выбор типа эффекта:
5942 Caption
:= _lc
[I_CAP_FX_TYPE
];
5943 lbTypeSelect
.Items
.Clear();
5945 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
5946 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
5947 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5948 lbTypeSelect
.ItemIndex
:= 1
5950 lbTypeSelect
.ItemIndex
:= 0;
5952 if ShowModal() = mrOK
then
5954 b
:= lbTypeSelect
.ItemIndex
;
5956 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
5958 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
5959 vleObjectPropertyApply(Sender
);
5962 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
5963 with ChooseTypeForm
, vleObjectProperty
do
5964 begin // Выбор подтипа эффекта:
5965 Caption
:= _lc
[I_CAP_FX_TYPE
];
5966 lbTypeSelect
.Items
.Clear();
5968 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5970 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
5971 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5973 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
5976 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
5977 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
5978 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
5979 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
5980 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
5981 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
5982 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
5983 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5984 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
5985 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5986 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
5987 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5988 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
5989 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5990 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
5991 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5992 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
5995 if ShowModal() = mrOK
then
5997 b
:= lbTypeSelect
.ItemIndex
;
5999 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6000 Values
[Key
] := EffectToStr(b
+ 1)
6002 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
6003 if b
= TRIGGER_EFFECT_LLIQUID
then
6004 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
6005 if b
= TRIGGER_EFFECT_DLIQUID
then
6006 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
6007 if b
= TRIGGER_EFFECT_BLOOD
then
6008 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
6009 if b
= TRIGGER_EFFECT_SPARK
then
6010 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
6011 if b
= TRIGGER_EFFECT_BUBBLE
then
6012 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
6015 vleObjectPropertyApply(Sender
);
6018 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
6019 with vleObjectProperty
do
6020 begin // Выбор цвета эффекта:
6021 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
6022 if ColorDialog
.Execute
then
6024 Values
[Key
] := IntToStr(ColorDialog
.Color
);
6025 vleObjectPropertyApply(Sender
);
6028 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
6029 begin // Смена текстуры:
6030 vleObjectProperty
.Values
[Key
] := SelectedTexture();
6031 vleObjectPropertyApply(Sender
);
6035 procedure TMainForm
.vleObjectPropertyApply(Sender
: TObject
);
6037 // hack to prevent empty ID in list
6038 RenderPanel
.SetFocus();
6039 bApplyProperty
.Click();
6040 vleObjectProperty
.SetFocus();
6043 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
6045 FileName
, Section
, Res
: String;
6047 if OpenedMap
= '' then
6049 aSaveMapAsExecute(nil);
6053 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
6055 SaveMap(FileName
+':\'+Res
);
6058 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
6060 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
6062 if OpenDialog
.Execute() then
6064 OpenMapFile(OpenDialog
.FileName
);
6065 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
6069 procedure TMainForm
.OpenMapFile(FileName
: String);
6071 if (Pos('.ini', LowerCase(ExtractFileName(FileName
))) > 0) then
6075 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
6076 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
6077 pLoadProgress
.Show();
6082 LoadMapOld(FileName
);
6084 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(FileName
)]);
6086 pLoadProgress
.Hide();
6087 MainForm
.FormResize(Self
);
6089 else // Карты из WAD:
6091 OpenMap(FileName
, '');
6095 procedure TMainForm
.FormActivate(Sender
: TObject
);
6100 MainForm
.ActiveControl
:= RenderPanel
;
6103 if gLanguage
= '' then
6105 lang
:= SelectLanguageForm
.ShowModal();
6107 1: gLanguage
:= LANGUAGE_ENGLISH
;
6108 else gLanguage
:= LANGUAGE_RUSSIAN
;
6111 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
6112 config
.WriteStr('Editor', 'Language', gLanguage
);
6113 config
.SaveFile(EditorDir
+'Editor.cfg');
6117 //e_WriteLog('Read language file', MSG_NOTIFY);
6118 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
6119 g_Language_Set(gLanguage
);
6122 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
6130 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6132 if not OpenDialog
.Execute() then
6135 WAD
:= TWADEditor_1
.Create();
6137 if not WAD
.ReadFile(OpenDialog
.FileName
) then
6145 MapList
:= WAD
.GetResourcesList('');
6147 SelectMapForm
.Caption
:= _lc
[I_CAP_REMOVE
];
6148 SelectMapForm
.lbMapList
.Items
.Clear();
6150 if MapList
<> nil then
6151 for a
:= 0 to High(MapList
) do
6152 SelectMapForm
.lbMapList
.Items
.Add(win2utf(MapList
[a
]));
6154 if (SelectMapForm
.ShowModal() = mrOK
) then
6156 str
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6158 Move(str
[1], MapName
[0], Min(16, Length(str
)));
6160 if MessageBox(0, PChar(Format(_lc
[I_MSG_DELETE_MAP_PROMT
],
6161 [MapName
, OpenDialog
.FileName
])),
6162 PChar(_lc
[I_MSG_DELETE_MAP
]),
6163 MB_ICONQUESTION
or MB_YESNO
or
6164 MB_DEFBUTTON2
) <> mrYes
then
6167 WAD
.RemoveResource('', utf2win(MapName
));
6169 MessageBox(0, PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
],
6171 PChar(_lc
[I_MSG_MAP_DELETED
]),
6172 MB_ICONINFORMATION
or MB_OK
or
6175 WAD
.SaveTo(OpenDialog
.FileName
);
6177 // Удалили текущую карту - сохранять по старому ее нельзя:
6178 if OpenedMap
= (OpenDialog
.FileName
+':\'+MapName
) then
6182 MainForm
.Caption
:= FormCaption
;
6189 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
6190 var Key
: Word; Shift
: TShiftState
);
6192 if Key
= VK_RETURN
then
6193 vleObjectPropertyApply(Sender
);
6196 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
6201 if (ID
= 0) and (MoveType
= 0) then
6203 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
6205 if (ID
> DWORD(High(gPanels
))) then
6210 if MoveType
= 0 then // to Back
6212 if gTriggers
<> nil then
6213 for a
:= 0 to High(gTriggers
) do
6214 with gTriggers
[a
] do
6216 if TriggerType
= TRIGGER_NONE
then
6219 if TexturePanel
= _id
then
6222 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
6226 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6227 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6228 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6229 if Data
.PanelID
= _id
then
6232 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
6236 if Data
.ShotPanelID
= _id
then
6237 Data
.ShotPanelID
:= 0
6239 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
6240 Inc(Data
.ShotPanelID
);
6244 tmp
:= gPanels
[_id
];
6246 for a
:= _id
downto 1 do
6247 gPanels
[a
] := gPanels
[a
-1];
6255 if gTriggers
<> nil then
6256 for a
:= 0 to High(gTriggers
) do
6257 with gTriggers
[a
] do
6259 if TriggerType
= TRIGGER_NONE
then
6262 if TexturePanel
= _id
then
6263 TexturePanel
:= High(gPanels
)
6265 if TexturePanel
> _id
then
6269 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6270 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6271 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6272 if Data
.PanelID
= _id
then
6273 Data
.PanelID
:= High(gPanels
)
6275 if Data
.PanelID
> _id
then
6279 if Data
.ShotPanelID
= _id
then
6280 Data
.ShotPanelID
:= High(gPanels
)
6282 if Data
.ShotPanelID
> _id
then
6283 Dec(Data
.ShotPanelID
);
6287 tmp
:= gPanels
[_id
];
6289 for a
:= _id
to High(gPanels
)-1 do
6290 gPanels
[a
] := gPanels
[a
+1];
6292 gPanels
[High(gPanels
)] := tmp
;
6294 ID
:= High(gPanels
);
6298 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6302 if SelectedObjects
= nil then
6305 for a
:= 0 to High(SelectedObjects
) do
6306 with SelectedObjects
[a
] do
6307 if Live
and (ObjectType
= OBJECT_PANEL
) then
6309 SelectedObjects
[0] := SelectedObjects
[a
];
6310 SetLength(SelectedObjects
, 1);
6317 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6321 if SelectedObjects
= nil then
6324 for a
:= 0 to High(SelectedObjects
) do
6325 with SelectedObjects
[a
] do
6326 if Live
and (ObjectType
= OBJECT_PANEL
) then
6328 SelectedObjects
[0] := SelectedObjects
[a
];
6329 SetLength(SelectedObjects
, 1);
6336 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6340 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6342 if not SaveDialog
.Execute() then
6345 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6347 if SaveMapForm
.ShowModal() <> mrOK
then
6350 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6351 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6352 OpenedWAD
:= SaveDialog
.FileName
;
6354 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6355 // Такая карта уже недавно открывалась:
6357 RecentFiles
.Delete(idx
);
6358 RecentFiles
.Insert(0, OpenedMap
);
6363 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6364 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6365 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6368 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6372 RemoveSelectFromObjects();
6374 case pcObjects
.ActivePageIndex
+1 of
6376 if gPanels
<> nil then
6377 for a
:= 0 to High(gPanels
) do
6378 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6379 SelectObject(OBJECT_PANEL
, a
, True);
6381 if gItems
<> nil then
6382 for a
:= 0 to High(gItems
) do
6383 if gItems
[a
].ItemType
<> ITEM_NONE
then
6384 SelectObject(OBJECT_ITEM
, a
, True);
6386 if gMonsters
<> nil then
6387 for a
:= 0 to High(gMonsters
) do
6388 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6389 SelectObject(OBJECT_MONSTER
, a
, True);
6391 if gAreas
<> nil then
6392 for a
:= 0 to High(gAreas
) do
6393 if gAreas
[a
].AreaType
<> AREA_NONE
then
6394 SelectObject(OBJECT_AREA
, a
, True);
6396 if gTriggers
<> nil then
6397 for a
:= 0 to High(gTriggers
) do
6398 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6399 SelectObject(OBJECT_TRIGGER
, a
, True);
6403 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6405 DotEnable
:= not DotEnable
;
6406 (Sender
as TToolButton
).Down
:= DotEnable
;
6409 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6411 // FIXME: this is a shitty hack
6412 if not gDataLoaded
then
6414 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6416 e_WriteLog('Loading data', MSG_NOTIFY
);
6417 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6418 e_WriteLog('Loading more data', MSG_NOTIFY
);
6420 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6421 gDataLoaded
:= True;
6422 MainForm
.FormResize(nil);
6427 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6429 if PreviewMode
= 2 then
6432 if PreviewMode
= 0 then
6434 Splitter2
.Visible
:= False;
6435 Splitter1
.Visible
:= False;
6436 StatusBar
.Visible
:= False;
6437 PanelObjs
.Visible
:= False;
6438 PanelProps
.Visible
:= False;
6439 MainToolBar
.Visible
:= False;
6440 sbHorizontal
.Visible
:= False;
6441 sbVertical
.Visible
:= False;
6445 StatusBar
.Visible
:= True;
6446 PanelObjs
.Visible
:= True;
6447 PanelProps
.Visible
:= True;
6448 Splitter2
.Visible
:= True;
6449 Splitter1
.Visible
:= True;
6450 MainToolBar
.Visible
:= True;
6451 sbHorizontal
.Visible
:= True;
6452 sbVertical
.Visible
:= True;
6455 PreviewMode
:= PreviewMode
xor 1;
6456 (Sender
as TMenuItem
).Checked
:= PreviewMode
> 0;
6461 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6463 SwitchLayer(LAYER_BACK
);
6466 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6468 SwitchLayer(LAYER_WALLS
);
6471 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6473 SwitchLayer(LAYER_FOREGROUND
);
6476 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6478 SwitchLayer(LAYER_STEPS
);
6481 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6483 SwitchLayer(LAYER_WATER
);
6486 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6488 SwitchLayer(LAYER_ITEMS
);
6491 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6493 SwitchLayer(LAYER_MONSTERS
);
6496 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6498 SwitchLayer(LAYER_AREAS
);
6501 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6503 SwitchLayer(LAYER_TRIGGERS
);
6506 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6512 for a
:= 0 to High(LayerEnabled
) do
6513 b
:= b
and LayerEnabled
[a
];
6517 ShowLayer(LAYER_BACK
, b
);
6518 ShowLayer(LAYER_WALLS
, b
);
6519 ShowLayer(LAYER_FOREGROUND
, b
);
6520 ShowLayer(LAYER_STEPS
, b
);
6521 ShowLayer(LAYER_WATER
, b
);
6522 ShowLayer(LAYER_ITEMS
, b
);
6523 ShowLayer(LAYER_MONSTERS
, b
);
6524 ShowLayer(LAYER_AREAS
, b
);
6525 ShowLayer(LAYER_TRIGGERS
, b
);
6528 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6533 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6535 if DotStep
= DotStepOne
then
6536 DotStep
:= DotStepTwo
6538 DotStep
:= DotStepOne
;
6540 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6541 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6544 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6549 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6551 SnapToGrid
:= not SnapToGrid
;
6553 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6554 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6556 miSnapToGrid
.Checked
:= SnapToGrid
;
6559 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6561 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6562 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6564 pcObjects
.ActivePageIndex
:= 0;
6567 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6569 SaveMiniMapForm
.ShowModal();
6572 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6574 lbTextureList
.ItemIndex
:= -1;
6575 lTextureWidth
.Caption
:= '';
6576 lTextureHeight
.Caption
:= '';
6579 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6581 PackMapForm
.ShowModal();
6584 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6586 MapTestForm
.ShowModal();
6589 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6591 cmd
, mapWAD
, mapToRun
, tempWAD
: String;
6598 if OpenedMap
<> '' then
6600 // Указываем текущую карту для теста:
6601 g_ProcessResourceStr(OpenedMap
, @mapWAD
, nil, @mapToRun
);
6602 mapToRun
:= mapWAD
+ ':\' + mapToRun
;
6603 mapToRun
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', mapToRun
);
6605 // Сохраняем временную карту:
6608 mapWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps/temp%.4d.wad', [time
]);
6610 until not FileExists(mapWAD
);
6611 tempWAD
:= mapWAD
+ ':\' + TEST_MAP_NAME
;
6614 tempWAD
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', tempWAD
);
6615 // Если карта не была открыта, указываем временную в качестве текущей:
6616 if mapToRun
= '' then
6617 mapToRun
:= tempWAD
;
6621 if TestOptionsTwoPlayers
then
6623 if TestOptionsTeamDamage
then
6625 if TestOptionsAllowExit
then
6627 if TestOptionsWeaponStay
then
6629 if TestOptionsMonstersDM
then
6632 // Составляем командную строку:
6633 cmd
:= '-map "' + mapToRun
+ '"';
6634 cmd
:= cmd
+ ' -testmap "' + tempWAD
+ '"';
6635 cmd
:= cmd
+ ' -gm ' + TestGameMode
;
6636 cmd
:= cmd
+ ' -limt ' + TestLimTime
;
6637 cmd
:= cmd
+ ' -lims ' + TestLimScore
;
6638 cmd
:= cmd
+ ' -opt ' + IntToStr(opt
);
6641 cmd
:= cmd
+ ' --close';
6643 cmd
:= cmd
+ ' --debug';
6646 proc
:= TProcessUTF8
.Create(nil);
6647 proc
.Executable
:= TestD2dExe
;
6648 proc
.Parameters
.Add(cmd
);
6657 Application
.Minimize();
6660 if (not res
) or (proc
.ExitCode
< 0) then
6662 MessageBox(0, 'FIXME',
6663 PChar(_lc
[I_MSG_EXEC_ERROR
]),
6664 MB_OK
or MB_ICONERROR
);
6668 SysUtils
.DeleteFile(mapWAD
);
6669 Application
.Restore();
6672 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6673 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6675 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
6678 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6679 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6681 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
6684 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6686 if OpenedWAD
<> '' then
6688 OpenMap(OpenedWAD
, '');
6692 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6696 RemoveSelectFromObjects();
6698 if gPanels
<> nil then
6699 for a
:= 0 to High(gPanels
) do
6700 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6701 SelectObject(OBJECT_PANEL
, a
, True);
6703 if gItems
<> nil then
6704 for a
:= 0 to High(gItems
) do
6705 if gItems
[a
].ItemType
<> ITEM_NONE
then
6706 SelectObject(OBJECT_ITEM
, a
, True);
6708 if gMonsters
<> nil then
6709 for a
:= 0 to High(gMonsters
) do
6710 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6711 SelectObject(OBJECT_MONSTER
, a
, True);
6713 if gAreas
<> nil then
6714 for a
:= 0 to High(gAreas
) do
6715 if gAreas
[a
].AreaType
<> AREA_NONE
then
6716 SelectObject(OBJECT_AREA
, a
, True);
6718 if gTriggers
<> nil then
6719 for a
:= 0 to High(gTriggers
) do
6720 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6721 SelectObject(OBJECT_TRIGGER
, a
, True);
6724 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6725 var NewSize
: Integer; var Accept
: Boolean);
6727 Accept
:= (NewSize
> 140);
6730 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6731 var NewSize
: Integer; var Accept
: Boolean);
6733 Accept
:= (NewSize
> 110);
6736 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6738 EditingProperties
:= True;
6741 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6743 EditingProperties
:= False;
6746 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word;
6747 Shift
: TShiftState
);
6749 // Объекты передвигались:
6750 if MainForm
.ActiveControl
= RenderPanel
then
6752 if (Key
= VK_NUMPAD4
) or
6753 (Key
= VK_NUMPAD6
) or
6754 (Key
= VK_NUMPAD8
) or
6755 (Key
= VK_NUMPAD5
) or
6756 (Key
= Ord('V')) then
6759 // Быстрое превью карты:
6760 if Key
= Ord('E') then
6762 if PreviewMode
= 2 then
6765 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);