3 {$INCLUDE ../shared/a_modes.inc}
8 LCLIntf
, LCLType
, SysUtils
, Variants
, Classes
, Graphics
,
9 Controls
, Forms
, Dialogs
, StdCtrls
, Buttons
,
10 ComCtrls
, ValEdit
, Types
, Menus
, ExtCtrls
,
11 CheckLst
, Grids
, OpenGLContext
, utils
, UTF8Process
;
17 TMainForm
= class(TForm
)
22 miMenuFile
: TMenuItem
;
26 miSaveMapAs
: TMenuItem
;
27 miOpenWadMap
: TMenuItem
;
29 miReopenMap
: TMenuItem
;
30 miSaveMiniMap
: TMenuItem
;
31 miDeleteMap
: TMenuItem
;
36 miMenuEdit
: TMenuItem
;
43 miSelectAll
: TMenuItem
;
48 miMenuTools
: TMenuItem
;
49 miSnapToGrid
: TMenuItem
;
51 miSwitchGrid
: TMenuItem
;
52 miShowEdges
: TMenuItem
;
64 miMenuService
: TMenuItem
;
65 miCheckMap
: TMenuItem
;
66 miOptimmization
: TMenuItem
;
67 miMapPreview
: TMenuItem
;
70 miMenuSettings
: TMenuItem
;
71 miMapOptions
: TMenuItem
;
75 miMapTestSettings
: TMenuItem
;
77 miMenuHelp
: TMenuItem
;
79 // Скрытый пункт меню для Ctrl+Tab:
83 // Панель инструментов:
84 MainToolBar
: TToolBar
;
86 pLoadProgress
: TPanel
;
87 RenderPanel
: TOpenGLControl
;
88 tbNewMap
: TToolButton
;
89 tbOpenMap
: TToolButton
;
90 tbSaveMap
: TToolButton
;
91 tbOpenWadMap
: TToolButton
;
93 tbShowMap
: TToolButton
;
97 tbGridOn
: TToolButton
;
100 tbTestMap
: TToolButton
;
101 // Всплывающее меню для кнопки слоев:
103 miLayerP1
: TMenuItem
;
104 miLayerP2
: TMenuItem
;
105 miLayerP3
: TMenuItem
;
106 miLayerP4
: TMenuItem
;
107 miLayerP5
: TMenuItem
;
108 miLayerP6
: TMenuItem
;
109 miLayerP7
: TMenuItem
;
110 miLayerP8
: TMenuItem
;
111 miLayerP9
: TMenuItem
;
112 // Всплывающее меню для кнопки теста карты:
113 pmMapTest
: TPopupMenu
;
114 miMapTestPMSet
: TMenuItem
;
119 sbHorizontal
: TScrollBar
;
120 sbVertical
: TScrollBar
;
124 // Панель применения свойств:
125 PanelPropApply
: TPanel
;
126 bApplyProperty
: TButton
;
127 // Редактор свойств объектов:
128 vleObjectProperty
: TValueListEditor
;
130 // Панель объектов - вкладки:
132 pcObjects
: TPageControl
;
135 lbTextureList
: TListBox
;
136 // Панель настройки текстур:
137 PanelTextures
: TPanel
;
139 lTextureWidth
: TLabel
;
141 lTextureHeight
: TLabel
;
142 cbPreview
: TCheckBox
;
143 bbAddTexture
: TBitBtn
;
144 bbRemoveTexture
: TBitBtn
;
145 bClearTexture
: TButton
;
146 // Панель типов панелей:
147 PanelPanelType
: TPanel
;
148 lbPanelType
: TListBox
;
149 // Вкладка "Предметы":
151 lbItemList
: TListBox
;
154 // Вкладка "Монстры":
155 tsMonsters
: TTabSheet
;
156 lbMonsterList
: TListBox
;
157 rbMonsterLeft
: TRadioButton
;
158 rbMonsterRight
: TRadioButton
;
159 // Вкладка "Области":
161 lbAreasList
: TListBox
;
162 rbAreaLeft
: TRadioButton
;
163 rbAreaRight
: TRadioButton
;
164 // Вкладка "Триггеры":
165 tsTriggers
: TTabSheet
;
166 lbTriggersList
: TListBox
;
167 clbActivationType
: TCheckListBox
;
168 clbKeys
: TCheckListBox
;
171 Splitter1
: TSplitter
;
172 Splitter2
: TSplitter
;
173 StatusBar
: TStatusBar
;
175 // Специальные объекты:
176 ImageList
: TImageList
;
177 ilToolbar
: TImageList
;
178 OpenDialog
: TOpenDialog
;
179 SaveDialog
: TSaveDialog
;
180 selectall1
: TMenuItem
;
181 ColorDialog
: TColorDialog
;
183 procedure aAboutExecute(Sender
: TObject
);
184 procedure aCheckMapExecute(Sender
: TObject
);
185 procedure aMoveToFore(Sender
: TObject
);
186 procedure aMoveToBack(Sender
: TObject
);
187 procedure aCopyObjectExecute(Sender
: TObject
);
188 procedure aCutObjectExecute(Sender
: TObject
);
189 procedure aEditorOptionsExecute(Sender
: TObject
);
190 procedure aExitExecute(Sender
: TObject
);
191 procedure aMapOptionsExecute(Sender
: TObject
);
192 procedure aNewMapExecute(Sender
: TObject
);
193 procedure aOpenMapExecute(Sender
: TObject
);
194 procedure aOptimizeExecute(Sender
: TObject
);
195 procedure aPasteObjectExecute(Sender
: TObject
);
196 procedure aSelectAllExecute(Sender
: TObject
);
197 procedure aSaveMapExecute(Sender
: TObject
);
198 procedure aSaveMapAsExecute(Sender
: TObject
);
199 procedure aUndoExecute(Sender
: TObject
);
200 procedure aDeleteMap(Sender
: TObject
);
201 procedure bApplyPropertyClick(Sender
: TObject
);
202 procedure bbAddTextureClick(Sender
: TObject
);
203 procedure bbRemoveTextureClick(Sender
: TObject
);
204 procedure FormActivate(Sender
: TObject
);
205 procedure FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
206 procedure FormCreate(Sender
: TObject
);
207 procedure FormDestroy(Sender
: TObject
);
208 procedure FormDropFiles(Sender
: TObject
; const FileNames
: array of String);
209 procedure FormKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
);
210 procedure FormResize(Sender
: TObject
);
211 procedure lbTextureListClick(Sender
: TObject
);
212 procedure lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
213 ARect
: TRect
; State
: TOwnerDrawState
);
214 procedure miReopenMapClick(Sender
: TObject
);
215 procedure RenderPanelMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
216 procedure RenderPanelMouseMove(Sender
: TObject
; Shift
: TShiftState
; X
, Y
: Integer);
217 procedure RenderPanelMouseUp(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
218 procedure RenderPanelPaint(Sender
: TObject
);
219 procedure RenderPanelResize(Sender
: TObject
);
220 procedure Splitter1Moved(Sender
: TObject
);
221 procedure vleObjectPropertyEditButtonClick(Sender
: TObject
);
222 procedure vleObjectPropertyApply(Sender
: TObject
);
223 procedure vleObjectPropertyGetPickList(Sender
: TObject
; const KeyName
: String; Values
: TStrings
);
224 procedure vleObjectPropertyKeyDown(Sender
: TObject
; var Key
: Word;
226 procedure tbGridOnClick(Sender
: TObject
);
227 procedure miMapPreviewClick(Sender
: TObject
);
228 procedure miLayer1Click(Sender
: TObject
);
229 procedure miLayer2Click(Sender
: TObject
);
230 procedure miLayer3Click(Sender
: TObject
);
231 procedure miLayer4Click(Sender
: TObject
);
232 procedure miLayer5Click(Sender
: TObject
);
233 procedure miLayer6Click(Sender
: TObject
);
234 procedure miLayer7Click(Sender
: TObject
);
235 procedure miLayer8Click(Sender
: TObject
);
236 procedure miLayer9Click(Sender
: TObject
);
237 procedure tbShowClick(Sender
: TObject
);
238 procedure miSnapToGridClick(Sender
: TObject
);
239 procedure miMiniMapClick(Sender
: TObject
);
240 procedure miSwitchGridClick(Sender
: TObject
);
241 procedure miShowEdgesClick(Sender
: TObject
);
242 procedure minexttabClick(Sender
: TObject
);
243 procedure miSaveMiniMapClick(Sender
: TObject
);
244 procedure bClearTextureClick(Sender
: TObject
);
245 procedure miPackMapClick(Sender
: TObject
);
246 procedure aRecentFileExecute(Sender
: TObject
);
247 procedure miMapTestSettingsClick(Sender
: TObject
);
248 procedure miTestMapClick(Sender
: TObject
);
249 procedure sbVerticalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
250 var ScrollPos
: Integer);
251 procedure sbHorizontalScroll(Sender
: TObject
; ScrollCode
: TScrollCode
;
252 var ScrollPos
: Integer);
253 procedure miOpenWadMapClick(Sender
: TObject
);
254 procedure selectall1Click(Sender
: TObject
);
255 procedure Splitter1CanResize(Sender
: TObject
; var NewSize
: Integer;
256 var Accept
: Boolean);
257 procedure Splitter2CanResize(Sender
: TObject
; var NewSize
: Integer;
258 var Accept
: Boolean);
259 procedure vleObjectPropertyEnter(Sender
: TObject
);
260 procedure vleObjectPropertyExit(Sender
: TObject
);
261 procedure FormKeyUp(Sender
: TObject
; var Key
: Word;
265 procedure OnIdle(Sender
: TObject
; var Done
: Boolean);
267 procedure RefreshRecentMenu();
268 procedure OpenMapFile(FileName
: String);
269 function RenderMousePos(): TPoint
;
270 procedure RecountSelectedObjects();
276 LAYER_FOREGROUND
= 2;
284 TEST_MAP_NAME
= '$$$_TEST_$$$';
285 LANGUAGE_FILE_NAME
= '_Editor.txt';
296 DotStepOne
, DotStepTwo
: Byte;
298 DrawTexturePanel
: Boolean;
299 DrawPanelSize
: Boolean;
301 PreviewColor
: TColor
;
302 UseCheckerboard
: Boolean;
304 RecentCount
: Integer;
305 RecentFiles
: TStringList
;
306 slInvalidTextures
: TStringList
;
308 TestGameMode
: String;
310 TestLimScore
: String;
311 TestOptionsTwoPlayers
: Boolean;
312 TestOptionsTeamDamage
: Boolean;
313 TestOptionsAllowExit
: Boolean;
314 TestOptionsWeaponStay
: Boolean;
315 TestOptionsMonstersDM
: Boolean;
317 TestMapOnce
: Boolean;
319 LayerEnabled
: Array [LAYER_BACK
..LAYER_TRIGGERS
] of Boolean =
320 (True, True, True, True, True, True, True, True, True);
321 PreviewMode
: Byte = 0;
327 procedure OpenMap(FileName
: String; mapN
: String);
328 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
329 procedure RemoveSelectFromObjects();
330 procedure ChangeShownProperty(Name
: String; NewValue
: String);
335 f_options
, e_graphics
, e_log
, GL
, Math
,
336 f_mapoptions
, g_basic
, f_about
, f_mapoptimization
,
337 f_mapcheck
, f_addresource_texture
, g_textures
,
338 f_activationtype
, f_keys
,
339 MAPREADER
, f_selectmap
, f_savemap
, WADEDITOR
, WADSTRUCT
, MAPDEF
,
340 g_map
, f_saveminimap
, f_addresource
, CONFIG
, f_packmap
,
341 f_addresource_sound
, f_maptest
, f_choosetype
,
342 g_language
, f_selectlang
, ClipBrd
;
345 UNDO_DELETE_PANEL
= 1;
346 UNDO_DELETE_ITEM
= 2;
347 UNDO_DELETE_AREA
= 3;
348 UNDO_DELETE_MONSTER
= 4;
349 UNDO_DELETE_TRIGGER
= 5;
353 UNDO_ADD_MONSTER
= 9;
354 UNDO_ADD_TRIGGER
= 10;
355 UNDO_MOVE_PANEL
= 11;
358 UNDO_MOVE_MONSTER
= 14;
359 UNDO_MOVE_TRIGGER
= 15;
360 UNDO_RESIZE_PANEL
= 16;
361 UNDO_RESIZE_TRIGGER
= 17;
363 MOUSEACTION_NONE
= 0;
364 MOUSEACTION_DRAWPANEL
= 1;
365 MOUSEACTION_DRAWTRIGGER
= 2;
366 MOUSEACTION_MOVEOBJ
= 3;
367 MOUSEACTION_RESIZE
= 4;
368 MOUSEACTION_MOVEMAP
= 5;
369 MOUSEACTION_DRAWPRESS
= 6;
370 MOUSEACTION_NOACTION
= 7;
373 RESIZETYPE_VERTICAL
= 1;
374 RESIZETYPE_HORIZONTAL
= 2;
383 SELECTFLAG_TELEPORT
= 1;
385 SELECTFLAG_TEXTURE
= 3;
387 SELECTFLAG_MONSTER
= 5;
388 SELECTFLAG_SPAWNPOINT
= 6;
389 SELECTFLAG_SHOTPANEL
= 7;
390 SELECTFLAG_SELECTED
= 8;
392 RECENT_FILES_MENU_START
= 12;
394 CLIPBOARD_SIG
= 'DF:ED';
400 UNDO_DELETE_PANEL
: (Panel
: ^TPanel
);
401 UNDO_DELETE_ITEM
: (Item
: TItem
);
402 UNDO_DELETE_AREA
: (Area
: TArea
);
403 UNDO_DELETE_MONSTER
: (Monster
: TMonster
);
404 UNDO_DELETE_TRIGGER
: (Trigger
: TTrigger
);
409 UNDO_ADD_TRIGGER
: (AddID
: DWORD
);
414 UNDO_MOVE_TRIGGER
: (MoveID
: DWORD
; dX
, dY
: Integer);
416 UNDO_RESIZE_TRIGGER
: (ResizeID
: DWORD
; dW
, dH
: Integer);
423 OBJECT_PANEL
: (Panel
: ^TPanel
);
424 OBJECT_ITEM
: (Item
: TItem
);
425 OBJECT_AREA
: (Area
: TArea
);
426 OBJECT_MONSTER
: (Monster
: TMonster
);
427 OBJECT_TRIGGER
: (Trigger
: TTrigger
);
430 TCopyRecArray
= Array of TCopyRec
;
434 gDataLoaded
: Boolean = False;
435 ShowMap
: Boolean = False;
436 DrawRect
: PRect
= nil;
437 SnapToGrid
: Boolean = True;
439 MousePos
: Types
.TPoint
;
440 LastMovePoint
: Types
.TPoint
;
443 MouseLDownPos
: Types
.TPoint
;
444 MouseRDownPos
: Types
.TPoint
;
447 SelectFlag
: Byte = SELECTFLAG_NONE
;
448 MouseAction
: Byte = MOUSEACTION_NONE
;
449 ResizeType
: Byte = RESIZETYPE_NONE
;
450 ResizeDirection
: Byte = RESIZEDIR_NONE
;
452 DrawPressRect
: Boolean = False;
453 EditingProperties
: Boolean = False;
455 UndoBuffer
: Array of Array of TUndoRec
= nil;
460 //----------------------------------------
461 //Далее идут вспомогательные процедуры
462 //----------------------------------------
464 function NameToBool(Name
: String): Boolean;
466 if Name
= BoolNames
[True] then
472 function NameToDir(Name
: String): TDirection
;
474 if Name
= DirNames
[D_LEFT
] then
480 function NameToDirAdv(Name
: String): Byte;
482 if Name
= DirNamesAdv
[1] then
485 if Name
= DirNamesAdv
[2] then
488 if Name
= DirNamesAdv
[3] then
494 function ActivateToStr(ActivateType
: Byte): String;
498 if ByteBool(ACTIVATE_PLAYERCOLLIDE
and ActivateType
) then
499 Result
:= Result
+ '+PC';
500 if ByteBool(ACTIVATE_MONSTERCOLLIDE
and ActivateType
) then
501 Result
:= Result
+ '+MC';
502 if ByteBool(ACTIVATE_PLAYERPRESS
and ActivateType
) then
503 Result
:= Result
+ '+PP';
504 if ByteBool(ACTIVATE_MONSTERPRESS
and ActivateType
) then
505 Result
:= Result
+ '+MP';
506 if ByteBool(ACTIVATE_SHOT
and ActivateType
) then
507 Result
:= Result
+ '+SH';
508 if ByteBool(ACTIVATE_NOMONSTER
and ActivateType
) then
509 Result
:= Result
+ '+NM';
511 if (Result
<> '') and (Result
[1] = '+') then
512 Delete(Result
, 1, 1);
515 function StrToActivate(Str
: String): Byte;
519 if Pos('PC', Str
) > 0 then
520 Result
:= ACTIVATE_PLAYERCOLLIDE
;
521 if Pos('MC', Str
) > 0 then
522 Result
:= Result
or ACTIVATE_MONSTERCOLLIDE
;
523 if Pos('PP', Str
) > 0 then
524 Result
:= Result
or ACTIVATE_PLAYERPRESS
;
525 if Pos('MP', Str
) > 0 then
526 Result
:= Result
or ACTIVATE_MONSTERPRESS
;
527 if Pos('SH', Str
) > 0 then
528 Result
:= Result
or ACTIVATE_SHOT
;
529 if Pos('NM', Str
) > 0 then
530 Result
:= Result
or ACTIVATE_NOMONSTER
;
533 function KeyToStr(Key
: Byte): String;
537 if ByteBool(KEY_RED
and Key
) then
538 Result
:= Result
+ '+RK';
539 if ByteBool(KEY_GREEN
and Key
) then
540 Result
:= Result
+ '+GK';
541 if ByteBool(KEY_BLUE
and Key
) then
542 Result
:= Result
+ '+BK';
543 if ByteBool(KEY_REDTEAM
and Key
) then
544 Result
:= Result
+ '+RT';
545 if ByteBool(KEY_BLUETEAM
and Key
) then
546 Result
:= Result
+ '+BT';
548 if (Result
<> '') and (Result
[1] = '+') then
549 Delete(Result
, 1, 1);
552 function StrToKey(Str
: String): Byte;
556 if Pos('RK', Str
) > 0 then
558 if Pos('GK', Str
) > 0 then
559 Result
:= Result
or KEY_GREEN
;
560 if Pos('BK', Str
) > 0 then
561 Result
:= Result
or KEY_BLUE
;
562 if Pos('RT', Str
) > 0 then
563 Result
:= Result
or KEY_REDTEAM
;
564 if Pos('BT', Str
) > 0 then
565 Result
:= Result
or KEY_BLUETEAM
;
568 function EffectToStr(Effect
: Byte): String;
570 if Effect
in [EFFECT_TELEPORT
..EFFECT_FIRE
] then
571 Result
:= EffectNames
[Effect
]
573 Result
:= EffectNames
[EFFECT_NONE
];
576 function StrToEffect(Str
: String): Byte;
580 Result
:= EFFECT_NONE
;
581 for i
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
582 if EffectNames
[i
] = Str
then
589 function MonsterToStr(MonType
: Byte): String;
591 if MonType
in [MONSTER_DEMON
..MONSTER_MAN
] then
592 Result
:= MonsterNames
[MonType
]
594 Result
:= MonsterNames
[MONSTER_ZOMBY
];
597 function StrToMonster(Str
: String): Byte;
601 Result
:= MONSTER_ZOMBY
;
602 for i
:= MONSTER_DEMON
to MONSTER_MAN
do
603 if MonsterNames
[i
] = Str
then
610 function ItemToStr(ItemType
: Byte): String;
612 if ItemType
in [ITEM_MEDKIT_SMALL
..ITEM_MAX
] then
613 Result
:= ItemNames
[ItemType
]
615 Result
:= ItemNames
[ITEM_AMMO_BULLETS
];
618 function StrToItem(Str
: String): Byte;
622 Result
:= ITEM_AMMO_BULLETS
;
623 for i
:= ITEM_MEDKIT_SMALL
to ITEM_MAX
do
624 if ItemNames
[i
] = Str
then
631 function ShotToStr(ShotType
: Byte): String;
633 if ShotType
in [TRIGGER_SHOT_PISTOL
..TRIGGER_SHOT_MAX
] then
634 Result
:= ShotNames
[ShotType
]
636 Result
:= ShotNames
[TRIGGER_SHOT_PISTOL
];
639 function StrToShot(Str
: String): Byte;
643 Result
:= TRIGGER_SHOT_PISTOL
;
644 for i
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
645 if ShotNames
[i
] = Str
then
652 function SelectedObjectCount(): Word;
658 if SelectedObjects
= nil then
661 for a
:= 0 to High(SelectedObjects
) do
662 if SelectedObjects
[a
].Live
then
663 Result
:= Result
+ 1;
666 function GetFirstSelected(): Integer;
672 if SelectedObjects
= nil then
675 for a
:= 0 to High(SelectedObjects
) do
676 if SelectedObjects
[a
].Live
then
683 function Normalize16(x
: Integer): Integer;
685 Result
:= (x
div 16) * 16;
688 procedure MoveMap(X
, Y
: Integer);
690 rx
, ry
, ScaleSz
: Integer;
692 with MainForm
.RenderPanel
do
694 ScaleSz
:= 16 div Scale
;
695 // Размер видимой части карты:
696 rx
:= min(Normalize16(Width
), Normalize16(gMapInfo
.Width
)) div 2;
697 ry
:= min(Normalize16(Height
), Normalize16(gMapInfo
.Height
)) div 2;
698 // Место клика на мини-карте:
699 MapOffset
.X
:= X
- (Width
-max(gMapInfo
.Width
div ScaleSz
, 1)-1);
700 MapOffset
.Y
:= Y
- 1;
701 // Это же место на "большой" карте:
702 MapOffset
.X
:= MapOffset
.X
* ScaleSz
;
703 MapOffset
.Y
:= MapOffset
.Y
* ScaleSz
;
704 // Левый верхний угол новой видимой части карты:
705 MapOffset
.X
:= MapOffset
.X
- rx
;
706 MapOffset
.Y
:= MapOffset
.Y
- ry
;
708 if MapOffset
.X
< 0 then
710 if MapOffset
.Y
< 0 then
712 if MapOffset
.X
> MainForm
.sbHorizontal
.Max
then
713 MapOffset
.X
:= MainForm
.sbHorizontal
.Max
;
714 if MapOffset
.Y
> MainForm
.sbVertical
.Max
then
715 MapOffset
.Y
:= MainForm
.sbVertical
.Max
;
717 MapOffset
.X
:= Normalize16(MapOffset
.X
);
718 MapOffset
.Y
:= Normalize16(MapOffset
.Y
);
721 MainForm
.sbHorizontal
.Position
:= MapOffset
.X
;
722 MainForm
.sbVertical
.Position
:= MapOffset
.Y
;
724 MapOffset
.X
:= -MapOffset
.X
;
725 MapOffset
.Y
:= -MapOffset
.Y
;
730 function IsTexturedPanel(PanelType
: Word): Boolean;
732 Result
:= WordBool(PanelType
and (PANEL_WALL
or PANEL_BACK
or PANEL_FORE
or
733 PANEL_STEP
or PANEL_OPENDOOR
or PANEL_CLOSEDOOR
or
734 PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
));
737 procedure FillProperty();
742 MainForm
.vleObjectProperty
.Strings
.Clear();
743 MainForm
.RecountSelectedObjects();
745 // Отображаем свойства если выделен только один объект:
746 if SelectedObjectCount() <> 1 then
749 _id
:= GetFirstSelected();
750 if not SelectedObjects
[_id
].Live
then
753 with MainForm
.vleObjectProperty
do
754 with ItemProps
[InsertRow(_lc
[I_PROP_ID
], IntToStr(SelectedObjects
[_id
].ID
), True)] do
756 EditStyle
:= esSimple
;
760 case SelectedObjects
[0].ObjectType
of
763 with MainForm
.vleObjectProperty
,
764 gPanels
[SelectedObjects
[_id
].ID
] do
766 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
768 EditStyle
:= esSimple
;
772 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
774 EditStyle
:= esSimple
;
778 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
780 EditStyle
:= esSimple
;
784 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
786 EditStyle
:= esSimple
;
790 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TYPE
], GetPanelName(PanelType
), True)] do
792 EditStyle
:= esEllipsis
;
796 if IsTexturedPanel(PanelType
) then
797 begin // Может быть текстура
798 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_TEX
], TextureName
, True)] do
800 EditStyle
:= esEllipsis
;
804 if TextureName
<> '' then
805 begin // Есть текстура
806 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_ALPHA
], IntToStr(Alpha
), True)] do
808 EditStyle
:= esSimple
;
812 with ItemProps
[InsertRow(_lc
[I_PROP_PANEL_BLEND
], BoolNames
[Blending
], True)] do
814 EditStyle
:= esPickList
;
824 with MainForm
.vleObjectProperty
,
825 gItems
[SelectedObjects
[_id
].ID
] do
827 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
829 EditStyle
:= esSimple
;
833 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
835 EditStyle
:= esSimple
;
839 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[OnlyDM
], True)] do
841 EditStyle
:= esPickList
;
845 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Fall
], True)] do
847 EditStyle
:= esPickList
;
855 with MainForm
.vleObjectProperty
,
856 gMonsters
[SelectedObjects
[_id
].ID
] do
858 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
860 EditStyle
:= esSimple
;
864 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
866 EditStyle
:= esSimple
;
870 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
872 EditStyle
:= esPickList
;
880 with MainForm
.vleObjectProperty
,
881 gAreas
[SelectedObjects
[_id
].ID
] do
883 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
885 EditStyle
:= esSimple
;
889 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
891 EditStyle
:= esSimple
;
895 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[Direction
], True)] do
897 EditStyle
:= esPickList
;
905 with MainForm
.vleObjectProperty
,
906 gTriggers
[SelectedObjects
[_id
].ID
] do
908 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TYPE
], GetTriggerName(TriggerType
), True)] do
910 EditStyle
:= esSimple
;
914 with ItemProps
[InsertRow(_lc
[I_PROP_X
], IntToStr(X
), True)] do
916 EditStyle
:= esSimple
;
920 with ItemProps
[InsertRow(_lc
[I_PROP_Y
], IntToStr(Y
), True)] do
922 EditStyle
:= esSimple
;
926 with ItemProps
[InsertRow(_lc
[I_PROP_WIDTH
], IntToStr(Width
), True)] do
928 EditStyle
:= esSimple
;
932 with ItemProps
[InsertRow(_lc
[I_PROP_HEIGHT
], IntToStr(Height
), True)] do
934 EditStyle
:= esSimple
;
938 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ENABLED
], BoolNames
[Enabled
], True)] do
940 EditStyle
:= esPickList
;
944 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], IntToStr(TexturePanel
), True)] do
946 EditStyle
:= esEllipsis
;
950 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ACTIVATION
], ActivateToStr(ActivateType
), True)] do
952 EditStyle
:= esEllipsis
;
956 with ItemProps
[InsertRow(_lc
[I_PROP_TR_KEYS
], KeyToStr(Key
), True)] do
958 EditStyle
:= esEllipsis
;
965 str
:= win2utf(Data
.MapName
);
966 with ItemProps
[InsertRow(_lc
[I_PROP_TR_NEXT_MAP
], str
, True)] do
968 EditStyle
:= esEllipsis
;
975 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_TO
], Format('(%d:%d)', [Data
.TargetPoint
.X
, Data
.TargetPoint
.Y
]), True)] do
977 EditStyle
:= esEllipsis
;
981 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_teleport
], True)] do
983 EditStyle
:= esPickList
;
987 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_SILENT
], BoolNames
[Data
.silent_teleport
], True)] do
989 EditStyle
:= esPickList
;
993 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TELEPORT_DIR
], DirNamesAdv
[Data
.TlpDir
], True)] do
995 EditStyle
:= esPickList
;
1000 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
,
1001 TRIGGER_DOOR
, TRIGGER_DOOR5
:
1003 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DOOR_PANEL
], IntToStr(Data
.PanelID
), True)] do
1005 EditStyle
:= esEllipsis
;
1009 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1011 EditStyle
:= esPickList
;
1015 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1017 EditStyle
:= esPickList
;
1022 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
:
1024 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TRAP_PANEL
], IntToStr(Data
.PanelID
), True)] do
1026 EditStyle
:= esEllipsis
;
1030 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1032 EditStyle
:= esPickList
;
1036 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1038 EditStyle
:= esPickList
;
1043 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
1046 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_AREA
],
1047 Format('(%d:%d %d:%d)', [Data
.tX
, Data
.tY
, Data
.tWidth
, Data
.tHeight
]), True)] do
1049 EditStyle
:= esEllipsis
;
1053 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.Wait
), True)] do
1055 EditStyle
:= esSimple
;
1059 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_COUNT
], IntToStr(Data
.Count
), True)] do
1061 EditStyle
:= esSimple
;
1065 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_MONSTER
], IntToStr(Data
.MonsterID
-1), True)] do
1067 EditStyle
:= esEllipsis
;
1071 if TriggerType
= TRIGGER_PRESS
then
1072 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_RANDOM
], BoolNames
[Data
.ExtRandom
], True)] do
1074 EditStyle
:= esPickList
;
1082 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
1084 with ItemProps
[InsertRow(_lc
[I_PROP_TR_LIFT_PANEL
], IntToStr(Data
.PanelID
), True)] do
1086 EditStyle
:= esEllipsis
;
1090 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.NoSound
], True)] do
1092 EditStyle
:= esPickList
;
1096 with ItemProps
[InsertRow(_lc
[I_PROP_TR_D2D
], BoolNames
[Data
.d2d_doors
], True)] do
1098 EditStyle
:= esPickList
;
1105 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ONCE
], BoolNames
[Data
.ActivateOnce
], True)] do
1107 EditStyle
:= esPickList
;
1111 with ItemProps
[InsertRow(_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
], BoolNames
[Data
.AnimOnce
], True)] do
1113 EditStyle
:= esPickList
;
1120 str
:= win2utf(Data
.SoundName
);
1121 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_NAME
], str
, True)] do
1123 EditStyle
:= esEllipsis
;
1127 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_VOLUME
], IntToStr(Data
.Volume
), True)] do
1129 EditStyle
:= esSimple
;
1133 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_PAN
], IntToStr(Data
.Pan
), True)] do
1135 EditStyle
:= esSimple
;
1139 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_COUNT
], IntToStr(Data
.PlayCount
), True)] do
1141 EditStyle
:= esSimple
;
1145 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_LOCAL
], BoolNames
[Data
.Local
], True)] do
1147 EditStyle
:= esPickList
;
1151 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SOUND_SWITCH
], BoolNames
[Data
.SoundSwitch
], True)] do
1153 EditStyle
:= esPickList
;
1158 TRIGGER_SPAWNMONSTER
:
1160 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_TYPE
], MonsterToStr(Data
.MonType
), True)] do
1162 EditStyle
:= esEllipsis
;
1166 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1167 Format('(%d:%d)', [Data
.MonPos
.X
, Data
.MonPos
.Y
]), True)] do
1169 EditStyle
:= esEllipsis
;
1173 with ItemProps
[InsertRow(_lc
[I_PROP_DIRECTION
], DirNames
[TDirection(Data
.MonDir
)], True)] do
1175 EditStyle
:= esPickList
;
1179 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.MonHealth
), True)] do
1181 EditStyle
:= esSimple
;
1185 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_ACTIVE
], BoolNames
[Data
.MonActive
], True)] do
1187 EditStyle
:= esPickList
;
1191 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.MonCount
), True)] do
1193 EditStyle
:= esSimple
;
1197 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.MonEffect
), True)] do
1199 EditStyle
:= esEllipsis
;
1203 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.MonMax
), True)] do
1205 EditStyle
:= esSimple
;
1209 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.MonDelay
), True)] do
1211 EditStyle
:= esSimple
;
1215 case Data
.MonBehav
of
1216 1: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
];
1217 2: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
];
1218 3: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
];
1219 4: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
];
1220 5: str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
];
1221 else str
:= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
];
1223 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
], str
, True)] do
1225 EditStyle
:= esPickList
;
1232 with ItemProps
[InsertRow(_lc
[I_PROP_TR_ITEM_TYPE
], ItemToStr(Data
.ItemType
), True)] do
1234 EditStyle
:= esEllipsis
;
1238 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1239 Format('(%d:%d)', [Data
.ItemPos
.X
, Data
.ItemPos
.Y
]), True)] do
1241 EditStyle
:= esEllipsis
;
1245 with ItemProps
[InsertRow(_lc
[I_PROP_DM_ONLY
], BoolNames
[Data
.ItemOnlyDM
], True)] do
1247 EditStyle
:= esPickList
;
1251 with ItemProps
[InsertRow(_lc
[I_PROP_ITEM_FALLS
], BoolNames
[Data
.ItemFalls
], True)] do
1253 EditStyle
:= esPickList
;
1257 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ItemCount
), True)] do
1259 EditStyle
:= esSimple
;
1263 with ItemProps
[InsertRow(_lc
[I_PROP_TR_FX_TYPE
], EffectToStr(Data
.ItemEffect
), True)] do
1265 EditStyle
:= esEllipsis
;
1269 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_MAX
], IntToStr(Data
.ItemMax
), True)] do
1271 EditStyle
:= esSimple
;
1275 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_DELAY
], IntToStr(Data
.ItemDelay
), True)] do
1277 EditStyle
:= esSimple
;
1284 str
:= win2utf(Data
.MusicName
);
1285 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_NAME
], str
, True)] do
1287 EditStyle
:= esEllipsis
;
1291 if Data
.MusicAction
= 1 then
1292 str
:= _lc
[I_PROP_TR_MUSIC_ON
]
1294 str
:= _lc
[I_PROP_TR_MUSIC_OFF
];
1296 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MUSIC_ACT
], str
, True)] do
1298 EditStyle
:= esPickList
;
1305 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_ANGLE
], IntToStr(Data
.PushAngle
), True)] do
1307 EditStyle
:= esSimple
;
1310 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_FORCE
], IntToStr(Data
.PushForce
), True)] do
1312 EditStyle
:= esSimple
;
1315 with ItemProps
[InsertRow(_lc
[I_PROP_TR_PUSH_RESET
], BoolNames
[Data
.ResetVel
], True)] do
1317 EditStyle
:= esPickList
;
1324 case Data
.ScoreAction
of
1325 1: str
:= _lc
[I_PROP_TR_SCORE_ACT_1
];
1326 2: str
:= _lc
[I_PROP_TR_SCORE_ACT_2
];
1327 3: str
:= _lc
[I_PROP_TR_SCORE_ACT_3
];
1328 else str
:= _lc
[I_PROP_TR_SCORE_ACT_0
];
1330 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_ACT
], str
, True)] do
1332 EditStyle
:= esPickList
;
1335 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.ScoreCount
), True)] do
1337 EditStyle
:= esSimple
;
1340 case Data
.ScoreTeam
of
1341 1: str
:= _lc
[I_PROP_TR_SCORE_TEAM_1
];
1342 2: str
:= _lc
[I_PROP_TR_SCORE_TEAM_2
];
1343 3: str
:= _lc
[I_PROP_TR_SCORE_TEAM_3
];
1344 else str
:= _lc
[I_PROP_TR_SCORE_TEAM_0
];
1346 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_TEAM
], str
, True)] do
1348 EditStyle
:= esPickList
;
1351 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_CON
], BoolNames
[Data
.ScoreCon
], True)] do
1353 EditStyle
:= esPickList
;
1356 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SCORE_MSG
], BoolNames
[Data
.ScoreMsg
], True)] do
1358 EditStyle
:= esPickList
;
1365 case Data
.MessageKind
of
1366 1: str
:= _lc
[I_PROP_TR_MESSAGE_KIND_1
];
1367 else str
:= _lc
[I_PROP_TR_MESSAGE_KIND_0
];
1369 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_KIND
], str
, True)] do
1371 EditStyle
:= esPickList
;
1374 case Data
.MessageSendTo
of
1375 1: str
:= _lc
[I_PROP_TR_MESSAGE_TO_1
];
1376 2: str
:= _lc
[I_PROP_TR_MESSAGE_TO_2
];
1377 3: str
:= _lc
[I_PROP_TR_MESSAGE_TO_3
];
1378 4: str
:= _lc
[I_PROP_TR_MESSAGE_TO_4
];
1379 5: str
:= _lc
[I_PROP_TR_MESSAGE_TO_5
];
1380 else str
:= _lc
[I_PROP_TR_MESSAGE_TO_0
];
1382 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TO
], str
, True)] do
1384 EditStyle
:= esPickList
;
1387 str
:= win2utf(Data
.MessageText
);
1388 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], str
, True)] do
1390 EditStyle
:= esSimple
;
1393 with ItemProps
[InsertRow(_lc
[I_PROP_TR_MESSAGE_TIME
], IntToStr(Data
.MessageTime
), True)] do
1395 EditStyle
:= esSimple
;
1402 with ItemProps
[InsertRow(_lc
[I_PROP_TR_DAMAGE_VALUE
], IntToStr(Data
.DamageValue
), True)] do
1404 EditStyle
:= esSimple
;
1407 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.DamageInterval
), True)] do
1409 EditStyle
:= esSimple
;
1416 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH
], IntToStr(Data
.HealValue
), True)] do
1418 EditStyle
:= esSimple
;
1421 with ItemProps
[InsertRow(_lc
[I_PROP_TR_INTERVAL
], IntToStr(Data
.HealInterval
), True)] do
1423 EditStyle
:= esSimple
;
1426 with ItemProps
[InsertRow(_lc
[I_PROP_TR_HEALTH_MAX
], BoolNames
[Data
.HealMax
], True)] do
1428 EditStyle
:= esPickList
;
1431 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SILENT
], BoolNames
[Data
.HealSilent
], True)] do
1433 EditStyle
:= esPickList
;
1440 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TYPE
], ShotToStr(Data
.ShotType
), True)] do
1442 EditStyle
:= esEllipsis
;
1446 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SOUND
], BoolNames
[Data
.ShotSound
], True)] do
1448 EditStyle
:= esPickList
;
1452 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_PANEL
], IntToStr(Data
.ShotPanelID
), True)] do
1454 EditStyle
:= esEllipsis
;
1458 case Data
.ShotTarget
of
1459 1: str
:= _lc
[I_PROP_TR_SHOT_TO_1
];
1460 2: str
:= _lc
[I_PROP_TR_SHOT_TO_2
];
1461 3: str
:= _lc
[I_PROP_TR_SHOT_TO_3
];
1462 4: str
:= _lc
[I_PROP_TR_SHOT_TO_4
];
1463 5: str
:= _lc
[I_PROP_TR_SHOT_TO_5
];
1464 6: str
:= _lc
[I_PROP_TR_SHOT_TO_6
];
1465 else str
:= _lc
[I_PROP_TR_SHOT_TO_0
];
1467 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_TO
], str
, True)] do
1469 EditStyle
:= esPickList
;
1473 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_SIGHT
], IntToStr(Data
.ShotIntSight
), True)] do
1475 EditStyle
:= esSimple
;
1479 case Data
.ShotAim
of
1480 1: str
:= _lc
[I_PROP_TR_SHOT_AIM_1
];
1481 2: str
:= _lc
[I_PROP_TR_SHOT_AIM_2
];
1482 3: str
:= _lc
[I_PROP_TR_SHOT_AIM_3
];
1483 else str
:= _lc
[I_PROP_TR_SHOT_AIM_0
];
1485 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AIM
], str
, True)] do
1487 EditStyle
:= esPickList
;
1491 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SPAWN_TO
],
1492 Format('(%d:%d)', [Data
.ShotPos
.X
, Data
.ShotPos
.Y
]), True)] do
1494 EditStyle
:= esEllipsis
;
1498 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ANGLE
], IntToStr(Data
.ShotAngle
), True)] do
1500 EditStyle
:= esSimple
;
1504 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.ShotWait
), True)] do
1506 EditStyle
:= esSimple
;
1510 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_ACC
], IntToStr(Data
.ShotAccuracy
), True)] do
1512 EditStyle
:= esSimple
;
1516 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_AMMO
], IntToStr(Data
.ShotAmmo
), True)] do
1518 EditStyle
:= esSimple
;
1522 with ItemProps
[InsertRow(_lc
[I_PROP_TR_SHOT_RELOAD
], IntToStr(Data
.ShotIntReload
), True)] do
1524 EditStyle
:= esSimple
;
1531 with ItemProps
[InsertRow(_lc
[I_PROP_TR_COUNT
], IntToStr(Data
.FXCount
), True)] do
1533 EditStyle
:= esSimple
;
1537 if Data
.FXType
= 0 then
1538 str
:= _lc
[I_PROP_TR_EFFECT_PARTICLE
]
1540 str
:= _lc
[I_PROP_TR_EFFECT_ANIMATION
];
1541 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_TYPE
], str
, True)] do
1543 EditStyle
:= esEllipsis
;
1548 if Data
.FXType
= 0 then
1549 case Data
.FXSubType
of
1550 TRIGGER_EFFECT_SLIQUID
:
1551 str
:= _lc
[I_PROP_TR_EFFECT_SLIQUID
];
1552 TRIGGER_EFFECT_LLIQUID
:
1553 str
:= _lc
[I_PROP_TR_EFFECT_LLIQUID
];
1554 TRIGGER_EFFECT_DLIQUID
:
1555 str
:= _lc
[I_PROP_TR_EFFECT_DLIQUID
];
1556 TRIGGER_EFFECT_BLOOD
:
1557 str
:= _lc
[I_PROP_TR_EFFECT_BLOOD
];
1558 TRIGGER_EFFECT_SPARK
:
1559 str
:= _lc
[I_PROP_TR_EFFECT_SPARK
];
1560 TRIGGER_EFFECT_BUBBLE
:
1561 str
:= _lc
[I_PROP_TR_EFFECT_BUBBLE
];
1563 if Data
.FXType
= 1 then
1565 if (Data
.FXSubType
= 0) or (Data
.FXSubType
> EFFECT_FIRE
) then
1566 Data
.FXSubType
:= EFFECT_TELEPORT
;
1567 str
:= EffectToStr(Data
.FXSubType
);
1569 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SUBTYPE
], str
, True)] do
1571 EditStyle
:= esEllipsis
;
1575 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_COLOR
], IntToStr(Data
.FXColorR
or (Data
.FXColorG
shl 8) or (Data
.FXColorB
shl 16)), True)] do
1577 EditStyle
:= esEllipsis
;
1581 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_CENTER
], BoolNames
[Data
.FXPos
= 0], True)] do
1583 EditStyle
:= esPickList
;
1587 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EX_DELAY
], IntToStr(Data
.FXWait
), True)] do
1589 EditStyle
:= esSimple
;
1593 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELX
], IntToStr(Data
.FXVelX
), True)] do
1595 EditStyle
:= esSimple
;
1599 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_VELY
], IntToStr(Data
.FXVelY
), True)] do
1601 EditStyle
:= esSimple
;
1605 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPL
], IntToStr(Data
.FXSpreadL
), True)] do
1607 EditStyle
:= esSimple
;
1611 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPR
], IntToStr(Data
.FXSpreadR
), True)] do
1613 EditStyle
:= esSimple
;
1617 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPU
], IntToStr(Data
.FXSpreadU
), True)] do
1619 EditStyle
:= esSimple
;
1623 with ItemProps
[InsertRow(_lc
[I_PROP_TR_EFFECT_SPD
], IntToStr(Data
.FXSpreadD
), True)] do
1625 EditStyle
:= esSimple
;
1629 end; //case TriggerType
1631 end; // OBJECT_TRIGGER:
1635 procedure ChangeShownProperty(Name
: String; NewValue
: String);
1639 if SelectedObjectCount() <> 1 then
1641 if not SelectedObjects
[GetFirstSelected()].Live
then
1644 // Есть ли такой ключ:
1645 if MainForm
.vleObjectProperty
.FindRow(Name
, row
) then
1647 MainForm
.vleObjectProperty
.Values
[Name
] := NewValue
;
1651 procedure SelectObject(fObjectType
: Byte; fID
: DWORD
; Multi
: Boolean);
1660 // Уже выделен - убираем:
1661 if SelectedObjects
<> nil then
1662 for a
:= 0 to High(SelectedObjects
) do
1663 with SelectedObjects
[a
] do
1664 if Live
and (ID
= fID
) and
1665 (ObjectType
= fObjectType
) then
1674 SetLength(SelectedObjects
, Length(SelectedObjects
)+1);
1676 with SelectedObjects
[High(SelectedObjects
)] do
1678 ObjectType
:= fObjectType
;
1685 SetLength(SelectedObjects
, 1);
1687 with SelectedObjects
[0] do
1689 ObjectType
:= fObjectType
;
1695 MainForm
.miCopy
.Enabled
:= True;
1696 MainForm
.miCut
.Enabled
:= True;
1698 if fObjectType
= OBJECT_PANEL
then
1700 MainForm
.miToFore
.Enabled
:= True;
1701 MainForm
.miToBack
.Enabled
:= True;
1705 procedure RemoveSelectFromObjects();
1707 SelectedObjects
:= nil;
1708 DrawPressRect
:= False;
1709 MouseLDown
:= False;
1710 MouseRDown
:= False;
1711 MouseAction
:= MOUSEACTION_NONE
;
1712 SelectFlag
:= SELECTFLAG_NONE
;
1713 ResizeType
:= RESIZETYPE_NONE
;
1714 ResizeDirection
:= RESIZEDIR_NONE
;
1716 MainForm
.vleObjectProperty
.Strings
.Clear();
1718 MainForm
.miCopy
.Enabled
:= False;
1719 MainForm
.miCut
.Enabled
:= False;
1720 MainForm
.miToFore
.Enabled
:= False;
1721 MainForm
.miToBack
.Enabled
:= False;
1724 procedure DeleteSelectedObjects();
1729 if SelectedObjects
= nil then
1735 for a
:= 0 to High(SelectedObjects
) do
1736 with SelectedObjects
[a
] do
1741 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1742 i
:= High(UndoBuffer
);
1746 SetLength(UndoBuffer
[i
], Length(UndoBuffer
[i
])+1);
1747 ii
:= High(UndoBuffer
[i
]);
1752 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_PANEL
;
1753 New(UndoBuffer
[i
, ii
].Panel
);
1754 UndoBuffer
[i
, ii
].Panel
^ := gPanels
[ID
];
1758 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_ITEM
;
1759 UndoBuffer
[i
, ii
].Item
:= gItems
[ID
];
1763 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_AREA
;
1764 UndoBuffer
[i
, ii
].Area
:= gAreas
[ID
];
1768 UndoBuffer
[i
, ii
].UndoType
:= UNDO_DELETE_TRIGGER
;
1769 UndoBuffer
[i
, ii
].Trigger
:= gTriggers
[ID
];
1773 RemoveObject(ID
, ObjectType
);
1776 RemoveSelectFromObjects();
1778 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1779 MainForm
.RecountSelectedObjects();
1782 procedure Undo_Add(ObjectType
: Byte; ID
: DWORD
; Group
: Boolean = False);
1786 if (not Group
) or (Length(UndoBuffer
) = 0) then
1787 SetLength(UndoBuffer
, Length(UndoBuffer
)+1);
1788 SetLength(UndoBuffer
[High(UndoBuffer
)], Length(UndoBuffer
[High(UndoBuffer
)])+1);
1789 i
:= High(UndoBuffer
);
1790 ii
:= High(UndoBuffer
[i
]);
1794 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_PANEL
;
1796 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_ITEM
;
1798 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_MONSTER
;
1800 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_AREA
;
1802 UndoBuffer
[i
, ii
].UndoType
:= UNDO_ADD_TRIGGER
;
1805 UndoBuffer
[i
, ii
].AddID
:= ID
;
1807 MainForm
.miUndo
.Enabled
:= UndoBuffer
<> nil;
1810 procedure FullClear();
1812 RemoveSelectFromObjects();
1814 LoadSky(gMapInfo
.SkyName
);
1816 slInvalidTextures
.Clear();
1817 MapCheckForm
.lbErrorList
.Clear();
1818 MapCheckForm
.mErrorDescription
.Clear();
1820 MainForm
.miUndo
.Enabled
:= False;
1821 MainForm
.sbHorizontal
.Position
:= 0;
1822 MainForm
.sbVertical
.Position
:= 0;
1823 MainForm
.FormResize(nil);
1824 MainForm
.Caption
:= FormCaption
;
1829 procedure ErrorMessageBox(str
: String);
1831 MessageBox(0, PChar(str
), PChar(_lc
[I_MSG_ERROR
]),
1832 MB_ICONINFORMATION
or MB_OK
or MB_DEFBUTTON1
);
1835 function CheckProperty(): Boolean;
1841 _id
:= GetFirstSelected();
1843 if SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
then
1844 with gPanels
[SelectedObjects
[_id
].ID
] do
1846 if TextureWidth
<> 0 then
1847 if StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 1) mod TextureWidth
<> 0 then
1849 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
1854 if TextureHeight
<> 0 then
1855 if StrToIntDef(Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]), 1) mod TextureHeight
<> 0 then
1857 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
1862 if IsTexturedPanel(PanelType
) and (TextureName
<> '') then
1863 if not (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]], -1) in [0..255]) then
1865 ErrorMessageBox(_lc
[I_MSG_WRONG_ALPHA
]);
1870 if SelectedObjects
[_id
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
1871 if (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]], 0) <= 0) or
1872 (StrToIntDef(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]], 0) <= 0) then
1874 ErrorMessageBox(_lc
[I_MSG_WRONG_SIZE
]);
1878 if (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_X
]]) = '') or
1879 (Trim(MainForm
.vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]) = '') then
1881 ErrorMessageBox(_lc
[I_MSG_WRONG_XY
]);
1888 procedure SelectTexture(ID
: Integer);
1890 MainForm
.lbTextureList
.ItemIndex
:= ID
;
1891 MainForm
.lbTextureListClick(nil);
1894 function AddTexture(aWAD
, aSection
, aTex
: String; silent
: Boolean): Boolean;
1896 a
, FrameLen
: Integer;
1899 ResourceName
: String;
1900 FullResourceName
: String;
1901 SectionName
: String;
1903 Width
, Height
: Word;
1911 if aSection
= '..' then
1914 SectionName
:= aSection
;
1917 aWAD
:= _lc
[I_WAD_SPECIAL_MAP
];
1919 if aWAD
= _lc
[I_WAD_SPECIAL_MAP
] then
1921 g_ProcessResourceStr(OpenedMap
, @fn
, nil, nil);
1922 //FileName := EditorDir+'maps\'+ExtractFileName(fn);
1924 ResourceName
:= ':'+SectionName
+'\'+aTex
;
1927 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1928 begin // Спец. текстуры
1930 ResourceName
:= aTex
;
1933 begin // Внешний WAD
1934 FileName
:= EditorDir
+'wads/'+aWAD
;
1935 ResourceName
:= aWAD
+':'+SectionName
+'\'+aTex
;
1940 // Есть ли уже такая текстура:
1941 for a
:= 0 to MainForm
.lbTextureList
.Items
.Count
-1 do
1942 if ResourceName
= MainForm
.lbTextureList
.Items
[a
] then
1945 ErrorMessageBox(Format(_lc
[I_MSG_TEXTURE_ALREADY
],
1950 // Название ресурса <= 64 символов:
1951 if Length(ResourceName
) > 64 then
1954 ErrorMessageBox(Format(_lc
[I_MSG_RES_NAME_64
],
1962 if aWAD
= _lc
[I_WAD_SPECIAL_TEXS
] then
1964 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1971 FullResourceName
:= FileName
+':'+SectionName
+'\'+aTex
;
1973 if IsAnim(FullResourceName
) then
1974 begin // Аним. текстура
1975 GetFrame(FullResourceName
, Data
, FrameLen
, Width
, Height
);
1977 if not g_CreateTextureMemorySize(Data
, FrameLen
, ResourceName
, 0, 0, Width
, Height
, 1) then
1979 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1981 else // Обычная текстура
1983 if not g_CreateTextureWAD(ResourceName
, FullResourceName
) then
1985 a
:= MainForm
.lbTextureList
.Items
.Add(ResourceName
);
1987 if (not ok
) and (slInvalidTextures
.IndexOf(ResourceName
) = -1) then
1989 slInvalidTextures
.Add(ResourceName
);
1992 if (a
> -1) and (not silent
) then
1999 procedure UpdateCaption(sMap
, sFile
, sRes
: String);
2002 if (sFile
= '') and (sRes
= '') and (sMap
= '') then
2003 Caption
:= FormCaption
2006 Caption
:= Format('%s - %s:%s', [FormCaption
, sFile
, sRes
])
2008 if (sFile
<> '') and (sRes
<> '') then
2009 Caption
:= Format('%s - %s (%s:%s)', [FormCaption
, sMap
, sFile
, sRes
])
2011 Caption
:= Format('%s - %s', [FormCaption
, sMap
]);
2014 procedure OpenMap(FileName
: String; mapN
: String);
2019 SelectMapForm
.Caption
:= _lc
[I_CAP_OPEN
];
2020 SelectMapForm
.GetMaps(FileName
);
2022 if (FileName
= OpenedWAD
) and
2023 (OpenedMap
<> '') then
2025 MapName
:= OpenedMap
;
2026 while (Pos(':\', MapName
) > 0) do
2027 Delete(MapName
, 1, Pos(':\', MapName
) + 1);
2029 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(MapName
);
2030 SelectMapForm
.lbMapList
.ItemIndex
:= idx
;
2033 if SelectMapForm
.lbMapList
.Count
> 0 then
2034 SelectMapForm
.lbMapList
.ItemIndex
:= 0
2036 SelectMapForm
.lbMapList
.ItemIndex
:= -1;
2041 idx
:= SelectMapForm
.lbMapList
.Items
.IndexOf(mapN
);
2045 if (SelectMapForm
.ShowModal() = mrOK
) and
2046 (SelectMapForm
.lbMapList
.ItemIndex
<> -1) then
2047 idx
:= SelectMapForm
.lbMapList
.ItemIndex
2052 MapName
:= SelectMapForm
.lbMapList
.Items
[idx
];
2058 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
2059 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
2060 pLoadProgress
.Show();
2062 OpenedMap
:= FileName
+':\'+MapName
;
2063 OpenedWAD
:= FileName
;
2065 idx
:= RecentFiles
.IndexOf(OpenedMap
);
2066 // Такая карта уже недавно открывалась:
2068 RecentFiles
.Delete(idx
);
2069 RecentFiles
.Insert(0, OpenedMap
);
2070 RefreshRecentMenu();
2074 pLoadProgress
.Hide();
2077 lbTextureList
.Sorted
:= True;
2078 lbTextureList
.Sorted
:= False;
2080 UpdateCaption(gMapInfo
.Name
, ExtractFileName(FileName
), MapName
);
2084 procedure MoveSelectedObjects(Wall
, alt
: Boolean; dx
, dy
: Integer);
2089 if SelectedObjects
= nil then
2096 for a
:= 0 to High(SelectedObjects
) do
2097 if SelectedObjects
[a
].Live
then
2099 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, dx
, 0) then
2102 if ObjectCollideLevel(SelectedObjects
[a
].ID
, SelectedObjects
[a
].ObjectType
, 0, dy
) then
2105 if (not okX
) or (not okY
) then
2111 for a
:= 0 to High(SelectedObjects
) do
2112 if SelectedObjects
[a
].Live
then
2115 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, dx
, 0);
2118 MoveObject(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
, 0, dy
);
2120 if alt
and (SelectedObjects
[a
].ObjectType
= OBJECT_TRIGGER
) then
2122 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_PRESS
,
2123 TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
] then
2124 begin // Двигаем зону Расширителя
2126 gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tX
+dx
;
2128 gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.tY
+dy
;
2131 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_TELEPORT
] then
2132 begin // Двигаем точку назначения Телепорта
2134 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.X
+dx
;
2136 gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.TargetPoint
.Y
+dy
;
2139 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNMONSTER
] then
2140 begin // Двигаем точку создания монстра
2142 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.X
+dx
;
2144 gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.MonPos
.Y
+dy
;
2147 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SPAWNITEM
] then
2148 begin // Двигаем точку создания предмета
2150 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.X
+dx
;
2152 gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ItemPos
.Y
+dy
;
2155 if gTriggers
[SelectedObjects
[a
].ID
].TriggerType
in [TRIGGER_SHOT
] then
2156 begin // Двигаем точку создания выстрела
2158 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.X
+dx
;
2160 gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
:= gTriggers
[SelectedObjects
[a
].ID
].Data
.ShotPos
.Y
+dy
;
2165 LastMovePoint
:= MousePos
;
2169 procedure ShowLayer(Layer
: Byte; show
: Boolean);
2171 LayerEnabled
[Layer
] := show
;
2176 MainForm
.miLayer1
.Checked
:= show
;
2177 MainForm
.miLayerP1
.Checked
:= show
;
2181 MainForm
.miLayer2
.Checked
:= show
;
2182 MainForm
.miLayerP2
.Checked
:= show
;
2186 MainForm
.miLayer3
.Checked
:= show
;
2187 MainForm
.miLayerP3
.Checked
:= show
;
2191 MainForm
.miLayer4
.Checked
:= show
;
2192 MainForm
.miLayerP4
.Checked
:= show
;
2196 MainForm
.miLayer5
.Checked
:= show
;
2197 MainForm
.miLayerP5
.Checked
:= show
;
2201 MainForm
.miLayer6
.Checked
:= show
;
2202 MainForm
.miLayerP6
.Checked
:= show
;
2206 MainForm
.miLayer7
.Checked
:= show
;
2207 MainForm
.miLayerP7
.Checked
:= show
;
2211 MainForm
.miLayer8
.Checked
:= show
;
2212 MainForm
.miLayerP8
.Checked
:= show
;
2216 MainForm
.miLayer9
.Checked
:= show
;
2217 MainForm
.miLayerP9
.Checked
:= show
;
2221 RemoveSelectFromObjects();
2224 procedure SwitchLayer(Layer
: Byte);
2226 ShowLayer(Layer
, not LayerEnabled
[Layer
]);
2229 procedure SwitchMap();
2231 ShowMap
:= not ShowMap
;
2232 MainForm
.tbShowMap
.Down
:= ShowMap
;
2235 procedure ShowEdges();
2237 if drEdge
[3] < 255 then
2240 drEdge
[3] := gAlphaEdge
;
2243 function SelectedTexture(): String;
2245 if MainForm
.lbTextureList
.ItemIndex
<> -1 then
2246 Result
:= MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]
2251 function IsSpecialTextureSel(): Boolean;
2253 Result
:= (MainForm
.lbTextureList
.ItemIndex
<> -1) and
2254 IsSpecialTexture(MainForm
.lbTextureList
.Items
[MainForm
.lbTextureList
.ItemIndex
]);
2257 function CopyBufferToString(var CopyBuf
: TCopyRecArray
): String;
2262 procedure AddInt(x
: Integer);
2264 Res
:= Res
+ IntToStr(x
) + ' ';
2270 if Length(CopyBuf
) = 0 then
2273 Res
:= CLIPBOARD_SIG
+ ' ';
2275 for i
:= 0 to High(CopyBuf
) do
2277 if (CopyBuf
[i
].ObjectType
= OBJECT_PANEL
) and
2278 (CopyBuf
[i
].Panel
= nil) then
2282 AddInt(CopyBuf
[i
].ObjectType
);
2285 // Свойства объекта:
2286 case CopyBuf
[i
].ObjectType
of
2288 with CopyBuf
[i
].Panel
^ do
2295 Res
:= Res
+ '"' + TextureName
+ '" ';
2297 AddInt(IfThen(Blending
, 1, 0));
2301 with CopyBuf
[i
].Item
do
2306 AddInt(IfThen(OnlyDM
, 1, 0));
2307 AddInt(IfThen(Fall
, 1, 0));
2311 with CopyBuf
[i
].Monster
do
2313 AddInt(MonsterType
);
2316 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2320 with CopyBuf
[i
].Area
do
2325 AddInt(IfThen(Direction
= D_LEFT
, 1, 0));
2329 with CopyBuf
[i
].Trigger
do
2331 AddInt(TriggerType
);
2336 AddInt(ActivateType
);
2338 AddInt(IfThen(Enabled
, 1, 0));
2339 AddInt(TexturePanel
);
2341 for j
:= 0 to 127 do
2342 AddInt(Data
.Default
[j
]);
2350 procedure StringToCopyBuffer(Str
: String; var CopyBuf
: TCopyRecArray
;
2355 function GetNext(): String;
2360 if Str
[1] = '"' then
2372 Result
:= Copy(Str
, 1, p
-1);
2388 Result
:= Copy(Str
, 1, p
-1);
2398 if GetNext() <> CLIPBOARD_SIG
then
2404 t
:= StrToIntDef(GetNext(), 0);
2406 if (t
< OBJECT_PANEL
) or (t
> OBJECT_TRIGGER
) or
2407 (GetNext() <> ';') then
2408 begin // Что-то не то => пропускаем:
2416 i
:= Length(CopyBuf
);
2417 SetLength(CopyBuf
, i
+ 1);
2419 CopyBuf
[i
].ObjectType
:= t
;
2420 CopyBuf
[i
].Panel
:= nil;
2422 // Свойства объекта:
2426 New(CopyBuf
[i
].Panel
);
2428 with CopyBuf
[i
].Panel
^ do
2430 PanelType
:= StrToIntDef(GetNext(), PANEL_WALL
);
2431 X
:= StrToIntDef(GetNext(), 0);
2432 Y
:= StrToIntDef(GetNext(), 0);
2433 pmin
.X
:= Min(X
, pmin
.X
);
2434 pmin
.Y
:= Min(Y
, pmin
.Y
);
2435 Width
:= StrToIntDef(GetNext(), 16);
2436 Height
:= StrToIntDef(GetNext(), 16);
2437 TextureName
:= GetNext();
2438 Alpha
:= StrToIntDef(GetNext(), 0);
2439 Blending
:= (GetNext() = '1');
2444 with CopyBuf
[i
].Item
do
2446 ItemType
:= StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL
);
2447 X
:= StrToIntDef(GetNext(), 0);
2448 Y
:= StrToIntDef(GetNext(), 0);
2449 pmin
.X
:= Min(X
, pmin
.X
);
2450 pmin
.Y
:= Min(Y
, pmin
.Y
);
2451 OnlyDM
:= (GetNext() = '1');
2452 Fall
:= (GetNext() = '1');
2456 with CopyBuf
[i
].Monster
do
2458 MonsterType
:= StrToIntDef(GetNext(), MONSTER_DEMON
);
2459 X
:= StrToIntDef(GetNext(), 0);
2460 Y
:= StrToIntDef(GetNext(), 0);
2461 pmin
.X
:= Min(X
, pmin
.X
);
2462 pmin
.Y
:= Min(Y
, pmin
.Y
);
2464 if GetNext() = '1' then
2467 Direction
:= D_RIGHT
;
2471 with CopyBuf
[i
].Area
do
2473 AreaType
:= StrToIntDef(GetNext(), AREA_PLAYERPOINT1
);
2474 X
:= StrToIntDef(GetNext(), 0);
2475 Y
:= StrToIntDef(GetNext(), 0);
2476 pmin
.X
:= Min(X
, pmin
.X
);
2477 pmin
.Y
:= Min(Y
, pmin
.Y
);
2478 if GetNext() = '1' then
2481 Direction
:= D_RIGHT
;
2485 with CopyBuf
[i
].Trigger
do
2487 TriggerType
:= StrToIntDef(GetNext(), TRIGGER_EXIT
);
2488 X
:= StrToIntDef(GetNext(), 0);
2489 Y
:= StrToIntDef(GetNext(), 0);
2490 pmin
.X
:= Min(X
, pmin
.X
);
2491 pmin
.Y
:= Min(Y
, pmin
.Y
);
2492 Width
:= StrToIntDef(GetNext(), 16);
2493 Height
:= StrToIntDef(GetNext(), 16);
2494 ActivateType
:= StrToIntDef(GetNext(), 0);
2495 Key
:= StrToIntDef(GetNext(), 0);
2496 Enabled
:= (GetNext() = '1');
2497 TexturePanel
:= StrToIntDef(GetNext(), 0);
2499 for j
:= 0 to 127 do
2500 Data
.Default
[j
] := StrToIntDef(GetNext(), 0);
2505 pmin
.X
:= Min(Data
.TargetPoint
.X
, pmin
.X
);
2506 pmin
.Y
:= Min(Data
.TargetPoint
.Y
, pmin
.Y
);
2508 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
2510 pmin
.X
:= Min(Data
.tX
, pmin
.X
);
2511 pmin
.Y
:= Min(Data
.tY
, pmin
.Y
);
2513 TRIGGER_SPAWNMONSTER
:
2515 pmin
.X
:= Min(Data
.MonPos
.X
, pmin
.X
);
2516 pmin
.Y
:= Min(Data
.MonPos
.Y
, pmin
.Y
);
2520 pmin
.X
:= Min(Data
.ItemPos
.X
, pmin
.X
);
2521 pmin
.Y
:= Min(Data
.ItemPos
.Y
, pmin
.Y
);
2525 pmin
.X
:= Min(Data
.ShotPos
.X
, pmin
.X
);
2526 pmin
.Y
:= Min(Data
.ShotPos
.Y
, pmin
.Y
);
2534 //----------------------------------------
2535 //Закончились вспомогательные процедуры
2536 //----------------------------------------
2538 procedure TMainForm
.RefreshRecentMenu();
2543 // Лишние запомненные карты:
2544 while RecentFiles
.Count
> RecentCount
do
2545 RecentFiles
.Delete(RecentFiles
.Count
-1);
2547 // Лишние строки меню:
2548 while MainMenu
.Items
[0].Count
> RECENT_FILES_MENU_START
do
2549 MainMenu
.Items
[0].Delete(MainMenu
.Items
[0].Count
-1);
2551 // Отделение списка карт от строки "Выход":
2552 if RecentFiles
.Count
> 0 then
2554 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2556 MainMenu
.Items
[0].Add(MI
);
2559 // Добавление в меню списка запомненных карт:
2560 for i
:= 0 to RecentFiles
.Count
-1 do
2562 MI
:= TMenuItem
.Create(MainMenu
.Items
[0]);
2563 MI
.Caption
:= IntToStr(i
+1) + ' ' + RecentFiles
[i
];
2564 MI
.OnClick
:= aRecentFileExecute
;
2565 MainMenu
.Items
[0].Add(MI
);
2569 procedure TMainForm
.aRecentFileExecute(Sender
: TObject
);
2575 s
:= LowerCase((Sender
as TMenuItem
).Caption
);
2576 Delete(s
, Pos('&', s
), 1);
2577 s
:= Trim(Copy(s
, 1, 2));
2578 n
:= StrToIntDef(s
, 0) - 1;
2580 if (n
< 0) or (n
>= RecentFiles
.Count
) then
2583 s
:= RecentFiles
[n
];
2584 pw
:= Pos('.wad:\', LowerCase(s
));
2588 begin // Map name included
2589 fn
:= Copy(s
, 1, pw
+ 3);
2590 Delete(s
, 1, pw
+ 5);
2591 if (FileExists(fn
)) then
2597 else // Only wad name
2598 if (FileExists(s
)) then
2604 if (not b
) and (MessageBox(0, PChar(_lc
[I_MSG_DEL_RECENT_PROMT
]),
2605 PChar(_lc
[I_MSG_DEL_RECENT
]), MB_ICONQUESTION
or MB_YESNO
) = idYes
) then
2607 RecentFiles
.Delete(n
);
2608 RefreshRecentMenu();
2612 procedure TMainForm
.aEditorOptionsExecute(Sender
: TObject
);
2614 OptionsForm
.ShowModal();
2617 procedure LoadStdFont(cfgres
, texture
: string; var FontID
: DWORD
);
2631 wad
:= TWADEditor_1
.Create
;
2632 if wad
.ReadFile(EditorDir
+'data/Game.wad') then
2633 wad
.GetResource('FONTS', cfgres
, cfgdata
, cfglen
);
2638 if not g_CreateTextureWAD('FONT_STD', EditorDir
+'data/Game.wad:FONTS\'+texture
) then
2639 e_WriteLog('ERROR ERROR ERROR', MSG_WARNING
);
2641 config
:= TConfig
.CreateMem(cfgdata
, cfglen
);
2642 cwdt
:= Min(Max(config
.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
2643 chgt
:= Min(Max(config
.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
2644 spc
:= Min(Max(config
.ReadInt('FontMap', 'Kerning', 0), -128), 127);
2646 if g_GetTexture('FONT_STD', ID
) then
2647 e_TextureFontBuild(ID
, FontID
, cwdt
, chgt
, spc
-2);
2652 e_WriteLog('Could not load FONT_STD', MSG_WARNING
);
2654 if cfglen
<> 0 then FreeMem(cfgdata
);
2657 procedure TMainForm
.FormCreate(Sender
: TObject
);
2665 EditorDir
:= ExtractFilePath(Application
.ExeName
);
2667 e_InitLog(EditorDir
+'Editor.log', WM_NEWFILE
);
2669 slInvalidTextures
:= TStringList
.Create
;
2671 ShowLayer(LAYER_BACK
, True);
2672 ShowLayer(LAYER_WALLS
, True);
2673 ShowLayer(LAYER_FOREGROUND
, True);
2674 ShowLayer(LAYER_STEPS
, True);
2675 ShowLayer(LAYER_WATER
, True);
2676 ShowLayer(LAYER_ITEMS
, True);
2677 ShowLayer(LAYER_MONSTERS
, True);
2678 ShowLayer(LAYER_AREAS
, True);
2679 ShowLayer(LAYER_TRIGGERS
, True);
2683 FormCaption
:= MainForm
.Caption
;
2687 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
2689 if config
.ReadInt('Editor', 'XPos', -1) = -1 then
2690 Position
:= poDesktopCenter
2692 Left
:= config
.ReadInt('Editor', 'XPos', Left
);
2693 Top
:= config
.ReadInt('Editor', 'YPos', Top
);
2694 Width
:= config
.ReadInt('Editor', 'Width', Width
);
2695 Height
:= config
.ReadInt('Editor', 'Height', Height
);
2697 if config
.ReadBool('Editor', 'Maximize', False) then
2698 WindowState
:= wsMaximized
;
2699 ShowMap
:= config
.ReadBool('Editor', 'Minimap', False);
2700 PanelProps
.Width
:= config
.ReadInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
2701 Splitter1
.Left
:= PanelProps
.Left
;
2702 PanelObjs
.Height
:= config
.ReadInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
2703 Splitter2
.Top
:= PanelObjs
.Top
;
2704 StatusBar
.Top
:= PanelObjs
.BoundsRect
.Bottom
;
2705 DotEnable
:= config
.ReadBool('Editor', 'DotEnable', True);
2706 DotColor
:= config
.ReadInt('Editor', 'DotColor', $FFFFFF);
2707 DotStepOne
:= config
.ReadInt('Editor', 'DotStepOne', 16);
2708 DotStepTwo
:= config
.ReadInt('Editor', 'DotStepTwo', 8);
2709 DotStep
:= config
.ReadInt('Editor', 'DotStep', DotStepOne
);
2710 DrawTexturePanel
:= config
.ReadBool('Editor', 'DrawTexturePanel', True);
2711 DrawPanelSize
:= config
.ReadBool('Editor', 'DrawPanelSize', True);
2712 BackColor
:= config
.ReadInt('Editor', 'BackColor', $7F6040);
2713 PreviewColor
:= config
.ReadInt('Editor', 'PreviewColor', $00FF00);
2714 UseCheckerboard
:= config
.ReadBool('Editor', 'UseCheckerboard', True);
2715 gColorEdge
:= config
.ReadInt('Editor', 'EdgeColor', COLOR_EDGE
);
2716 gAlphaEdge
:= config
.ReadInt('Editor', 'EdgeAlpha', ALPHA_EDGE
);
2717 if gAlphaEdge
= 255 then
2718 gAlphaEdge
:= ALPHA_EDGE
;
2719 drEdge
[0] := GetRValue(gColorEdge
);
2720 drEdge
[1] := GetGValue(gColorEdge
);
2721 drEdge
[2] := GetBValue(gColorEdge
);
2722 if not config
.ReadBool('Editor', 'EdgeShow', True) then
2725 drEdge
[3] := gAlphaEdge
;
2726 gAlphaTriggerLine
:= config
.ReadInt('Editor', 'LineAlpha', ALPHA_LINE
);
2727 if gAlphaTriggerLine
= 255 then
2728 gAlphaTriggerLine
:= ALPHA_LINE
;
2729 gAlphaTriggerArea
:= config
.ReadInt('Editor', 'TriggerAlpha', ALPHA_AREA
);
2730 if gAlphaTriggerArea
= 255 then
2731 gAlphaTriggerArea
:= ALPHA_AREA
;
2732 gAlphaMonsterRect
:= config
.ReadInt('Editor', 'MonsterRectAlpha', 0);
2733 gAlphaAreaRect
:= config
.ReadInt('Editor', 'AreaRectAlpha', 0);
2734 if config
.ReadInt('Editor', 'Scale', 0) = 1 then
2738 if config
.ReadInt('Editor', 'DotSize', 0) = 1 then
2742 OpenDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastOpenDir', EditorDir
);
2743 SaveDialog
.InitialDir
:= config
.ReadStr('Editor', 'LastSaveDir', EditorDir
);
2745 s
:= config
.ReadStr('Editor', 'Language', '');
2748 RecentCount
:= config
.ReadInt('Editor', 'RecentCount', 5);
2749 if RecentCount
> 10 then
2751 if RecentCount
< 2 then
2754 RecentFiles
:= TStringList
.Create();
2755 for i
:= 0 to RecentCount
-1 do
2757 s
:= config
.ReadStr('RecentFiles', IntToStr(i
+1), '');
2761 RefreshRecentMenu();
2765 tbShowMap
.Down
:= ShowMap
;
2766 tbGridOn
.Down
:= DotEnable
;
2767 pcObjects
.ActivePageIndex
:= 0;
2768 Application
.Title
:= _lc
[I_EDITOR_TITLE
];
2770 Application
.OnIdle
:= OnIdle
;
2773 procedure PrintBlack(X
, Y
: Integer; Text: string; FontID
: DWORD
);
2775 // NOTE: all the font printing routines assume CP1251
2776 e_TextureFontPrintEx(X
, Y
, Text, FontID
, 0, 0, 0, 1.0);
2779 procedure TMainForm
.Draw();
2784 Width
, Height
: Word;
2787 aX
, aY
, aX2
, aY2
, XX
, ScaleSz
: Integer;
2796 e_Clear(GL_COLOR_BUFFER_BIT
,
2797 GetRValue(BackColor
)/255,
2798 GetGValue(BackColor
)/255,
2799 GetBValue(BackColor
)/255);
2803 ObjCount
:= SelectedObjectCount();
2805 // Обводим выделенные объекты красной рамкой:
2806 if ObjCount
> 0 then
2808 for a
:= 0 to High(SelectedObjects
) do
2809 if SelectedObjects
[a
].Live
then
2811 Rect
:= ObjectGetRect(SelectedObjects
[a
].ObjectType
, SelectedObjects
[a
].ID
);
2815 e_DrawQuad(X
+MapOffset
.X
, Y
+MapOffset
.Y
,
2816 X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+Height
-1,
2819 // Рисуем точки изменения размеров:
2820 if (ObjCount
= 1) and
2821 (SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) then
2823 e_DrawPoint(5, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2824 e_DrawPoint(5, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 255, 255);
2825 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 255, 255);
2826 e_DrawPoint(5, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 255, 255);
2828 e_DrawPoint(3, X
+MapOffset
.X
, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2829 e_DrawPoint(3, X
+MapOffset
.X
+Width
-1, Y
+MapOffset
.Y
+(Height
div 2), 255, 0, 0);
2830 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
, 255, 0, 0);
2831 e_DrawPoint(3, X
+MapOffset
.X
+(Width
div 2), Y
+MapOffset
.Y
+Height
-1, 255, 0, 0);
2838 if DotEnable
and (PreviewMode
= 0) then
2845 for x
:= 0 to (RenderPanel
.Width
div DotStep
) do
2846 for y
:= 0 to (RenderPanel
.Height
div DotStep
) do
2847 e_DrawPoint(DotSize
, x
*DotStep
+ a
, y
*DotStep
+ a
,
2848 GetRValue(DotColor
),
2849 GetGValue(DotColor
),
2850 GetBValue(DotColor
));
2854 if (lbTextureList
.ItemIndex
<> -1) and (cbPreview
.Checked
) and
2855 (not IsSpecialTextureSel()) and (PreviewMode
= 0) then
2857 if not g_GetTexture(SelectedTexture(), ID
) then
2858 g_GetTexture('NOTEXTURE', ID
);
2859 g_GetTextureSizeByID(ID
, Width
, Height
);
2860 if UseCheckerboard
then
2862 if g_GetTexture('PREVIEW', PID
) then
2863 e_DrawFill(PID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, Width
div 16 + 1, Height
div 16 + 1, 0, True, False);
2865 e_DrawFillQuad(RenderPanel
.Width
-Width
-2, RenderPanel
.Height
-Height
-2,
2866 RenderPanel
.Width
-1, RenderPanel
.Height
-1,
2867 GetRValue(PreviewColor
), GetGValue(PreviewColor
), GetBValue(PreviewColor
), 0);
2868 e_Draw(ID
, RenderPanel
.Width
-Width
, RenderPanel
.Height
-Height
, 0, True, False);
2871 // Подсказка при выборе точки Телепорта:
2872 if SelectFlag
= SELECTFLAG_TELEPORT
then
2874 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
2875 if Data
.d2d_teleport
then
2876 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2877 MousePos
.X
+16, MousePos
.Y
-1,
2880 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+AreaSize
[AREA_DMPOINT
].Width
-1,
2881 MousePos
.Y
+AreaSize
[AREA_DMPOINT
].Height
-1, 255, 255, 255);
2883 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2884 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2885 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_TELEPORT
], gEditorFont
);
2888 // Подсказка при выборе точки появления:
2889 if SelectFlag
= SELECTFLAG_SPAWNPOINT
then
2891 e_DrawLine(2, MousePos
.X
-16, MousePos
.Y
-1,
2892 MousePos
.X
+16, MousePos
.Y
-1,
2894 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2895 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2896 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_SPAWN
], gEditorFont
);
2899 // Подсказка при выборе панели двери:
2900 if SelectFlag
= SELECTFLAG_DOOR
then
2902 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2903 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2904 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_DOOR
], gEditorFont
);
2907 // Подсказка при выборе панели с текстурой:
2908 if SelectFlag
= SELECTFLAG_TEXTURE
then
2910 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 192, 192, 192, 127);
2911 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+196, MousePos
.Y
+18, 255, 255, 255);
2912 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_TEXTURE
], gEditorFont
);
2915 // Подсказка при выборе панели индикации выстрела:
2916 if SelectFlag
= SELECTFLAG_SHOTPANEL
then
2918 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 192, 192, 192, 127);
2919 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+316, MousePos
.Y
+18, 255, 255, 255);
2920 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_SHOT
], gEditorFont
);
2923 // Подсказка при выборе панели лифта:
2924 if SelectFlag
= SELECTFLAG_LIFT
then
2926 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 192, 192, 192, 127);
2927 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+180, MousePos
.Y
+18, 255, 255, 255);
2928 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_PANEL_LIFT
], gEditorFont
);
2931 // Подсказка при выборе монстра:
2932 if SelectFlag
= SELECTFLAG_MONSTER
then
2934 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 192, 192, 192, 127);
2935 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+120, MousePos
.Y
+18, 255, 255, 255);
2936 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_MONSTER
], gEditorFont
);
2939 // Подсказка при выборе области воздействия:
2940 if DrawPressRect
then
2942 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 192, 192, 192, 127);
2943 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+204, MousePos
.Y
+18, 255, 255, 255);
2944 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, _glc
[I_HINT_EXT_AREA
], gEditorFont
);
2947 // Рисуем текстуры, если чертим панель:
2948 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and (DrawTexturePanel
) and
2949 (lbTextureList
.ItemIndex
<> -1) and (DrawRect
<> nil) and
2950 (lbPanelType
.ItemIndex
in [0..8]) and not IsSpecialTextureSel() then
2952 if not g_GetTexture(SelectedTexture(), ID
) then
2953 g_GetTexture('NOTEXTURE', ID
);
2954 g_GetTextureSizeByID(ID
, Width
, Height
);
2956 if (Abs(Right
-Left
) >= Width
) and (Abs(Bottom
-Top
) >= Height
) then
2957 e_DrawFill(ID
, Min(Left
, Right
), Min(Top
, Bottom
), Abs(Right
-Left
) div Width
,
2958 Abs(Bottom
-Top
) div Height
, 64, True, False);
2961 // Прямоугольник выделения:
2962 if DrawRect
<> nil then
2964 e_DrawQuad(Left
, Top
, Right
-1, Bottom
-1, 255, 255, 255);
2966 // Чертим мышью панель/триггер или меняем мышью их размер:
2967 if (((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
2968 not(ssCtrl
in GetKeyShiftState())) or (MouseAction
= MOUSEACTION_RESIZE
)) and
2969 (DrawPanelSize
) then
2971 e_DrawFillQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 192, 192, 192, 127);
2972 e_DrawQuad(MousePos
.X
, MousePos
.Y
, MousePos
.X
+88, MousePos
.Y
+33, 255, 255, 255);
2974 if MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
] then
2975 begin // Чертим новый
2976 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
],
2977 [Abs(MousePos
.X
-MouseLDownPos
.X
)]), gEditorFont
);
2978 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
],
2979 [Abs(MousePos
.Y
-MouseLDownPos
.Y
)]), gEditorFont
);
2981 else // Растягиваем существующий
2982 if SelectedObjects
[GetFirstSelected
].ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
] then
2984 if SelectedObjects
[GetFirstSelected
].ObjectType
= OBJECT_PANEL
then
2986 Width
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2987 Height
:= gPanels
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2991 Width
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Width
;
2992 Height
:= gTriggers
[SelectedObjects
[GetFirstSelected
].ID
].Height
;
2995 PrintBlack(MousePos
.X
+2, MousePos
.Y
+2, Format(_glc
[I_HINT_WIDTH
], [Width
]),
2997 PrintBlack(MousePos
.X
+2, MousePos
.Y
+16, Format(_glc
[I_HINT_HEIGHT
], [Height
]),
3002 // Ближайшая к курсору мыши точка на сетке:
3003 e_DrawPoint(3, MousePos
.X
, MousePos
.Y
, 0, 0, 255);
3008 // Сколько пикселов карты в 1 пикселе мини-карты:
3009 ScaleSz
:= 16 div Scale
;
3010 // Размеры мини-карты:
3011 aX
:= max(gMapInfo
.Width
div ScaleSz
, 1);
3012 aY
:= max(gMapInfo
.Height
div ScaleSz
, 1);
3013 // X-координата на RenderPanel нулевой x-координаты карты:
3014 XX
:= RenderPanel
.Width
- aX
- 1;
3016 e_DrawFillQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 0, 0, 0, 0);
3017 e_DrawQuad(XX
-1, 0, RenderPanel
.Width
-1, aY
+1, 197, 197, 197);
3019 if gPanels
<> nil then
3022 for a
:= 0 to High(gPanels
) do
3024 if PanelType
<> 0 then
3026 // Левый верхний угол:
3027 aX
:= XX
+ (X
div ScaleSz
);
3028 aY
:= 1 + (Y
div ScaleSz
);
3030 aX2
:= max(Width
div ScaleSz
, 1);
3031 aY2
:= max(Height
div ScaleSz
, 1);
3032 // Правый нижний угол:
3033 aX2
:= aX
+ aX2
- 1;
3034 aY2
:= aY
+ aY2
- 1;
3037 PANEL_WALL
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 208, 208, 208, 0);
3038 PANEL_WATER
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 0, 192, 0);
3039 PANEL_ACID1
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 0, 176, 0, 0);
3040 PANEL_ACID2
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 176, 0, 0, 0);
3041 PANEL_STEP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 128, 128, 128, 0);
3042 PANEL_LIFTUP
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 72, 36, 0);
3043 PANEL_LIFTDOWN
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 116, 124, 96, 0);
3044 PANEL_LIFTLEFT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 200, 80, 4, 0);
3045 PANEL_LIFTRIGHT
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 252, 140, 56, 0);
3046 PANEL_OPENDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 100, 220, 92, 0);
3047 PANEL_CLOSEDOOR
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 212, 184, 64, 0);
3048 PANEL_BLOCKMON
: e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 192, 0, 192, 0);
3052 // Рисуем красным выделенные панели:
3053 if SelectedObjects
<> nil then
3054 for b
:= 0 to High(SelectedObjects
) do
3055 with SelectedObjects
[b
] do
3056 if Live
and (ObjectType
= OBJECT_PANEL
) then
3057 with gPanels
[SelectedObjects
[b
].ID
] do
3058 if PanelType
and not(PANEL_BACK
or PANEL_FORE
) <> 0 then
3060 // Левый верхний угол:
3061 aX
:= XX
+ (X
div ScaleSz
);
3062 aY
:= 1 + (Y
div ScaleSz
);
3064 aX2
:= max(Width
div ScaleSz
, 1);
3065 aY2
:= max(Height
div ScaleSz
, 1);
3066 // Правый нижний угол:
3067 aX2
:= aX
+ aX2
- 1;
3068 aY2
:= aY
+ aY2
- 1;
3070 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0, 0)
3074 if (gMapInfo
.Width
> RenderPanel
.Width
) or
3075 (gMapInfo
.Height
> RenderPanel
.Height
) then
3077 // Окно, показывающее текущее положение экрана на карте:
3079 x
:= max(min(RenderPanel
.Width
, gMapInfo
.Width
) div ScaleSz
, 1);
3080 y
:= max(min(RenderPanel
.Height
, gMapInfo
.Height
) div ScaleSz
, 1);
3081 // Левый верхний угол:
3082 aX
:= XX
+ ((-MapOffset
.X
) div ScaleSz
);
3083 aY
:= 1 + ((-MapOffset
.Y
) div ScaleSz
);
3084 // Правый нижний угол:
3088 e_DrawFillQuad(aX
, aY
, aX2
, aY2
, 127, 192, 127, 127, B_BLEND
);
3089 e_DrawQuad(aX
, aY
, aX2
, aY2
, 255, 0, 0);
3094 RenderPanel
.SwapBuffers();
3097 procedure TMainForm
.FormResize(Sender
: TObject
);
3099 e_SetViewPort(0, 0, RenderPanel
.Width
, RenderPanel
.Height
);
3101 if gMapInfo
.Width
>= RenderPanel
.Width
then
3102 sbHorizontal
.Max
:= Normalize16(gMapInfo
.Width
-RenderPanel
.Width
+16)
3104 sbHorizontal
.Max
:= 0;
3106 if gMapInfo
.Height
>= RenderPanel
.Height
then
3107 sbVertical
.Max
:= Normalize16(gMapInfo
.Height
-RenderPanel
.Height
+16)
3109 sbVertical
.Max
:= 0;
3111 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
3112 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
3115 procedure SelectNextObject(X
, Y
: Integer; ObjectType
: Byte; ID
: DWORD
);
3120 j_max
:= 0; // shut up compiler
3124 res
:= (gPanels
<> nil) and
3125 PanelInShownLayer(gPanels
[ID
].PanelType
) and
3126 g_CollidePoint(X
, Y
, gPanels
[ID
].X
, gPanels
[ID
].Y
,
3128 gPanels
[ID
].Height
);
3129 j_max
:= Length(gPanels
) - 1;
3134 res
:= (gItems
<> nil) and
3135 LayerEnabled
[LAYER_ITEMS
] and
3136 g_CollidePoint(X
, Y
, gItems
[ID
].X
, gItems
[ID
].Y
,
3137 ItemSize
[gItems
[ID
].ItemType
][0],
3138 ItemSize
[gItems
[ID
].ItemType
][1]);
3139 j_max
:= Length(gItems
) - 1;
3144 res
:= (gMonsters
<> nil) and
3145 LayerEnabled
[LAYER_MONSTERS
] and
3146 g_CollidePoint(X
, Y
, gMonsters
[ID
].X
, gMonsters
[ID
].Y
,
3147 MonsterSize
[gMonsters
[ID
].MonsterType
].Width
,
3148 MonsterSize
[gMonsters
[ID
].MonsterType
].Height
);
3149 j_max
:= Length(gMonsters
) - 1;
3154 res
:= (gAreas
<> nil) and
3155 LayerEnabled
[LAYER_AREAS
] and
3156 g_CollidePoint(X
, Y
, gAreas
[ID
].X
, gAreas
[ID
].Y
,
3157 AreaSize
[gAreas
[ID
].AreaType
].Width
,
3158 AreaSize
[gAreas
[ID
].AreaType
].Height
);
3159 j_max
:= Length(gAreas
) - 1;
3164 res
:= (gTriggers
<> nil) and
3165 LayerEnabled
[LAYER_TRIGGERS
] and
3166 g_CollidePoint(X
, Y
, gTriggers
[ID
].X
, gTriggers
[ID
].Y
,
3167 gTriggers
[ID
].Width
,
3168 gTriggers
[ID
].Height
);
3169 j_max
:= Length(gTriggers
) - 1;
3179 // Перебор ID: от ID-1 до 0; потом от High до ID+1:
3188 if j
= Integer(ID
) then
3193 res
:= PanelInShownLayer(gPanels
[j
].PanelType
) and
3194 g_CollidePoint(X
, Y
, gPanels
[j
].X
, gPanels
[j
].Y
,
3198 res
:= (gItems
[j
].ItemType
<> ITEM_NONE
) and
3199 g_CollidePoint(X
, Y
, gItems
[j
].X
, gItems
[j
].Y
,
3200 ItemSize
[gItems
[j
].ItemType
][0],
3201 ItemSize
[gItems
[j
].ItemType
][1]);
3203 res
:= (gMonsters
[j
].MonsterType
<> MONSTER_NONE
) and
3204 g_CollidePoint(X
, Y
, gMonsters
[j
].X
, gMonsters
[j
].Y
,
3205 MonsterSize
[gMonsters
[j
].MonsterType
].Width
,
3206 MonsterSize
[gMonsters
[j
].MonsterType
].Height
);
3208 res
:= (gAreas
[j
].AreaType
<> AREA_NONE
) and
3209 g_CollidePoint(X
, Y
, gAreas
[j
].X
, gAreas
[j
].Y
,
3210 AreaSize
[gAreas
[j
].AreaType
].Width
,
3211 AreaSize
[gAreas
[j
].AreaType
].Height
);
3213 res
:= (gTriggers
[j
].TriggerType
<> TRIGGER_NONE
) and
3214 g_CollidePoint(X
, Y
, gTriggers
[j
].X
, gTriggers
[j
].Y
,
3216 gTriggers
[j
].Height
);
3223 SetLength(SelectedObjects
, 1);
3225 SelectedObjects
[0].ObjectType
:= ObjectType
;
3226 SelectedObjects
[0].ID
:= j
;
3227 SelectedObjects
[0].Live
:= True;
3235 procedure TMainForm
.RenderPanelMouseDown(Sender
: TObject
;
3236 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3240 c1
, c2
, c3
, c4
: Boolean;
3246 MainForm
.ActiveControl
:= RenderPanel
;
3247 RenderPanel
.SetFocus();
3249 RenderPanelMouseMove(RenderPanel
, Shift
, X
, Y
);
3251 if Button
= mbLeft
then // Left Mouse Button
3253 // Двигаем карту с помощью мыши и мини-карты:
3255 g_CollidePoint(X
, Y
,
3256 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3258 max(gMapInfo
.Width
div (16 div Scale
), 1),
3259 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3262 MouseAction
:= MOUSEACTION_MOVEMAP
;
3264 else // Ставим предмет/монстра/область:
3265 if (pcObjects
.ActivePageIndex
in [1, 2, 3]) and
3266 (not (ssShift
in Shift
)) then
3268 case pcObjects
.ActivePageIndex
of
3270 if lbItemList
.ItemIndex
= -1 then
3271 ErrorMessageBox(_lc
[I_MSG_CHOOSE_ITEM
])
3274 item
.ItemType
:= lbItemList
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
3275 if item
.ItemType
>= ITEM_WEAPON_KASTET
then
3276 item
.ItemType
:= item
.ItemType
+ 2;
3277 item
.X
:= MousePos
.X
-MapOffset
.X
;
3278 item
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3280 if not (ssCtrl
in Shift
) then
3282 item
.X
:= item
.X
- (ItemSize
[item
.ItemType
][0] div 2);
3283 item
.Y
:= item
.Y
- ItemSize
[item
.ItemType
][1];
3286 item
.OnlyDM
:= cbOnlyDM
.Checked
;
3287 item
.Fall
:= cbFall
.Checked
;
3288 Undo_Add(OBJECT_ITEM
, AddItem(item
));
3291 if lbMonsterList
.ItemIndex
= -1 then
3292 ErrorMessageBox(_lc
[I_MSG_CHOOSE_MONSTER
])
3295 monster
.MonsterType
:= lbMonsterList
.ItemIndex
+ MONSTER_DEMON
;
3296 monster
.X
:= MousePos
.X
-MapOffset
.X
;
3297 monster
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3299 if not (ssCtrl
in Shift
) then
3301 monster
.X
:= monster
.X
- (MonsterSize
[monster
.MonsterType
].Width
div 2);
3302 monster
.Y
:= monster
.Y
- MonsterSize
[monster
.MonsterType
].Height
;
3305 if rbMonsterLeft
.Checked
then
3306 monster
.Direction
:= D_LEFT
3308 monster
.Direction
:= D_RIGHT
;
3309 Undo_Add(OBJECT_MONSTER
, AddMonster(monster
));
3312 if lbAreasList
.ItemIndex
= -1 then
3313 ErrorMessageBox(_lc
[I_MSG_CHOOSE_AREA
])
3315 if (lbAreasList
.ItemIndex
+ 1) <> AREA_DOMFLAG
then
3317 area
.AreaType
:= lbAreasList
.ItemIndex
+ AREA_PLAYERPOINT1
;
3318 area
.X
:= MousePos
.X
-MapOffset
.X
;
3319 area
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3321 if not (ssCtrl
in Shift
) then
3323 area
.X
:= area
.X
- (AreaSize
[area
.AreaType
].Width
div 2);
3324 area
.Y
:= area
.Y
- AreaSize
[area
.AreaType
].Height
;
3327 if rbAreaLeft
.Checked
then
3328 area
.Direction
:= D_LEFT
3330 area
.Direction
:= D_RIGHT
;
3331 Undo_Add(OBJECT_AREA
, AddArea(area
));
3337 i
:= GetFirstSelected();
3339 // Выбираем объект под текущим:
3340 if (SelectedObjects
<> nil) and
3341 (ssShift
in Shift
) and (i
>= 0) and
3342 (SelectedObjects
[i
].Live
) then
3344 if SelectedObjectCount() = 1 then
3345 SelectNextObject(X
-MapOffset
.X
, Y
-MapOffset
.Y
,
3346 SelectedObjects
[i
].ObjectType
,
3347 SelectedObjects
[i
].ID
);
3351 // Рисуем область триггера "Расширитель":
3352 if DrawPressRect
and (i
>= 0) and
3353 (SelectedObjects
[i
].ObjectType
= OBJECT_TRIGGER
) and
3354 (gTriggers
[SelectedObjects
[i
].ID
].TriggerType
in
3355 [TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
]) then
3356 MouseAction
:= MOUSEACTION_DRAWPRESS
3357 else // Рисуем панель:
3358 if pcObjects
.ActivePageIndex
= 0 then
3360 if (lbPanelType
.ItemIndex
>= 0) then
3361 MouseAction
:= MOUSEACTION_DRAWPANEL
3363 else // Рисуем триггер:
3364 if (lbTriggersList
.ItemIndex
>= 0) then
3366 MouseAction
:= MOUSEACTION_DRAWTRIGGER
;
3370 end; // if Button = mbLeft
3372 if Button
= mbRight
then // Right Mouse Button
3374 // Клик по мини-карте:
3376 g_CollidePoint(X
, Y
,
3377 RenderPanel
.Width
-max(gMapInfo
.Width
div (16 div Scale
), 1)-1,
3379 max(gMapInfo
.Width
div (16 div Scale
), 1),
3380 max(gMapInfo
.Height
div (16 div Scale
), 1) ) then
3382 MouseAction
:= MOUSEACTION_NOACTION
;
3384 else // Нужно что-то выбрать мышью:
3385 if SelectFlag
<> SELECTFLAG_NONE
then
3388 SELECTFLAG_TELEPORT
:
3389 // Точку назначения телепортации:
3390 with gTriggers
[SelectedObjects
[
3391 GetFirstSelected() ].ID
].Data
.TargetPoint
do
3393 X
:= MousePos
.X
-MapOffset
.X
;
3394 Y
:= MousePos
.Y
-MapOffset
.Y
;
3397 SELECTFLAG_SPAWNPOINT
:
3398 // Точку создания монстра:
3399 with gTriggers
[SelectedObjects
[GetFirstSelected()].ID
] do
3400 if TriggerType
= TRIGGER_SPAWNMONSTER
then
3402 Data
.MonPos
.X
:= MousePos
.X
-MapOffset
.X
;
3403 Data
.MonPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3405 else if TriggerType
= TRIGGER_SPAWNITEM
then
3406 begin // Точка создания предмета:
3407 Data
.ItemPos
.X
:= MousePos
.X
-MapOffset
.X
;
3408 Data
.ItemPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3410 else if TriggerType
= TRIGGER_SHOT
then
3411 begin // Точка создания выстрела:
3412 Data
.ShotPos
.X
:= MousePos
.X
-MapOffset
.X
;
3413 Data
.ShotPos
.Y
:= MousePos
.Y
-MapOffset
.Y
;
3419 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3421 2, 2, OBJECT_PANEL
, True);
3422 if IDArray
<> nil then
3424 for i
:= 0 to High(IDArray
) do
3425 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3426 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
) then
3428 gTriggers
[SelectedObjects
[
3429 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3434 gTriggers
[SelectedObjects
[
3435 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3439 // Панель с текстурой:
3441 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3443 2, 2, OBJECT_PANEL
, True);
3444 if IDArray
<> nil then
3446 for i
:= 0 to High(IDArray
) do
3447 if ((gPanels
[IDArray
[i
]].PanelType
in
3448 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3449 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3451 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3452 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3453 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3455 gTriggers
[SelectedObjects
[
3456 GetFirstSelected() ].ID
].TexturePanel
:= IDArray
[i
];
3461 gTriggers
[SelectedObjects
[
3462 GetFirstSelected() ].ID
].TexturePanel
:= -1;
3468 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3470 2, 2, OBJECT_PANEL
, True);
3471 if IDArray
<> nil then
3473 for i
:= 0 to High(IDArray
) do
3474 if (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTUP
) or
3475 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTDOWN
) or
3476 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTLEFT
) or
3477 (gPanels
[IDArray
[i
]].PanelType
= PANEL_LIFTRIGHT
) then
3479 gTriggers
[SelectedObjects
[
3480 GetFirstSelected() ].ID
].Data
.PanelID
:= IDArray
[i
];
3485 gTriggers
[SelectedObjects
[
3486 GetFirstSelected() ].ID
].Data
.PanelID
:= -1;
3492 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3494 2, 2, OBJECT_MONSTER
, False);
3495 if IDArray
<> nil then
3496 gTriggers
[SelectedObjects
[
3497 GetFirstSelected() ].ID
].Data
.MonsterID
:= IDArray
[0]+1
3499 gTriggers
[SelectedObjects
[
3500 GetFirstSelected() ].ID
].Data
.MonsterID
:= 0;
3503 SELECTFLAG_SHOTPANEL
:
3504 // Панель индикации выстрела:
3506 if gTriggers
[SelectedObjects
[
3507 GetFirstSelected() ].ID
].TriggerType
= TRIGGER_SHOT
then
3509 IDArray
:= ObjectInRect(X
-MapOffset
.X
,
3511 2, 2, OBJECT_PANEL
, True);
3512 if IDArray
<> nil then
3514 for i
:= 0 to High(IDArray
) do
3515 if ((gPanels
[IDArray
[i
]].PanelType
in
3516 [PANEL_WALL
, PANEL_BACK
, PANEL_FORE
,
3517 PANEL_WATER
, PANEL_ACID1
, PANEL_ACID2
,
3519 (gPanels
[IDArray
[i
]].PanelType
= PANEL_OPENDOOR
) or
3520 (gPanels
[IDArray
[i
]].PanelType
= PANEL_CLOSEDOOR
)) and
3521 (gPanels
[IDArray
[i
]].TextureName
<> '') then
3523 gTriggers
[SelectedObjects
[
3524 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= IDArray
[i
];
3529 gTriggers
[SelectedObjects
[
3530 GetFirstSelected() ].ID
].Data
.ShotPanelID
:= -1;
3535 SelectFlag
:= SELECTFLAG_SELECTED
;
3537 else // if SelectFlag <> SELECTFLAG_NONE...
3539 // Что уже выбрано и не нажат Ctrl:
3540 if (SelectedObjects
<> nil) and
3541 (not (ssCtrl
in Shift
)) then
3542 for i
:= 0 to High(SelectedObjects
) do
3543 with SelectedObjects
[i
] do
3546 if (ObjectType
in [OBJECT_PANEL
, OBJECT_TRIGGER
]) and
3547 (SelectedObjectCount() = 1) then
3549 Rect
:= ObjectGetRect(ObjectType
, ID
);
3551 c1
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3552 Rect
.X
-2, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3553 c2
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3554 Rect
.X
+Rect
.Width
-3, Rect
.Y
+(Rect
.Height
div 2)-2, 4, 4);
3555 c3
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3556 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
-2, 4, 4);
3557 c4
:= g_Collide(X
-MapOffset
.X
-1, Y
-MapOffset
.Y
-1, 2, 2,
3558 Rect
.X
+(Rect
.Width
div 2)-2, Rect
.Y
+Rect
.Height
-3, 4, 4);
3560 // Меняем размер панели или триггера:
3561 if c1
or c2
or c3
or c4
then
3563 MouseAction
:= MOUSEACTION_RESIZE
;
3564 LastMovePoint
:= MousePos
;
3568 ResizeType
:= RESIZETYPE_HORIZONTAL
;
3570 ResizeDirection
:= RESIZEDIR_LEFT
3572 ResizeDirection
:= RESIZEDIR_RIGHT
;
3573 RenderPanel
.Cursor
:= crSizeWE
;
3577 ResizeType
:= RESIZETYPE_VERTICAL
;
3579 ResizeDirection
:= RESIZEDIR_UP
3581 ResizeDirection
:= RESIZEDIR_DOWN
;
3582 RenderPanel
.Cursor
:= crSizeNS
;
3589 // Перемещаем панель или триггер:
3590 if ObjectCollide(ObjectType
, ID
,
3592 Y
-MapOffset
.Y
-1, 2, 2) then
3594 MouseAction
:= MOUSEACTION_MOVEOBJ
;
3595 LastMovePoint
:= MousePos
;
3601 end; // if Button = mbRight
3603 MouseRDown
:= Button
= mbRight
;
3605 MouseRDownPos
:= MousePos
;
3607 MouseLDown
:= Button
= mbLeft
;
3609 MouseLDownPos
:= MousePos
;
3612 procedure TMainForm
.RenderPanelMouseUp(Sender
: TObject
;
3613 Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer);
3618 rSelectRect
: Boolean;
3619 wWidth
, wHeight
: Word;
3622 procedure SelectObjects(ObjectType
: Byte);
3627 IDArray
:= ObjectInRect(rRect
.X
, rRect
.Y
,
3628 rRect
.Width
, rRect
.Height
,
3629 ObjectType
, rSelectRect
);
3631 if IDArray
<> nil then
3632 for i
:= 0 to High(IDArray
) do
3633 SelectObject(ObjectType
, IDArray
[i
], (ssCtrl
in Shift
) or rSelectRect
);
3636 if Button
= mbLeft
then
3637 MouseLDown
:= False;
3638 if Button
= mbRight
then
3639 MouseRDown
:= False;
3642 ResizeType
:= RESIZETYPE_NONE
;
3645 if Button
= mbLeft
then // Left Mouse Button
3647 if MouseAction
<> MOUSEACTION_NONE
then
3648 begin // Было действие мышью
3649 // Мышь сдвинулась во время удержания клавиши,
3650 // либо активирован режим быстрого рисования:
3651 if ((MousePos
.X
<> MouseLDownPos
.X
) and
3652 (MousePos
.Y
<> MouseLDownPos
.Y
)) or
3653 ((MouseAction
in [MOUSEACTION_DRAWPANEL
, MOUSEACTION_DRAWTRIGGER
]) and
3654 (ssCtrl
in Shift
)) then
3657 MOUSEACTION_DRAWPANEL
:
3659 // Фон или передний план без текстуры - ошибка:
3660 if (lbPanelType
.ItemIndex
in [1, 2]) and
3661 (lbTextureList
.ItemIndex
= -1) then
3662 ErrorMessageBox(_lc
[I_MSG_CHOOSE_TEXTURE
])
3663 else // Назначаем параметры панели:
3665 case lbPanelType
.ItemIndex
of
3666 0: Panel
.PanelType
:= PANEL_WALL
;
3667 1: Panel
.PanelType
:= PANEL_BACK
;
3668 2: Panel
.PanelType
:= PANEL_FORE
;
3669 3: Panel
.PanelType
:= PANEL_OPENDOOR
;
3670 4: Panel
.PanelType
:= PANEL_CLOSEDOOR
;
3671 5: Panel
.PanelType
:= PANEL_STEP
;
3672 6: Panel
.PanelType
:= PANEL_WATER
;
3673 7: Panel
.PanelType
:= PANEL_ACID1
;
3674 8: Panel
.PanelType
:= PANEL_ACID2
;
3675 9: Panel
.PanelType
:= PANEL_LIFTUP
;
3676 10: Panel
.PanelType
:= PANEL_LIFTDOWN
;
3677 11: Panel
.PanelType
:= PANEL_LIFTLEFT
;
3678 12: Panel
.PanelType
:= PANEL_LIFTRIGHT
;
3679 13: Panel
.PanelType
:= PANEL_BLOCKMON
;
3682 Panel
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3683 Panel
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3684 if ssCtrl
in Shift
then
3688 if (lbTextureList
.ItemIndex
<> -1) and
3689 (not IsSpecialTextureSel()) then
3691 if not g_GetTexture(SelectedTexture(), TextureID
) then
3692 g_GetTexture('NOTEXTURE', TextureID
);
3693 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
3695 Panel
.Width
:= wWidth
;
3696 Panel
.Height
:= wHeight
;
3700 Panel
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3701 Panel
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3704 // Лифты, блокМон или отсутствие текстуры - пустая текстура:
3705 if (lbPanelType
.ItemIndex
in [9, 10, 11, 12, 13]) or
3706 (lbTextureList
.ItemIndex
= -1) then
3708 Panel
.TextureHeight
:= 1;
3709 Panel
.TextureWidth
:= 1;
3710 Panel
.TextureName
:= '';
3711 Panel
.TextureID
:= TEXTURE_SPECIAL_NONE
;
3713 else // Есть текстура:
3715 Panel
.TextureName
:= SelectedTexture();
3717 // Обычная текстура:
3718 if not IsSpecialTextureSel() then
3720 g_GetTextureSizeByName(Panel
.TextureName
,
3721 Panel
.TextureWidth
, Panel
.TextureHeight
);
3722 g_GetTexture(Panel
.TextureName
, Panel
.TextureID
);
3724 else // Спец.текстура:
3726 Panel
.TextureHeight
:= 1;
3727 Panel
.TextureWidth
:= 1;
3728 Panel
.TextureID
:= SpecialTextureID(SelectedTexture());
3733 Panel
.Blending
:= False;
3735 Undo_Add(OBJECT_PANEL
, AddPanel(Panel
));
3739 // Рисовали триггер:
3740 MOUSEACTION_DRAWTRIGGER
:
3742 trigger
.X
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3743 trigger
.Y
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3744 if ssCtrl
in Shift
then
3748 trigger
.Width
:= wWidth
;
3749 trigger
.Height
:= wHeight
;
3753 trigger
.Width
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3754 trigger
.Height
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3757 trigger
.Enabled
:= True;
3758 trigger
.TriggerType
:= lbTriggersList
.ItemIndex
+1;
3759 trigger
.TexturePanel
:= -1;
3762 trigger
.ActivateType
:= 0;
3764 if clbActivationType
.Checked
[0] then
3765 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERCOLLIDE
;
3766 if clbActivationType
.Checked
[1] then
3767 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERCOLLIDE
;
3768 if clbActivationType
.Checked
[2] then
3769 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_PLAYERPRESS
;
3770 if clbActivationType
.Checked
[3] then
3771 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_MONSTERPRESS
;
3772 if clbActivationType
.Checked
[4] then
3773 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_SHOT
;
3774 if clbActivationType
.Checked
[5] then
3775 trigger
.ActivateType
:= Trigger
.ActivateType
or ACTIVATE_NOMONSTER
;
3777 // Необходимые для активации ключи:
3780 if clbKeys
.Checked
[0] then
3781 trigger
.Key
:= Trigger
.Key
or KEY_RED
;
3782 if clbKeys
.Checked
[1] then
3783 trigger
.Key
:= Trigger
.Key
or KEY_GREEN
;
3784 if clbKeys
.Checked
[2] then
3785 trigger
.Key
:= Trigger
.Key
or KEY_BLUE
;
3786 if clbKeys
.Checked
[3] then
3787 trigger
.Key
:= Trigger
.Key
or KEY_REDTEAM
;
3788 if clbKeys
.Checked
[4] then
3789 trigger
.Key
:= Trigger
.Key
or KEY_BLUETEAM
;
3791 // Параметры триггера:
3792 FillByte(trigger
.Data
.Default
[0], 128, 0);
3794 case trigger
.TriggerType
of
3795 // Переключаемая панель:
3796 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
3797 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
3798 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
3800 Trigger
.Data
.PanelID
:= -1;
3806 trigger
.Data
.TargetPoint
.X
:= trigger
.X
-64;
3807 trigger
.Data
.TargetPoint
.Y
:= trigger
.Y
-64;
3808 trigger
.Data
.d2d_teleport
:= True;
3809 trigger
.Data
.TlpDir
:= 0;
3812 // Изменение других триггеров:
3813 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
,
3816 trigger
.Data
.Count
:= 1;
3822 trigger
.Data
.Volume
:= 255;
3823 trigger
.Data
.Pan
:= 127;
3824 trigger
.Data
.PlayCount
:= 1;
3825 trigger
.Data
.Local
:= True;
3826 trigger
.Data
.SoundSwitch
:= False;
3832 trigger
.Data
.MusicAction
:= 1;
3835 // Создание монстра:
3836 TRIGGER_SPAWNMONSTER
:
3838 trigger
.Data
.MonType
:= MONSTER_ZOMBY
;
3839 trigger
.Data
.MonPos
.X
:= trigger
.X
-64;
3840 trigger
.Data
.MonPos
.Y
:= trigger
.Y
-64;
3841 trigger
.Data
.MonHealth
:= 0;
3842 trigger
.Data
.MonActive
:= False;
3843 trigger
.Data
.MonCount
:= 1;
3846 // Создание предмета:
3849 trigger
.Data
.ItemType
:= ITEM_AMMO_BULLETS
;
3850 trigger
.Data
.ItemPos
.X
:= trigger
.X
-64;
3851 trigger
.Data
.ItemPos
.Y
:= trigger
.Y
-64;
3852 trigger
.Data
.ItemOnlyDM
:= False;
3853 trigger
.Data
.ItemFalls
:= False;
3854 trigger
.Data
.ItemCount
:= 1;
3855 trigger
.Data
.ItemMax
:= 0;
3856 trigger
.Data
.ItemDelay
:= 0;
3862 trigger
.Data
.PushAngle
:= 90;
3863 trigger
.Data
.PushForce
:= 10;
3864 trigger
.Data
.ResetVel
:= True;
3869 trigger
.Data
.ScoreCount
:= 1;
3870 trigger
.Data
.ScoreCon
:= True;
3871 trigger
.Data
.ScoreMsg
:= True;
3876 trigger
.Data
.MessageKind
:= 0;
3877 trigger
.Data
.MessageSendTo
:= 0;
3878 trigger
.Data
.MessageText
:= '';
3879 trigger
.Data
.MessageTime
:= 144;
3884 trigger
.Data
.DamageValue
:= 5;
3885 trigger
.Data
.DamageInterval
:= 12;
3890 trigger
.Data
.HealValue
:= 5;
3891 trigger
.Data
.HealInterval
:= 36;
3896 trigger
.Data
.ShotType
:= TRIGGER_SHOT_BULLET
;
3897 trigger
.Data
.ShotSound
:= True;
3898 trigger
.Data
.ShotPanelID
:= -1;
3899 trigger
.Data
.ShotTarget
:= 0;
3900 trigger
.Data
.ShotIntSight
:= 0;
3901 trigger
.Data
.ShotAim
:= TRIGGER_SHOT_AIM_DEFAULT
;
3902 trigger
.Data
.ShotPos
.X
:= trigger
.X
-64;
3903 trigger
.Data
.ShotPos
.Y
:= trigger
.Y
-64;
3904 trigger
.Data
.ShotAngle
:= 0;
3905 trigger
.Data
.ShotWait
:= 18;
3906 trigger
.Data
.ShotAccuracy
:= 0;
3907 trigger
.Data
.ShotAmmo
:= 0;
3908 trigger
.Data
.ShotIntReload
:= 0;
3913 trigger
.Data
.FXCount
:= 1;
3914 trigger
.Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
3915 trigger
.Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
3916 trigger
.Data
.FXColorR
:= 0;
3917 trigger
.Data
.FXColorG
:= 0;
3918 trigger
.Data
.FXColorB
:= 255;
3919 trigger
.Data
.FXPos
:= TRIGGER_EFFECT_POS_CENTER
;
3920 trigger
.Data
.FXWait
:= 1;
3921 trigger
.Data
.FXVelX
:= 0;
3922 trigger
.Data
.FXVelY
:= -20;
3923 trigger
.Data
.FXSpreadL
:= 5;
3924 trigger
.Data
.FXSpreadR
:= 5;
3925 trigger
.Data
.FXSpreadU
:= 4;
3926 trigger
.Data
.FXSpreadD
:= 0;
3930 Undo_Add(OBJECT_TRIGGER
, AddTrigger(trigger
));
3933 // Рисовали область триггера "Расширитель":
3934 MOUSEACTION_DRAWPRESS
:
3935 with gTriggers
[SelectedObjects
[GetFirstSelected
].ID
] do
3937 Data
.tX
:= Min(MousePos
.X
-MapOffset
.X
, MouseLDownPos
.X
-MapOffset
.X
);
3938 Data
.tY
:= Min(MousePos
.Y
-MapOffset
.Y
, MouseLDownPos
.Y
-MapOffset
.Y
);
3939 Data
.tWidth
:= Abs(MousePos
.X
-MouseLDownPos
.X
);
3940 Data
.tHeight
:= Abs(MousePos
.Y
-MouseLDownPos
.Y
);
3942 DrawPressRect
:= False;
3946 MouseAction
:= MOUSEACTION_NONE
;
3948 end // if Button = mbLeft...
3949 else // Right Mouse Button:
3951 if MouseAction
= MOUSEACTION_NOACTION
then
3953 MouseAction
:= MOUSEACTION_NONE
;
3957 // Объект передвинут или изменен в размере:
3958 if MouseAction
in [MOUSEACTION_MOVEOBJ
, MOUSEACTION_RESIZE
] then
3960 MouseAction
:= MOUSEACTION_NONE
;
3965 // Еще не все выбрали:
3966 if SelectFlag
<> SELECTFLAG_NONE
then
3968 if SelectFlag
= SELECTFLAG_SELECTED
then
3969 SelectFlag
:= SELECTFLAG_NONE
;
3974 // Мышь сдвинулась во время удержания клавиши:
3975 if (MousePos
.X
<> MouseRDownPos
.X
) and
3976 (MousePos
.Y
<> MouseRDownPos
.Y
) then
3978 rSelectRect
:= True;
3980 rRect
.X
:= Min(MousePos
.X
, MouseRDownPos
.X
)-MapOffset
.X
;
3981 rRect
.Y
:= Min(MousePos
.Y
, MouseRDownPos
.Y
)-MapOffset
.Y
;
3982 rRect
.Width
:= Abs(MousePos
.X
-MouseRDownPos
.X
);
3983 rRect
.Height
:= Abs(MousePos
.Y
-MouseRDownPos
.Y
);
3985 else // Мышь не сдвинулась - нет прямоугольника:
3987 rSelectRect
:= False;
3989 rRect
.X
:= X
-MapOffset
.X
-1;
3990 rRect
.Y
:= Y
-MapOffset
.Y
-1;
3995 // Если зажат Ctrl - выделять еще, иначе только один выделенный объект:
3996 if not (ssCtrl
in Shift
) then
3997 RemoveSelectFromObjects();
3999 // Выделяем всё в выбранном прямоугольнике:
4000 if (ssCtrl
in Shift
) and (ssAlt
in Shift
) then
4002 SelectObjects(OBJECT_PANEL
);
4003 SelectObjects(OBJECT_ITEM
);
4004 SelectObjects(OBJECT_MONSTER
);
4005 SelectObjects(OBJECT_AREA
);
4006 SelectObjects(OBJECT_TRIGGER
);
4009 SelectObjects(pcObjects
.ActivePageIndex
+1);
4015 procedure TMainForm
.RenderPanelPaint(Sender
: TObject
);
4020 function TMainForm
.RenderMousePos(): Types
.TPoint
;
4022 Result
:= RenderPanel
.ScreenToClient(Mouse
.CursorPos
);
4025 procedure TMainForm
.RecountSelectedObjects();
4027 if SelectedObjectCount() = 0 then
4028 StatusBar
.Panels
[0].Text := ''
4030 StatusBar
.Panels
[0].Text := Format(_lc
[I_CAP_STAT_SELECTED
], [SelectedObjectCount()]);
4033 procedure TMainForm
.RenderPanelMouseMove(Sender
: TObject
;
4034 Shift
: TShiftState
; X
, Y
: Integer);
4037 dWidth
, dHeight
: Integer;
4040 wWidth
, wHeight
: Word;
4042 _id
:= GetFirstSelected();
4045 // Рисуем панель с текстурой, сетка - размеры текстуры:
4046 if (MouseAction
= MOUSEACTION_DRAWPANEL
) and
4047 (lbPanelType
.ItemIndex
in [0..8]) and
4048 (lbTextureList
.ItemIndex
<> -1) and
4049 (not IsSpecialTextureSel()) then
4051 sX
:= StrToIntDef(lTextureWidth
.Caption
, DotStep
);
4052 sY
:= StrToIntDef(lTextureHeight
.Caption
, DotStep
);
4055 // Меняем размер панели с текстурой, сетка - размеры текстуры:
4056 if (MouseAction
= MOUSEACTION_RESIZE
) and
4057 ( (SelectedObjects
[_id
].ObjectType
= OBJECT_PANEL
) and
4058 IsTexturedPanel(gPanels
[SelectedObjects
[_id
].ID
].PanelType
) and
4059 (gPanels
[SelectedObjects
[_id
].ID
].TextureName
<> '') and
4060 (not IsSpecialTexture(gPanels
[SelectedObjects
[_id
].ID
].TextureName
)) ) then
4062 sX
:= gPanels
[SelectedObjects
[_id
].ID
].TextureWidth
;
4063 sY
:= gPanels
[SelectedObjects
[_id
].ID
].TextureHeight
;
4066 // Выравнивание по сетке:
4072 else // Нет выравнивания по сетке:
4078 // Новая позиция мыши:
4080 begin // Зажата левая кнопка мыши
4081 MousePos
.X
:= (Round((X
-MouseLDownPos
.X
)/sX
)*sX
)+MouseLDownPos
.X
;
4082 MousePos
.Y
:= (Round((Y
-MouseLDownPos
.Y
)/sY
)*sY
)+MouseLDownPos
.Y
;
4086 begin // Зажата правая кнопка мыши
4087 MousePos
.X
:= (Round((X
-MouseRDownPos
.X
)/sX
)*sX
)+MouseRDownPos
.X
;
4088 MousePos
.Y
:= (Round((Y
-MouseRDownPos
.Y
)/sY
)*sY
)+MouseRDownPos
.Y
;
4091 begin // Кнопки мыши не зажаты
4092 MousePos
.X
:= (Round(X
/sX
)*sX
);
4093 MousePos
.Y
:= (Round(Y
/sY
)*sY
);
4096 // Изменение размера закончилось - ставим обычный курсор:
4097 if ResizeType
= RESIZETYPE_NONE
then
4098 RenderPanel
.Cursor
:= crDefault
;
4100 // Зажата только правая кнопка мыши:
4101 if (not MouseLDown
) and (MouseRDown
) then
4103 // Рисуем прямоугольник выделения:
4104 if MouseAction
= MOUSEACTION_NONE
then
4106 if DrawRect
= nil then
4108 DrawRect
.Top
:= MouseRDownPos
.y
;
4109 DrawRect
.Left
:= MouseRDownPos
.x
;
4110 DrawRect
.Bottom
:= MousePos
.y
;
4111 DrawRect
.Right
:= MousePos
.x
;
4114 // Двигаем выделенные объекты:
4115 if MouseAction
= MOUSEACTION_MOVEOBJ
then
4117 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
,
4118 MousePos
.X
-LastMovePoint
.X
+WASDOffset
.X
,
4119 MousePos
.Y
-LastMovePoint
.Y
+WASDOffset
.Y
);
4124 // Меняем размер выделенного объекта:
4125 if MouseAction
= MOUSEACTION_RESIZE
then
4127 if (SelectedObjectCount
= 1) and
4128 (SelectedObjects
[GetFirstSelected
].Live
) then
4130 dWidth
:= MousePos
.X
-LastMovePoint
.X
+WASDOffset
.X
;
4131 dHeight
:= MousePos
.Y
-LastMovePoint
.Y
+WASDOffset
.Y
;
4136 RESIZETYPE_VERTICAL
: dWidth
:= 0;
4137 RESIZETYPE_HORIZONTAL
: dHeight
:= 0;
4140 case ResizeDirection
of
4141 RESIZEDIR_UP
: dHeight
:= -dHeight
;
4142 RESIZEDIR_LEFT
: dWidth
:= -dWidth
;
4145 ResizeObject(SelectedObjects
[GetFirstSelected
].ObjectType
,
4146 SelectedObjects
[GetFirstSelected
].ID
,
4147 dWidth
, dHeight
, ResizeDirection
);
4149 LastMovePoint
:= MousePos
;
4154 // Зажата только левая кнопка мыши:
4155 if (not MouseRDown
) and (MouseLDown
) then
4157 // Рисуем прямоугольник планирования панели:
4158 if MouseAction
in [MOUSEACTION_DRAWPANEL
,
4159 MOUSEACTION_DRAWTRIGGER
,
4160 MOUSEACTION_DRAWPRESS
] then
4162 if DrawRect
= nil then
4164 if ssCtrl
in Shift
then
4168 if (lbTextureList
.ItemIndex
<> -1) and (not IsSpecialTextureSel()) and
4169 (MouseAction
= MOUSEACTION_DRAWPANEL
) then
4171 if not g_GetTexture(SelectedTexture(), TextureID
) then
4172 g_GetTexture('NOTEXTURE', TextureID
);
4173 g_GetTextureSizeByID(TextureID
, wWidth
, wHeight
);
4175 DrawRect
.Top
:= MouseLDownPos
.y
;
4176 DrawRect
.Left
:= MouseLDownPos
.x
;
4177 DrawRect
.Bottom
:= DrawRect
.Top
+ wHeight
;
4178 DrawRect
.Right
:= DrawRect
.Left
+ wWidth
;
4182 DrawRect
.Top
:= MouseLDownPos
.y
;
4183 DrawRect
.Left
:= MouseLDownPos
.x
;
4184 DrawRect
.Bottom
:= MousePos
.y
;
4185 DrawRect
.Right
:= MousePos
.x
;
4188 else // Двигаем карту:
4189 if MouseAction
= MOUSEACTION_MOVEMAP
then
4195 // Клавиши мыши не зажаты:
4196 if (not MouseRDown
) and (not MouseLDown
) then
4199 // Строка состояния - координаты мыши:
4200 StatusBar
.Panels
[1].Text := Format('(%d:%d)',
4201 [MousePos
.X
-MapOffset
.X
, MousePos
.Y
-MapOffset
.Y
]);
4204 procedure TMainForm
.FormCloseQuery(Sender
: TObject
; var CanClose
: Boolean);
4206 CanClose
:= MessageBox(0, PChar(_lc
[I_MSG_EXIT_PROMT
]),
4207 PChar(_lc
[I_MSG_EXIT
]),
4208 MB_ICONQUESTION
or MB_YESNO
or
4209 MB_DEFBUTTON1
) = idYes
;
4212 procedure TMainForm
.aExitExecute(Sender
: TObject
);
4217 procedure TMainForm
.FormDestroy(Sender
: TObject
);
4222 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
4224 if WindowState
<> wsMaximized
then
4226 config
.WriteInt('Editor', 'XPos', Left
);
4227 config
.WriteInt('Editor', 'YPos', Top
);
4228 config
.WriteInt('Editor', 'Width', Width
);
4229 config
.WriteInt('Editor', 'Height', Height
);
4233 config
.WriteInt('Editor', 'XPos', RestoredLeft
);
4234 config
.WriteInt('Editor', 'YPos', RestoredTop
);
4235 config
.WriteInt('Editor', 'Width', RestoredWidth
);
4236 config
.WriteInt('Editor', 'Height', RestoredHeight
);
4238 config
.WriteBool('Editor', 'Maximize', WindowState
= wsMaximized
);
4239 config
.WriteBool('Editor', 'Minimap', ShowMap
);
4240 config
.WriteInt('Editor', 'PanelProps', PanelProps
.ClientWidth
);
4241 config
.WriteInt('Editor', 'PanelObjs', PanelObjs
.ClientHeight
);
4242 config
.WriteBool('Editor', 'DotEnable', DotEnable
);
4243 config
.WriteInt('Editor', 'DotStep', DotStep
);
4244 config
.WriteStr('Editor', 'LastOpenDir', OpenDialog
.InitialDir
);
4245 config
.WriteStr('Editor', 'LastSaveDir', SaveDialog
.InitialDir
);
4246 config
.WriteBool('Editor', 'EdgeShow', drEdge
[3] < 255);
4247 config
.WriteInt('Editor', 'EdgeColor', gColorEdge
);
4248 config
.WriteInt('Editor', 'EdgeAlpha', gAlphaEdge
);
4249 config
.WriteInt('Editor', 'LineAlpha', gAlphaTriggerLine
);
4250 config
.WriteInt('Editor', 'TriggerAlpha', gAlphaTriggerArea
);
4251 config
.WriteInt('Editor', 'MonsterRectAlpha', gAlphaMonsterRect
);
4252 config
.WriteInt('Editor', 'AreaRectAlpha', gAlphaAreaRect
);
4254 for i
:= 0 to RecentCount
-1 do
4255 if i
< RecentFiles
.Count
then
4256 config
.WriteStr('RecentFiles', IntToStr(i
+1), RecentFiles
[i
])
4258 config
.WriteStr('RecentFiles', IntToStr(i
+1), '');
4261 config
.SaveFile(EditorDir
+'Editor.cfg');
4264 slInvalidTextures
.Free
;
4267 procedure TMainForm
.FormDropFiles(Sender
: TObject
;
4268 const FileNames
: array of String);
4270 if Length(FileNames
) <> 1 then
4273 OpenMapFile(FileNames
[0]);
4276 procedure TMainForm
.RenderPanelResize(Sender
: TObject
);
4278 if MainForm
.Visible
then
4282 procedure TMainForm
.Splitter1Moved(Sender
: TObject
);
4287 procedure TMainForm
.aMapOptionsExecute(Sender
: TObject
);
4291 MapOptionsForm
.ShowModal();
4293 ResName
:= OpenedMap
;
4294 while (Pos(':\', ResName
) > 0) do
4295 Delete(ResName
, 1, Pos(':\', ResName
) + 1);
4297 UpdateCaption(gMapInfo
.Name
, ExtractFileName(OpenedWAD
), ResName
);
4300 procedure TMainForm
.aAboutExecute(Sender
: TObject
);
4302 AboutForm
.ShowModal();
4305 procedure TMainForm
.FormKeyDown(Sender
: TObject
; var Key
: Word;
4306 Shift
: TShiftState
);
4311 if (not EditingProperties
) then
4313 if Key
= Ord('1') then
4314 SwitchLayer(LAYER_BACK
);
4315 if Key
= Ord('2') then
4316 SwitchLayer(LAYER_WALLS
);
4317 if Key
= Ord('3') then
4318 SwitchLayer(LAYER_FOREGROUND
);
4319 if Key
= Ord('4') then
4320 SwitchLayer(LAYER_STEPS
);
4321 if Key
= Ord('5') then
4322 SwitchLayer(LAYER_WATER
);
4323 if Key
= Ord('6') then
4324 SwitchLayer(LAYER_ITEMS
);
4325 if Key
= Ord('7') then
4326 SwitchLayer(LAYER_MONSTERS
);
4327 if Key
= Ord('8') then
4328 SwitchLayer(LAYER_AREAS
);
4329 if Key
= Ord('9') then
4330 SwitchLayer(LAYER_TRIGGERS
);
4331 if Key
= Ord('0') then
4332 tbShowClick(tbShow
);
4334 if Key
= Ord('V') then
4335 begin // Поворот монстров и областей:
4336 if (SelectedObjects
<> nil) then
4338 for i
:= 0 to High(SelectedObjects
) do
4339 if (SelectedObjects
[i
].Live
) then
4341 if (SelectedObjects
[i
].ObjectType
= OBJECT_MONSTER
) then
4343 g_ChangeDir(gMonsters
[SelectedObjects
[i
].ID
].Direction
);
4346 if (SelectedObjects
[i
].ObjectType
= OBJECT_AREA
) then
4348 g_ChangeDir(gAreas
[SelectedObjects
[i
].ID
].Direction
);
4354 if pcObjects
.ActivePage
= tsMonsters
then
4356 if rbMonsterLeft
.Checked
then
4357 rbMonsterRight
.Checked
:= True
4359 rbMonsterLeft
.Checked
:= True;
4361 if pcObjects
.ActivePage
= tsAreas
then
4363 if rbAreaLeft
.Checked
then
4364 rbAreaRight
.Checked
:= True
4366 rbAreaLeft
.Checked
:= True;
4371 if not (ssCtrl
in Shift
) then
4373 // Быстрое превью карты:
4374 if Key
= Ord('E') then
4376 if PreviewMode
= 0 then
4380 // Вертикальный скролл карты:
4383 if Key
= Ord('W') then
4385 if (MouseLDown
or MouseRDown
) and (Position
>= DotStep
) then
4387 Dec(WASDOffset
.Y
, DotStep
);
4388 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4390 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4391 MapOffset
.Y
:= -Round(Position
/16) * 16;
4394 if Key
= Ord('S') then
4396 if (MouseLDown
or MouseRDown
) and (Position
+DotStep
<= Max
) then
4398 Inc(WASDOffset
.Y
, DotStep
);
4399 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4401 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4402 MapOffset
.Y
:= -Round(Position
/16) * 16;
4406 // Горизонтальный скролл карты:
4407 with sbHorizontal
do
4409 if Key
= Ord('A') then
4411 if (MouseLDown
or MouseRDown
) and (Position
>= DotStep
) then
4413 Dec(WASDOffset
.X
, DotStep
);
4414 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4416 Position
:= IfThen(Position
> DotStep
, Position
-DotStep
, 0);
4417 MapOffset
.X
:= -Round(Position
/16) * 16;
4420 if Key
= Ord('D') then
4422 if (MouseLDown
or MouseRDown
) and (Position
+DotStep
<= Max
) then
4424 Inc(WASDOffset
.X
, DotStep
);
4425 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4427 Position
:= IfThen(Position
+DotStep
< Max
, Position
+DotStep
, Max
);
4428 MapOffset
.X
:= -Round(Position
/16) * 16;
4432 else // ssCtrl in Shift
4434 if ssShift
in Shift
then
4436 // Вставка по абсолютному смещению:
4437 if Key
= Ord('V') then
4438 aPasteObjectExecute(Sender
);
4440 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);
4444 // Удалить выделенные объекты:
4445 if (Key
= VK_DELETE
) and (SelectedObjects
<> nil) and
4446 RenderPanel
.Focused() then
4447 DeleteSelectedObjects();
4450 if (Key
= VK_ESCAPE
) and (SelectedObjects
<> nil) then
4451 RemoveSelectFromObjects();
4453 // Передвинуть объекты:
4454 if MainForm
.ActiveControl
= RenderPanel
then
4459 if Key
= VK_NUMPAD4
then
4460 dx
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4461 if Key
= VK_NUMPAD6
then
4462 dx
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4463 if Key
= VK_NUMPAD8
then
4464 dy
:= IfThen(ssAlt
in Shift
, -1, -DotStep
);
4465 if Key
= VK_NUMPAD5
then
4466 dy
:= IfThen(ssAlt
in Shift
, 1, DotStep
);
4468 if (dx
<> 0) or (dy
<> 0) then
4470 MoveSelectedObjects(ssShift
in Shift
, ssCtrl
in Shift
, dx
, dy
);
4475 if ssCtrl
in Shift
then
4477 // Выбор панели с текстурой для триггера
4478 if Key
= Ord('T') then
4480 DrawPressRect
:= False;
4481 if SelectFlag
= SELECTFLAG_TEXTURE
then
4483 SelectFlag
:= SELECTFLAG_NONE
;
4486 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TEXTURE_PANEL
], i
);
4488 SelectFlag
:= SELECTFLAG_TEXTURE
;
4491 if Key
= Ord('D') then
4493 SelectFlag
:= SELECTFLAG_NONE
;
4494 if DrawPressRect
then
4496 DrawPressRect
:= False;
4501 // Выбор области воздействия, в зависимости от типа триггера
4502 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_EX_AREA
], i
);
4505 DrawPressRect
:= True;
4508 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_DOOR_PANEL
], i
);
4510 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TRAP_PANEL
], i
);
4513 SelectFlag
:= SELECTFLAG_DOOR
;
4516 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_LIFT_PANEL
], i
);
4519 SelectFlag
:= SELECTFLAG_LIFT
;
4522 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_TELEPORT_TO
], i
);
4525 SelectFlag
:= SELECTFLAG_TELEPORT
;
4528 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SPAWN_TO
], i
);
4531 SelectFlag
:= SELECTFLAG_SPAWNPOINT
;
4535 // Выбор основного параметра, в зависимости от типа триггера
4536 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_NEXT_MAP
], i
);
4539 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
4540 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
4541 SelectMapForm
.GetMaps(FileName
);
4543 if SelectMapForm
.ShowModal() = mrOK
then
4545 vleObjectProperty
.Cells
[1, i
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
4546 bApplyProperty
.Click();
4550 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_SOUND_NAME
], i
);
4552 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MUSIC_NAME
], i
);
4555 AddSoundForm
.OKFunction
:= nil;
4556 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
4557 AddSoundForm
.SetResource
:= vleObjectProperty
.Cells
[1, i
];
4559 if (AddSoundForm
.ShowModal() = mrOk
) then
4561 vleObjectProperty
.Cells
[1, i
] := AddSoundForm
.ResourceName
;
4562 bApplyProperty
.Click();
4566 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_PUSH_ANGLE
], i
);
4568 vleObjectProperty
.FindRow(_lc
[I_PROP_TR_MESSAGE_TEXT
], i
);
4571 vleObjectProperty
.Row
:= i
;
4572 vleObjectProperty
.SetFocus();
4579 procedure TMainForm
.aOptimizeExecute(Sender
: TObject
);
4581 RemoveSelectFromObjects();
4582 MapOptimizationForm
.ShowModal();
4585 procedure TMainForm
.aCheckMapExecute(Sender
: TObject
);
4587 MapCheckForm
.ShowModal();
4590 procedure TMainForm
.bbAddTextureClick(Sender
: TObject
);
4592 AddTextureForm
.lbResourcesList
.MultiSelect
:= True;
4593 AddTextureForm
.ShowModal();
4596 procedure TMainForm
.lbTextureListClick(Sender
: TObject
);
4599 TextureWidth
, TextureHeight
: Word;
4604 if (lbTextureList
.ItemIndex
<> -1) and
4605 (not IsSpecialTextureSel()) then
4607 if g_GetTexture(SelectedTexture(), TextureID
) then
4609 g_GetTextureSizeByID(TextureID
, TextureWidth
, TextureHeight
);
4611 lTextureWidth
.Caption
:= IntToStr(TextureWidth
);
4612 lTextureHeight
.Caption
:= IntToStr(TextureHeight
);
4615 lTextureWidth
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4616 lTextureHeight
.Caption
:= _lc
[I_NOT_ACCESSIBLE
];
4621 lTextureWidth
.Caption
:= '';
4622 lTextureHeight
.Caption
:= '';
4626 procedure TMainForm
.lbTextureListDrawItem(Control
: TWinControl
; Index
: Integer;
4627 ARect
: TRect
; State
: TOwnerDrawState
);
4629 with Control
as TListBox
do
4631 if LCLType
.odSelected
in State
then
4633 Canvas
.Brush
.Color
:= clHighlight
;
4634 Canvas
.Font
.Color
:= clHighlightText
;
4636 if (Items
<> nil) and (Index
>= 0) then
4637 if slInvalidTextures
.IndexOf(Items
[Index
]) > -1 then
4639 Canvas
.Brush
.Color
:= clRed
;
4640 Canvas
.Font
.Color
:= clWhite
;
4642 Canvas
.FillRect(ARect
);
4643 Canvas
.TextRect(ARect
, ARect
.Left
, ARect
.Top
, Items
[Index
]);
4647 procedure TMainForm
.miReopenMapClick(Sender
: TObject
);
4649 FileName
, Resource
: String;
4651 if OpenedMap
= '' then
4654 if MessageBox(0, PChar(_lc
[I_MSG_REOPEN_MAP_PROMT
]),
4655 PChar(_lc
[I_MENU_FILE_REOPEN
]), MB_ICONQUESTION
or MB_YESNO
) <> idYes
then
4658 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, @Resource
);
4659 OpenMap(FileName
, Resource
);
4662 procedure TMainForm
.vleObjectPropertyGetPickList(Sender
: TObject
;
4663 const KeyName
: String; Values
: TStrings
);
4665 if vleObjectProperty
.ItemProps
[KeyName
].EditStyle
= esPickList
then
4667 if KeyName
= _lc
[I_PROP_DIRECTION
] then
4669 Values
.Add(DirNames
[D_LEFT
]);
4670 Values
.Add(DirNames
[D_RIGHT
]);
4672 else if KeyName
= _lc
[I_PROP_TR_TELEPORT_DIR
] then
4674 Values
.Add(DirNamesAdv
[0]);
4675 Values
.Add(DirNamesAdv
[1]);
4676 Values
.Add(DirNamesAdv
[2]);
4677 Values
.Add(DirNamesAdv
[3]);
4679 else if KeyName
= _lc
[I_PROP_TR_MUSIC_ACT
] then
4681 Values
.Add(_lc
[I_PROP_TR_MUSIC_ON
]);
4682 Values
.Add(_lc
[I_PROP_TR_MUSIC_OFF
]);
4684 else if KeyName
= _lc
[I_PROP_TR_MONSTER_BEHAVIOUR
] then
4686 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_0
]);
4687 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
]);
4688 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
]);
4689 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
]);
4690 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
]);
4691 Values
.Add(_lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
]);
4693 else if KeyName
= _lc
[I_PROP_TR_SCORE_ACT
] then
4695 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_0
]);
4696 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_1
]);
4697 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_2
]);
4698 Values
.Add(_lc
[I_PROP_TR_SCORE_ACT_3
]);
4700 else if KeyName
= _lc
[I_PROP_TR_SCORE_TEAM
] then
4702 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_0
]);
4703 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_1
]);
4704 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_2
]);
4705 Values
.Add(_lc
[I_PROP_TR_SCORE_TEAM_3
]);
4707 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_KIND
] then
4709 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_0
]);
4710 Values
.Add(_lc
[I_PROP_TR_MESSAGE_KIND_1
]);
4712 else if KeyName
= _lc
[I_PROP_TR_MESSAGE_TO
] then
4714 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_0
]);
4715 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_1
]);
4716 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_2
]);
4717 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_3
]);
4718 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_4
]);
4719 Values
.Add(_lc
[I_PROP_TR_MESSAGE_TO_5
]);
4721 else if KeyName
= _lc
[I_PROP_TR_SHOT_TO
] then
4723 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_0
]);
4724 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_1
]);
4725 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_2
]);
4726 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_3
]);
4727 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_4
]);
4728 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_5
]);
4729 Values
.Add(_lc
[I_PROP_TR_SHOT_TO_6
]);
4731 else if KeyName
= _lc
[I_PROP_TR_SHOT_AIM
] then
4733 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_0
]);
4734 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_1
]);
4735 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_2
]);
4736 Values
.Add(_lc
[I_PROP_TR_SHOT_AIM_3
]);
4738 else if (KeyName
= _lc
[I_PROP_PANEL_BLEND
]) or
4739 (KeyName
= _lc
[I_PROP_DM_ONLY
]) or
4740 (KeyName
= _lc
[I_PROP_ITEM_FALLS
]) or
4741 (KeyName
= _lc
[I_PROP_TR_ENABLED
]) or
4742 (KeyName
= _lc
[I_PROP_TR_D2D
]) or
4743 (KeyName
= _lc
[I_PROP_TR_SILENT
]) or
4744 (KeyName
= _lc
[I_PROP_TR_TELEPORT_SILENT
]) or
4745 (KeyName
= _lc
[I_PROP_TR_EX_RANDOM
]) or
4746 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ONCE
]) or
4747 (KeyName
= _lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]) or
4748 (KeyName
= _lc
[I_PROP_TR_SOUND_LOCAL
]) or
4749 (KeyName
= _lc
[I_PROP_TR_SOUND_SWITCH
]) or
4750 (KeyName
= _lc
[I_PROP_TR_MONSTER_ACTIVE
]) or
4751 (KeyName
= _lc
[I_PROP_TR_PUSH_RESET
]) or
4752 (KeyName
= _lc
[I_PROP_TR_SCORE_CON
]) or
4753 (KeyName
= _lc
[I_PROP_TR_SCORE_MSG
]) or
4754 (KeyName
= _lc
[I_PROP_TR_HEALTH_MAX
]) or
4755 (KeyName
= _lc
[I_PROP_TR_SHOT_SOUND
]) or
4756 (KeyName
= _lc
[I_PROP_TR_EFFECT_CENTER
]) then
4758 Values
.Add(BoolNames
[True]);
4759 Values
.Add(BoolNames
[False]);
4764 procedure TMainForm
.bApplyPropertyClick(Sender
: TObject
);
4766 _id
, a
, r
, c
: Integer;
4776 if SelectedObjectCount() <> 1 then
4778 if not SelectedObjects
[GetFirstSelected()].Live
then
4782 if not CheckProperty() then
4788 _id
:= GetFirstSelected();
4790 r
:= vleObjectProperty
.Row
;
4791 c
:= vleObjectProperty
.Col
;
4793 case SelectedObjects
[_id
].ObjectType
of
4796 with gPanels
[SelectedObjects
[_id
].ID
] do
4798 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4799 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4800 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4801 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4803 PanelType
:= GetPanelType(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TYPE
]]);
4805 // Сброс ссылки на триггеры смены текстуры:
4806 if not WordBool(PanelType
and (PANEL_WALL
or PANEL_FORE
or PANEL_BACK
)) then
4807 if gTriggers
<> nil then
4808 for a
:= 0 to High(gTriggers
) do
4810 if (gTriggers
[a
].TriggerType
<> 0) and
4811 (gTriggers
[a
].TexturePanel
= Integer(SelectedObjects
[_id
].ID
)) then
4812 gTriggers
[a
].TexturePanel
:= -1;
4813 if (gTriggers
[a
].TriggerType
= TRIGGER_SHOT
) and
4814 (gTriggers
[a
].Data
.ShotPanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4815 gTriggers
[a
].Data
.ShotPanelID
:= -1;
4818 // Сброс ссылки на триггеры лифта:
4819 if not WordBool(PanelType
and (PANEL_LIFTUP
or PANEL_LIFTDOWN
or PANEL_LIFTLEFT
or PANEL_LIFTRIGHT
)) then
4820 if gTriggers
<> nil then
4821 for a
:= 0 to High(gTriggers
) do
4822 if (gTriggers
[a
].TriggerType
in [TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
]) and
4823 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4824 gTriggers
[a
].Data
.PanelID
:= -1;
4826 // Сброс ссылки на триггеры двери:
4827 if not WordBool(PanelType
and (PANEL_OPENDOOR
or PANEL_CLOSEDOOR
)) then
4828 if gTriggers
<> nil then
4829 for a
:= 0 to High(gTriggers
) do
4830 if (gTriggers
[a
].TriggerType
in [TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
4831 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
]) and
4832 (gTriggers
[a
].Data
.PanelID
= Integer(SelectedObjects
[_id
].ID
)) then
4833 gTriggers
[a
].Data
.PanelID
:= -1;
4835 if IsTexturedPanel(PanelType
) then
4836 begin // Может быть текстура
4837 if TextureName
<> '' then
4838 begin // Была текстура
4839 Alpha
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_ALPHA
]]));
4840 Blending
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_BLEND
]]);
4849 TextureName
:= vleObjectProperty
.Values
[_lc
[I_PROP_PANEL_TEX
]];
4851 if TextureName
<> '' then
4852 begin // Есть текстура
4853 // Обычная текстура:
4854 if not IsSpecialTexture(TextureName
) then
4856 g_GetTextureSizeByName(TextureName
,
4857 TextureWidth
, TextureHeight
);
4859 // Проверка кратности размеров панели:
4861 if TextureWidth
<> 0 then
4862 if gPanels
[SelectedObjects
[_id
].ID
].Width
mod TextureWidth
<> 0 then
4864 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXWIDTH
],
4868 if Res
and (TextureHeight
<> 0) then
4869 if gPanels
[SelectedObjects
[_id
].ID
].Height
mod TextureHeight
<> 0 then
4871 ErrorMessageBox(Format(_lc
[I_MSG_WRONG_TEXHEIGHT
],
4878 if not g_GetTexture(TextureName
, TextureID
) then
4879 // Не удалось загрузить текстуру, рисуем NOTEXTURE
4880 if g_GetTexture('NOTEXTURE', NoTextureID
) then
4882 TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
4883 g_GetTextureSizeByID(NoTextureID
, NW
, NH
);
4885 TextureHeight
:= NH
;
4888 TextureID
:= TEXTURE_SPECIAL_NONE
;
4898 TextureID
:= TEXTURE_SPECIAL_NONE
;
4901 else // Спец.текстура
4905 TextureID
:= SpecialTextureID(TextureName
);
4908 else // Нет текстуры
4912 TextureID
:= TEXTURE_SPECIAL_NONE
;
4915 else // Не может быть текстуры
4922 TextureID
:= TEXTURE_SPECIAL_NONE
;
4929 with gItems
[SelectedObjects
[_id
].ID
] do
4931 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4932 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4933 OnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
4934 Fall
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
4940 with gMonsters
[SelectedObjects
[_id
].ID
] do
4942 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4943 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4944 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4950 with gAreas
[SelectedObjects
[_id
].ID
] do
4952 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4953 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4954 Direction
:= NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]);
4960 with gTriggers
[SelectedObjects
[_id
].ID
] do
4962 X
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_X
]]));
4963 Y
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_Y
]]));
4964 Width
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_WIDTH
]]));
4965 Height
:= StrToInt(Trim(vleObjectProperty
.Values
[_lc
[I_PROP_HEIGHT
]]));
4966 Enabled
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ENABLED
]]);
4967 ActivateType
:= StrToActivate(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ACTIVATION
]]);
4968 Key
:= StrToKey(vleObjectProperty
.Values
[_lc
[I_PROP_TR_KEYS
]]);
4973 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_NEXT_MAP
]]);
4974 FillByte(Data
.MapName
[0], 16, 0);
4976 Move(s
[1], Data
.MapName
[0], Min(Length(s
), 16));
4981 Data
.ActivateOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ONCE
]]);
4982 Data
.AnimOnce
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TEXTURE_ANIM_ONCE
]]);
4985 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
4987 Data
.Wait
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 65535);
4988 Data
.Count
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_COUNT
]], 0), 65535);
4989 if Data
.Count
< 1 then
4991 if TriggerType
= TRIGGER_PRESS
then
4992 Data
.ExtRandom
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_RANDOM
]]);
4995 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
4996 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
4999 Data
.NoSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5000 Data
.d2d_doors
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5005 Data
.d2d_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_D2D
]]);
5006 Data
.silent_teleport
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_SILENT
]]);
5007 Data
.TlpDir
:= NameToDirAdv(vleObjectProperty
.Values
[_lc
[I_PROP_TR_TELEPORT_DIR
]]);
5012 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_NAME
]]);
5013 FillByte(Data
.SoundName
[0], 64, 0);
5015 Move(s
[1], Data
.SoundName
[0], Min(Length(s
), 64));
5017 Data
.Volume
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_VOLUME
]], 0), 255);
5018 Data
.Pan
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_PAN
]], 0), 255);
5019 Data
.PlayCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_COUNT
]], 0), 255);
5020 Data
.Local
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_LOCAL
]]);
5021 Data
.SoundSwitch
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SOUND_SWITCH
]]);
5024 TRIGGER_SPAWNMONSTER
:
5026 Data
.MonType
:= StrToMonster(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_TYPE
]]);
5027 Data
.MonDir
:= Byte(NameToDir(vleObjectProperty
.Values
[_lc
[I_PROP_DIRECTION
]]));
5028 Data
.MonHealth
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 1000000);
5029 if Data
.MonHealth
< 0 then
5030 Data
.MonHealth
:= 0;
5031 Data
.MonActive
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_ACTIVE
]]);
5032 Data
.MonCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5033 if Data
.MonCount
< 1 then
5035 Data
.MonEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5036 Data
.MonMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5037 Data
.MonDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5039 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_1
] then
5041 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_2
] then
5043 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_3
] then
5045 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_4
] then
5047 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MONSTER_BEHAVIOUR
]] = _lc
[I_PROP_TR_MONSTER_BEHAVIOUR_5
] then
5053 Data
.ItemType
:= StrToItem(vleObjectProperty
.Values
[_lc
[I_PROP_TR_ITEM_TYPE
]]);
5054 Data
.ItemOnlyDM
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_DM_ONLY
]]);
5055 Data
.ItemFalls
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_ITEM_FALLS
]]);
5056 Data
.ItemCount
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 64);
5057 if Data
.ItemCount
< 1 then
5058 Data
.ItemCount
:= 1;
5059 Data
.ItemEffect
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_FX_TYPE
]]);
5060 Data
.ItemMax
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_MAX
]], 0), 65535);
5061 Data
.ItemDelay
:= Min(StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SPAWN_DELAY
]], 0), 65535);
5066 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_NAME
]]);
5067 FillByte(Data
.MusicName
[0], 64, 0);
5069 Move(s
[1], Data
.MusicName
[0], Min(Length(s
), 64));
5071 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MUSIC_ACT
]] = _lc
[I_PROP_TR_MUSIC_ON
] then
5072 Data
.MusicAction
:= 1
5074 Data
.MusicAction
:= 2;
5079 Data
.PushAngle
:= Min(
5080 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_ANGLE
]], 0), 360);
5081 Data
.PushForce
:= Min(
5082 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_FORCE
]], 0), 255);
5083 Data
.ResetVel
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_PUSH_RESET
]]);
5088 Data
.ScoreAction
:= 0;
5089 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_1
] then
5090 Data
.ScoreAction
:= 1
5091 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_2
] then
5092 Data
.ScoreAction
:= 2
5093 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_ACT
]] = _lc
[I_PROP_TR_SCORE_ACT_3
] then
5094 Data
.ScoreAction
:= 3;
5095 Data
.ScoreCount
:= Min(Max(
5096 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5097 Data
.ScoreTeam
:= 0;
5098 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_1
] then
5100 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_2
] then
5102 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_TEAM
]] = _lc
[I_PROP_TR_SCORE_TEAM_3
] then
5103 Data
.ScoreTeam
:= 3;
5104 Data
.ScoreCon
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_CON
]]);
5105 Data
.ScoreMsg
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SCORE_MSG
]]);
5110 Data
.MessageKind
:= 0;
5111 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_KIND
]] = _lc
[I_PROP_TR_MESSAGE_KIND_1
] then
5112 Data
.MessageKind
:= 1;
5114 Data
.MessageSendTo
:= 0;
5115 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_1
] then
5116 Data
.MessageSendTo
:= 1
5117 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_2
] then
5118 Data
.MessageSendTo
:= 2
5119 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_3
] then
5120 Data
.MessageSendTo
:= 3
5121 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_4
] then
5122 Data
.MessageSendTo
:= 4
5123 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TO
]] = _lc
[I_PROP_TR_MESSAGE_TO_5
] then
5124 Data
.MessageSendTo
:= 5;
5126 s
:= utf2win(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TEXT
]]);
5127 FillByte(Data
.MessageText
[0], 100, 0);
5129 Move(s
[1], Data
.MessageText
[0], Min(Length(s
), 100));
5131 Data
.MessageTime
:= Min(Max(
5132 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_MESSAGE_TIME
]], 0), 0), 65535);
5137 Data
.DamageValue
:= Min(Max(
5138 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_DAMAGE_VALUE
]], 0), 0), 65535);
5139 Data
.DamageInterval
:= Min(Max(
5140 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5145 Data
.HealValue
:= Min(Max(
5146 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH
]], 0), 0), 65535);
5147 Data
.HealInterval
:= Min(Max(
5148 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_INTERVAL
]], 0), 0), 65535);
5149 Data
.HealMax
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_HEALTH_MAX
]]);
5150 Data
.HealSilent
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SILENT
]]);
5155 Data
.ShotType
:= StrToShot(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TYPE
]]);
5156 Data
.ShotSound
:= NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SOUND
]]);
5157 Data
.ShotTarget
:= 0;
5158 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_1
] then
5159 Data
.ShotTarget
:= 1
5160 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_2
] then
5161 Data
.ShotTarget
:= 2
5162 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_3
] then
5163 Data
.ShotTarget
:= 3
5164 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_4
] then
5165 Data
.ShotTarget
:= 4
5166 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_5
] then
5167 Data
.ShotTarget
:= 5
5168 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_TO
]] = _lc
[I_PROP_TR_SHOT_TO_6
] then
5169 Data
.ShotTarget
:= 6;
5170 Data
.ShotIntSight
:= Min(Max(
5171 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_SIGHT
]], 0), 0), 65535);
5173 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_1
] then
5175 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_2
] then
5177 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AIM
]] = _lc
[I_PROP_TR_SHOT_AIM_3
] then
5179 Data
.ShotAngle
:= Min(
5180 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ANGLE
]], 0), 360);
5181 Data
.ShotWait
:= Min(Max(
5182 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5183 Data
.ShotAccuracy
:= Min(Max(
5184 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_ACC
]], 0), 0), 65535);
5185 Data
.ShotAmmo
:= Min(Max(
5186 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_AMMO
]], 0), 0), 65535);
5187 Data
.ShotIntReload
:= Min(Max(
5188 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_SHOT_RELOAD
]], 0), 0), 65535);
5193 Data
.FXCount
:= Min(Max(
5194 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_COUNT
]], 0), 0), 255);
5195 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_PARTICLE
] then
5197 Data
.FXType
:= TRIGGER_EFFECT_PARTICLE
;
5198 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
;
5199 if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SLIQUID
] then
5200 Data
.FXSubType
:= TRIGGER_EFFECT_SLIQUID
5201 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
5202 Data
.FXSubType
:= TRIGGER_EFFECT_LLIQUID
5203 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
5204 Data
.FXSubType
:= TRIGGER_EFFECT_DLIQUID
5205 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
5206 Data
.FXSubType
:= TRIGGER_EFFECT_BLOOD
5207 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
5208 Data
.FXSubType
:= TRIGGER_EFFECT_SPARK
5209 else if vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
5210 Data
.FXSubType
:= TRIGGER_EFFECT_BUBBLE
;
5213 Data
.FXType
:= TRIGGER_EFFECT_ANIMATION
;
5214 Data
.FXSubType
:= StrToEffect(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SUBTYPE
]]);
5217 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_COLOR
]], 0), 0), $FFFFFF);
5218 Data
.FXColorR
:= a
and $FF;
5219 Data
.FXColorG
:= (a
shr 8) and $FF;
5220 Data
.FXColorB
:= (a
shr 16) and $FF;
5221 if NameToBool(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_CENTER
]]) then
5225 Data
.FXWait
:= Min(Max(
5226 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EX_DELAY
]], 0), 0), 65535);
5227 Data
.FXVelX
:= Min(Max(
5228 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELX
]], 0), -128), 127);
5229 Data
.FXVelY
:= Min(Max(
5230 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_VELY
]], 0), -128), 127);
5231 Data
.FXSpreadL
:= Min(Max(
5232 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPL
]], 0), 0), 255);
5233 Data
.FXSpreadR
:= Min(Max(
5234 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPR
]], 0), 0), 255);
5235 Data
.FXSpreadU
:= Min(Max(
5236 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPU
]], 0), 0), 255);
5237 Data
.FXSpreadD
:= Min(Max(
5238 StrToIntDef(vleObjectProperty
.Values
[_lc
[I_PROP_TR_EFFECT_SPD
]], 0), 0), 255);
5247 vleObjectProperty
.Row
:= r
;
5248 vleObjectProperty
.Col
:= c
;
5251 procedure TMainForm
.bbRemoveTextureClick(Sender
: TObject
);
5255 i
:= lbTextureList
.ItemIndex
;
5259 if MessageBox(0, PChar(Format(_lc
[I_MSG_DEL_TEXTURE_PROMT
],
5260 [SelectedTexture()])),
5261 PChar(_lc
[I_MSG_DEL_TEXTURE
]),
5262 MB_ICONQUESTION
or MB_YESNO
or
5263 MB_DEFBUTTON1
) <> idYes
then
5266 if gPanels
<> nil then
5267 for a
:= 0 to High(gPanels
) do
5268 if (gPanels
[a
].PanelType
<> 0) and
5269 (gPanels
[a
].TextureName
= SelectedTexture()) then
5271 ErrorMessageBox(_lc
[I_MSG_DEL_TEXTURE_CANT
]);
5275 g_DeleteTexture(SelectedTexture());
5276 i
:= slInvalidTextures
.IndexOf(lbTextureList
.Items
[i
]);
5278 slInvalidTextures
.Delete(i
);
5279 if lbTextureList
.ItemIndex
> -1 then
5280 lbTextureList
.Items
.Delete(lbTextureList
.ItemIndex
)
5283 procedure TMainForm
.aNewMapExecute(Sender
: TObject
);
5285 if (MessageBox(0, PChar(_lc
[I_MSG_CLEAR_MAP_PROMT
]),
5286 PChar(_lc
[I_MSG_CLEAR_MAP
]),
5287 MB_ICONQUESTION
or MB_YESNO
or
5288 MB_DEFBUTTON1
) = mrYes
) then
5292 procedure TMainForm
.aUndoExecute(Sender
: TObject
);
5296 if UndoBuffer
= nil then
5298 if UndoBuffer
[High(UndoBuffer
)] = nil then
5301 for a
:= 0 to High(UndoBuffer
[High(UndoBuffer
)]) do
5302 with UndoBuffer
[High(UndoBuffer
)][a
] do
5310 UNDO_DELETE_ITEM
: AddItem(Item
);
5311 UNDO_DELETE_AREA
: AddArea(Area
);
5312 UNDO_DELETE_MONSTER
: AddMonster(Monster
);
5313 UNDO_DELETE_TRIGGER
: AddTrigger(Trigger
);
5314 UNDO_ADD_PANEL
: RemoveObject(AddID
, OBJECT_PANEL
);
5315 UNDO_ADD_ITEM
: RemoveObject(AddID
, OBJECT_ITEM
);
5316 UNDO_ADD_AREA
: RemoveObject(AddID
, OBJECT_AREA
);
5317 UNDO_ADD_MONSTER
: RemoveObject(AddID
, OBJECT_MONSTER
);
5318 UNDO_ADD_TRIGGER
: RemoveObject(AddID
, OBJECT_TRIGGER
);
5322 SetLength(UndoBuffer
, Length(UndoBuffer
)-1);
5324 RemoveSelectFromObjects();
5326 miUndo
.Enabled
:= UndoBuffer
<> nil;
5330 procedure TMainForm
.aCopyObjectExecute(Sender
: TObject
);
5333 CopyBuffer
: TCopyRecArray
;
5337 function CB_Compare(I1
, I2
: TCopyRec
): Integer;
5339 Result
:= Integer(I1
.ObjectType
) - Integer(I2
.ObjectType
);
5341 if Result
= 0 then // Одного типа
5342 Result
:= Integer(I1
.ID
) - Integer(I2
.ID
);
5345 procedure QuickSortCopyBuffer(L
, R
: Integer);
5353 P
:= CopyBuffer
[(L
+ R
) shr 1];
5356 while CB_Compare(CopyBuffer
[I
], P
) < 0 do
5358 while CB_Compare(CopyBuffer
[J
], P
) > 0 do
5364 CopyBuffer
[I
] := CopyBuffer
[J
];
5372 QuickSortCopyBuffer(L
, J
);
5379 if SelectedObjects
= nil then
5385 // Копируем объекты:
5386 for a
:= 0 to High(SelectedObjects
) do
5387 if SelectedObjects
[a
].Live
then
5388 with SelectedObjects
[a
] do
5390 SetLength(CopyBuffer
, Length(CopyBuffer
)+1);
5391 b
:= High(CopyBuffer
);
5392 CopyBuffer
[b
].ID
:= ID
;
5393 CopyBuffer
[b
].Panel
:= nil;
5398 CopyBuffer
[b
].ObjectType
:= OBJECT_PANEL
;
5399 New(CopyBuffer
[b
].Panel
);
5400 CopyBuffer
[b
].Panel
^ := gPanels
[ID
];
5405 CopyBuffer
[b
].ObjectType
:= OBJECT_ITEM
;
5406 CopyBuffer
[b
].Item
:= gItems
[ID
];
5411 CopyBuffer
[b
].ObjectType
:= OBJECT_MONSTER
;
5412 CopyBuffer
[b
].Monster
:= gMonsters
[ID
];
5417 CopyBuffer
[b
].ObjectType
:= OBJECT_AREA
;
5418 CopyBuffer
[b
].Area
:= gAreas
[ID
];
5423 CopyBuffer
[b
].ObjectType
:= OBJECT_TRIGGER
;
5424 CopyBuffer
[b
].Trigger
:= gTriggers
[ID
];
5429 // Сортировка по ID:
5430 if CopyBuffer
<> nil then
5432 QuickSortCopyBuffer(0, b
);
5435 // Пестановка ссылок триггеров:
5436 for a
:= 0 to Length(CopyBuffer
)-1 do
5437 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5439 case CopyBuffer
[a
].Trigger
.TriggerType
of
5440 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5441 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5442 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5443 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5447 for b
:= 0 to Length(CopyBuffer
)-1 do
5448 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5449 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.PanelID
) then
5451 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= b
;
5456 // Этих панелей нет среди копируемых:
5458 CopyBuffer
[a
].Trigger
.Data
.PanelID
:= -1;
5461 TRIGGER_PRESS
, TRIGGER_ON
,
5462 TRIGGER_OFF
, TRIGGER_ONOFF
:
5463 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5467 for b
:= 0 to Length(CopyBuffer
)-1 do
5468 if (CopyBuffer
[b
].ObjectType
= OBJECT_MONSTER
) and
5469 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1) then
5471 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= b
+1;
5476 // Этих монстров нет среди копируемых:
5478 CopyBuffer
[a
].Trigger
.Data
.MonsterID
:= 0;
5482 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5486 for b
:= 0 to Length(CopyBuffer
)-1 do
5487 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5488 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
) then
5490 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= b
;
5495 // Этих панелей нет среди копируемых:
5497 CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
:= -1;
5501 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5505 for b
:= 0 to Length(CopyBuffer
)-1 do
5506 if (CopyBuffer
[b
].ObjectType
= OBJECT_PANEL
) and
5507 (Integer(CopyBuffer
[b
].ID
) = CopyBuffer
[a
].Trigger
.TexturePanel
) then
5509 CopyBuffer
[a
].Trigger
.TexturePanel
:= b
;
5514 // Этих панелей нет среди копируемых:
5516 CopyBuffer
[a
].Trigger
.TexturePanel
:= -1;
5521 str
:= CopyBufferToString(CopyBuffer
);
5522 ClipBoard
.AsText
:= str
;
5524 for a
:= 0 to Length(CopyBuffer
)-1 do
5525 if (CopyBuffer
[a
].ObjectType
= OBJECT_PANEL
) and
5526 (CopyBuffer
[a
].Panel
<> nil) then
5527 Dispose(CopyBuffer
[a
].Panel
);
5532 procedure TMainForm
.aPasteObjectExecute(Sender
: TObject
);
5535 CopyBuffer
: TCopyRecArray
;
5537 swad
, ssec
, sres
: String;
5543 pmin
.X
:= High(pmin
.X
);
5544 pmin
.Y
:= High(pmin
.Y
);
5546 StringToCopyBuffer(ClipBoard
.AsText
, CopyBuffer
, pmin
);
5547 rel
:= not(ssShift
in GetKeyShiftState());
5549 if CopyBuffer
= nil then
5552 RemoveSelectFromObjects();
5554 h
:= High(CopyBuffer
);
5556 with CopyBuffer
[a
] do
5560 if Panel
<> nil then
5564 Panel
^.X
:= Panel
^.X
- pmin
.X
- MapOffset
.X
+ 32;
5565 Panel
^.Y
:= Panel
^.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5568 Panel
^.TextureID
:= TEXTURE_SPECIAL_NONE
;
5569 Panel
^.TextureWidth
:= 1;
5570 Panel
^.TextureHeight
:= 1;
5572 if (Panel
^.PanelType
= PANEL_LIFTUP
) or
5573 (Panel
^.PanelType
= PANEL_LIFTDOWN
) or
5574 (Panel
^.PanelType
= PANEL_LIFTLEFT
) or
5575 (Panel
^.PanelType
= PANEL_LIFTRIGHT
) or
5576 (Panel
^.PanelType
= PANEL_BLOCKMON
) or
5577 (Panel
^.TextureName
= '') then
5578 begin // Нет или не может быть текстуры:
5580 else // Есть текстура:
5582 // Обычная текстура:
5583 if not IsSpecialTexture(Panel
^.TextureName
) then
5585 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5589 g_ProcessResourceStr(Panel
^.TextureName
, swad
, ssec
, sres
);
5590 AddTexture(swad
, ssec
, sres
, True);
5591 res
:= g_GetTexture(Panel
^.TextureName
, Panel
^.TextureID
);
5595 g_GetTextureSizeByName(Panel
^.TextureName
,
5596 Panel
^.TextureWidth
, Panel
^.TextureHeight
)
5598 if g_GetTexture('NOTEXTURE', NoTextureID
) then
5600 Panel
^.TextureID
:= TEXTURE_SPECIAL_NOTEXTURE
;
5601 g_GetTextureSizeByID(NoTextureID
, Panel
^.TextureWidth
, Panel
^.TextureHeight
);
5604 else // Спец.текстура:
5606 Panel
^.TextureID
:= SpecialTextureID(Panel
^.TextureName
);
5607 with MainForm
.lbTextureList
.Items
do
5608 if IndexOf(Panel
^.TextureName
) = -1 then
5609 Add(Panel
^.TextureName
);
5613 ID
:= AddPanel(Panel
^);
5615 Undo_Add(OBJECT_PANEL
, ID
, a
> 0);
5616 SelectObject(OBJECT_PANEL
, ID
, True);
5623 Item
.X
:= Item
.X
- pmin
.X
- MapOffset
.X
+ 32;
5624 Item
.Y
:= Item
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5627 ID
:= AddItem(Item
);
5628 Undo_Add(OBJECT_ITEM
, ID
, a
> 0);
5629 SelectObject(OBJECT_ITEM
, ID
, True);
5636 Monster
.X
:= Monster
.X
- pmin
.X
- MapOffset
.X
+ 32;
5637 Monster
.Y
:= Monster
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5640 ID
:= AddMonster(Monster
);
5641 Undo_Add(OBJECT_MONSTER
, ID
, a
> 0);
5642 SelectObject(OBJECT_MONSTER
, ID
, True);
5649 Area
.X
:= Area
.X
- pmin
.X
- MapOffset
.X
+ 32;
5650 Area
.Y
:= Area
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5653 ID
:= AddArea(Area
);
5654 Undo_Add(OBJECT_AREA
, ID
, a
> 0);
5655 SelectObject(OBJECT_AREA
, ID
, True);
5663 X
:= X
- pmin
.X
- MapOffset
.X
+ 32;
5664 Y
:= Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5669 Data
.TargetPoint
.X
:=
5670 Data
.TargetPoint
.X
- pmin
.X
- MapOffset
.X
+ 32;
5671 Data
.TargetPoint
.Y
:=
5672 Data
.TargetPoint
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5674 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
5676 Data
.tX
:= Data
.tX
- pmin
.X
- MapOffset
.X
+ 32;
5677 Data
.tY
:= Data
.tY
- pmin
.Y
- MapOffset
.Y
+ 32;
5679 TRIGGER_SPAWNMONSTER
:
5682 Data
.MonPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5684 Data
.MonPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5689 Data
.ItemPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5691 Data
.ItemPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5696 Data
.ShotPos
.X
- pmin
.X
- MapOffset
.X
+ 32;
5698 Data
.ShotPos
.Y
- pmin
.Y
- MapOffset
.Y
+ 32;
5703 ID
:= AddTrigger(Trigger
);
5704 Undo_Add(OBJECT_TRIGGER
, ID
, a
> 0);
5705 SelectObject(OBJECT_TRIGGER
, ID
, True);
5710 // Переставляем ссылки триггеров:
5711 for a
:= 0 to High(CopyBuffer
) do
5712 if CopyBuffer
[a
].ObjectType
= OBJECT_TRIGGER
then
5714 case CopyBuffer
[a
].Trigger
.TriggerType
of
5715 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
5716 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
5717 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
5718 if CopyBuffer
[a
].Trigger
.Data
.PanelID
<> -1 then
5719 gTriggers
[CopyBuffer
[a
].ID
].Data
.PanelID
:=
5720 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.PanelID
].ID
;
5722 TRIGGER_PRESS
, TRIGGER_ON
,
5723 TRIGGER_OFF
, TRIGGER_ONOFF
:
5724 if CopyBuffer
[a
].Trigger
.Data
.MonsterID
<> 0 then
5725 gTriggers
[CopyBuffer
[a
].ID
].Data
.MonsterID
:=
5726 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.MonsterID
-1].ID
+1;
5729 if CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
<> -1 then
5730 gTriggers
[CopyBuffer
[a
].ID
].Data
.ShotPanelID
:=
5731 CopyBuffer
[CopyBuffer
[a
].Trigger
.Data
.ShotPanelID
].ID
;
5734 if CopyBuffer
[a
].Trigger
.TexturePanel
<> -1 then
5735 gTriggers
[CopyBuffer
[a
].ID
].TexturePanel
:=
5736 CopyBuffer
[CopyBuffer
[a
].Trigger
.TexturePanel
].ID
;
5745 procedure TMainForm
.aCutObjectExecute(Sender
: TObject
);
5748 DeleteSelectedObjects();
5751 procedure TMainForm
.vleObjectPropertyEditButtonClick(Sender
: TObject
);
5753 Key
, FileName
: String;
5756 Key
:= vleObjectProperty
.Keys
[vleObjectProperty
.Row
];
5758 if Key
= _lc
[I_PROP_PANEL_TYPE
] then
5760 with ChooseTypeForm
, vleObjectProperty
do
5761 begin // Выбор типа панели:
5762 Caption
:= _lc
[I_PROP_PANEL_TYPE
];
5763 lbTypeSelect
.Items
.Clear();
5765 for b
:= 0 to High(PANELNAMES
) do
5767 lbTypeSelect
.Items
.Add(PANELNAMES
[b
]);
5768 if Values
[Key
] = PANELNAMES
[b
] then
5769 lbTypeSelect
.ItemIndex
:= b
;
5772 if ShowModal() = mrOK
then
5774 b
:= lbTypeSelect
.ItemIndex
;
5775 Values
[Key
] := PANELNAMES
[b
];
5776 vleObjectPropertyApply(Sender
);
5780 else if Key
= _lc
[I_PROP_TR_TELEPORT_TO
] then
5781 SelectFlag
:= SELECTFLAG_TELEPORT
5782 else if Key
= _lc
[I_PROP_TR_SPAWN_TO
] then
5783 SelectFlag
:= SELECTFLAG_SPAWNPOINT
5784 else if (Key
= _lc
[I_PROP_TR_DOOR_PANEL
]) or
5785 (Key
= _lc
[I_PROP_TR_TRAP_PANEL
]) then
5786 SelectFlag
:= SELECTFLAG_DOOR
5787 else if Key
= _lc
[I_PROP_TR_TEXTURE_PANEL
] then
5789 DrawPressRect
:= False;
5790 SelectFlag
:= SELECTFLAG_TEXTURE
;
5792 else if Key
= _lc
[I_PROP_TR_SHOT_PANEL
] then
5793 SelectFlag
:= SELECTFLAG_SHOTPANEL
5794 else if Key
= _lc
[I_PROP_TR_LIFT_PANEL
] then
5795 SelectFlag
:= SELECTFLAG_LIFT
5796 else if key
= _lc
[I_PROP_TR_EX_MONSTER
] then
5797 SelectFlag
:= SELECTFLAG_MONSTER
5798 else if Key
= _lc
[I_PROP_TR_EX_AREA
] then
5800 SelectFlag
:= SELECTFLAG_NONE
;
5801 DrawPressRect
:= True;
5803 else if Key
= _lc
[I_PROP_TR_NEXT_MAP
] then
5804 begin // Выбор следующей карты:
5805 g_ProcessResourceStr(OpenedMap
, @FileName
, nil, nil);
5806 SelectMapForm
.Caption
:= _lc
[I_CAP_SELECT
];
5807 SelectMapForm
.GetMaps(FileName
);
5809 if SelectMapForm
.ShowModal() = mrOK
then
5811 vleObjectProperty
.Values
[Key
] := SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
5812 vleObjectPropertyApply(Sender
);
5815 else if (Key
= _lc
[I_PROP_TR_SOUND_NAME
]) or
5816 (Key
= _lc
[I_PROP_TR_MUSIC_NAME
]) then
5817 begin // Выбор файла звука/музыки:
5818 AddSoundForm
.OKFunction
:= nil;
5819 AddSoundForm
.lbResourcesList
.MultiSelect
:= False;
5820 AddSoundForm
.SetResource
:= vleObjectProperty
.Values
[Key
];
5822 if (AddSoundForm
.ShowModal() = mrOk
) then
5824 vleObjectProperty
.Values
[Key
] := AddSoundForm
.ResourceName
;
5825 vleObjectPropertyApply(Sender
);
5828 else if Key
= _lc
[I_PROP_TR_ACTIVATION
] then
5829 with ActivationTypeForm
, vleObjectProperty
do
5830 begin // Выбор типов активации:
5831 cbPlayerCollide
.Checked
:= Pos('PC', Values
[Key
]) > 0;
5832 cbMonsterCollide
.Checked
:= Pos('MC', Values
[Key
]) > 0;
5833 cbPlayerPress
.Checked
:= Pos('PP', Values
[Key
]) > 0;
5834 cbMonsterPress
.Checked
:= Pos('MP', Values
[Key
]) > 0;
5835 cbShot
.Checked
:= Pos('SH', Values
[Key
]) > 0;
5836 cbNoMonster
.Checked
:= Pos('NM', Values
[Key
]) > 0;
5838 if ShowModal() = mrOK
then
5841 if cbPlayerCollide
.Checked
then
5842 b
:= ACTIVATE_PLAYERCOLLIDE
;
5843 if cbMonsterCollide
.Checked
then
5844 b
:= b
or ACTIVATE_MONSTERCOLLIDE
;
5845 if cbPlayerPress
.Checked
then
5846 b
:= b
or ACTIVATE_PLAYERPRESS
;
5847 if cbMonsterPress
.Checked
then
5848 b
:= b
or ACTIVATE_MONSTERPRESS
;
5849 if cbShot
.Checked
then
5850 b
:= b
or ACTIVATE_SHOT
;
5851 if cbNoMonster
.Checked
then
5852 b
:= b
or ACTIVATE_NOMONSTER
;
5854 Values
[Key
] := ActivateToStr(b
);
5855 vleObjectPropertyApply(Sender
);
5858 else if Key
= _lc
[I_PROP_TR_KEYS
] then
5859 with KeysForm
, vleObjectProperty
do
5860 begin // Выбор необходимых ключей:
5861 cbRedKey
.Checked
:= Pos('RK', Values
[Key
]) > 0;
5862 cbGreenKey
.Checked
:= Pos('GK', Values
[Key
]) > 0;
5863 cbBlueKey
.Checked
:= Pos('BK', Values
[Key
]) > 0;
5864 cbRedTeam
.Checked
:= Pos('RT', Values
[Key
]) > 0;
5865 cbBlueTeam
.Checked
:= Pos('BT', Values
[Key
]) > 0;
5867 if ShowModal() = mrOK
then
5870 if cbRedKey
.Checked
then
5872 if cbGreenKey
.Checked
then
5873 b
:= b
or KEY_GREEN
;
5874 if cbBlueKey
.Checked
then
5876 if cbRedTeam
.Checked
then
5877 b
:= b
or KEY_REDTEAM
;
5878 if cbBlueTeam
.Checked
then
5879 b
:= b
or KEY_BLUETEAM
;
5881 Values
[Key
] := KeyToStr(b
);
5882 vleObjectPropertyApply(Sender
);
5885 else if Key
= _lc
[I_PROP_TR_FX_TYPE
] then
5886 with ChooseTypeForm
, vleObjectProperty
do
5887 begin // Выбор типа эффекта:
5888 Caption
:= _lc
[I_CAP_FX_TYPE
];
5889 lbTypeSelect
.Items
.Clear();
5891 for b
:= EFFECT_NONE
to EFFECT_FIRE
do
5892 lbTypeSelect
.Items
.Add(EffectToStr(b
));
5894 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]);
5896 if ShowModal() = mrOK
then
5898 b
:= lbTypeSelect
.ItemIndex
;
5899 Values
[Key
] := EffectToStr(b
);
5900 vleObjectPropertyApply(Sender
);
5903 else if Key
= _lc
[I_PROP_TR_MONSTER_TYPE
] then
5904 with ChooseTypeForm
, vleObjectProperty
do
5905 begin // Выбор типа монстра:
5906 Caption
:= _lc
[I_CAP_MONSTER_TYPE
];
5907 lbTypeSelect
.Items
.Clear();
5909 for b
:= MONSTER_DEMON
to MONSTER_MAN
do
5910 lbTypeSelect
.Items
.Add(MonsterToStr(b
));
5912 lbTypeSelect
.ItemIndex
:= StrToMonster(Values
[Key
]) - MONSTER_DEMON
;
5914 if ShowModal() = mrOK
then
5916 b
:= lbTypeSelect
.ItemIndex
+ MONSTER_DEMON
;
5917 Values
[Key
] := MonsterToStr(b
);
5918 vleObjectPropertyApply(Sender
);
5921 else if Key
= _lc
[I_PROP_TR_ITEM_TYPE
] then
5922 with ChooseTypeForm
, vleObjectProperty
do
5923 begin // Выбор типа предмета:
5924 Caption
:= _lc
[I_CAP_ITEM_TYPE
];
5925 lbTypeSelect
.Items
.Clear();
5927 for b
:= ITEM_MEDKIT_SMALL
to ITEM_KEY_BLUE
do
5928 lbTypeSelect
.Items
.Add(ItemToStr(b
));
5929 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_BOTTLE
));
5930 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_HELMET
));
5931 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_JETPACK
));
5932 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_INVIS
));
5933 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER
));
5934 lbTypeSelect
.Items
.Add(ItemToStr(ITEM_AMMO_FUELCAN
));
5936 b
:= StrToItem(Values
[Key
]);
5937 if b
>= ITEM_BOTTLE
then
5939 lbTypeSelect
.ItemIndex
:= b
- ITEM_MEDKIT_SMALL
;
5941 if ShowModal() = mrOK
then
5943 b
:= lbTypeSelect
.ItemIndex
+ ITEM_MEDKIT_SMALL
;
5944 if b
>= ITEM_WEAPON_KASTET
then
5946 Values
[Key
] := ItemToStr(b
);
5947 vleObjectPropertyApply(Sender
);
5950 else if Key
= _lc
[I_PROP_TR_SHOT_TYPE
] then
5951 with ChooseTypeForm
, vleObjectProperty
do
5952 begin // Выбор типа предмета:
5953 Caption
:= _lc
[I_PROP_TR_SHOT_TYPE
];
5954 lbTypeSelect
.Items
.Clear();
5956 for b
:= TRIGGER_SHOT_PISTOL
to TRIGGER_SHOT_MAX
do
5957 lbTypeSelect
.Items
.Add(ShotToStr(b
));
5959 lbTypeSelect
.ItemIndex
:= StrToShot(Values
[Key
]);
5961 if ShowModal() = mrOK
then
5963 b
:= lbTypeSelect
.ItemIndex
;
5964 Values
[Key
] := ShotToStr(b
);
5965 vleObjectPropertyApply(Sender
);
5968 else if Key
= _lc
[I_PROP_TR_EFFECT_TYPE
] then
5969 with ChooseTypeForm
, vleObjectProperty
do
5970 begin // Выбор типа эффекта:
5971 Caption
:= _lc
[I_CAP_FX_TYPE
];
5972 lbTypeSelect
.Items
.Clear();
5974 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_PARTICLE
]);
5975 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_ANIMATION
]);
5976 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5977 lbTypeSelect
.ItemIndex
:= 1
5979 lbTypeSelect
.ItemIndex
:= 0;
5981 if ShowModal() = mrOK
then
5983 b
:= lbTypeSelect
.ItemIndex
;
5985 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_PARTICLE
]
5987 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_ANIMATION
];
5988 vleObjectPropertyApply(Sender
);
5991 else if Key
= _lc
[I_PROP_TR_EFFECT_SUBTYPE
] then
5992 with ChooseTypeForm
, vleObjectProperty
do
5993 begin // Выбор подтипа эффекта:
5994 Caption
:= _lc
[I_CAP_FX_TYPE
];
5995 lbTypeSelect
.Items
.Clear();
5997 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
5999 for b
:= EFFECT_TELEPORT
to EFFECT_FIRE
do
6000 lbTypeSelect
.Items
.Add(EffectToStr(b
));
6002 lbTypeSelect
.ItemIndex
:= StrToEffect(Values
[Key
]) - 1;
6005 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SLIQUID
]);
6006 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_LLIQUID
]);
6007 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_DLIQUID
]);
6008 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BLOOD
]);
6009 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_SPARK
]);
6010 lbTypeSelect
.Items
.Add(_lc
[I_PROP_TR_EFFECT_BUBBLE
]);
6011 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SLIQUID
;
6012 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_LLIQUID
] then
6013 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_LLIQUID
;
6014 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_DLIQUID
] then
6015 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_DLIQUID
;
6016 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BLOOD
] then
6017 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BLOOD
;
6018 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_SPARK
] then
6019 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_SPARK
;
6020 if Values
[Key
] = _lc
[I_PROP_TR_EFFECT_BUBBLE
] then
6021 lbTypeSelect
.ItemIndex
:= TRIGGER_EFFECT_BUBBLE
;
6024 if ShowModal() = mrOK
then
6026 b
:= lbTypeSelect
.ItemIndex
;
6028 if Values
[_lc
[I_PROP_TR_EFFECT_TYPE
]] = _lc
[I_PROP_TR_EFFECT_ANIMATION
] then
6029 Values
[Key
] := EffectToStr(b
+ 1)
6031 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SLIQUID
];
6032 if b
= TRIGGER_EFFECT_LLIQUID
then
6033 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_LLIQUID
];
6034 if b
= TRIGGER_EFFECT_DLIQUID
then
6035 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_DLIQUID
];
6036 if b
= TRIGGER_EFFECT_BLOOD
then
6037 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BLOOD
];
6038 if b
= TRIGGER_EFFECT_SPARK
then
6039 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_SPARK
];
6040 if b
= TRIGGER_EFFECT_BUBBLE
then
6041 Values
[Key
] := _lc
[I_PROP_TR_EFFECT_BUBBLE
];
6044 vleObjectPropertyApply(Sender
);
6047 else if Key
= _lc
[I_PROP_TR_EFFECT_COLOR
] then
6048 with vleObjectProperty
do
6049 begin // Выбор цвета эффекта:
6050 ColorDialog
.Color
:= StrToIntDef(Values
[Key
], 0);
6051 if ColorDialog
.Execute
then
6053 Values
[Key
] := IntToStr(ColorDialog
.Color
);
6054 vleObjectPropertyApply(Sender
);
6057 else if Key
= _lc
[I_PROP_PANEL_TEX
] then
6058 begin // Смена текстуры:
6059 vleObjectProperty
.Values
[Key
] := SelectedTexture();
6060 vleObjectPropertyApply(Sender
);
6064 procedure TMainForm
.vleObjectPropertyApply(Sender
: TObject
);
6066 // hack to prevent empty ID in list
6067 RenderPanel
.SetFocus();
6068 bApplyProperty
.Click();
6069 vleObjectProperty
.SetFocus();
6072 procedure TMainForm
.aSaveMapExecute(Sender
: TObject
);
6074 FileName
, Section
, Res
: String;
6076 if OpenedMap
= '' then
6078 aSaveMapAsExecute(nil);
6082 g_ProcessResourceStr(OpenedMap
, FileName
, Section
, Res
);
6084 SaveMap(FileName
+':\'+Res
);
6087 procedure TMainForm
.aOpenMapExecute(Sender
: TObject
);
6089 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_ALL
];
6091 if OpenDialog
.Execute() then
6093 OpenMapFile(OpenDialog
.FileName
);
6094 OpenDialog
.InitialDir
:= ExtractFileDir(OpenDialog
.FileName
);
6098 procedure TMainForm
.OpenMapFile(FileName
: String);
6100 if (Pos('.ini', LowerCase(ExtractFileName(FileName
))) > 0) then
6104 pLoadProgress
.Left
:= (RenderPanel
.Width
div 2)-(pLoadProgress
.Width
div 2);
6105 pLoadProgress
.Top
:= (RenderPanel
.Height
div 2)-(pLoadProgress
.Height
div 2);
6106 pLoadProgress
.Show();
6111 LoadMapOld(FileName
);
6113 MainForm
.Caption
:= Format('%s - %s', [FormCaption
, ExtractFileName(FileName
)]);
6115 pLoadProgress
.Hide();
6116 MainForm
.FormResize(Self
);
6118 else // Карты из WAD:
6120 OpenMap(FileName
, '');
6124 procedure TMainForm
.FormActivate(Sender
: TObject
);
6129 MainForm
.ActiveControl
:= RenderPanel
;
6132 if gLanguage
= '' then
6134 lang
:= SelectLanguageForm
.ShowModal();
6136 1: gLanguage
:= LANGUAGE_ENGLISH
;
6137 else gLanguage
:= LANGUAGE_RUSSIAN
;
6140 config
:= TConfig
.CreateFile(EditorDir
+'Editor.cfg');
6141 config
.WriteStr('Editor', 'Language', gLanguage
);
6142 config
.SaveFile(EditorDir
+'Editor.cfg');
6146 //e_WriteLog('Read language file', MSG_NOTIFY);
6147 //g_Language_Load(EditorDir+'\data\'+gLanguage+LANGUAGE_FILE_NAME);
6148 g_Language_Set(gLanguage
);
6151 procedure TMainForm
.aDeleteMap(Sender
: TObject
);
6159 OpenDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6161 if not OpenDialog
.Execute() then
6164 WAD
:= TWADEditor_1
.Create();
6166 if not WAD
.ReadFile(OpenDialog
.FileName
) then
6174 MapList
:= WAD
.GetResourcesList('');
6176 SelectMapForm
.Caption
:= _lc
[I_CAP_REMOVE
];
6177 SelectMapForm
.lbMapList
.Items
.Clear();
6179 if MapList
<> nil then
6180 for a
:= 0 to High(MapList
) do
6181 SelectMapForm
.lbMapList
.Items
.Add(win2utf(MapList
[a
]));
6183 if (SelectMapForm
.ShowModal() = mrOK
) then
6185 str
:= SelectMapForm
.lbMapList
.Items
[SelectMapForm
.lbMapList
.ItemIndex
];
6187 Move(str
[1], MapName
[0], Min(16, Length(str
)));
6189 if MessageBox(0, PChar(Format(_lc
[I_MSG_DELETE_MAP_PROMT
],
6190 [MapName
, OpenDialog
.FileName
])),
6191 PChar(_lc
[I_MSG_DELETE_MAP
]),
6192 MB_ICONQUESTION
or MB_YESNO
or
6193 MB_DEFBUTTON2
) <> mrYes
then
6196 WAD
.RemoveResource('', utf2win(MapName
));
6198 MessageBox(0, PChar(Format(_lc
[I_MSG_MAP_DELETED_PROMT
],
6200 PChar(_lc
[I_MSG_MAP_DELETED
]),
6201 MB_ICONINFORMATION
or MB_OK
or
6204 WAD
.SaveTo(OpenDialog
.FileName
);
6206 // Удалили текущую карту - сохранять по старому ее нельзя:
6207 if OpenedMap
= (OpenDialog
.FileName
+':\'+MapName
) then
6211 MainForm
.Caption
:= FormCaption
;
6218 procedure TMainForm
.vleObjectPropertyKeyDown(Sender
: TObject
;
6219 var Key
: Word; Shift
: TShiftState
);
6221 if Key
= VK_RETURN
then
6222 vleObjectPropertyApply(Sender
);
6225 procedure MovePanel(var ID
: DWORD
; MoveType
: Byte);
6230 if (ID
= 0) and (MoveType
= 0) then
6232 if (ID
= DWORD(High(gPanels
))) and (MoveType
<> 0) then
6234 if (ID
> DWORD(High(gPanels
))) then
6239 if MoveType
= 0 then // to Back
6241 if gTriggers
<> nil then
6242 for a
:= 0 to High(gTriggers
) do
6243 with gTriggers
[a
] do
6245 if TriggerType
= TRIGGER_NONE
then
6248 if TexturePanel
= _id
then
6251 if (TexturePanel
>= 0) and (TexturePanel
< _id
) then
6255 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6256 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6257 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6258 if Data
.PanelID
= _id
then
6261 if (Data
.PanelID
>= 0) and (Data
.PanelID
< _id
) then
6265 if Data
.ShotPanelID
= _id
then
6266 Data
.ShotPanelID
:= 0
6268 if (Data
.ShotPanelID
>= 0) and (Data
.ShotPanelID
< _id
) then
6269 Inc(Data
.ShotPanelID
);
6273 tmp
:= gPanels
[_id
];
6275 for a
:= _id
downto 1 do
6276 gPanels
[a
] := gPanels
[a
-1];
6284 if gTriggers
<> nil then
6285 for a
:= 0 to High(gTriggers
) do
6286 with gTriggers
[a
] do
6288 if TriggerType
= TRIGGER_NONE
then
6291 if TexturePanel
= _id
then
6292 TexturePanel
:= High(gPanels
)
6294 if TexturePanel
> _id
then
6298 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
,
6299 TRIGGER_DOOR5
, TRIGGER_CLOSETRAP
, TRIGGER_TRAP
,
6300 TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
, TRIGGER_LIFT
:
6301 if Data
.PanelID
= _id
then
6302 Data
.PanelID
:= High(gPanels
)
6304 if Data
.PanelID
> _id
then
6308 if Data
.ShotPanelID
= _id
then
6309 Data
.ShotPanelID
:= High(gPanels
)
6311 if Data
.ShotPanelID
> _id
then
6312 Dec(Data
.ShotPanelID
);
6316 tmp
:= gPanels
[_id
];
6318 for a
:= _id
to High(gPanels
)-1 do
6319 gPanels
[a
] := gPanels
[a
+1];
6321 gPanels
[High(gPanels
)] := tmp
;
6323 ID
:= High(gPanels
);
6327 procedure TMainForm
.aMoveToBack(Sender
: TObject
);
6331 if SelectedObjects
= nil then
6334 for a
:= 0 to High(SelectedObjects
) do
6335 with SelectedObjects
[a
] do
6336 if Live
and (ObjectType
= OBJECT_PANEL
) then
6338 SelectedObjects
[0] := SelectedObjects
[a
];
6339 SetLength(SelectedObjects
, 1);
6346 procedure TMainForm
.aMoveToFore(Sender
: TObject
);
6350 if SelectedObjects
= nil then
6353 for a
:= 0 to High(SelectedObjects
) do
6354 with SelectedObjects
[a
] do
6355 if Live
and (ObjectType
= OBJECT_PANEL
) then
6357 SelectedObjects
[0] := SelectedObjects
[a
];
6358 SetLength(SelectedObjects
, 1);
6365 procedure TMainForm
.aSaveMapAsExecute(Sender
: TObject
);
6369 SaveDialog
.Filter
:= _lc
[I_FILE_FILTER_WAD
];
6371 if not SaveDialog
.Execute() then
6374 SaveMapForm
.GetMaps(SaveDialog
.FileName
, True);
6376 if SaveMapForm
.ShowModal() <> mrOK
then
6379 SaveDialog
.InitialDir
:= ExtractFileDir(SaveDialog
.FileName
);
6380 OpenedMap
:= SaveDialog
.FileName
+':\'+SaveMapForm
.eMapName
.Text;
6381 OpenedWAD
:= SaveDialog
.FileName
;
6383 idx
:= RecentFiles
.IndexOf(OpenedMap
);
6384 // Такая карта уже недавно открывалась:
6386 RecentFiles
.Delete(idx
);
6387 RecentFiles
.Insert(0, OpenedMap
);
6392 gMapInfo
.FileName
:= SaveDialog
.FileName
;
6393 gMapInfo
.MapName
:= SaveMapForm
.eMapName
.Text;
6394 UpdateCaption(gMapInfo
.Name
, ExtractFileName(gMapInfo
.FileName
), gMapInfo
.MapName
);
6397 procedure TMainForm
.aSelectAllExecute(Sender
: TObject
);
6401 RemoveSelectFromObjects();
6403 case pcObjects
.ActivePageIndex
+1 of
6405 if gPanels
<> nil then
6406 for a
:= 0 to High(gPanels
) do
6407 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6408 SelectObject(OBJECT_PANEL
, a
, True);
6410 if gItems
<> nil then
6411 for a
:= 0 to High(gItems
) do
6412 if gItems
[a
].ItemType
<> ITEM_NONE
then
6413 SelectObject(OBJECT_ITEM
, a
, True);
6415 if gMonsters
<> nil then
6416 for a
:= 0 to High(gMonsters
) do
6417 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6418 SelectObject(OBJECT_MONSTER
, a
, True);
6420 if gAreas
<> nil then
6421 for a
:= 0 to High(gAreas
) do
6422 if gAreas
[a
].AreaType
<> AREA_NONE
then
6423 SelectObject(OBJECT_AREA
, a
, True);
6425 if gTriggers
<> nil then
6426 for a
:= 0 to High(gTriggers
) do
6427 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6428 SelectObject(OBJECT_TRIGGER
, a
, True);
6431 RecountSelectedObjects();
6434 procedure TMainForm
.tbGridOnClick(Sender
: TObject
);
6436 DotEnable
:= not DotEnable
;
6437 (Sender
as TToolButton
).Down
:= DotEnable
;
6440 procedure TMainForm
.OnIdle(Sender
: TObject
; var Done
: Boolean);
6442 // FIXME: this is a shitty hack
6443 if not gDataLoaded
then
6445 e_WriteLog('Init OpenGL', MSG_NOTIFY
);
6447 e_WriteLog('Loading data', MSG_NOTIFY
);
6448 LoadStdFont('STDTXT', 'STDFONT', gEditorFont
);
6449 e_WriteLog('Loading more data', MSG_NOTIFY
);
6451 e_WriteLog('Loading even more data', MSG_NOTIFY
);
6452 gDataLoaded
:= True;
6453 MainForm
.FormResize(nil);
6458 procedure TMainForm
.miMapPreviewClick(Sender
: TObject
);
6460 if PreviewMode
= 2 then
6463 if PreviewMode
= 0 then
6465 Splitter2
.Visible
:= False;
6466 Splitter1
.Visible
:= False;
6467 StatusBar
.Visible
:= False;
6468 PanelObjs
.Visible
:= False;
6469 PanelProps
.Visible
:= False;
6470 MainToolBar
.Visible
:= False;
6471 sbHorizontal
.Visible
:= False;
6472 sbVertical
.Visible
:= False;
6476 StatusBar
.Visible
:= True;
6477 PanelObjs
.Visible
:= True;
6478 PanelProps
.Visible
:= True;
6479 Splitter2
.Visible
:= True;
6480 Splitter1
.Visible
:= True;
6481 MainToolBar
.Visible
:= True;
6482 sbHorizontal
.Visible
:= True;
6483 sbVertical
.Visible
:= True;
6486 PreviewMode
:= PreviewMode
xor 1;
6487 (Sender
as TMenuItem
).Checked
:= PreviewMode
> 0;
6492 procedure TMainForm
.miLayer1Click(Sender
: TObject
);
6494 SwitchLayer(LAYER_BACK
);
6497 procedure TMainForm
.miLayer2Click(Sender
: TObject
);
6499 SwitchLayer(LAYER_WALLS
);
6502 procedure TMainForm
.miLayer3Click(Sender
: TObject
);
6504 SwitchLayer(LAYER_FOREGROUND
);
6507 procedure TMainForm
.miLayer4Click(Sender
: TObject
);
6509 SwitchLayer(LAYER_STEPS
);
6512 procedure TMainForm
.miLayer5Click(Sender
: TObject
);
6514 SwitchLayer(LAYER_WATER
);
6517 procedure TMainForm
.miLayer6Click(Sender
: TObject
);
6519 SwitchLayer(LAYER_ITEMS
);
6522 procedure TMainForm
.miLayer7Click(Sender
: TObject
);
6524 SwitchLayer(LAYER_MONSTERS
);
6527 procedure TMainForm
.miLayer8Click(Sender
: TObject
);
6529 SwitchLayer(LAYER_AREAS
);
6532 procedure TMainForm
.miLayer9Click(Sender
: TObject
);
6534 SwitchLayer(LAYER_TRIGGERS
);
6537 procedure TMainForm
.tbShowClick(Sender
: TObject
);
6543 for a
:= 0 to High(LayerEnabled
) do
6544 b
:= b
and LayerEnabled
[a
];
6548 ShowLayer(LAYER_BACK
, b
);
6549 ShowLayer(LAYER_WALLS
, b
);
6550 ShowLayer(LAYER_FOREGROUND
, b
);
6551 ShowLayer(LAYER_STEPS
, b
);
6552 ShowLayer(LAYER_WATER
, b
);
6553 ShowLayer(LAYER_ITEMS
, b
);
6554 ShowLayer(LAYER_MONSTERS
, b
);
6555 ShowLayer(LAYER_AREAS
, b
);
6556 ShowLayer(LAYER_TRIGGERS
, b
);
6559 procedure TMainForm
.miMiniMapClick(Sender
: TObject
);
6564 procedure TMainForm
.miSwitchGridClick(Sender
: TObject
);
6566 if DotStep
= DotStepOne
then
6567 DotStep
:= DotStepTwo
6569 DotStep
:= DotStepOne
;
6571 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6572 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6575 procedure TMainForm
.miShowEdgesClick(Sender
: TObject
);
6580 procedure TMainForm
.miSnapToGridClick(Sender
: TObject
);
6582 SnapToGrid
:= not SnapToGrid
;
6584 MousePos
.X
:= (MousePos
.X
div DotStep
) * DotStep
;
6585 MousePos
.Y
:= (MousePos
.Y
div DotStep
) * DotStep
;
6587 miSnapToGrid
.Checked
:= SnapToGrid
;
6590 procedure TMainForm
.minexttabClick(Sender
: TObject
);
6592 if pcObjects
.ActivePageIndex
< pcObjects
.PageCount
-1 then
6593 pcObjects
.ActivePageIndex
:= pcObjects
.ActivePageIndex
+1
6595 pcObjects
.ActivePageIndex
:= 0;
6598 procedure TMainForm
.miSaveMiniMapClick(Sender
: TObject
);
6600 SaveMiniMapForm
.ShowModal();
6603 procedure TMainForm
.bClearTextureClick(Sender
: TObject
);
6605 lbTextureList
.ItemIndex
:= -1;
6606 lTextureWidth
.Caption
:= '';
6607 lTextureHeight
.Caption
:= '';
6610 procedure TMainForm
.miPackMapClick(Sender
: TObject
);
6612 PackMapForm
.ShowModal();
6615 procedure TMainForm
.miMapTestSettingsClick(Sender
: TObject
);
6617 MapTestForm
.ShowModal();
6620 procedure TMainForm
.miTestMapClick(Sender
: TObject
);
6622 cmd
, mapWAD
, mapToRun
, tempWAD
: String;
6629 if OpenedMap
<> '' then
6631 // Указываем текущую карту для теста:
6632 g_ProcessResourceStr(OpenedMap
, @mapWAD
, nil, @mapToRun
);
6633 mapToRun
:= mapWAD
+ ':\' + mapToRun
;
6634 mapToRun
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', mapToRun
);
6636 // Сохраняем временную карту:
6639 mapWAD
:= ExtractFilePath(TestD2dExe
) + Format('maps/temp%.4d.wad', [time
]);
6641 until not FileExists(mapWAD
);
6642 tempWAD
:= mapWAD
+ ':\' + TEST_MAP_NAME
;
6645 tempWAD
:= ExtractRelativePath(ExtractFilePath(TestD2dExe
) + 'maps/', tempWAD
);
6646 // Если карта не была открыта, указываем временную в качестве текущей:
6647 if mapToRun
= '' then
6648 mapToRun
:= tempWAD
;
6652 if TestOptionsTwoPlayers
then
6654 if TestOptionsTeamDamage
then
6656 if TestOptionsAllowExit
then
6658 if TestOptionsWeaponStay
then
6660 if TestOptionsMonstersDM
then
6663 // Составляем командную строку:
6664 cmd
:= '-map "' + mapToRun
+ '"';
6665 cmd
:= cmd
+ ' -testmap "' + tempWAD
+ '"';
6666 cmd
:= cmd
+ ' -gm ' + TestGameMode
;
6667 cmd
:= cmd
+ ' -limt ' + TestLimTime
;
6668 cmd
:= cmd
+ ' -lims ' + TestLimScore
;
6669 cmd
:= cmd
+ ' -opt ' + IntToStr(opt
);
6672 cmd
:= cmd
+ ' --close';
6674 cmd
:= cmd
+ ' --debug';
6677 proc
:= TProcessUTF8
.Create(nil);
6678 proc
.Executable
:= TestD2dExe
;
6679 proc
.Parameters
.Add(cmd
);
6688 Application
.Minimize();
6691 if (not res
) or (proc
.ExitCode
< 0) then
6693 MessageBox(0, 'FIXME',
6694 PChar(_lc
[I_MSG_EXEC_ERROR
]),
6695 MB_OK
or MB_ICONERROR
);
6699 SysUtils
.DeleteFile(mapWAD
);
6700 Application
.Restore();
6703 procedure TMainForm
.sbVerticalScroll(Sender
: TObject
;
6704 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6706 MapOffset
.Y
:= -Normalize16(sbVertical
.Position
);
6709 procedure TMainForm
.sbHorizontalScroll(Sender
: TObject
;
6710 ScrollCode
: TScrollCode
; var ScrollPos
: Integer);
6712 MapOffset
.X
:= -Normalize16(sbHorizontal
.Position
);
6715 procedure TMainForm
.miOpenWadMapClick(Sender
: TObject
);
6717 if OpenedWAD
<> '' then
6719 OpenMap(OpenedWAD
, '');
6723 procedure TMainForm
.selectall1Click(Sender
: TObject
);
6727 RemoveSelectFromObjects();
6729 if gPanels
<> nil then
6730 for a
:= 0 to High(gPanels
) do
6731 if gPanels
[a
].PanelType
<> PANEL_NONE
then
6732 SelectObject(OBJECT_PANEL
, a
, True);
6734 if gItems
<> nil then
6735 for a
:= 0 to High(gItems
) do
6736 if gItems
[a
].ItemType
<> ITEM_NONE
then
6737 SelectObject(OBJECT_ITEM
, a
, True);
6739 if gMonsters
<> nil then
6740 for a
:= 0 to High(gMonsters
) do
6741 if gMonsters
[a
].MonsterType
<> MONSTER_NONE
then
6742 SelectObject(OBJECT_MONSTER
, a
, True);
6744 if gAreas
<> nil then
6745 for a
:= 0 to High(gAreas
) do
6746 if gAreas
[a
].AreaType
<> AREA_NONE
then
6747 SelectObject(OBJECT_AREA
, a
, True);
6749 if gTriggers
<> nil then
6750 for a
:= 0 to High(gTriggers
) do
6751 if gTriggers
[a
].TriggerType
<> TRIGGER_NONE
then
6752 SelectObject(OBJECT_TRIGGER
, a
, True);
6754 RecountSelectedObjects();
6757 procedure TMainForm
.Splitter1CanResize(Sender
: TObject
;
6758 var NewSize
: Integer; var Accept
: Boolean);
6760 Accept
:= (NewSize
> 140);
6763 procedure TMainForm
.Splitter2CanResize(Sender
: TObject
;
6764 var NewSize
: Integer; var Accept
: Boolean);
6766 Accept
:= (NewSize
> 110);
6769 procedure TMainForm
.vleObjectPropertyEnter(Sender
: TObject
);
6771 EditingProperties
:= True;
6774 procedure TMainForm
.vleObjectPropertyExit(Sender
: TObject
);
6776 EditingProperties
:= False;
6779 procedure TMainForm
.FormKeyUp(Sender
: TObject
; var Key
: Word;
6780 Shift
: TShiftState
);
6782 // Объекты передвигались:
6783 if MainForm
.ActiveControl
= RenderPanel
then
6785 if (Key
= VK_NUMPAD4
) or
6786 (Key
= VK_NUMPAD6
) or
6787 (Key
= VK_NUMPAD8
) or
6788 (Key
= VK_NUMPAD5
) or
6789 (Key
= Ord('V')) then
6792 // Быстрое превью карты:
6793 if Key
= Ord('E') then
6795 if PreviewMode
= 2 then
6798 RenderPanelMouseMove(Sender
, Shift
, RenderMousePos().X
, RenderMousePos().Y
);