DEADSOFTWARE

0a97da7d911e29672ea2b28cc708ee8070da762a
[d2df-editor.git] / src / editor / g_map.pas
1 Unit g_map;
3 {$INCLUDE ../shared/a_modes.inc}
5 Interface
7 Uses
8 LCLIntf, LCLType, LMessages, g_basic, e_graphics, MAPREADER, MAPSTRUCT,
9 MAPWRITER, e_log, MAPDEF, utils;
11 Type
12 TMapObject = record
13 ObjectType: Byte;
14 ID: DWORD;
15 Live: Boolean;
16 end;
18 TPanel = record
19 TextureID: DWORD;
20 TextureWidth,
21 TextureHeight: Word;
22 X, Y: Integer;
23 Width, Height: Word;
24 PanelType: Word;
25 Alpha: Byte;
26 Blending: Boolean;
27 TextureName: String;
28 end;
30 TItem = record
31 X, Y: Integer;
32 ItemType: Byte;
33 OnlyDM: Boolean;
34 Fall: Boolean;
35 end;
37 TArea = record
38 X, Y: Integer;
39 AreaType: Byte;
40 Direction: TDirection;
41 end;
43 TMonster = record
44 X, Y: Integer;
45 MonsterType: Byte;
46 Direction: TDirection;
47 end;
49 TTrigger = record
50 X, Y: Integer;
51 Width, Height: Word;
52 Enabled: Boolean;
53 TexturePanel: Integer;
54 TriggerType: Byte;
55 ActivateType: Byte;
56 Key: Byte;
57 Data: TTriggerData;
58 end;
60 TMapInfo = record
61 FileName: String;
62 MapName: String;
63 Name: String;
64 Description: String;
65 Author: String;
66 MusicName: String;
67 SkyName: String;
68 Height: Word;
69 Width: Word;
70 end;
72 TMonsterSizeDelta = record
73 X, Y: Integer;
74 Width: Word;
75 end;
77 const
78 OBJECT_PANEL = 1;
79 OBJECT_ITEM = 2;
80 OBJECT_MONSTER = 3;
81 OBJECT_AREA = 4;
82 OBJECT_TRIGGER = 5;
84 COLOR_EDGE: Integer = $000000;
85 ALPHA_EDGE: Byte = 96;
86 ALPHA_LINE: Byte = 208;
87 ALPHA_AREA: Byte = 96;
89 TEXTURE_NAME_WATER = '_water_0';
90 TEXTURE_NAME_ACID1 = '_water_1';
91 TEXTURE_NAME_ACID2 = '_water_2';
92 TEXTURE_SPECIAL_NONE = DWORD(-1);
93 TEXTURE_SPECIAL_WATER = DWORD(-2);
94 TEXTURE_SPECIAL_ACID1 = DWORD(-3);
95 TEXTURE_SPECIAL_ACID2 = DWORD(-4);
96 TEXTURE_SPECIAL_NOTEXTURE = DWORD(-8);
98 ItemSize: Array [ITEM_MEDKIT_SMALL..ITEM_MAX] of Array [0..1] of Byte =
99 (((14), (15)), // MEDKIT_SMALL
100 ((28), (19)), // MEDKIT_LARGE
101 ((28), (19)), // MEDKIT_BLACK
102 ((31), (16)), // ARMOR_GREEN
103 ((31), (16)), // ARMOR_BLUE
104 ((25), (25)), // SPHERE_BLUE
105 ((25), (25)), // SPHERE_WHITE
106 ((24), (47)), // SUIT
107 ((14), (27)), // OXYGEN
108 ((25), (25)), // INVUL
109 ((62), (24)), // WEAPON_SAW
110 ((63), (12)), // WEAPON_SHOTGUN1
111 ((54), (13)), // WEAPON_SHOTGUN2
112 ((54), (16)), // WEAPON_CHAINGUN
113 ((62), (16)), // WEAPON_ROCKETLAUNCHER
114 ((54), (16)), // WEAPON_PLASMA
115 ((61), (36)), // WEAPON_BFG
116 ((54), (16)), // WEAPON_SUPERPULEMET
117 (( 9), (11)), // AMMO_BULLETS
118 ((28), (16)), // AMMO_BULLETS_BOX
119 ((15), ( 7)), // AMMO_SHELLS
120 ((32), (12)), // AMMO_SHELLS_BOX
121 ((12), (27)), // AMMO_ROCKET
122 ((54), (21)), // AMMO_ROCKET_BOX
123 ((15), (12)), // AMMO_CELL
124 ((32), (21)), // AMMO_CELL_BIG
125 ((22), (29)), // AMMO_BACKPACK
126 ((16), (16)), // KEY_RED
127 ((16), (16)), // KEY_GREEN
128 ((16), (16)), // KEY_BLUE
129 (( 1), ( 1)), // WEAPON_KASTET
130 ((43), (16)), // WEAPON_PISTOL
131 ((14), (18)), // BOTTLE
132 ((16), (15)), // HELMET
133 ((32), (24)), // JETPACK
134 ((25), (25)), // INVIS
135 ((53), (20)), // WEAPON_FLAMETHROWER
136 ((13), (20))); // AMMO_FUELCAN
138 AreaSize: Array [AREA_PLAYERPOINT1..AREA_BLUETEAMPOINT] of TRectWH =
139 ((X:15; Y:12; Width:34; Height:52), // PLAYERPOINT1
140 (X:15; Y:12; Width:34; Height:52), // PLAYERPOINT2
141 (X:15; Y:12; Width:34; Height:52), // DMPOINT
142 (X:15; Y:11; Width:34; Height:52), // REDFLAG
143 (X:15; Y:11; Width:34; Height:52), // BLUEFLAG
144 (X:15; Y:11; Width:34; Height:52), // DOMFLAG
145 (X:15; Y:12; Width:34; Height:52), // REDTEAMPOINT
146 (X:15; Y:12; Width:34; Height:52)); // BLUETEAMPOINT
148 MonsterSize: Array [MONSTER_DEMON..MONSTER_MAN] of TRectWH =
149 ((X: 7; Y: 8; Width: 50; Height: 52), // DEMON
150 (X: 15; Y: 10; Width: 34; Height: 50), // IMP
151 (X: 15; Y: 8; Width: 34; Height: 52), // ZOMBY
152 (X: 15; Y: 8; Width: 34; Height: 52), // SERG
153 (X: 24; Y: 9; Width: 80; Height: 110), // CYBER
154 (X: 15; Y: 4; Width: 34; Height: 56), // CGUN
155 (X: 39; Y: 32; Width: 50; Height: 64), // BARON
156 (X: 39; Y: 32; Width: 50; Height: 64), // KNIGHT
157 (X: 34; Y: 36; Width: 60; Height: 56), // CACO
158 (X: 16; Y: 14; Width: 32; Height: 36), // SOUL
159 (X: 34; Y: 36; Width: 60; Height: 56), // PAIN
160 (X: 23; Y: 14; Width: 210; Height: 100), // SPIDER
161 (X: 14; Y: 17; Width: 100; Height: 42), // BSP
162 (X: 28; Y: 34; Width: 72; Height: 60), // MANCUB
163 (X: 30; Y: 28; Width: 68; Height: 72), // SKEL
164 (X: 30; Y: 28; Width: 68; Height: 72), // VILE
165 (X: 6; Y: 11; Width: 20; Height: 10), // FISH
166 (X: 20; Y: 13; Width: 24; Height: 36), // BARREL
167 (X: 30; Y: 26; Width: 68; Height: 76), // ROBO
168 (X: 15; Y: 6; Width: 34; Height: 52)); // MAN
170 MonsterSizeDelta: Array [MONSTER_DEMON..MONSTER_MAN] of TMonsterSizeDelta =
171 ((X: 1; Y: 4; Width: 64), // DEMON
172 (X: 8; Y: -4; Width: 64), // IMP
173 (X: 1; Y: -4; Width: 64), // ZOMBY
174 (X: 0; Y: -4; Width: 64), // SERG
175 (X: 2; Y: -6; Width: 128), // CYBER
176 (X: -1; Y: -2; Width: 64), // CGUN
177 (X: 4; Y: 0; Width: 128), // BARON
178 (X: 4; Y: 0; Width: 128), // KNIGHT
179 (X: 0; Y: -4; Width: 128), // CACO
180 (X: 1; Y: -10; Width: 64), // SOUL
181 (X: -1; Y: -3; Width: 128), // PAIN
182 (X: -4; Y: -4; Width: 256), // SPIDER
183 (X: 0; Y: -1; Width: 128), // BSP
184 (X: -2; Y: -7; Width: 128), // MANCUB
185 (X: -1; Y: 4; Width: 128), // SKEL
186 (X: 5; Y: -21; Width: 128), // VILE
187 (X: -1; Y: 0; Width: 32), // FISH
188 (X: 0; Y: -15; Width: 64), // BARREL
189 (X: -2; Y: -26; Width: 128), // ROBO
190 (X: 0; Y: -6; Width: 64)); // MAN
192 var
193 gColorEdge: Integer;
194 gAlphaEdge: Byte;
195 gAlphaTriggerLine: Byte;
196 gAlphaTriggerArea: Byte;
197 drEdge: Array[0..3] of Byte;
198 gPanels: Array of TPanel;
199 gItems: Array of TItem;
200 gAreas: Array of TArea;
201 gMonsters: Array of TMonster;
202 gTriggers: Array of TTrigger;
203 gMapInfo: TMapInfo;
204 MapOffset: TPoint = (X: 0; Y: 0);
205 SelectedObjects: Array of TMapObject = nil;
207 procedure LoadSky(Res: String);
209 function AddItem(Item: TItem): DWORD;
210 function AddPanel(Panel: TPanel): DWORD;
211 function AddArea(Area: TArea): DWORD;
212 function AddMonster(Monster: TMonster): DWORD;
213 function AddTrigger(Trigger: TTrigger): DWORD;
215 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
216 function PanelInShownLayer(PanelType: Word): Boolean;
217 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
218 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
219 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
220 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
221 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
222 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
223 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
225 function GetPanelName(PanelType: Word): String;
226 function GetPanelType(PanelName: String): Word;
227 function GetTriggerName(TriggerType: Byte): String;
228 function GetTriggerType(TriggerName: String): Byte;
230 function IsSpecialTexture(TextureName: String): Boolean;
231 function SpecialTextureID(TextureName: String): DWORD;
233 procedure ClearMap();
234 function SaveMap(Res: String): Pointer;
235 function LoadMap(Res: String): Boolean;
236 function LoadMapOld(_FileName: String): Boolean;
237 procedure DrawMap();
238 procedure LoadData();
239 procedure FreeData();
241 procedure ShiftMapObjects(dx, dy: Integer);
243 Implementation
245 Uses
246 BinEditor, g_textures, Dialogs, SysUtils, CONFIG, f_main,
247 Forms, Math, f_addresource_texture, WADEDITOR,
248 Masks, g_Language;
250 const
251 OLD_ITEM_MEDKIT_SMALL = 1;
252 OLD_ITEM_MEDKIT_LARGE = 2;
253 OLD_ITEM_ARMOR_GREEN = 3;
254 OLD_ITEM_ARMOR_BLUE = 4;
255 OLD_ITEM_SPHERE_BLUE = 5;
256 OLD_ITEM_SPHERE_WHITE = 6;
257 OLD_ITEM_WEAPON_SAW = 7;
258 OLD_ITEM_WEAPON_SHOTGUN1 = 8;
259 OLD_ITEM_WEAPON_SHOTGUN2 = 9;
260 OLD_ITEM_WEAPON_CHAINGUN = 10;
261 OLD_ITEM_WEAPON_ROCKETLAUNCHER = 11;
262 OLD_ITEM_WEAPON_PLASMA = 12;
263 OLD_ITEM_WEAPON_BFG = 13;
264 OLD_ITEM_WEAPON_SUPERPULEMET = 14;
265 OLD_ITEM_AMMO_BULLETS = 15;
266 OLD_ITEM_AMMO_BULLETS_BOX = 16;
267 OLD_ITEM_AMMO_SHELLS = 17;
268 OLD_ITEM_AMMO_SHELLS_BOX = 18;
269 OLD_ITEM_AMMO_ROCKET = 19;
270 OLD_ITEM_AMMO_ROCKET_BOX = 20;
271 OLD_ITEM_AMMO_CELL = 21;
272 OLD_ITEM_AMMO_CELL_BIG = 22;
273 OLD_ITEM_AMMO_BACKPACK = 23;
274 OLD_ITEM_KEY_RED = 24;
275 OLD_ITEM_KEY_GREEN = 25;
276 OLD_ITEM_KEY_BLUE = 26;
277 OLD_ITEM_SUIT = 27;
278 OLD_ITEM_OXYGEN = 28;
279 OLD_ITEM_MEDKIT_BLACK = 29;
280 OLD_ITEM_INVUL = 30;
282 ITEMSCONVERT: Array [OLD_ITEM_MEDKIT_SMALL..OLD_ITEM_INVUL] of Integer =
283 ((ITEM_MEDKIT_SMALL),
284 (ITEM_MEDKIT_LARGE),
285 (ITEM_ARMOR_GREEN),
286 (ITEM_ARMOR_BLUE),
287 (ITEM_SPHERE_BLUE),
288 (ITEM_SPHERE_WHITE),
289 (ITEM_WEAPON_SAW),
290 (ITEM_WEAPON_SHOTGUN1),
291 (ITEM_WEAPON_SHOTGUN2),
292 (ITEM_WEAPON_CHAINGUN),
293 (ITEM_WEAPON_ROCKETLAUNCHER),
294 (ITEM_WEAPON_PLASMA),
295 (ITEM_WEAPON_BFG),
296 (ITEM_WEAPON_SUPERPULEMET),
297 (ITEM_AMMO_BULLETS),
298 (ITEM_AMMO_BULLETS_BOX),
299 (ITEM_AMMO_SHELLS),
300 (ITEM_AMMO_SHELLS_BOX),
301 (ITEM_AMMO_ROCKET),
302 (ITEM_AMMO_ROCKET_BOX),
303 (ITEM_AMMO_CELL),
304 (ITEM_AMMO_CELL_BIG),
305 (ITEM_AMMO_BACKPACK),
306 (ITEM_KEY_RED),
307 (ITEM_KEY_GREEN),
308 (ITEM_KEY_BLUE),
309 (ITEM_SUIT),
310 (ITEM_OXYGEN),
311 (ITEM_MEDKIT_BLACK),
312 (ITEM_INVUL));
314 OldItemSize: Array [ITEM_MEDKIT_SMALL..ITEM_KEY_BLUE] of Array [0..1] of Byte =
315 (((14), (15)), // MEDKIT_SMALL
316 ((28), (19)), // MEDKIT_LARGE
317 ((28), (19)), // MEDKIT_BLACK - not in map generator
318 ((30), (16)), // ARMOR_GREEN
319 ((30), (16)), // ARMOR_BLUE
320 ((24), (24)), // SPHERE_BLUE
321 ((24), (24)), // SPHERE_WHITE
322 ((24), (46)), // SUIT
323 ((14), (27)), // OXYGEN
324 ((25), (25)), // INVUL - not in map generator
325 ((61), (23)), // WEAPON_SAW
326 ((62), (10)), // WEAPON_SHOTGUN1
327 ((52), (12)), // WEAPON_SHOTGUN2
328 ((53), (15)), // WEAPON_CHAINGUN
329 ((61), (15)), // WEAPON_ROCKETLAUNCHER
330 ((53), (14)), // WEAPON_PLASMA
331 ((61), (34)), // WEAPON_BFG
332 ((53), (16)), // WEAPON_SUPERPULEMET
333 (( 9), (10)), // AMMO_BULLETS
334 ((28), (16)), // AMMO_BULLETS_BOX
335 ((15), ( 7)), // AMMO_SHELLS
336 ((32), (12)), // AMMO_SHELLS_BOX
337 ((12), (26)), // AMMO_ROCKET
338 ((54), (21)), // AMMO_ROCKET_BOX
339 ((15), (12)), // AMMO_CELL
340 ((32), (21)), // AMMO_CELL_BIG
341 ((22), (29)), // AMMO_BACKPACK
342 ((16), (16)), // KEY_RED
343 ((16), (16)), // KEY_GREEN
344 ((16), (16))); // KEY_BLUE
346 OldAreaSize: Array [0..1] of Byte = ((34), (56));
348 SKY_TEXTURE = 'SKY';
350 procedure LoadSky(Res: String);
351 var
352 fn: String;
354 begin
355 g_DeleteTexture(SKY_TEXTURE);
357 if Res = '' then
358 Exit;
360 g_ProcessResourceStr(Res, @fn, nil, nil);
362 if fn = '' then
363 begin
364 g_ProcessResourceStr(OpenedMap, @fn, nil, nil);
365 fn := fn + Res;
366 end
367 else
368 fn := EditorDir + 'wads/' + Res;
370 g_CreateTextureWAD(SKY_TEXTURE, fn);
371 end;
373 function AddItem(Item: TItem): DWORD;
374 var
375 a: Integer;
376 ok: Boolean;
378 begin
379 ok := False;
380 a := 0;
382 if gItems <> nil then
383 for a := 0 to High(gItems) do
384 if gItems[a].ItemType = ITEM_NONE then
385 begin
386 ok := True;
387 Break;
388 end;
390 if not ok then
391 begin
392 a := Length(gItems);
393 SetLength(gItems, a + 128);
394 end;
396 gItems[a] := Item;
398 Result := a;
399 end;
401 function AddPanel(Panel: TPanel): DWORD;
402 var
403 a, b: Integer;
404 ok: Boolean;
406 begin
407 ok := False;
408 a := 0;
409 b := -1;
411 if gPanels <> nil then
412 for a := High(gPanels) downto 0 do
413 if gPanels[a].PanelType = PANEL_NONE then
414 b := a
415 else
416 Break;
418 if b <> -1 then
419 begin
420 a := b;
421 ok := True;
422 end;
424 if not ok then
425 begin
426 a := Length(gPanels);
427 SetLength(gPanels, a + 512);
428 end;
430 gPanels[a] := Panel;
432 Result := a;
433 end;
435 function AddArea(Area: TArea): DWORD;
436 var
437 a: Integer;
438 ok: Boolean;
440 begin
441 ok := False;
442 a := 0;
444 if gAreas <> nil then
445 for a := 0 to High(gAreas) do
446 if gAreas[a].AreaType = AREA_NONE then
447 begin
448 ok := True;
449 Break;
450 end;
452 if not ok then
453 begin
454 a := Length(gAreas);
455 SetLength(gAreas, a + 64);
456 end;
458 gAreas[a] := Area;
460 Result := a;
461 end;
463 function AddMonster(Monster: TMonster): DWORD;
464 var
465 a: Integer;
466 ok: Boolean;
468 begin
469 ok := False;
470 a := 0;
472 if gMonsters <> nil then
473 for a := 0 to High(gMonsters) do
474 if gMonsters[a].MonsterType = MONSTER_NONE then
475 begin
476 ok := True;
477 Break;
478 end;
480 if not ok then
481 begin
482 a := Length(gMonsters);
483 SetLength(gMonsters, a + 128);
484 end;
486 gMonsters[a] := Monster;
488 Result := a;
489 end;
491 function AddTrigger(Trigger: TTrigger): DWORD;
492 var
493 a: Integer;
494 ok: Boolean;
496 begin
497 ok := False;
498 a := 0;
500 if gTriggers <> nil then
501 for a := 0 to High(gTriggers) do
502 if gTriggers[a].TriggerType = TRIGGER_NONE then
503 begin
504 ok := True;
505 Break;
506 end;
508 if not ok then
509 begin
510 a := Length(gTriggers);
511 SetLength(gTriggers, a + 64);
512 end;
514 gTriggers[a] := Trigger;
516 Result := a;
517 end;
519 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
520 var
521 a: Integer;
523 begin
524 case ObjectType of
525 OBJECT_PANEL:
526 begin
527 // Убираем ссылки триггеров на эту панель:
528 if gTriggers <> nil then
529 for a := 0 to High(gTriggers) do
530 if gTriggers[a].TriggerType <> 0 then
531 begin
532 if gTriggers[a].TexturePanel = Integer(ID) then
533 gTriggers[a].TexturePanel := -1;
535 if gTriggers[a].TriggerType in [
536 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
537 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
538 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
539 TRIGGER_LIFT] then
540 if gTriggers[a].Data.PanelID = Integer(ID) then
541 gTriggers[a].Data.PanelID := -1;
543 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
544 (gTriggers[a].Data.ShotPanelID = Integer(ID)) then
545 gTriggers[a].Data.ShotPanelID := -1;
546 end;
548 gPanels[ID].PanelType := 0;
549 end;
551 OBJECT_ITEM:
552 gItems[ID].ItemType := 0;
554 OBJECT_MONSTER:
555 begin
556 // Убираем ссылки триггеров на этого монстра:
557 if gTriggers <> nil then
558 for a := 0 to High(gTriggers) do
559 if gTriggers[a].TriggerType <> 0 then
560 begin
561 if gTriggers[a].TriggerType in [TRIGGER_PRESS,
562 TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
563 if (gTriggers[a].Data.MonsterID-1 = Integer(ID)) then
564 gTriggers[a].Data.MonsterID := 0;
565 end;
567 gMonsters[ID].MonsterType := 0;
568 end;
570 OBJECT_AREA:
571 gAreas[ID].AreaType := 0;
573 OBJECT_TRIGGER:
574 gTriggers[ID].TriggerType := 0;
575 end;
576 end;
578 function PanelInShownLayer(PanelType: Word): Boolean;
579 begin
580 case PanelType of
581 PANEL_WALL:
582 Result := LayerEnabled[LAYER_WALLS];
584 PANEL_BACK:
585 Result := LayerEnabled[LAYER_BACK];
587 PANEL_FORE:
588 Result := LayerEnabled[LAYER_FOREGROUND];
590 PANEL_STEP:
591 Result := LayerEnabled[LAYER_STEPS];
593 PANEL_WATER, PANEL_ACID1, PANEL_ACID2,
594 PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT,
595 PANEL_OPENDOOR, PANEL_CLOSEDOOR,
596 PANEL_BLOCKMON:
597 Result := LayerEnabled[LAYER_WATER];
599 else
600 Result := False;
601 end;
602 end;
604 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
605 var
606 a: Integer;
608 begin
609 Result := nil;
611 case ObjectType of
612 OBJECT_PANEL:
613 if gPanels <> nil then
614 for a := High(gPanels) downto 0 do
615 with gPanels[a] do
616 begin
617 if not PanelInShownLayer(gPanels[a].PanelType) then
618 Continue;
620 if g_Collide(X, Y, Width, Height,
621 fX, fY, fWidth, fHeight) then
622 begin
623 SetLength(Result, Length(Result)+1);
624 Result[High(Result)] := a;
626 if not All then
627 Break;
628 end;
629 end;
631 OBJECT_ITEM:
632 if LayerEnabled[LAYER_ITEMS] and (gItems <> nil) then
633 for a := High(gItems) downto 0 do
634 with gItems[a] do
635 if (ItemType <> ITEM_NONE) and
636 g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
637 fX, fY, fWidth, fHeight) then
638 begin
639 SetLength(Result, Length(Result)+1);
640 Result[High(Result)] := a;
642 if not All then
643 Break;
644 end;
646 OBJECT_MONSTER:
647 if LayerEnabled[LAYER_MONSTERS] and (gMonsters <> nil) then
648 for a := High(gMonsters) downto 0 do
649 if gMonsters[a].MonsterType <> MONSTER_NONE then
650 with MonsterSize[gMonsters[a].MonsterType] do
651 if (gMonsters[a].MonsterType <> 0) and
652 g_Collide(gMonsters[a].X, gMonsters[a].Y, Width, Height,
653 fX, fY, fWidth, fHeight) then
654 begin
655 SetLength(Result, Length(Result)+1);
656 Result[High(Result)] := a;
658 if not All then
659 Break;
660 end;
662 OBJECT_AREA:
663 if LayerEnabled[LAYER_AREAS] and (gAreas <> nil) then
664 for a := High(gAreas) downto 0 do
665 if gAreas[a].AreaType <> AREA_NONE then
666 with AreaSize[gAreas[a].AreaType] do
667 if (gAreas[a].AreaType <> 0) and
668 g_Collide(gAreas[a].X, gAreas[a].Y, Width, Height,
669 fX, fY, fWidth, fHeight) then
670 begin
671 SetLength(Result, Length(Result)+1);
672 Result[High(Result)] := a;
674 if not All then
675 Break;
676 end;
678 OBJECT_TRIGGER:
679 if LayerEnabled[LAYER_TRIGGERS] and (gTriggers <> nil) then
680 for a := High(gTriggers) downto 0 do
681 if gTriggers[a].TriggerType <> TRIGGER_NONE then
682 with gTriggers[a] do
683 begin
684 if (TriggerType <> 0) and
685 g_Collide(X, Y, Width, Height,
686 fX, fY, fWidth, fHeight) then
687 begin
688 SetLength(Result, Length(Result)+1);
689 Result[High(Result)] := a;
691 if not All then
692 Break;
693 end;
694 end;
695 end;
696 end;
698 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
699 var
700 PanelID: DWORD;
702 begin
703 Result := False;
704 PanelID := DWORD(-1);
706 case ObjectType of
707 OBJECT_PANEL:
708 with gPanels[fID] do
709 Result := (PanelID <> fID) and
710 g_CollideLevel2(X+dX, Y+dY,
711 Width, Height,
712 fID, PanelID);
714 OBJECT_ITEM:
715 with gItems[fID] do
716 Result := g_CollideLevel(X+dX, Y+dY,
717 ItemSize[ItemType][0], ItemSize[ItemType][1]);
719 OBJECT_MONSTER:
720 with MonsterSize[gMonsters[fID].MonsterType] do
721 Result := g_CollideLevel(gMonsters[fID].X+dX, gMonsters[fID].Y+dY,
722 Width, Height);
724 OBJECT_AREA:
725 with AreaSize[gAreas[fID].AreaType] do
726 Result := g_CollideLevel(gAreas[fID].X+dX, gAreas[fID].Y+dY,
727 Width, Height);
729 OBJECT_TRIGGER:
730 with gTriggers[fID] do
731 Result := g_CollideLevel(X+dX, Y+dY,
732 Width, Height);
733 end;
734 end;
736 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
737 begin
738 Result := False;
740 case ObjectType of
741 OBJECT_PANEL:
742 with gPanels[ID] do
743 Result := g_Collide(X, Y, Width, Height,
744 fX, fY, fWidth, fHeight);
746 OBJECT_ITEM:
747 with gItems[ID] do
748 Result := g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
749 fX, fY, fWidth, fHeight);
751 OBJECT_MONSTER:
752 with MonsterSize[gMonsters[ID].MonsterType] do
753 Result := g_Collide(gMonsters[ID].X, gMonsters[ID].Y, Width, Height,
754 fX, fY, fWidth, fHeight);
756 OBJECT_AREA:
757 with AreaSize[gAreas[ID].AreaType] do
758 Result := g_Collide(gAreas[ID].X, gAreas[ID].Y, Width, Height,
759 fX, fY, fWidth, fHeight);
761 OBJECT_TRIGGER:
762 with gTriggers[ID] do
763 Result := g_Collide(X, Y, Width, Height,
764 fX, fY, fWidth, fHeight);
765 end;
766 end;
768 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
769 begin
770 case ObjectType of
771 OBJECT_PANEL:
772 with gPanels[ID] do
773 begin
774 Result.X := X;
775 Result.Y := Y;
776 Result.Width := Width;
777 Result.Height := Height;
778 end;
780 OBJECT_ITEM:
781 with gItems[ID] do
782 begin
783 Result.X := X;
784 Result.Y := Y;
785 Result.Width := ItemSize[ItemType][0];
786 Result.Height := ItemSize[ItemType][1];
787 end;
789 OBJECT_MONSTER:
790 with MonsterSize[gMonsters[ID].MonsterType] do
791 begin
792 Result.X := gMonsters[ID].X;
793 Result.Y := gMonsters[ID].Y;
794 Result.Width := Width;
795 Result.Height := Height;
796 end;
798 OBJECT_AREA:
799 with AreaSize[gAreas[ID].AreaType] do
800 begin
801 Result.X := gAreas[ID].X;
802 Result.Y := gAreas[ID].Y;
803 Result.Width := Width;
804 Result.Height := Height;
805 end;
807 OBJECT_TRIGGER:
808 with gTriggers[ID] do
809 begin
810 Result.X := X;
811 Result.Y := Y;
812 Result.Width := Width;
813 Result.Height := Height;
814 end;
816 else
817 begin
818 Result.X := 0;
819 Result.Y := 0;
820 Result.Width := 0;
821 Result.Height := 0;
822 end;
823 end;
824 end;
826 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
827 begin
828 case ObjectType of
829 OBJECT_PANEL:
830 with gPanels[ID] do
831 begin
832 X := X + dX;
833 Y := Y + dY;
834 end;
836 OBJECT_ITEM:
837 with gItems[ID] do
838 begin
839 X := X + dX;
840 Y := Y + dY;
841 end;
843 OBJECT_MONSTER:
844 with gMonsters[ID] do
845 begin
846 X := X + dX;
847 Y := Y + dY;
848 end;
850 OBJECT_AREA:
851 with gAreas[ID] do
852 begin
853 X := X + dX;
854 Y := Y + dY;
855 end;
857 OBJECT_TRIGGER:
858 with gTriggers[ID] do
859 begin
860 X := X + dX;
861 Y := Y + dY;
862 end;
863 end;
864 end;
866 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
867 begin
868 case ObjectType of
869 OBJECT_PANEL:
870 with gPanels[ID] do
871 begin
872 if Width >= -dWidth then
873 Width := Width+dWidth
874 else
875 begin
876 Width := 0;
877 Exit;
878 end;
880 if Height >= -dHeight then
881 Height := Height+dHeight
882 else
883 begin
884 Height := 0;
885 Exit;
886 end;
888 case ResizeDir of
889 2: Y := Y - dHeight;
890 4: X := X - dWidth;
891 end;
892 end;
894 OBJECT_ITEM, OBJECT_MONSTER, OBJECT_AREA:
895 Exit;
897 OBJECT_TRIGGER:
898 with gTriggers[ID] do
899 begin
900 if Width >= -dWidth then
901 Width := Width+dWidth
902 else
903 begin
904 Width := 0;
905 Exit;
906 end;
908 if Height >= -dHeight then
909 Height := Height+dHeight
910 else
911 begin
912 Height := 0;
913 Exit;
914 end;
916 case ResizeDir of
917 2: Y := Y - dHeight;
918 4: X := X - dWidth;
919 end;
920 end;
921 end;
922 end;
924 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
925 var
926 a: Integer;
928 begin
929 Result := False;
931 if SelectedObjects <> nil then
932 for a := 0 to High(SelectedObjects) do
933 if SelectedObjects[a].Live and
934 (SelectedObjects[a].ObjectType = ObjectType) and
935 (SelectedObjects[a].ID = ID) then
936 begin
937 Result := True;
938 Break;
939 end;
940 end;
942 function GetPanelName(PanelType: Word): String;
943 begin
944 Result := '';
946 case PanelType of
947 PANEL_WALL: Result := PANELNAMES[0];
948 PANEL_BACK: Result := PANELNAMES[1];
949 PANEL_FORE: Result := PANELNAMES[2];
950 PANEL_OPENDOOR: Result := PANELNAMES[3];
951 PANEL_CLOSEDOOR: Result := PANELNAMES[4];
952 PANEL_STEP: Result := PANELNAMES[5];
953 PANEL_WATER: Result := PANELNAMES[6];
954 PANEL_ACID1: Result := PANELNAMES[7];
955 PANEL_ACID2: Result := PANELNAMES[8];
956 PANEL_LIFTUP: Result := PANELNAMES[9];
957 PANEL_LIFTDOWN: Result := PANELNAMES[10];
958 PANEL_LIFTLEFT: Result := PANELNAMES[11];
959 PANEL_LIFTRIGHT: Result := PANELNAMES[12];
960 PANEL_BLOCKMON: Result := PANELNAMES[13];
961 else Assert(False);
962 end;
963 end;
965 function GetPanelType(PanelName: String): Word;
966 begin
967 Result := 0;
969 if PanelName = PANELNAMES[0] then
970 Result := PANEL_WALL
971 else if PanelName = PANELNAMES[1] then
972 Result := PANEL_BACK
973 else if PanelName = PANELNAMES[2] then
974 Result := PANEL_FORE
975 else if PanelName = PANELNAMES[3] then
976 Result := PANEL_OPENDOOR
977 else if PanelName = PANELNAMES[4] then
978 Result := PANEL_CLOSEDOOR
979 else if PanelName = PANELNAMES[5] then
980 Result := PANEL_STEP
981 else if PanelName = PANELNAMES[6] then
982 Result := PANEL_WATER
983 else if PanelName = PANELNAMES[7] then
984 Result := PANEL_ACID1
985 else if PanelName = PANELNAMES[8] then
986 Result := PANEL_ACID2
987 else if PanelName = PANELNAMES[9] then
988 Result := PANEL_LIFTUP
989 else if PanelName = PANELNAMES[10] then
990 Result := PANEL_LIFTDOWN
991 else if PanelName = PANELNAMES[11] then
992 Result := PANEL_LIFTLEFT
993 else if PanelName = PANELNAMES[12] then
994 Result := PANEL_LIFTRIGHT
995 else if PanelName = PANELNAMES[13] then
996 Result := PANEL_BLOCKMON;
998 Assert(Result <> 0);
999 end;
1001 function GetTriggerName(TriggerType: Byte): String;
1002 begin
1003 if TriggerType in [TRIGGER_EXIT..TRIGGER_MAX] then
1004 Result := TriggerNames[TriggerType]
1005 else
1006 Assert(False);
1007 end;
1009 function GetTriggerType(TriggerName: String): Byte;
1010 var
1011 i: Integer;
1013 begin
1014 Result := TRIGGER_NONE;
1015 for i := TRIGGER_EXIT to TRIGGER_MAX do
1016 if TriggerNames[i] = TriggerName then
1017 begin
1018 Result := i;
1019 Exit;
1020 end;
1022 Assert(False);
1023 end;
1025 function IsSpecialTexture(TextureName: string): Boolean;
1026 begin
1027 Result := (TextureName = TEXTURE_NAME_WATER) or
1028 (TextureName = TEXTURE_NAME_ACID1) or
1029 (TextureName = TEXTURE_NAME_ACID2);
1030 end;
1032 function SpecialTextureID(TextureName: string): DWORD;
1033 begin
1034 Assert(IsSpecialTexture(TextureName));
1036 Result := 0;
1038 if TextureName = TEXTURE_NAME_WATER then
1039 Result := TEXTURE_SPECIAL_WATER
1040 else
1041 if TextureName = TEXTURE_NAME_ACID1 then
1042 Result := TEXTURE_SPECIAL_ACID1
1043 else
1044 if TextureName = TEXTURE_NAME_ACID2 then
1045 Result := TEXTURE_SPECIAL_ACID2;
1046 end;
1048 function SaveMap(Res: String): Pointer;
1049 var
1050 WAD: TWADEditor_1;
1051 MapWriter: TMapWriter_1;
1052 textures: TTexturesRec1Array;
1053 panels: TPanelsRec1Array;
1054 items: TItemsRec1Array;
1055 areas: TAreasRec1Array;
1056 monsters: TMonsterRec1Array;
1057 triggers: TTriggersRec1Array;
1058 header: TMapHeaderRec_1;
1059 a, b, c: Integer;
1060 s: String;
1061 PanelTable: Array of Array [0..1] of Word;
1062 MonsterTable: Array of Array [0..1] of Word;
1063 Data: Pointer;
1064 FileName, SectionName, ResName: String;
1065 Len: LongWord;
1067 begin
1068 WAD := nil;
1069 textures := nil;
1070 panels := nil;
1071 items := nil;
1072 areas := nil;
1073 monsters := nil;
1074 triggers := nil;
1075 PanelTable := nil;
1076 MonsterTable := nil;
1078 // Открываем WAD, если надо:
1079 if Res <> '' then
1080 begin
1081 WAD := TWADEditor_1.Create();
1082 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1083 if not WAD.ReadFile(FileName) then
1084 WAD.FreeWAD();
1086 WAD.CreateImage();
1087 end;
1089 MapWriter := TMapWriter_1.Create();
1091 // Сохраняем заголовок:
1092 with header do
1093 begin
1094 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1096 if gMapInfo.Name <> '' then
1097 CopyMemory(@MapName[0], @gMapInfo.Name[1], Min(32, Length(gMapInfo.Name)));
1099 if gMapInfo.Description <> '' then
1100 CopyMemory(@MapDescription[0], @gMapInfo.Description[1], Min(256, Length(gMapInfo.Description)));
1102 if gMapInfo.Author <> '' then
1103 CopyMemory(@MapAuthor[0], @gMapInfo.Author[1], Min(32, Length(gMapInfo.Author)));
1105 if gMapInfo.MusicName <> '' then
1106 CopyMemory(@MusicName[0], @gMapInfo.MusicName[1], Min(64, Length(gMapInfo.MusicName)));
1108 if gMapInfo.SkyName <> '' then
1109 CopyMemory(@SkyName[0], @gMapInfo.SkyName[1], Min(64, Length(gMapInfo.SkyName)));
1111 Width := gMapInfo.Width;
1112 Height := gMapInfo.Height;
1113 end;
1115 MapWriter.AddHeader(header);
1117 // Сохраняем названия текстур:
1118 if MainForm.lbTextureList.Items.Count > 0 then
1119 begin
1120 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1121 begin
1122 SetLength(textures, Length(textures)+1);
1123 s := utf2win(MainForm.lbTextureList.Items[a]);
1124 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1125 if g_GetTextureFlagByName(s) = 1 then
1126 textures[High(textures)].Anim := 1
1127 else
1128 textures[High(textures)].Anim := 0;
1129 end;
1131 MapWriter.AddTextures(textures);
1132 end;
1134 // Сохраняем панели:
1135 if gPanels <> nil then
1136 begin
1137 c := 0;
1139 for a := 0 to High(gPanels) do
1140 if gPanels[a].PanelType <> 0 then
1141 begin
1142 SetLength(PanelTable, Length(PanelTable)+1);
1143 PanelTable[High(PanelTable)][0] := a;
1144 PanelTable[High(PanelTable)][1] := c;
1145 c := c + 1;
1147 SetLength(panels, Length(panels)+1);
1149 with panels[High(panels)] do
1150 begin
1151 X := gPanels[a].X;
1152 Y := gPanels[a].Y;
1153 Width := gPanels[a].Width;
1154 Height := gPanels[a].Height;
1155 PanelType := gPanels[a].PanelType;
1156 Alpha := gPanels[a].Alpha;
1158 TextureNum := 0;
1159 Flags := 0;
1161 if WordBool(gPanels[a].PanelType and
1162 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1163 Flags := PANEL_FLAG_WATERTEXTURES;
1165 // Может быть текстура:
1166 if not WordBool(gPanels[a].PanelType and
1167 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1168 begin
1169 if gPanels[a].Blending then
1170 Flags := Flags or PANEL_FLAG_BLENDING;
1171 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1172 Flags := Flags or PANEL_FLAG_HIDE;
1174 // Номер текстуры в списке текстур:
1175 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1176 for b := 0 to High(textures) do
1177 if gPanels[a].TextureName = textures[b].Resource then
1178 begin
1179 TextureNum := b;
1180 Break;
1181 end;
1182 end;
1183 end;
1184 end;
1186 MapWriter.AddPanels(panels);
1187 end;
1189 // Сохраняем предметы:
1190 if gItems <> nil then
1191 begin
1192 for a := 0 to High(gItems) do
1193 if gItems[a].ItemType <> 0 then
1194 begin
1195 SetLength(items, Length(items)+1);
1197 with items[High(items)] do
1198 begin
1199 X := gItems[a].X;
1200 Y := gItems[a].Y;
1201 ItemType := gItems[a].ItemType;
1202 if gItems[a].OnlyDM then
1203 Options := Options or ITEM_OPTION_ONLYDM;
1204 if gItems[a].Fall then
1205 Options := Options or ITEM_OPTION_FALL;
1206 end;
1207 end;
1209 MapWriter.AddItems(items);
1210 end;
1212 // Сохраняем монстров:
1213 if gMonsters <> nil then
1214 begin
1215 c := 0;
1217 for a := 0 to High(gMonsters) do
1218 if gMonsters[a].MonsterType <> 0 then
1219 begin
1220 SetLength(MonsterTable, Length(MonsterTable)+1);
1221 MonsterTable[High(MonsterTable)][0] := a;
1222 MonsterTable[High(MonsterTable)][1] := c;
1223 c := c + 1;
1225 SetLength(monsters, Length(monsters)+1);
1227 with monsters[High(monsters)] do
1228 begin
1229 X := gMonsters[a].X;
1230 Y := gMonsters[a].Y;
1231 MonsterType := gMonsters[a].MonsterType;
1232 Direction := Ord(gMonsters[a].Direction);
1233 end;
1234 end;
1236 MapWriter.AddMonsters(monsters);
1237 end;
1239 // Сохраняем области:
1240 if gAreas <> nil then
1241 begin
1242 for a := 0 to High(gAreas) do
1243 if gAreas[a].AreaType <> 0 then
1244 begin
1245 SetLength(areas, Length(areas)+1);
1247 with areas[High(areas)] do
1248 begin
1249 X := gAreas[a].X;
1250 Y := gAreas[a].Y;
1251 AreaType := gAreas[a].AreaType;
1252 Direction := Ord(gAreas[a].Direction);
1253 end;
1254 end;
1256 MapWriter.AddAreas(areas);
1257 end;
1259 // Сохраняем триггеры:
1260 if gTriggers <> nil then
1261 begin
1262 for a := 0 to High(gTriggers) do
1263 if gTriggers[a].TriggerType <> 0 then
1264 begin
1265 SetLength(triggers, Length(triggers)+1);
1267 with triggers[High(triggers)] do
1268 begin
1269 X := gTriggers[a].X;
1270 Y := gTriggers[a].Y;
1271 Width := gTriggers[a].Width;
1272 Height := gTriggers[a].Height;
1273 Enabled := Byte(gTriggers[a].Enabled);
1274 TexturePanel := -1;
1275 TriggerType := gTriggers[a].TriggerType;
1276 ActivateType := gTriggers[a].ActivateType;
1277 Keys := gTriggers[a].Key;
1278 DATA := gTriggers[a].Data.Default;
1280 if PanelTable <> nil then
1281 begin
1282 // Ищем номер панели, которой этот триггер меняет текстуру:
1283 if gTriggers[a].TexturePanel <> -1 then
1284 begin
1285 for c := 0 to High(PanelTable) do
1286 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1287 TexturePanel := PanelTable[c][1];
1288 end;
1290 // Ищем номер панели, которую меняет этот триггер:
1291 if gTriggers[a].TriggerType in [
1292 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1293 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1294 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1295 if TTriggerData(DATA).PanelID <> -1 then
1296 for c := 0 to High(PanelTable) do
1297 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1298 begin
1299 TTriggerData(DATA).PanelID := PanelTable[c][1];
1300 Break;
1301 end;
1303 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1304 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1305 (TTriggerData(DATA).ShotPanelID <> -1) then
1306 begin
1307 for c := 0 to High(PanelTable) do
1308 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1309 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1310 end;
1311 end;
1313 if MonsterTable <> nil then
1314 begin
1315 // Ищем номер монстра - условие активации триггера:
1316 if gTriggers[a].TriggerType in [
1317 TRIGGER_PRESS, TRIGGER_ON,
1318 TRIGGER_OFF, TRIGGER_ONOFF] then
1319 if TTriggerData(DATA).MonsterID <> 0 then
1320 for c := 0 to High(MonsterTable) do
1321 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1322 begin
1323 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1324 Break;
1325 end;
1326 end;
1327 end;
1328 end;
1330 MapWriter.AddTriggers(triggers);
1331 end;
1333 // Сохраняем карту в память:
1334 Len := MapWriter.SaveMap(Data);
1336 MapWriter.Free();
1338 // Записываем в WAD, если надо:
1339 if Res <> '' then
1340 begin
1341 e_WriteLog('Fuck me (A) ' + ResName, MSG_NOTIFY);
1342 WAD.RemoveResource('', ResName);
1343 WAD.AddResource(Data, Len, ResName, '');
1344 WAD.SaveTo(FileName);
1346 FreeMem(Data);
1347 WAD.Free();
1349 Result := nil;
1350 end
1351 else
1352 Result := Data;
1353 end;
1355 procedure AddTexture(res: String; Error: Boolean);
1356 var
1357 a: Integer;
1358 ures: String;
1359 begin
1360 ures := win2utf(res);
1361 with MainForm.lbTextureList do
1362 begin
1363 for a := 0 to Count-1 do
1364 if Items[a] = ures then
1365 Exit;
1367 if Error and (slInvalidTextures.IndexOf(ures) = -1) then
1368 slInvalidTextures.Add(ures);
1369 Items.Add(ures);
1370 end;
1371 end;
1373 function LoadMap(Res: String): Boolean;
1374 var
1375 WAD: TWADEditor_1;
1376 MapReader: TMapReader_1;
1377 Header: TMapHeaderRec_1;
1378 textures: TTexturesRec1Array;
1379 panels: TPanelsRec1Array;
1380 items: TItemsRec1Array;
1381 monsters: TMonsterRec1Array;
1382 areas: TAreasRec1Array;
1383 triggers: TTriggersRec1Array;
1384 panel: TPanel;
1385 item: TItem;
1386 monster: TMonster;
1387 area: TArea;
1388 trigger: TTrigger;
1389 a: Integer;
1390 Data: Pointer;
1391 Width, Height, m: Word;
1392 FileName, SectionName, ResName, _fn: String;
1393 TextureRes: String;
1394 pData: Pointer;
1395 Len, FrameLen: Integer;
1396 Error: Boolean;
1397 NoTextureID: DWORD;
1398 NW, NH: Word;
1399 begin
1400 Result := False;
1402 MainForm.pbLoad.Position := 0;
1403 MainForm.lLoad.Caption := _lc[I_LOAD_WAD];
1404 Application.ProcessMessages();
1406 // Открываем WAD:
1407 WAD := TWADEditor_1.Create();
1408 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1410 if not WAD.ReadFile(FileName) then
1411 begin
1412 WAD.Free();
1413 Exit;
1414 end;
1416 // Читаем ресурс карты:
1417 if not WAD.GetResource('', ResName, pData, Len) then
1418 begin
1419 WAD.Free();
1420 Exit;
1421 end;
1423 WAD.Free();
1425 MapReader := TMapReader_1.Create();
1427 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];
1428 Application.ProcessMessages();
1430 MapReader.LoadMap(pData);
1432 // Загружаем текстуры:
1433 textures := MapReader.GetTextures();
1435 if textures <> nil then
1436 begin
1437 MainForm.pbLoad.Position := 0;
1438 MainForm.pbLoad.Max := Length(textures);
1439 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1441 for a := 0 to High(textures) do
1442 begin
1443 MainForm.pbLoad.StepIt();
1444 Application.ProcessMessages();
1446 if IsSpecialTexture(textures[a].Resource) then
1447 begin
1448 AddTexture(textures[a].Resource, False);
1449 Continue;
1450 end;
1452 g_ProcessResourceStr(textures[a].Resource, @_fn, nil, nil);
1454 if _fn = '' then
1455 TextureRes := FileName + textures[a].Resource
1456 else
1457 TextureRes := EditorDir+'wads/'+textures[a].Resource;
1459 Error := False;
1461 if not ByteBool(textures[a].Anim) then
1462 begin // Обычная текстура
1463 if not g_CreateTextureWAD(textures[a].Resource, TextureRes) then
1464 begin
1465 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s',
1466 [textures[a].Resource]), MSG_WARNING);
1467 Error := True;
1468 end;
1470 AddTexture(textures[a].Resource, Error);
1471 end
1472 else // Anim
1473 begin // Анимированная текстура
1474 if not GetFrame(TextureRes, Data, FrameLen, Width, Height) then
1475 begin // Кадры
1476 e_WriteLog(Format('GetFrame() error, res=%s',
1477 [textures[a].Resource]), MSG_WARNING);
1478 Error := True;
1479 end;
1481 if not g_CreateTextureMemorySize(Data, FrameLen, textures[a].Resource, 0, 0, Width, Height, 1) then
1482 begin // Сама текстура
1483 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s',
1484 [textures[a].Resource]), MSG_WARNING);
1485 Error := True;
1486 end;
1488 AddTexture(textures[a].Resource, Error);
1489 end;
1490 end;
1491 end;
1493 // Загружаем панели:
1494 panels := MapReader.GetPanels();
1496 if panels <> nil then
1497 begin
1498 MainForm.pbLoad.Position := 0;
1499 MainForm.pbLoad.Max := Length(panels);
1500 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1502 for a := 0 to High(panels) do
1503 begin
1504 MainForm.pbLoad.StepIt();
1505 Application.ProcessMessages();
1507 panel.X := panels[a].X;
1508 panel.Y := panels[a].Y;
1509 panel.Height := panels[a].Height;
1510 panel.Width := panels[a].Width;
1511 panel.PanelType := panels[a].PanelType;
1512 panel.Alpha := panels[a].Alpha;
1514 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1516 panel.TextureWidth := 0;
1517 panel.TextureHeight := 0;
1518 panel.TextureName := '';
1519 panel.TextureID := TEXTURE_SPECIAL_NONE;
1521 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_STEP or
1522 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1524 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1525 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1527 // Если панель видима:
1528 if WordBool(panel.PanelType and m) and
1529 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1530 begin
1531 if not IsSpecialTexture(textures[panels[a].TextureNum].Resource) then
1532 begin // Текстура
1533 if g_GetTexture(textures[panels[a].TextureNum].Resource, panel.TextureID) then
1534 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1535 else begin
1536 panel.TextureWidth := 1;
1537 panel.TextureHeight := 1;
1538 if g_GetTexture('NOTEXTURE', NoTextureID) then
1539 begin
1540 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1541 g_GetTextureSizeByID(NoTextureID, NW, NH);
1542 panel.TextureWidth := NW;
1543 panel.TextureHeight := NH;
1544 end;
1545 end;
1546 end
1547 else // Спец. текстура
1548 panel.TextureID := SpecialTextureID(textures[panels[a].TextureNum].Resource);
1550 panel.TextureName := textures[panels[a].TextureNum].Resource;
1551 end;
1553 // Жидкость без текстуры:
1554 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1555 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1556 begin
1557 case panel.PanelType of
1558 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1559 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1560 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1561 end;
1563 panel.TextureID := SpecialTextureID(panel.TextureName);
1564 AddTexture(panel.TextureName, False);
1565 end;
1567 AddPanel(panel);
1568 end;
1569 end;
1571 // Загружаем предметы:
1572 items := MapReader.GetItems();
1574 if items <> nil then
1575 begin
1576 MainForm.pbLoad.Position := 0;
1577 MainForm.pbLoad.Max := Length(items);
1578 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1580 for a := 0 to High(items) do
1581 begin
1582 MainForm.pbLoad.StepIt();
1583 Application.ProcessMessages();
1585 item.X := items[a].X;
1586 item.Y := items[a].Y;
1587 item.ItemType := items[a].ItemType;
1588 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1589 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1591 AddItem(item);
1592 end;
1593 end;
1595 // Загружаем монстров:
1596 monsters := MapReader.GetMonsters();
1598 if monsters <> nil then
1599 begin
1600 MainForm.pbLoad.Position := 0;
1601 MainForm.pbLoad.Max := Length(monsters);
1602 MainForm.lLoad.Caption := _lc[I_LOAD_MONSTERS];
1604 for a := 0 to High(monsters) do
1605 begin
1606 MainForm.pbLoad.StepIt();
1607 Application.ProcessMessages();
1609 monster.X := monsters[a].X;
1610 monster.Y := monsters[a].Y;
1611 monster.MonsterType := monsters[a].MonsterType;
1612 monster.Direction := TDirection(monsters[a].Direction);
1614 AddMonster(monster);
1615 end;
1616 end;
1618 // Загружаем области:
1619 areas := MapReader.GetAreas();
1621 if areas <> nil then
1622 begin
1623 MainForm.pbLoad.Position := 0;
1624 MainForm.pbLoad.Max := Length(areas);
1625 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1627 for a := 0 to High(areas) do
1628 begin
1629 MainForm.pbLoad.StepIt();
1630 Application.ProcessMessages();
1632 area.X := areas[a].X;
1633 area.Y := areas[a].Y;
1634 area.AreaType := areas[a].AreaType;
1635 area.Direction := TDirection(areas[a].Direction);
1637 AddArea(area);
1638 end;
1639 end;
1641 // Загружаем триггеры:
1642 triggers := MapReader.GetTriggers();
1644 if triggers <> nil then
1645 begin
1646 MainForm.pbLoad.Position := 0;
1647 MainForm.pbLoad.Max := Length(triggers);
1648 MainForm.lLoad.Caption := _lc[I_LOAD_TRIGGERS];
1650 for a := 0 to High(triggers) do
1651 begin
1652 MainForm.pbLoad.StepIt();
1653 Application.ProcessMessages();
1655 trigger.X := triggers[a].X;
1656 trigger.Y := triggers[a].Y;
1657 trigger.Width := triggers[a].Width;
1658 trigger.Height := triggers[a].Height;
1660 trigger.Enabled := ByteBool(triggers[a].Enabled);
1661 trigger.TexturePanel := triggers[a].TexturePanel;
1662 trigger.TriggerType := triggers[a].TriggerType;
1663 trigger.ActivateType := triggers[a].ActivateType;
1664 trigger.Key := triggers[a].Keys;
1665 trigger.Data.Default := triggers[a].DATA;
1667 AddTrigger(trigger);
1668 end;
1669 end;
1671 // Загружаем заголовок карты:
1672 Header := MapReader.GetMapHeader();
1674 gMapInfo.FileName := FileName;
1676 with gMapInfo do
1677 begin
1678 MapName := ResName;
1679 Name := Header.MapName;
1680 Description := Header.MapDescription;
1681 Author := Header.MapAuthor;
1682 MusicName := Header.MusicName;
1683 SkyName := Header.SkyName;
1684 Height := Header.Height;
1685 Width := Header.Width;
1686 end;
1688 LoadSky(gMapInfo.SkyName);
1690 textures := nil;
1691 panels := nil;
1692 items := nil;
1693 areas := nil;
1694 triggers := nil;
1696 MapReader.Free();
1697 FreeMem(pData);
1699 Result := True;
1700 end;
1702 function LoadMapOld(_FileName: String): Boolean;
1703 const
1704 TexturePrefix = 'Standart.wad:STDTEXTURES\';
1705 DefaultMusRes = 'Standart.wad:STDMUS\MUS1';
1706 DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
1708 var
1709 map: TConfig;
1710 i, a: Integer;
1711 s, us, section: String;
1712 panel: TPanel;
1713 item: TItem;
1714 area: TArea;
1716 begin
1717 Result := False;
1719 if not FileExists(_FileName) then
1720 Exit;
1722 // Открытие карты:
1723 MainForm.pbLoad.Position := 0;
1724 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];;
1725 Application.ProcessMessages();
1727 map := TConfig.CreateFile(_FileName);
1729 // Чтение текстур:
1730 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1732 MainForm.pbLoad.Max := i;
1733 MainForm.pbLoad.Position := 0;
1734 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1736 for a := 1 to i do
1737 begin
1738 MainForm.pbLoad.StepIt();
1739 Application.ProcessMessages();
1741 s := TexturePrefix + UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1742 if s = TexturePrefix then
1743 Continue;
1745 // Нет такой текстуры - ищем в WAD карты:
1746 if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
1747 begin
1748 s := ExtractFileName(_FileName);
1749 Delete(s, Length(s)-3, 4);
1750 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1752 if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
1753 Continue;
1754 end;
1756 MainForm.lbTextureList.Items.Add(win2utf(s));
1757 end;
1759 // Чтение панелей:
1760 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1762 MainForm.pbLoad.Max := i;
1763 MainForm.pbLoad.Position := 0;
1764 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1766 for a := 1 to i do
1767 begin
1768 MainForm.pbLoad.StepIt();
1769 Application.ProcessMessages();
1771 section := 'Panel' + IntToStr(a);
1772 if not map.SectionExists(section) then
1773 Continue;
1775 panel.X := map.ReadInt(section, 'X1', 0);
1776 panel.Y := map.ReadInt(section, 'Y1', 0);
1777 panel.Height := map.ReadInt(section, 'Height', 16);
1778 panel.Width := map.ReadInt(section, 'Width', 16);
1780 case map.ReadInt(section, 'PanelType', 0) of
1781 0: panel.PanelType := PANEL_WALL;
1782 1: panel.PanelType := PANEL_BACK;
1783 2: panel.PanelType := PANEL_FORE;
1784 3: panel.PanelType := PANEL_STEP;
1785 4: panel.PanelType := PANEL_WATER;
1786 5: panel.PanelType := PANEL_ACID1;
1787 6: panel.PanelType := PANEL_ACID2;
1788 end;
1790 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1792 // Текстура панели:
1793 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_STEP] then
1794 begin
1795 s := TexturePrefix + UpperCase(map.ReadStr(section, 'TextureName', ''));
1797 if g_GetTexture(s, panel.TextureID) then
1798 begin
1799 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1800 panel.TextureName := s;
1801 end
1802 else // Нет такой текстуры - ищем в WAD карты:
1803 begin
1804 s := ExtractFileName(_FileName);
1805 Delete(s, Length(s)-3, 4);
1806 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(map.ReadStr(section, 'TextureName', ''));
1808 if g_GetTexture(s, panel.TextureID) then
1809 begin
1810 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1811 panel.TextureName := s;
1812 end
1813 else
1814 Continue;
1815 end;
1816 end
1817 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1818 begin
1819 case panel.PanelType of
1820 PANEL_WATER:
1821 begin
1822 s := TEXTURE_NAME_WATER;
1823 panel.TextureID := TEXTURE_SPECIAL_WATER;
1824 end;
1825 PANEL_ACID1:
1826 begin
1827 s := TEXTURE_NAME_ACID2;
1828 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1829 end;
1830 PANEL_ACID2:
1831 begin
1832 s := TEXTURE_NAME_ACID1;
1833 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1834 end;
1835 end;
1837 us := win2utf(s);
1838 with MainForm.lbTextureList.Items do
1839 if IndexOf(us) = -1 then
1840 Add(us);
1841 panel.TextureName := s;
1842 panel.TextureWidth := 1;
1843 panel.TextureHeight := 1;
1844 end;
1846 AddPanel(panel);
1847 end;
1849 // Чтение предметов:
1850 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1852 MainForm.pbLoad.Max := i;
1853 MainForm.pbLoad.Position := 0;
1854 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1856 for a := 1 to i do
1857 begin
1858 MainForm.pbLoad.StepIt();
1859 Application.ProcessMessages();
1861 section := 'Item' + IntToStr(a);
1862 if not map.SectionExists(section) then
1863 Continue;
1865 item.X := map.ReadInt(section, 'X', 0);
1866 item.Y := map.ReadInt(section, 'Y', 0);
1867 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1868 item.OnlyDM := False;
1869 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1871 // Размер предметов теперь другой:
1872 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1873 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1875 AddItem(item);
1876 end;
1878 // Чтение областей:
1879 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1881 MainForm.pbLoad.Max := i;
1882 MainForm.pbLoad.Position := 0;
1883 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1885 for a := 1 to i do
1886 begin
1887 MainForm.pbLoad.StepIt();
1888 Application.ProcessMessages();
1890 section := 'Area' + IntToStr(a);
1891 if not map.SectionExists(section) then
1892 Continue;
1894 area.X := map.ReadInt(section, 'X', 0);
1895 area.Y := map.ReadInt(section, 'Y', 0);
1896 area.AreaType := map.ReadInt(section, 'Type', 0);
1897 area.Direction := D_RIGHT;
1899 // Размер областей теперь другой:
1900 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1901 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1903 AddArea(area);
1904 end;
1906 // Чтение параметров карты:
1907 with gMapInfo do
1908 begin
1909 Name := map.ReadStr('MapOptions', 'MapName', '');
1910 Description := map.ReadStr('MapOptions', 'MapDescription', '');
1911 Author := '';
1912 MusicName := DefaultMusRes;
1913 SkyName := DefaultSkyRes;
1914 FileName := _FileName;
1915 Height := map.ReadInt('MapOptions', 'Height', 1600);
1916 Width := map.ReadInt('MapOptions', 'Width', 1600);
1918 if Length(Name) > 32 then
1919 SetLength(Name, 32);
1920 if Length(Description) > 256 then
1921 SetLength(Description, 256);
1922 end;
1924 map.Free();
1926 Result := True;
1927 end;
1929 procedure ClearMap();
1930 var
1931 a: Integer;
1933 begin
1934 if gPanels <> nil then
1935 for a := 0 to High(gPanels) do
1936 if gPanels[a].TextureName <> '' then
1937 g_DeleteTexture(gPanels[a].TextureName);
1939 SetLength(gPanels, 0);
1940 gPanels := nil;
1941 SetLength(gItems, 0);
1942 gItems := nil;
1943 SetLength(gAreas, 0);
1944 gAreas := nil;
1945 SetLength(gMonsters, 0);
1946 gMonsters := nil;
1947 SetLength(gTriggers, 0);
1948 gTriggers := nil;
1950 with gMapInfo do
1951 begin
1952 Name := '';
1953 Description := '';
1954 Author := '';
1955 MusicName := '';
1956 SkyName := '';
1957 FileName := '';
1958 Height := 1600;
1959 Width := 1600;
1960 end;
1962 with MainForm.lbTextureList do
1963 begin
1964 if Items.Count > 0 then
1965 for a := Items.Count-1 downto 0 do
1966 if not IsSpecialTexture(utf2win(Items[a])) then
1967 g_DeleteTexture(utf2win(Items[a]));
1969 Clear();
1970 end;
1972 MapOffset.X := 0;
1973 MapOffset.Y := 0;
1974 end;
1976 procedure DrawPanels(fPanelType: Word);
1978 procedure DrawTexture(a: Integer);
1979 var
1980 NoTextureID: DWORD;
1981 NW, NH: Word;
1982 begin
1983 with gPanels[a] do
1984 begin
1985 case TextureID of
1986 TEXTURE_SPECIAL_NONE:
1987 if not PreviewMode then
1988 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1989 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1990 64, 64, 64, 127);
1992 TEXTURE_SPECIAL_NOTEXTURE:
1993 if g_GetTexture('NOTEXTURE', NoTextureID) then
1994 begin
1995 g_GetTextureSizeByID(NoTextureID, NW, NH);
1996 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
1997 Width div NW, Height div NH, 0, False, False);
1998 end;
2000 TEXTURE_SPECIAL_WATER:
2001 if PreviewMode then
2002 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2003 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2004 0, 0, 255, 0, B_FILTER)
2005 else
2006 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2007 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2008 0, 0, 255, 127);
2010 TEXTURE_SPECIAL_ACID1:
2011 if PreviewMode then
2012 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2013 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2014 0, 127, 0, 0, B_FILTER)
2015 else
2016 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2017 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2018 0, 255, 0, 127);
2020 TEXTURE_SPECIAL_ACID2:
2021 if PreviewMode then
2022 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2023 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2024 127, 0, 0, 0, B_FILTER)
2025 else
2026 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2027 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2028 255, 0, 0, 127);
2030 else
2031 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2032 Width div TextureWidth, Height div TextureHeight,
2033 Alpha, True, Blending);
2034 end;
2035 end;
2036 end;
2038 var
2039 a: Integer;
2040 begin
2041 if gPanels <> nil then
2042 for a := 0 to High(gPanels) do
2043 if (gPanels[a].PanelType <> 0) and
2044 WordBool(gPanels[a].PanelType and fPanelType) then
2045 with gPanels[a] do
2046 begin
2047 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2048 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2049 case PanelType of
2050 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2051 PANEL_STEP, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2052 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2053 DrawTexture(a);
2055 PANEL_LIFTUP:
2056 if not PreviewMode then
2057 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2058 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2059 128, 64, 0, 0);
2060 PANEL_LIFTDOWN:
2061 if not PreviewMode then
2062 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2063 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2064 90, 154, 138, 0);
2065 PANEL_LIFTLEFT:
2066 if not PreviewMode then
2067 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2068 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2069 200, 80, 4, 0);
2070 PANEL_LIFTRIGHT:
2071 if not PreviewMode then
2072 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2073 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2074 252, 140, 56, 0);
2075 PANEL_BLOCKMON:
2076 if not PreviewMode then
2077 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2078 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2079 192, 0, 192, 0);
2080 end;
2081 end;
2082 end;
2084 procedure DrawMap();
2085 var
2086 a, w, h: Integer;
2087 ID: DWORD;
2088 xx, yy, dx, dy: Integer;
2089 ww, hh: Word;
2090 sel: Boolean;
2091 r: TRectWH;
2093 begin
2094 // В режиме Превью рисуем небо:
2095 if PreviewMode then
2096 begin
2097 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2098 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2099 w := Round(w*4/3);
2100 h := Round(w*3/4);
2102 if g_GetTexture(SKY_TEXTURE, ID) then
2103 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2104 else
2105 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2106 end;
2108 // Рисуем панели (если Превью или если включен слой):
2109 if LayerEnabled[LAYER_BACK] or PreviewMode then
2110 DrawPanels(PANEL_BACK);
2111 if PreviewMode then
2112 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
2113 else
2114 if LayerEnabled[LAYER_WATER] then
2115 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
2116 PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
2117 if LayerEnabled[LAYER_WALLS] or PreviewMode then
2118 DrawPanels(PANEL_WALL);
2119 if LayerEnabled[LAYER_STEPS] or PreviewMode then
2120 DrawPanels(PANEL_STEP);
2122 // Рисуем предметы:
2123 if (LayerEnabled[LAYER_ITEMS] or PreviewMode) and
2124 (gItems <> nil) then
2125 for a := 0 to High(gItems) do
2126 if gItems[a].ItemType <> ITEM_NONE then
2127 with gItems[a] do
2128 begin
2129 ID := DWORD(-1);
2131 case ItemType of
2132 0: Continue;
2133 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2134 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2135 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2136 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2137 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2138 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2139 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2140 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2141 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2142 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2143 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2144 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2145 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2146 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2147 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2148 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2149 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2150 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2151 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2152 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2153 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2154 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2155 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2156 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2157 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2158 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2159 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2160 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2161 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2162 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2163 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2164 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2165 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2166 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2167 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2168 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2169 end;
2171 if ID <> DWORD(-1) then
2172 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2173 end;
2175 // Рисуем монстров:
2176 if (LayerEnabled[LAYER_MONSTERS] or PreviewMode) and
2177 (gMonsters <> nil) then
2178 for a := 0 to High(gMonsters) do
2179 if gMonsters[a].MonsterType <> MONSTER_NONE then
2180 with MonsterSize[gMonsters[a].MonsterType] do
2181 begin
2182 ID := DWORD(-1);
2184 case gMonsters[a].MonsterType of
2185 0: Continue;
2186 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2187 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2188 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2189 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2190 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2191 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2192 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2193 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2194 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2195 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2196 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2197 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2198 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2199 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2200 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2201 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2202 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2203 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2204 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2205 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2206 end;
2208 if ID <> DWORD(-1) then
2209 if gMonsters[a].Direction = D_LEFT then
2210 begin
2211 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2212 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2213 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2214 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2215 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2216 xx := (gMonsters[a].X - X) - xx;
2218 yy := (gMonsters[a].Y - Y) +
2219 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2221 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2222 0, True, False, M_HORIZONTAL);
2223 end
2224 else
2225 begin
2226 // Левый верхний угол текстуры + смещение анимации:
2227 xx := (gMonsters[a].X - X) +
2228 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2229 yy := (gMonsters[a].Y - Y) +
2230 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2232 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2233 0, True, False);
2234 end;
2236 // Рамка:
2237 if not PreviewMode then
2238 begin
2239 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2240 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2241 255, 255, 255);
2242 end;
2243 end;
2245 // Рисуем закрытые двери после монстров:
2246 if PreviewMode then
2247 DrawPanels(PANEL_CLOSEDOOR);
2249 // Рисуем области:
2250 if (LayerEnabled[LAYER_AREAS] or PreviewMode) and
2251 (gAreas <> nil) then
2252 for a := 0 to High(gAreas) do
2253 if gAreas[a].AreaType <> AREA_NONE then
2254 with AreaSize[gAreas[a].AreaType] do
2255 begin
2256 ID := DWORD(-1);
2258 case gAreas[a].AreaType of
2259 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2260 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2261 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2262 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2263 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2264 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2265 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2266 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2267 end;
2269 if (not PreviewMode) or
2270 (gAreas[a].AreaType = AREA_REDFLAG) or
2271 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2272 (gAreas[a].AreaType = AREA_DOMFLAG) then
2273 if ID <> DWORD(-1) then
2274 if gAreas[a].Direction = D_LEFT then
2275 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2276 0, True, False, M_HORIZONTAL)
2277 else
2278 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2279 0, True, False);
2281 // Рамка:
2282 if not PreviewMode then
2283 begin
2284 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2285 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2286 255, 255, 255);
2288 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2289 end;
2290 end;
2292 // Рисуем жидкости и передний план после областей:
2293 if LayerEnabled[LAYER_WATER] or PreviewMode then
2294 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2295 if LayerEnabled[LAYER_FOREGROUND] or PreviewMode then
2296 DrawPanels(PANEL_FORE);
2298 // Рисуем триггеры:
2299 if LayerEnabled[LAYER_TRIGGERS] and
2300 (not PreviewMode) and (gTriggers <> nil) then
2301 for a := 0 to High(gTriggers) do
2302 with gTriggers[a] do
2303 if TriggerType <> TRIGGER_NONE then
2304 begin
2305 // Если выбран - рисуем красным, иначе - белым:
2306 sel := ObjectSelected(OBJECT_TRIGGER, a);
2308 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2309 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2310 0, 0, 0, 150);
2312 if TexturePanel <> -1 then
2313 begin
2314 with gPanels[TexturePanel] do
2315 begin
2316 xx := X;
2317 yy := Y;
2318 ww := Width;
2319 hh := Height;
2320 end;
2322 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2323 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2324 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2325 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2326 MapOffset.X+xx, MapOffset.Y+yy,
2327 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2328 end;
2330 case TriggerType of
2331 TRIGGER_EXIT: ;
2333 TRIGGER_TELEPORT:
2334 begin
2335 // Точка назначения Телепорта:
2336 if Data.d2d_teleport then
2337 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2338 MapOffset.Y+Data.TargetPoint.Y-1,
2339 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2340 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2341 else
2342 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2343 MapOffset.Y+Data.TargetPoint.Y,
2344 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2345 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2346 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2347 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2348 MapOffset.Y+Data.TargetPoint.Y,
2349 255, 0, 0);
2350 // Линия к точке назначения Телепорта:
2351 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2352 MapOffset.Y+Y+(Height div 2),
2353 MapOffset.X+Data.TargetPoint.X,
2354 MapOffset.Y+Data.TargetPoint.Y,
2355 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2356 end;
2358 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2359 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2360 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2361 TRIGGER_LIFT:
2362 if Data.PanelID <> -1 then
2363 begin
2364 // Дверь/Ловушка/Лифт:
2365 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2366 MapOffset.Y+gPanels[Data.PanelID].Y,
2367 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2368 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2369 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2370 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2371 MapOffset.Y+gPanels[Data.PanelID].Y,
2372 255, 0, 0);
2373 // Линия к Двери/Ловушке/Лифту:
2374 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2375 MapOffset.Y+Y+(Height div 2),
2376 MapOffset.X+gPanels[Data.PanelID].X,
2377 MapOffset.Y+gPanels[Data.PanelID].Y,
2378 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2379 end;
2381 TRIGGER_PRESS, TRIGGER_ON,
2382 TRIGGER_OFF, TRIGGER_ONOFF:
2383 begin
2384 if (Data.tWidth > 0) and
2385 (Data.tHeight > 0) then
2386 begin
2387 // Область Расширителя:
2388 e_DrawQuad(MapOffset.X+Data.tX,
2389 MapOffset.Y+Data.tY,
2390 MapOffset.X+Data.tX+Data.tWidth-1,
2391 MapOffset.Y+Data.tY+Data.tHeight-1,
2392 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2393 e_DrawPoint(2, MapOffset.X+Data.tX,
2394 MapOffset.Y+Data.tY,
2395 255, 0, 0);
2396 // Линия к области Расширителя:
2397 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2398 MapOffset.Y+Y+(Height div 2),
2399 MapOffset.X+Data.tX,
2400 MapOffset.Y+Data.tY,
2401 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2402 end;
2404 if Data.MonsterID <> 0 then
2405 if (gMonsters <> nil) and
2406 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2407 begin
2408 // Рамка вокруг Монстра - условия активации:
2409 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2410 e_DrawQuad(MapOffset.X+r.X,
2411 MapOffset.Y+r.Y,
2412 MapOffset.X+r.X+r.Width-1,
2413 MapOffset.Y+r.Y+r.Height-1,
2414 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2415 // Линия к Монстру - условию активации:
2416 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2417 MapOffset.Y+Y+(Height div 2),
2418 MapOffset.X+r.X,
2419 MapOffset.Y+r.Y,
2420 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2422 end;
2423 end;
2425 TRIGGER_SECRET: ;
2427 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2428 begin
2429 if TriggerType = TRIGGER_SPAWNMONSTER then
2430 begin
2431 xx := Data.MonPos.X;
2432 yy := Data.MonPos.Y;
2433 end
2434 else
2435 begin
2436 xx := Data.ItemPos.X;
2437 yy := Data.ItemPos.Y;
2438 end;
2439 // Точка появления Монстра/Предмета:
2440 e_DrawLine(2, MapOffset.X+xx-16,
2441 MapOffset.Y+yy-1,
2442 MapOffset.X+xx+16,
2443 MapOffset.Y+yy-1,
2444 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2445 e_DrawPoint(2, MapOffset.X+xx,
2446 MapOffset.Y+yy,
2447 255, 0, 0);
2448 // Линия к точке появления Монстра/Предмета:
2449 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2450 MapOffset.Y+Y+(Height div 2),
2451 MapOffset.X+xx,
2452 MapOffset.Y+yy,
2453 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2454 // Предпросмотр создаваемого объекта:
2455 if sel then
2456 begin
2457 // Монстр:
2458 if TriggerType = TRIGGER_SPAWNMONSTER then
2459 begin
2460 if Data.MonType <> MONSTER_NONE then
2461 with MonsterSize[Data.MonType] do
2462 begin
2463 ID := DWORD(-1);
2464 case Data.MonType of
2465 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2466 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2467 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2468 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2469 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2470 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2471 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2472 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2473 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2474 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2475 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2476 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2477 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2478 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2479 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2480 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2481 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2482 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2483 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2484 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2485 end;
2486 if ID <> DWORD(-1) then
2487 begin
2488 if Data.MonDir = Byte(D_LEFT) then
2489 begin
2490 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2491 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2492 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2494 yy := Data.TargetPoint.Y - Y +
2495 MonsterSizeDelta[Data.MonType].Y-Height;
2497 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2498 128, True, False, M_HORIZONTAL);
2499 end
2500 else
2501 begin
2502 xx := Data.TargetPoint.X - X +
2503 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2504 yy := Data.TargetPoint.Y - Y +
2505 MonsterSizeDelta[Data.MonType].Y-Height;
2507 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2508 128, True, False);
2509 end;
2510 // Рамка:
2511 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2512 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2513 255, 255, 0, 128);
2514 end;
2515 end;
2516 end
2517 else
2518 // Предмет:
2519 begin
2520 if Data.ItemType <> ITEM_NONE then
2521 begin
2522 ID := DWORD(-1);
2523 case Data.ItemType of
2524 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2525 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2526 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2527 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2528 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2529 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2530 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2531 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2532 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2533 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2534 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2535 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2536 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2537 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2538 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2539 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2540 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2541 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2542 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2543 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2544 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2545 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2546 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2547 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2548 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2549 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2550 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2551 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2552 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2553 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2554 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2555 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2556 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2557 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2558 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2559 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2560 end;
2561 if ID <> DWORD(-1) then
2562 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2563 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2564 128, True, False);
2565 // Рамка:
2566 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2567 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2568 255, 255, 0, 128);
2569 end;
2570 end;
2571 end;
2572 end;
2574 TRIGGER_PUSH:
2575 begin
2576 // Линия направления и силы ускорения:
2577 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2578 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2579 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2580 MapOffset.Y+Y+(Height div 2),
2581 MapOffset.X+xx,
2582 MapOffset.Y+yy,
2583 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2584 end;
2586 TRIGGER_SHOT:
2587 begin;
2588 xx := Data.ShotPos.X;
2589 yy := Data.ShotPos.Y;
2590 // Точка появления снаряда:
2591 e_DrawPoint(2, MapOffset.X+xx,
2592 MapOffset.Y+yy,
2593 255, 0, 0);
2594 // Линия к точке появления снаряда:
2595 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2596 MapOffset.Y+Y+(Height div 2),
2597 MapOffset.X+xx,
2598 MapOffset.Y+yy,
2599 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2600 // Линия направления выстрела:
2601 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2602 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2603 e_DrawLine(1, MapOffset.X+xx,
2604 MapOffset.Y+yy,
2605 MapOffset.X+xx+dx,
2606 MapOffset.Y+yy+dy,
2607 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2609 if (Data.ShotPanelID <> -1) and
2610 (Data.ShotPanelID <= High(gPanels)) then
2611 begin
2612 // Линия к панели индикации выстрела
2613 with gPanels[Data.ShotPanelID] do
2614 begin
2615 xx := X;
2616 yy := Y;
2617 ww := Width;
2618 hh := Height;
2619 end;
2621 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2622 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2623 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2624 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2625 MapOffset.X+xx, MapOffset.Y+yy,
2626 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2627 end;
2628 end;
2629 end;
2630 end;
2632 // Границы карты:
2633 if not PreviewMode then
2634 begin
2635 e_DrawFillQuad(-32+MapOffset.X,
2636 -32+MapOffset.Y,
2637 gMapInfo.Width+31+MapOffset.X,
2638 -1+MapOffset.Y,
2639 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2640 e_DrawFillQuad(-32+MapOffset.X,
2641 gMapInfo.Height+MapOffset.Y,
2642 gMapInfo.Width+31+MapOffset.X,
2643 gMapInfo.Height+31+MapOffset.Y,
2644 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2645 e_DrawFillQuad(-32+MapOffset.X,
2646 MapOffset.Y,
2647 -1+MapOffset.X,
2648 gMapInfo.Height+MapOffset.Y-1,
2649 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2650 e_DrawFillQuad(gMapInfo.Width+MapOffset.X,
2651 MapOffset.Y,
2652 gMapInfo.Width+31+MapOffset.X,
2653 gMapInfo.Height+MapOffset.Y-1,
2654 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2655 end;
2656 end;
2658 procedure ShiftMapObjects(dx, dy: Integer);
2659 var
2660 i: Integer;
2661 begin
2662 if gPanels <> nil then
2663 for i := 0 to High(gPanels) do
2664 if gPanels[i].PanelType <> 0 then
2665 begin
2666 Inc(gPanels[i].X, dx);
2667 Inc(gPanels[i].Y, dy);
2668 end;
2670 if gItems <> nil then
2671 for i := 0 to High(gItems) do
2672 if gItems[i].ItemType <> 0 then
2673 begin
2674 Inc(gItems[i].X, dx);
2675 Inc(gItems[i].Y, dy);
2676 end;
2678 if gAreas <> nil then
2679 for i := 0 to High(gAreas) do
2680 if gAreas[i].AreaType <> 0 then
2681 begin
2682 Inc(gAreas[i].X, dx);
2683 Inc(gAreas[i].Y, dy);
2684 end;
2686 if gMonsters <> nil then
2687 for i := 0 to High(gMonsters) do
2688 if gMonsters[i].MonsterType <> 0 then
2689 begin
2690 Inc(gMonsters[i].X, dx);
2691 Inc(gMonsters[i].Y, dy);
2692 end;
2694 if gTriggers <> nil then
2695 for i := 0 to High(gTriggers) do
2696 if gTriggers[i].TriggerType <> 0 then
2697 begin
2698 Inc(gTriggers[i].X, dx);
2699 Inc(gTriggers[i].Y, dy);
2701 case gTriggers[i].TriggerType of
2702 TRIGGER_TELEPORT:
2703 begin
2704 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2705 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2706 end;
2708 TRIGGER_PRESS, TRIGGER_ON,
2709 TRIGGER_OFF, TRIGGER_ONOFF:
2710 begin
2711 Inc(gTriggers[i].Data.tX, dx);
2712 Inc(gTriggers[i].Data.tY, dy);
2713 end;
2715 TRIGGER_SPAWNMONSTER:
2716 begin
2717 Inc(gTriggers[i].Data.MonPos.X, dx);
2718 Inc(gTriggers[i].Data.MonPos.Y, dy);
2719 end;
2721 TRIGGER_SPAWNITEM:
2722 begin
2723 Inc(gTriggers[i].Data.ItemPos.X, dx);
2724 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2725 end;
2727 TRIGGER_SHOT:
2728 begin
2729 Inc(gTriggers[i].Data.ShotPos.X, dx);
2730 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2731 end;
2732 end;
2733 end;
2734 end;
2736 procedure LoadData();
2737 begin
2738 g_CreateTextureWAD('PREVIEW', EditorDir+'data/Editor.wad:TEXTURES\CHECKERS');
2739 g_CreateTextureWAD('NOTEXTURE', EditorDir+'data/Game.wad:TEXTURES\NOTEXTURE');
2741 g_CreateTextureWADSize('AREA_REDFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGRED', 0, 0, 64, 64);
2742 g_CreateTextureWADSize('AREA_BLUEFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2743 g_CreateTextureWADSize('AREA_DOMFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGDOM', 0, 0, 64, 64);
2745 g_CreateTextureWADSize('MONSTER_DEMON', EditorDir+'data/Game.wad:MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2746 g_CreateTextureWADSize('MONSTER_IMP', EditorDir+'data/Game.wad:MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2747 g_CreateTextureWADSize('MONSTER_ZOMBY', EditorDir+'data/Game.wad:MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2748 g_CreateTextureWADSize('MONSTER_SERG', EditorDir+'data/Game.wad:MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2749 g_CreateTextureWADSize('MONSTER_CYBER', EditorDir+'data/Game.wad:MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2750 g_CreateTextureWADSize('MONSTER_CGUN', EditorDir+'data/Game.wad:MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2751 g_CreateTextureWADSize('MONSTER_BARON', EditorDir+'data/Game.wad:MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2752 g_CreateTextureWADSize('MONSTER_KNIGHT', EditorDir+'data/Game.wad:MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2753 g_CreateTextureWADSize('MONSTER_CACO', EditorDir+'data/Game.wad:MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2754 g_CreateTextureWADSize('MONSTER_SOUL', EditorDir+'data/Game.wad:MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2755 g_CreateTextureWADSize('MONSTER_PAIN', EditorDir+'data/Game.wad:MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2756 g_CreateTextureWADSize('MONSTER_SPIDER', EditorDir+'data/Game.wad:MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2757 g_CreateTextureWADSize('MONSTER_BSP', EditorDir+'data/Game.wad:MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2758 g_CreateTextureWADSize('MONSTER_MANCUB', EditorDir+'data/Game.wad:MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2759 g_CreateTextureWADSize('MONSTER_SKEL', EditorDir+'data/Game.wad:MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2760 g_CreateTextureWADSize('MONSTER_VILE', EditorDir+'data/Game.wad:MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2761 g_CreateTextureWADSize('MONSTER_FISH', EditorDir+'data/Game.wad:MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2762 g_CreateTextureWADSize('MONSTER_BARREL', EditorDir+'data/Game.wad:MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2763 g_CreateTextureWADSize('MONSTER_ROBO', EditorDir+'data/Game.wad:MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2764 g_CreateTextureWADSize('MONSTER_MAN', EditorDir+'data/Game.wad:MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2766 g_CreateTextureWADSize('ITEM_BLUESPHERE', EditorDir+'data/Game.wad:TEXTURES\SBLUE', 0, 0, 32, 32);
2767 g_CreateTextureWADSize('ITEM_WHITESPHERE', EditorDir+'data/Game.wad:TEXTURES\SWHITE', 0, 0, 32, 32);
2768 g_CreateTextureWADSize('ITEM_ARMORGREEN', EditorDir+'data/Game.wad:TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2769 g_CreateTextureWADSize('ITEM_ARMORBLUE', EditorDir+'data/Game.wad:TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2770 g_CreateTextureWADSize('ITEM_INVUL', EditorDir+'data/Game.wad:TEXTURES\INVUL', 0, 0, 32, 32);
2771 g_CreateTextureWADSize('ITEM_BOTTLE', EditorDir+'data/Game.wad:TEXTURES\BOTTLE', 0, 0, 16, 32);
2772 g_CreateTextureWADSize('ITEM_HELMET', EditorDir+'data/Game.wad:TEXTURES\HELMET', 0, 0, 16, 16);
2773 g_CreateTextureWADSize('ITEM_INVIS', EditorDir+'data/Game.wad:TEXTURES\INVIS', 0, 0, 32, 32);
2774 g_CreateTextureWADSize('ITEM_WEAPON_FLAMETHROWER', EditorDir+'data/Game.wad:TEXTURES\FLAMETHROWER', 0, 0, 64, 32);
2775 g_CreateTextureWADSize('ITEM_AMMO_FUELCAN', EditorDir+'data/Game.wad:TEXTURES\FUELCAN', 0, 0, 16, 32);
2777 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', EditorDir+'data/Game.wad:TEXTURES\MED1');
2778 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', EditorDir+'data/Game.wad:TEXTURES\MED2');
2779 g_CreateTextureWAD('ITEM_WEAPON_SAW', EditorDir+'data/Game.wad:TEXTURES\SAW');
2780 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', EditorDir+'data/Game.wad:TEXTURES\PISTOL');
2781 g_CreateTextureWAD('ITEM_WEAPON_KASTET', EditorDir+'data/Game.wad:TEXTURES\KASTET');
2782 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', EditorDir+'data/Game.wad:TEXTURES\SHOTGUN1');
2783 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', EditorDir+'data/Game.wad:TEXTURES\SHOTGUN2');
2784 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', EditorDir+'data/Game.wad:TEXTURES\MGUN');
2785 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', EditorDir+'data/Game.wad:TEXTURES\RLAUNCHER');
2786 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', EditorDir+'data/Game.wad:TEXTURES\PGUN');
2787 g_CreateTextureWAD('ITEM_WEAPON_BFG', EditorDir+'data/Game.wad:TEXTURES\BFG');
2788 g_CreateTextureWAD('ITEM_WEAPON_SUPERPULEMET', EditorDir+'data/Game.wad:TEXTURES\SPULEMET');
2789 g_CreateTextureWAD('ITEM_AMMO_BULLETS', EditorDir+'data/Game.wad:TEXTURES\CLIP');
2790 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', EditorDir+'data/Game.wad:TEXTURES\AMMO');
2791 g_CreateTextureWAD('ITEM_AMMO_SHELLS', EditorDir+'data/Game.wad:TEXTURES\SHELL1');
2792 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', EditorDir+'data/Game.wad:TEXTURES\SHELL2');
2793 g_CreateTextureWAD('ITEM_AMMO_ROCKET', EditorDir+'data/Game.wad:TEXTURES\ROCKET');
2794 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', EditorDir+'data/Game.wad:TEXTURES\ROCKETS');
2795 g_CreateTextureWAD('ITEM_AMMO_CELL', EditorDir+'data/Game.wad:TEXTURES\CELL');
2796 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', EditorDir+'data/Game.wad:TEXTURES\CELL2');
2797 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', EditorDir+'data/Game.wad:TEXTURES\BPACK');
2798 g_CreateTextureWAD('ITEM_KEY_RED', EditorDir+'data/Game.wad:TEXTURES\KEYR');
2799 g_CreateTextureWAD('ITEM_KEY_GREEN', EditorDir+'data/Game.wad:TEXTURES\KEYG');
2800 g_CreateTextureWAD('ITEM_KEY_BLUE', EditorDir+'data/Game.wad:TEXTURES\KEYB');
2801 g_CreateTextureWAD('ITEM_OXYGEN', EditorDir+'data/Game.wad:TEXTURES\OXYGEN');
2802 g_CreateTextureWAD('ITEM_SUIT', EditorDir+'data/Game.wad:TEXTURES\SUIT');
2803 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', EditorDir+'data/Game.wad:TEXTURES\BMED');
2804 g_CreateTextureWAD('ITEM_JETPACK', EditorDir+'data/Game.wad:TEXTURES\JETPACK');
2806 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorDir+'data/Editor.wad:TEXTURES\P1POINT');
2807 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorDir+'data/Editor.wad:TEXTURES\P2POINT');
2808 g_CreateTextureWAD('AREA_DMPOINT', EditorDir+'data/Editor.wad:TEXTURES\DMPOINT');
2809 g_CreateTextureWAD('AREA_REDPOINT', EditorDir+'data/Editor.wad:TEXTURES\REDPOINT');
2810 g_CreateTextureWAD('AREA_BLUEPOINT', EditorDir+'data/Editor.wad:TEXTURES\BLUEPOINT');
2811 end;
2813 procedure FreeData();
2814 begin
2815 g_DeleteTexture('NOTEXTURE');
2817 g_DeleteTexture('ITEM_BLUESPHERE');
2818 g_DeleteTexture('ITEM_WHITESPHERE');
2819 g_DeleteTexture('ITEM_ARMORGREEN');
2820 g_DeleteTexture('ITEM_ARMORBLUE');
2821 g_DeleteTexture('ITEM_INVUL');
2822 g_DeleteTexture('ITEM_BOTTLE');
2823 g_DeleteTexture('ITEM_HELMET');
2824 g_DeleteTexture('AREA_REDFLAG');
2825 g_DeleteTexture('AREA_BLUEFLAG');
2826 g_DeleteTexture('AREA_DOMFLAG');
2828 g_DeleteTexture('MONSTER_DEMON');
2829 g_DeleteTexture('MONSTER_IMP');
2830 g_DeleteTexture('MONSTER_ZOMBY');
2831 g_DeleteTexture('MONSTER_SERG');
2832 g_DeleteTexture('MONSTER_CGUN');
2833 g_DeleteTexture('MONSTER_BARREL');
2834 g_DeleteTexture('MONSTER_MAN');
2836 g_DeleteTexture('MONSTER_DEMON');
2837 g_DeleteTexture('MONSTER_IMP');
2838 g_DeleteTexture('MONSTER_ZOMBY');
2839 g_DeleteTexture('MONSTER_SERG');
2840 g_DeleteTexture('MONSTER_CYBER');
2841 g_DeleteTexture('MONSTER_CGUN');
2842 g_DeleteTexture('MONSTER_BARON');
2843 g_DeleteTexture('MONSTER_KNIGHT');
2844 g_DeleteTexture('MONSTER_CACO');
2845 g_DeleteTexture('MONSTER_SOUL');
2846 g_DeleteTexture('MONSTER_PAIN');
2847 g_DeleteTexture('MONSTER_SPIDER');
2848 g_DeleteTexture('MONSTER_BSP');
2849 g_DeleteTexture('MONSTER_MANCUB');
2850 g_DeleteTexture('MONSTER_SKEL');
2851 g_DeleteTexture('MONSTER_VILE');
2852 g_DeleteTexture('MONSTER_FISH');
2853 g_DeleteTexture('MONSTER_BARREL');
2854 g_DeleteTexture('MONSTER_ROBO');
2855 g_DeleteTexture('MONSTER_MAN');
2857 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2858 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2859 g_DeleteTexture('ITEM_WEAPON_SAW');
2860 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2861 g_DeleteTexture('ITEM_WEAPON_KASTET');
2862 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2863 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2864 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2865 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
2866 g_DeleteTexture('ITEM_WEAPON_PLASMA');
2867 g_DeleteTexture('ITEM_WEAPON_BFG');
2868 g_DeleteTexture('ITEM_WEAPON_SUPERPULEMET');
2869 g_DeleteTexture('ITEM_AMMO_BULLETS');
2870 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
2871 g_DeleteTexture('ITEM_AMMO_SHELLS');
2872 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
2873 g_DeleteTexture('ITEM_AMMO_ROCKET');
2874 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
2875 g_DeleteTexture('ITEM_AMMO_CELL');
2876 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
2877 g_DeleteTexture('ITEM_AMMO_BACKPACK');
2878 g_DeleteTexture('ITEM_KEY_RED');
2879 g_DeleteTexture('ITEM_KEY_GREEN');
2880 g_DeleteTexture('ITEM_KEY_BLUE');
2881 g_DeleteTexture('ITEM_OXYGEN');
2882 g_DeleteTexture('ITEM_SUIT');
2883 g_DeleteTexture('ITEM_MEDKIT_BLACK');
2884 g_DeleteTexture('ITEM_JETPACK');
2885 g_DeleteTexture('ITEM_INVIS');
2886 g_DeleteTexture('ITEM_WEAPON_FLAMETHROWER');
2887 g_DeleteTexture('ITEM_AMMO_FUELCAN');
2889 g_DeleteTexture('AREA_PLAYERPOINT1');
2890 g_DeleteTexture('AREA_PLAYERPOINT2');
2891 g_DeleteTexture('AREA_DMPOINT');
2892 g_DeleteTexture('AREA_REDPOINT');
2893 g_DeleteTexture('AREA_BLUEPOINT');
2894 end;
2896 end.