DEADSOFTWARE

Two small additional fixes for Lazarus
[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, 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, g_language;
249 const
250 OLD_ITEM_MEDKIT_SMALL = 1;
251 OLD_ITEM_MEDKIT_LARGE = 2;
252 OLD_ITEM_ARMOR_GREEN = 3;
253 OLD_ITEM_ARMOR_BLUE = 4;
254 OLD_ITEM_SPHERE_BLUE = 5;
255 OLD_ITEM_SPHERE_WHITE = 6;
256 OLD_ITEM_WEAPON_SAW = 7;
257 OLD_ITEM_WEAPON_SHOTGUN1 = 8;
258 OLD_ITEM_WEAPON_SHOTGUN2 = 9;
259 OLD_ITEM_WEAPON_CHAINGUN = 10;
260 OLD_ITEM_WEAPON_ROCKETLAUNCHER = 11;
261 OLD_ITEM_WEAPON_PLASMA = 12;
262 OLD_ITEM_WEAPON_BFG = 13;
263 OLD_ITEM_WEAPON_SUPERPULEMET = 14;
264 OLD_ITEM_AMMO_BULLETS = 15;
265 OLD_ITEM_AMMO_BULLETS_BOX = 16;
266 OLD_ITEM_AMMO_SHELLS = 17;
267 OLD_ITEM_AMMO_SHELLS_BOX = 18;
268 OLD_ITEM_AMMO_ROCKET = 19;
269 OLD_ITEM_AMMO_ROCKET_BOX = 20;
270 OLD_ITEM_AMMO_CELL = 21;
271 OLD_ITEM_AMMO_CELL_BIG = 22;
272 OLD_ITEM_AMMO_BACKPACK = 23;
273 OLD_ITEM_KEY_RED = 24;
274 OLD_ITEM_KEY_GREEN = 25;
275 OLD_ITEM_KEY_BLUE = 26;
276 OLD_ITEM_SUIT = 27;
277 OLD_ITEM_OXYGEN = 28;
278 OLD_ITEM_MEDKIT_BLACK = 29;
279 OLD_ITEM_INVUL = 30;
281 ITEMSCONVERT: Array [OLD_ITEM_MEDKIT_SMALL..OLD_ITEM_INVUL] of Integer =
282 ((ITEM_MEDKIT_SMALL),
283 (ITEM_MEDKIT_LARGE),
284 (ITEM_ARMOR_GREEN),
285 (ITEM_ARMOR_BLUE),
286 (ITEM_SPHERE_BLUE),
287 (ITEM_SPHERE_WHITE),
288 (ITEM_WEAPON_SAW),
289 (ITEM_WEAPON_SHOTGUN1),
290 (ITEM_WEAPON_SHOTGUN2),
291 (ITEM_WEAPON_CHAINGUN),
292 (ITEM_WEAPON_ROCKETLAUNCHER),
293 (ITEM_WEAPON_PLASMA),
294 (ITEM_WEAPON_BFG),
295 (ITEM_WEAPON_SUPERPULEMET),
296 (ITEM_AMMO_BULLETS),
297 (ITEM_AMMO_BULLETS_BOX),
298 (ITEM_AMMO_SHELLS),
299 (ITEM_AMMO_SHELLS_BOX),
300 (ITEM_AMMO_ROCKET),
301 (ITEM_AMMO_ROCKET_BOX),
302 (ITEM_AMMO_CELL),
303 (ITEM_AMMO_CELL_BIG),
304 (ITEM_AMMO_BACKPACK),
305 (ITEM_KEY_RED),
306 (ITEM_KEY_GREEN),
307 (ITEM_KEY_BLUE),
308 (ITEM_SUIT),
309 (ITEM_OXYGEN),
310 (ITEM_MEDKIT_BLACK),
311 (ITEM_INVUL));
313 OldItemSize: Array [ITEM_MEDKIT_SMALL..ITEM_KEY_BLUE] of Array [0..1] of Byte =
314 (((14), (15)), // MEDKIT_SMALL
315 ((28), (19)), // MEDKIT_LARGE
316 ((28), (19)), // MEDKIT_BLACK - not in map generator
317 ((30), (16)), // ARMOR_GREEN
318 ((30), (16)), // ARMOR_BLUE
319 ((24), (24)), // SPHERE_BLUE
320 ((24), (24)), // SPHERE_WHITE
321 ((24), (46)), // SUIT
322 ((14), (27)), // OXYGEN
323 ((25), (25)), // INVUL - not in map generator
324 ((61), (23)), // WEAPON_SAW
325 ((62), (10)), // WEAPON_SHOTGUN1
326 ((52), (12)), // WEAPON_SHOTGUN2
327 ((53), (15)), // WEAPON_CHAINGUN
328 ((61), (15)), // WEAPON_ROCKETLAUNCHER
329 ((53), (14)), // WEAPON_PLASMA
330 ((61), (34)), // WEAPON_BFG
331 ((53), (16)), // WEAPON_SUPERPULEMET
332 (( 9), (10)), // AMMO_BULLETS
333 ((28), (16)), // AMMO_BULLETS_BOX
334 ((15), ( 7)), // AMMO_SHELLS
335 ((32), (12)), // AMMO_SHELLS_BOX
336 ((12), (26)), // AMMO_ROCKET
337 ((54), (21)), // AMMO_ROCKET_BOX
338 ((15), (12)), // AMMO_CELL
339 ((32), (21)), // AMMO_CELL_BIG
340 ((22), (29)), // AMMO_BACKPACK
341 ((16), (16)), // KEY_RED
342 ((16), (16)), // KEY_GREEN
343 ((16), (16))); // KEY_BLUE
345 OldAreaSize: Array [0..1] of Byte = ((34), (56));
347 SKY_TEXTURE = 'SKY';
349 procedure LoadSky(Res: String);
350 var
351 fn: String;
353 begin
354 g_DeleteTexture(SKY_TEXTURE);
356 if Res = '' then
357 Exit;
359 g_ProcessResourceStr(Res, @fn, nil, nil);
361 if fn = '' then
362 begin
363 g_ProcessResourceStr(OpenedMap, @fn, nil, nil);
364 fn := fn + Res;
365 end
366 else
367 fn := EditorDir + 'wads/' + Res;
369 g_CreateTextureWAD(SKY_TEXTURE, fn);
370 end;
372 function AddItem(Item: TItem): DWORD;
373 var
374 a: Integer;
375 ok: Boolean;
377 begin
378 ok := False;
379 a := 0;
381 if gItems <> nil then
382 for a := 0 to High(gItems) do
383 if gItems[a].ItemType = ITEM_NONE then
384 begin
385 ok := True;
386 Break;
387 end;
389 if not ok then
390 begin
391 a := Length(gItems);
392 SetLength(gItems, a + 128);
393 end;
395 gItems[a] := Item;
397 Result := a;
398 end;
400 function AddPanel(Panel: TPanel): DWORD;
401 var
402 a, b: Integer;
403 ok: Boolean;
405 begin
406 ok := False;
407 a := 0;
408 b := -1;
410 if gPanels <> nil then
411 for a := High(gPanels) downto 0 do
412 if gPanels[a].PanelType = PANEL_NONE then
413 b := a
414 else
415 Break;
417 if b <> -1 then
418 begin
419 a := b;
420 ok := True;
421 end;
423 if not ok then
424 begin
425 a := Length(gPanels);
426 SetLength(gPanels, a + 512);
427 end;
429 gPanels[a] := Panel;
431 Result := a;
432 end;
434 function AddArea(Area: TArea): DWORD;
435 var
436 a: Integer;
437 ok: Boolean;
439 begin
440 ok := False;
441 a := 0;
443 if gAreas <> nil then
444 for a := 0 to High(gAreas) do
445 if gAreas[a].AreaType = AREA_NONE then
446 begin
447 ok := True;
448 Break;
449 end;
451 if not ok then
452 begin
453 a := Length(gAreas);
454 SetLength(gAreas, a + 64);
455 end;
457 gAreas[a] := Area;
459 Result := a;
460 end;
462 function AddMonster(Monster: TMonster): DWORD;
463 var
464 a: Integer;
465 ok: Boolean;
467 begin
468 ok := False;
469 a := 0;
471 if gMonsters <> nil then
472 for a := 0 to High(gMonsters) do
473 if gMonsters[a].MonsterType = MONSTER_NONE then
474 begin
475 ok := True;
476 Break;
477 end;
479 if not ok then
480 begin
481 a := Length(gMonsters);
482 SetLength(gMonsters, a + 128);
483 end;
485 gMonsters[a] := Monster;
487 Result := a;
488 end;
490 function AddTrigger(Trigger: TTrigger): DWORD;
491 var
492 a: Integer;
493 ok: Boolean;
495 begin
496 ok := False;
497 a := 0;
499 if gTriggers <> nil then
500 for a := 0 to High(gTriggers) do
501 if gTriggers[a].TriggerType = TRIGGER_NONE then
502 begin
503 ok := True;
504 Break;
505 end;
507 if not ok then
508 begin
509 a := Length(gTriggers);
510 SetLength(gTriggers, a + 64);
511 end;
513 gTriggers[a] := Trigger;
515 Result := a;
516 end;
518 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
519 var
520 a: Integer;
522 begin
523 case ObjectType of
524 OBJECT_PANEL:
525 begin
526 // Убираем ссылки триггеров на эту панель:
527 if gTriggers <> nil then
528 for a := 0 to High(gTriggers) do
529 if gTriggers[a].TriggerType <> 0 then
530 begin
531 if gTriggers[a].TexturePanel = Integer(ID) then
532 gTriggers[a].TexturePanel := -1;
534 if gTriggers[a].TriggerType in [
535 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
536 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
537 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
538 TRIGGER_LIFT] then
539 if gTriggers[a].Data.PanelID = Integer(ID) then
540 gTriggers[a].Data.PanelID := -1;
542 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
543 (gTriggers[a].Data.ShotPanelID = Integer(ID)) then
544 gTriggers[a].Data.ShotPanelID := -1;
545 end;
547 gPanels[ID].PanelType := 0;
548 end;
550 OBJECT_ITEM:
551 gItems[ID].ItemType := 0;
553 OBJECT_MONSTER:
554 begin
555 // Убираем ссылки триггеров на этого монстра:
556 if gTriggers <> nil then
557 for a := 0 to High(gTriggers) do
558 if gTriggers[a].TriggerType <> 0 then
559 begin
560 if gTriggers[a].TriggerType in [TRIGGER_PRESS,
561 TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
562 if (gTriggers[a].Data.MonsterID-1 = Integer(ID)) then
563 gTriggers[a].Data.MonsterID := 0;
564 end;
566 gMonsters[ID].MonsterType := 0;
567 end;
569 OBJECT_AREA:
570 gAreas[ID].AreaType := 0;
572 OBJECT_TRIGGER:
573 gTriggers[ID].TriggerType := 0;
574 end;
575 end;
577 function PanelInShownLayer(PanelType: Word): Boolean;
578 begin
579 case PanelType of
580 PANEL_WALL:
581 Result := LayerEnabled[LAYER_WALLS];
583 PANEL_BACK:
584 Result := LayerEnabled[LAYER_BACK];
586 PANEL_FORE:
587 Result := LayerEnabled[LAYER_FOREGROUND];
589 PANEL_STEP:
590 Result := LayerEnabled[LAYER_STEPS];
592 PANEL_WATER, PANEL_ACID1, PANEL_ACID2,
593 PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT,
594 PANEL_OPENDOOR, PANEL_CLOSEDOOR,
595 PANEL_BLOCKMON:
596 Result := LayerEnabled[LAYER_WATER];
598 else
599 Result := False;
600 end;
601 end;
603 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
604 var
605 a: Integer;
607 begin
608 Result := nil;
610 case ObjectType of
611 OBJECT_PANEL:
612 if gPanels <> nil then
613 for a := High(gPanels) downto 0 do
614 with gPanels[a] do
615 begin
616 if not PanelInShownLayer(gPanels[a].PanelType) then
617 Continue;
619 if g_Collide(X, Y, Width, Height,
620 fX, fY, fWidth, fHeight) then
621 begin
622 SetLength(Result, Length(Result)+1);
623 Result[High(Result)] := a;
625 if not All then
626 Break;
627 end;
628 end;
630 OBJECT_ITEM:
631 if LayerEnabled[LAYER_ITEMS] and (gItems <> nil) then
632 for a := High(gItems) downto 0 do
633 with gItems[a] do
634 if (ItemType <> ITEM_NONE) and
635 g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
636 fX, fY, fWidth, fHeight) then
637 begin
638 SetLength(Result, Length(Result)+1);
639 Result[High(Result)] := a;
641 if not All then
642 Break;
643 end;
645 OBJECT_MONSTER:
646 if LayerEnabled[LAYER_MONSTERS] and (gMonsters <> nil) then
647 for a := High(gMonsters) downto 0 do
648 if gMonsters[a].MonsterType <> MONSTER_NONE then
649 with MonsterSize[gMonsters[a].MonsterType] do
650 if (gMonsters[a].MonsterType <> 0) and
651 g_Collide(gMonsters[a].X, gMonsters[a].Y, Width, Height,
652 fX, fY, fWidth, fHeight) then
653 begin
654 SetLength(Result, Length(Result)+1);
655 Result[High(Result)] := a;
657 if not All then
658 Break;
659 end;
661 OBJECT_AREA:
662 if LayerEnabled[LAYER_AREAS] and (gAreas <> nil) then
663 for a := High(gAreas) downto 0 do
664 if gAreas[a].AreaType <> AREA_NONE then
665 with AreaSize[gAreas[a].AreaType] do
666 if (gAreas[a].AreaType <> 0) and
667 g_Collide(gAreas[a].X, gAreas[a].Y, Width, Height,
668 fX, fY, fWidth, fHeight) then
669 begin
670 SetLength(Result, Length(Result)+1);
671 Result[High(Result)] := a;
673 if not All then
674 Break;
675 end;
677 OBJECT_TRIGGER:
678 if LayerEnabled[LAYER_TRIGGERS] and (gTriggers <> nil) then
679 for a := High(gTriggers) downto 0 do
680 if gTriggers[a].TriggerType <> TRIGGER_NONE then
681 with gTriggers[a] do
682 begin
683 if (TriggerType <> 0) and
684 g_Collide(X, Y, Width, Height,
685 fX, fY, fWidth, fHeight) then
686 begin
687 SetLength(Result, Length(Result)+1);
688 Result[High(Result)] := a;
690 if not All then
691 Break;
692 end;
693 end;
694 end;
695 end;
697 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
698 var
699 PanelID: DWORD;
701 begin
702 Result := False;
703 PanelID := DWORD(-1);
705 case ObjectType of
706 OBJECT_PANEL:
707 with gPanels[fID] do
708 Result := (PanelID <> fID) and
709 g_CollideLevel2(X+dX, Y+dY,
710 Width, Height,
711 fID, PanelID);
713 OBJECT_ITEM:
714 with gItems[fID] do
715 Result := g_CollideLevel(X+dX, Y+dY,
716 ItemSize[ItemType][0], ItemSize[ItemType][1]);
718 OBJECT_MONSTER:
719 with MonsterSize[gMonsters[fID].MonsterType] do
720 Result := g_CollideLevel(gMonsters[fID].X+dX, gMonsters[fID].Y+dY,
721 Width, Height);
723 OBJECT_AREA:
724 with AreaSize[gAreas[fID].AreaType] do
725 Result := g_CollideLevel(gAreas[fID].X+dX, gAreas[fID].Y+dY,
726 Width, Height);
728 OBJECT_TRIGGER:
729 with gTriggers[fID] do
730 Result := g_CollideLevel(X+dX, Y+dY,
731 Width, Height);
732 end;
733 end;
735 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
736 begin
737 Result := False;
739 case ObjectType of
740 OBJECT_PANEL:
741 with gPanels[ID] do
742 Result := g_Collide(X, Y, Width, Height,
743 fX, fY, fWidth, fHeight);
745 OBJECT_ITEM:
746 with gItems[ID] do
747 Result := g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
748 fX, fY, fWidth, fHeight);
750 OBJECT_MONSTER:
751 with MonsterSize[gMonsters[ID].MonsterType] do
752 Result := g_Collide(gMonsters[ID].X, gMonsters[ID].Y, Width, Height,
753 fX, fY, fWidth, fHeight);
755 OBJECT_AREA:
756 with AreaSize[gAreas[ID].AreaType] do
757 Result := g_Collide(gAreas[ID].X, gAreas[ID].Y, Width, Height,
758 fX, fY, fWidth, fHeight);
760 OBJECT_TRIGGER:
761 with gTriggers[ID] do
762 Result := g_Collide(X, Y, Width, Height,
763 fX, fY, fWidth, fHeight);
764 end;
765 end;
767 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
768 begin
769 case ObjectType of
770 OBJECT_PANEL:
771 with gPanels[ID] do
772 begin
773 Result.X := X;
774 Result.Y := Y;
775 Result.Width := Width;
776 Result.Height := Height;
777 end;
779 OBJECT_ITEM:
780 with gItems[ID] do
781 begin
782 Result.X := X;
783 Result.Y := Y;
784 Result.Width := ItemSize[ItemType][0];
785 Result.Height := ItemSize[ItemType][1];
786 end;
788 OBJECT_MONSTER:
789 with MonsterSize[gMonsters[ID].MonsterType] do
790 begin
791 Result.X := gMonsters[ID].X;
792 Result.Y := gMonsters[ID].Y;
793 Result.Width := Width;
794 Result.Height := Height;
795 end;
797 OBJECT_AREA:
798 with AreaSize[gAreas[ID].AreaType] do
799 begin
800 Result.X := gAreas[ID].X;
801 Result.Y := gAreas[ID].Y;
802 Result.Width := Width;
803 Result.Height := Height;
804 end;
806 OBJECT_TRIGGER:
807 with gTriggers[ID] do
808 begin
809 Result.X := X;
810 Result.Y := Y;
811 Result.Width := Width;
812 Result.Height := Height;
813 end;
815 else
816 begin
817 Result.X := 0;
818 Result.Y := 0;
819 Result.Width := 0;
820 Result.Height := 0;
821 end;
822 end;
823 end;
825 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
826 begin
827 case ObjectType of
828 OBJECT_PANEL:
829 with gPanels[ID] do
830 begin
831 X := X + dX;
832 Y := Y + dY;
833 end;
835 OBJECT_ITEM:
836 with gItems[ID] do
837 begin
838 X := X + dX;
839 Y := Y + dY;
840 end;
842 OBJECT_MONSTER:
843 with gMonsters[ID] do
844 begin
845 X := X + dX;
846 Y := Y + dY;
847 end;
849 OBJECT_AREA:
850 with gAreas[ID] do
851 begin
852 X := X + dX;
853 Y := Y + dY;
854 end;
856 OBJECT_TRIGGER:
857 with gTriggers[ID] do
858 begin
859 X := X + dX;
860 Y := Y + dY;
861 end;
862 end;
863 end;
865 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
866 begin
867 case ObjectType of
868 OBJECT_PANEL:
869 with gPanels[ID] do
870 begin
871 if Width >= -dWidth then
872 Width := Width+dWidth
873 else
874 begin
875 Width := 0;
876 Exit;
877 end;
879 if Height >= -dHeight then
880 Height := Height+dHeight
881 else
882 begin
883 Height := 0;
884 Exit;
885 end;
887 case ResizeDir of
888 2: Y := Y - dHeight;
889 4: X := X - dWidth;
890 end;
891 end;
893 OBJECT_ITEM, OBJECT_MONSTER, OBJECT_AREA:
894 Exit;
896 OBJECT_TRIGGER:
897 with gTriggers[ID] do
898 begin
899 if Width >= -dWidth then
900 Width := Width+dWidth
901 else
902 begin
903 Width := 0;
904 Exit;
905 end;
907 if Height >= -dHeight then
908 Height := Height+dHeight
909 else
910 begin
911 Height := 0;
912 Exit;
913 end;
915 case ResizeDir of
916 2: Y := Y - dHeight;
917 4: X := X - dWidth;
918 end;
919 end;
920 end;
921 end;
923 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
924 var
925 a: Integer;
927 begin
928 Result := False;
930 if SelectedObjects <> nil then
931 for a := 0 to High(SelectedObjects) do
932 if SelectedObjects[a].Live and
933 (SelectedObjects[a].ObjectType = ObjectType) and
934 (SelectedObjects[a].ID = ID) then
935 begin
936 Result := True;
937 Break;
938 end;
939 end;
941 function GetPanelName(PanelType: Word): String;
942 begin
943 Result := '';
945 case PanelType of
946 PANEL_WALL: Result := PANELNAMES[0];
947 PANEL_BACK: Result := PANELNAMES[1];
948 PANEL_FORE: Result := PANELNAMES[2];
949 PANEL_OPENDOOR: Result := PANELNAMES[3];
950 PANEL_CLOSEDOOR: Result := PANELNAMES[4];
951 PANEL_STEP: Result := PANELNAMES[5];
952 PANEL_WATER: Result := PANELNAMES[6];
953 PANEL_ACID1: Result := PANELNAMES[7];
954 PANEL_ACID2: Result := PANELNAMES[8];
955 PANEL_LIFTUP: Result := PANELNAMES[9];
956 PANEL_LIFTDOWN: Result := PANELNAMES[10];
957 PANEL_LIFTLEFT: Result := PANELNAMES[11];
958 PANEL_LIFTRIGHT: Result := PANELNAMES[12];
959 PANEL_BLOCKMON: Result := PANELNAMES[13];
960 else Assert(False);
961 end;
962 end;
964 function GetPanelType(PanelName: String): Word;
965 begin
966 Result := 0;
968 if PanelName = PANELNAMES[0] then
969 Result := PANEL_WALL
970 else if PanelName = PANELNAMES[1] then
971 Result := PANEL_BACK
972 else if PanelName = PANELNAMES[2] then
973 Result := PANEL_FORE
974 else if PanelName = PANELNAMES[3] then
975 Result := PANEL_OPENDOOR
976 else if PanelName = PANELNAMES[4] then
977 Result := PANEL_CLOSEDOOR
978 else if PanelName = PANELNAMES[5] then
979 Result := PANEL_STEP
980 else if PanelName = PANELNAMES[6] then
981 Result := PANEL_WATER
982 else if PanelName = PANELNAMES[7] then
983 Result := PANEL_ACID1
984 else if PanelName = PANELNAMES[8] then
985 Result := PANEL_ACID2
986 else if PanelName = PANELNAMES[9] then
987 Result := PANEL_LIFTUP
988 else if PanelName = PANELNAMES[10] then
989 Result := PANEL_LIFTDOWN
990 else if PanelName = PANELNAMES[11] then
991 Result := PANEL_LIFTLEFT
992 else if PanelName = PANELNAMES[12] then
993 Result := PANEL_LIFTRIGHT
994 else if PanelName = PANELNAMES[13] then
995 Result := PANEL_BLOCKMON;
997 Assert(Result <> 0);
998 end;
1000 function GetTriggerName(TriggerType: Byte): String;
1001 begin
1002 if TriggerType in [TRIGGER_EXIT..TRIGGER_MAX] then
1003 Result := TriggerNames[TriggerType]
1004 else
1005 Assert(False);
1006 end;
1008 function GetTriggerType(TriggerName: String): Byte;
1009 var
1010 i: Integer;
1012 begin
1013 Result := TRIGGER_NONE;
1014 for i := TRIGGER_EXIT to TRIGGER_MAX do
1015 if TriggerNames[i] = TriggerName then
1016 begin
1017 Result := i;
1018 Exit;
1019 end;
1021 Assert(False);
1022 end;
1024 function IsSpecialTexture(TextureName: string): Boolean;
1025 begin
1026 Result := (TextureName = TEXTURE_NAME_WATER) or
1027 (TextureName = TEXTURE_NAME_ACID1) or
1028 (TextureName = TEXTURE_NAME_ACID2);
1029 end;
1031 function SpecialTextureID(TextureName: string): DWORD;
1032 begin
1033 Assert(IsSpecialTexture(TextureName));
1035 Result := 0;
1037 if TextureName = TEXTURE_NAME_WATER then
1038 Result := TEXTURE_SPECIAL_WATER
1039 else
1040 if TextureName = TEXTURE_NAME_ACID1 then
1041 Result := TEXTURE_SPECIAL_ACID1
1042 else
1043 if TextureName = TEXTURE_NAME_ACID2 then
1044 Result := TEXTURE_SPECIAL_ACID2;
1045 end;
1047 function SaveMap(Res: String): Pointer;
1048 var
1049 WAD: TWADEditor_1;
1050 MapWriter: TMapWriter_1;
1051 textures: TTexturesRec1Array;
1052 panels: TPanelsRec1Array;
1053 items: TItemsRec1Array;
1054 areas: TAreasRec1Array;
1055 monsters: TMonsterRec1Array;
1056 triggers: TTriggersRec1Array;
1057 header: TMapHeaderRec_1;
1058 a, b, c: Integer;
1059 s: String;
1060 PanelTable: Array of Array [0..1] of Word;
1061 MonsterTable: Array of Array [0..1] of Word;
1062 Data: Pointer;
1063 FileName, SectionName, ResName: String;
1064 Len: LongWord;
1066 begin
1067 WAD := nil;
1068 textures := nil;
1069 panels := nil;
1070 items := nil;
1071 areas := nil;
1072 monsters := nil;
1073 triggers := nil;
1074 PanelTable := nil;
1075 MonsterTable := nil;
1076 Data := nil;
1077 Len := 0;
1079 // Открываем WAD, если надо:
1080 if Res <> '' then
1081 begin
1082 WAD := TWADEditor_1.Create();
1083 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1084 if not WAD.ReadFile(FileName) then
1085 WAD.FreeWAD();
1087 WAD.CreateImage();
1088 end;
1090 MapWriter := TMapWriter_1.Create();
1092 // Сохраняем заголовок:
1093 with header do
1094 begin
1095 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1097 s := utf2win(gMapInfo.Name);
1098 if s <> '' then
1099 CopyMemory(@MapName[0], @s[1], Min(32, Length(s)));
1101 s := utf2win(gMapInfo.Description);
1102 if s <> '' then
1103 CopyMemory(@MapDescription[0], @s[1], Min(256, Length(s)));
1105 s := utf2win(gMapInfo.Author);
1106 if s <> '' then
1107 CopyMemory(@MapAuthor[0], @s[1], Min(32, Length(s)));
1109 s := utf2win(gMapInfo.MusicName);
1110 if s <> '' then
1111 CopyMemory(@MusicName[0], @s[1], Min(64, Length(s)));
1113 s := utf2win(gMapInfo.SkyName);
1114 if s <> '' then
1115 CopyMemory(@SkyName[0], @s[1], Min(64, Length(s)));
1117 Width := gMapInfo.Width;
1118 Height := gMapInfo.Height;
1119 end;
1121 MapWriter.AddHeader(header);
1123 // Сохраняем названия текстур:
1124 if MainForm.lbTextureList.Items.Count > 0 then
1125 begin
1126 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1127 begin
1128 SetLength(textures, Length(textures)+1);
1129 s := utf2win(MainForm.lbTextureList.Items[a]);
1130 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1131 if g_GetTextureFlagByName(MainForm.lbTextureList.Items[a]) = 1 then
1132 textures[High(textures)].Anim := 1
1133 else
1134 textures[High(textures)].Anim := 0;
1135 end;
1137 MapWriter.AddTextures(textures);
1138 end;
1140 // Сохраняем панели:
1141 if gPanels <> nil then
1142 begin
1143 c := 0;
1145 for a := 0 to High(gPanels) do
1146 if gPanels[a].PanelType <> 0 then
1147 begin
1148 SetLength(PanelTable, Length(PanelTable)+1);
1149 PanelTable[High(PanelTable)][0] := a;
1150 PanelTable[High(PanelTable)][1] := c;
1151 c := c + 1;
1153 SetLength(panels, Length(panels)+1);
1155 with panels[High(panels)] do
1156 begin
1157 X := gPanels[a].X;
1158 Y := gPanels[a].Y;
1159 Width := gPanels[a].Width;
1160 Height := gPanels[a].Height;
1161 PanelType := gPanels[a].PanelType;
1162 Alpha := gPanels[a].Alpha;
1164 TextureNum := 0;
1165 Flags := 0;
1167 if WordBool(gPanels[a].PanelType and
1168 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1169 Flags := PANEL_FLAG_WATERTEXTURES;
1171 // Может быть текстура:
1172 if not WordBool(gPanels[a].PanelType and
1173 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1174 begin
1175 if gPanels[a].Blending then
1176 Flags := Flags or PANEL_FLAG_BLENDING;
1177 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1178 Flags := Flags or PANEL_FLAG_HIDE;
1180 // Номер текстуры в списке текстур:
1181 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1182 for b := 0 to High(textures) do
1183 if utf2win(gPanels[a].TextureName) = textures[b].Resource then
1184 begin
1185 TextureNum := b;
1186 Break;
1187 end;
1188 end;
1189 end;
1190 end;
1192 MapWriter.AddPanels(panels);
1193 end;
1195 // Сохраняем предметы:
1196 if gItems <> nil then
1197 begin
1198 for a := 0 to High(gItems) do
1199 if gItems[a].ItemType <> 0 then
1200 begin
1201 SetLength(items, Length(items)+1);
1203 with items[High(items)] do
1204 begin
1205 X := gItems[a].X;
1206 Y := gItems[a].Y;
1207 ItemType := gItems[a].ItemType;
1208 if gItems[a].OnlyDM then
1209 Options := Options or ITEM_OPTION_ONLYDM;
1210 if gItems[a].Fall then
1211 Options := Options or ITEM_OPTION_FALL;
1212 end;
1213 end;
1215 MapWriter.AddItems(items);
1216 end;
1218 // Сохраняем монстров:
1219 if gMonsters <> nil then
1220 begin
1221 c := 0;
1223 for a := 0 to High(gMonsters) do
1224 if gMonsters[a].MonsterType <> 0 then
1225 begin
1226 SetLength(MonsterTable, Length(MonsterTable)+1);
1227 MonsterTable[High(MonsterTable)][0] := a;
1228 MonsterTable[High(MonsterTable)][1] := c;
1229 c := c + 1;
1231 SetLength(monsters, Length(monsters)+1);
1233 with monsters[High(monsters)] do
1234 begin
1235 X := gMonsters[a].X;
1236 Y := gMonsters[a].Y;
1237 MonsterType := gMonsters[a].MonsterType;
1238 Direction := Ord(gMonsters[a].Direction);
1239 end;
1240 end;
1242 MapWriter.AddMonsters(monsters);
1243 end;
1245 // Сохраняем области:
1246 if gAreas <> nil then
1247 begin
1248 for a := 0 to High(gAreas) do
1249 if gAreas[a].AreaType <> 0 then
1250 begin
1251 SetLength(areas, Length(areas)+1);
1253 with areas[High(areas)] do
1254 begin
1255 X := gAreas[a].X;
1256 Y := gAreas[a].Y;
1257 AreaType := gAreas[a].AreaType;
1258 Direction := Ord(gAreas[a].Direction);
1259 end;
1260 end;
1262 MapWriter.AddAreas(areas);
1263 end;
1265 // Сохраняем триггеры:
1266 if gTriggers <> nil then
1267 begin
1268 for a := 0 to High(gTriggers) do
1269 if gTriggers[a].TriggerType <> 0 then
1270 begin
1271 SetLength(triggers, Length(triggers)+1);
1273 with triggers[High(triggers)] do
1274 begin
1275 X := gTriggers[a].X;
1276 Y := gTriggers[a].Y;
1277 Width := gTriggers[a].Width;
1278 Height := gTriggers[a].Height;
1279 Enabled := Byte(gTriggers[a].Enabled);
1280 TexturePanel := -1;
1281 TriggerType := gTriggers[a].TriggerType;
1282 ActivateType := gTriggers[a].ActivateType;
1283 Keys := gTriggers[a].Key;
1284 DATA := gTriggers[a].Data.Default;
1286 if PanelTable <> nil then
1287 begin
1288 // Ищем номер панели, которой этот триггер меняет текстуру:
1289 if gTriggers[a].TexturePanel <> -1 then
1290 begin
1291 for c := 0 to High(PanelTable) do
1292 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1293 TexturePanel := PanelTable[c][1];
1294 end;
1296 // Ищем номер панели, которую меняет этот триггер:
1297 if gTriggers[a].TriggerType in [
1298 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1299 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1300 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1301 if TTriggerData(DATA).PanelID <> -1 then
1302 for c := 0 to High(PanelTable) do
1303 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1304 begin
1305 TTriggerData(DATA).PanelID := PanelTable[c][1];
1306 Break;
1307 end;
1309 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1310 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1311 (TTriggerData(DATA).ShotPanelID <> -1) then
1312 begin
1313 for c := 0 to High(PanelTable) do
1314 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1315 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1316 end;
1317 end;
1319 if MonsterTable <> nil then
1320 begin
1321 // Ищем номер монстра - условие активации триггера:
1322 if gTriggers[a].TriggerType in [
1323 TRIGGER_PRESS, TRIGGER_ON,
1324 TRIGGER_OFF, TRIGGER_ONOFF] then
1325 if TTriggerData(DATA).MonsterID <> 0 then
1326 for c := 0 to High(MonsterTable) do
1327 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1328 begin
1329 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1330 Break;
1331 end;
1332 end;
1333 end;
1334 end;
1336 MapWriter.AddTriggers(triggers);
1337 end;
1339 // Сохраняем карту в память:
1340 Len := MapWriter.SaveMap(Data);
1342 MapWriter.Free();
1344 // Записываем в WAD, если надо:
1345 if Res <> '' then
1346 begin
1347 s := utf2win(ResName);
1348 WAD.RemoveResource('', s);
1349 WAD.AddResource(Data, Len, s, '');
1350 WAD.SaveTo(FileName);
1352 FreeMem(Data);
1353 WAD.Free();
1355 Result := nil;
1356 end
1357 else
1358 Result := Data;
1359 end;
1361 procedure AddTexture(res: String; Error: Boolean);
1362 var
1363 a: Integer;
1364 begin
1365 with MainForm.lbTextureList do
1366 begin
1367 for a := 0 to Count-1 do
1368 if Items[a] = res then
1369 Exit;
1371 if Error and (slInvalidTextures.IndexOf(res) = -1) then
1372 slInvalidTextures.Add(res);
1373 Items.Add(res);
1374 end;
1375 end;
1377 function LoadMap(Res: String): Boolean;
1378 var
1379 WAD: TWADEditor_1;
1380 MapReader: TMapReader_1;
1381 Header: TMapHeaderRec_1;
1382 textures: TTexturesRec1Array;
1383 panels: TPanelsRec1Array;
1384 items: TItemsRec1Array;
1385 monsters: TMonsterRec1Array;
1386 areas: TAreasRec1Array;
1387 triggers: TTriggersRec1Array;
1388 panel: TPanel;
1389 item: TItem;
1390 monster: TMonster;
1391 area: TArea;
1392 trigger: TTrigger;
1393 a: Integer;
1394 Data: Pointer;
1395 Width, Height, m: Word;
1396 FileName, SectionName, ResName, _fn: String;
1397 TextureRes, ustr: String;
1398 pData: Pointer;
1399 Len, FrameLen: Integer;
1400 Error: Boolean;
1401 NoTextureID: DWORD;
1402 NW, NH: Word;
1403 begin
1404 Result := False;
1405 pData := nil;
1406 Len := 0;
1407 Data := nil;
1408 FrameLen := 0;
1409 Width := 0;
1410 Height := 0;
1411 NoTextureID := 0;
1412 NW := 0;
1413 NH := 0;
1415 MainForm.pbLoad.Position := 0;
1416 MainForm.lLoad.Caption := _lc[I_LOAD_WAD];
1417 Application.ProcessMessages();
1419 // Открываем WAD:
1420 WAD := TWADEditor_1.Create();
1421 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1423 if not WAD.ReadFile(FileName) then
1424 begin
1425 WAD.Free();
1426 Exit;
1427 end;
1429 // Читаем ресурс карты:
1430 if not WAD.GetResource('', utf2win(ResName), pData, Len) then
1431 begin
1432 WAD.Free();
1433 Exit;
1434 end;
1436 WAD.Free();
1438 MapReader := TMapReader_1.Create();
1440 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];
1441 Application.ProcessMessages();
1443 MapReader.LoadMap(pData);
1445 // Загружаем текстуры:
1446 textures := MapReader.GetTextures();
1448 if textures <> nil then
1449 begin
1450 MainForm.pbLoad.Position := 0;
1451 MainForm.pbLoad.Max := Length(textures);
1452 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1454 for a := 0 to High(textures) do
1455 begin
1456 MainForm.pbLoad.StepIt();
1457 Application.ProcessMessages();
1458 ustr := win2utf(textures[a].Resource);
1460 if IsSpecialTexture(ustr) then
1461 begin
1462 AddTexture(ustr, False);
1463 Continue;
1464 end;
1466 g_ProcessResourceStr(ustr, @_fn, nil, nil);
1468 if _fn = '' then
1469 TextureRes := FileName + ustr
1470 else
1471 TextureRes := EditorDir+'wads/'+ustr;
1473 Error := False;
1475 if not ByteBool(textures[a].Anim) then
1476 begin // Обычная текстура
1477 if not g_CreateTextureWAD(ustr, TextureRes) then
1478 begin
1479 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s',
1480 [ustr]), MSG_WARNING);
1481 Error := True;
1482 end;
1484 AddTexture(ustr, Error);
1485 end
1486 else // Anim
1487 begin // Анимированная текстура
1488 if not GetFrame(TextureRes, Data, FrameLen, Width, Height) then
1489 begin // Кадры
1490 e_WriteLog(Format('GetFrame() error, res=%s',
1491 [ustr]), MSG_WARNING);
1492 Error := True;
1493 end;
1495 if not g_CreateTextureMemorySize(Data, FrameLen, ustr, 0, 0, Width, Height, 1) then
1496 begin // Сама текстура
1497 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s',
1498 [ustr]), MSG_WARNING);
1499 Error := True;
1500 end;
1502 AddTexture(ustr, Error);
1503 end;
1504 end;
1505 end;
1507 // Загружаем панели:
1508 panels := MapReader.GetPanels();
1510 if panels <> nil then
1511 begin
1512 MainForm.pbLoad.Position := 0;
1513 MainForm.pbLoad.Max := Length(panels);
1514 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1516 for a := 0 to High(panels) do
1517 begin
1518 MainForm.pbLoad.StepIt();
1519 Application.ProcessMessages();
1521 panel.X := panels[a].X;
1522 panel.Y := panels[a].Y;
1523 panel.Height := panels[a].Height;
1524 panel.Width := panels[a].Width;
1525 panel.PanelType := panels[a].PanelType;
1526 panel.Alpha := panels[a].Alpha;
1528 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1530 panel.TextureWidth := 0;
1531 panel.TextureHeight := 0;
1532 panel.TextureName := '';
1533 panel.TextureID := TEXTURE_SPECIAL_NONE;
1535 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_STEP or
1536 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1538 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1539 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1541 // Если панель видима:
1542 if WordBool(panel.PanelType and m) and
1543 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1544 begin
1545 ustr := win2utf(textures[panels[a].TextureNum].Resource);
1546 if not IsSpecialTexture(ustr) then
1547 begin // Текстура
1548 if g_GetTexture(ustr, panel.TextureID) then
1549 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1550 else begin
1551 panel.TextureWidth := 1;
1552 panel.TextureHeight := 1;
1553 if g_GetTexture('NOTEXTURE', NoTextureID) then
1554 begin
1555 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1556 g_GetTextureSizeByID(NoTextureID, NW, NH);
1557 panel.TextureWidth := NW;
1558 panel.TextureHeight := NH;
1559 end;
1560 end;
1561 end
1562 else // Спец. текстура
1563 panel.TextureID := SpecialTextureID(ustr);
1565 panel.TextureName := ustr;
1566 end;
1568 // Жидкость без текстуры:
1569 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1570 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1571 begin
1572 case panel.PanelType of
1573 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1574 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1575 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1576 end;
1578 panel.TextureID := SpecialTextureID(panel.TextureName);
1579 AddTexture(panel.TextureName, False);
1580 end;
1582 AddPanel(panel);
1583 end;
1584 end;
1586 // Загружаем предметы:
1587 items := MapReader.GetItems();
1589 if items <> nil then
1590 begin
1591 MainForm.pbLoad.Position := 0;
1592 MainForm.pbLoad.Max := Length(items);
1593 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1595 for a := 0 to High(items) do
1596 begin
1597 MainForm.pbLoad.StepIt();
1598 Application.ProcessMessages();
1600 item.X := items[a].X;
1601 item.Y := items[a].Y;
1602 item.ItemType := items[a].ItemType;
1603 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1604 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1606 AddItem(item);
1607 end;
1608 end;
1610 // Загружаем монстров:
1611 monsters := MapReader.GetMonsters();
1613 if monsters <> nil then
1614 begin
1615 MainForm.pbLoad.Position := 0;
1616 MainForm.pbLoad.Max := Length(monsters);
1617 MainForm.lLoad.Caption := _lc[I_LOAD_MONSTERS];
1619 for a := 0 to High(monsters) do
1620 begin
1621 MainForm.pbLoad.StepIt();
1622 Application.ProcessMessages();
1624 monster.X := monsters[a].X;
1625 monster.Y := monsters[a].Y;
1626 monster.MonsterType := monsters[a].MonsterType;
1627 monster.Direction := TDirection(monsters[a].Direction);
1629 AddMonster(monster);
1630 end;
1631 end;
1633 // Загружаем области:
1634 areas := MapReader.GetAreas();
1636 if areas <> nil then
1637 begin
1638 MainForm.pbLoad.Position := 0;
1639 MainForm.pbLoad.Max := Length(areas);
1640 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1642 for a := 0 to High(areas) do
1643 begin
1644 MainForm.pbLoad.StepIt();
1645 Application.ProcessMessages();
1647 area.X := areas[a].X;
1648 area.Y := areas[a].Y;
1649 area.AreaType := areas[a].AreaType;
1650 area.Direction := TDirection(areas[a].Direction);
1652 AddArea(area);
1653 end;
1654 end;
1656 // Загружаем триггеры:
1657 triggers := MapReader.GetTriggers();
1659 if triggers <> nil then
1660 begin
1661 MainForm.pbLoad.Position := 0;
1662 MainForm.pbLoad.Max := Length(triggers);
1663 MainForm.lLoad.Caption := _lc[I_LOAD_TRIGGERS];
1665 for a := 0 to High(triggers) do
1666 begin
1667 MainForm.pbLoad.StepIt();
1668 Application.ProcessMessages();
1670 trigger.X := triggers[a].X;
1671 trigger.Y := triggers[a].Y;
1672 trigger.Width := triggers[a].Width;
1673 trigger.Height := triggers[a].Height;
1675 trigger.Enabled := ByteBool(triggers[a].Enabled);
1676 trigger.TexturePanel := triggers[a].TexturePanel;
1677 trigger.TriggerType := triggers[a].TriggerType;
1678 trigger.ActivateType := triggers[a].ActivateType;
1679 trigger.Key := triggers[a].Keys;
1680 trigger.Data.Default := triggers[a].DATA;
1682 AddTrigger(trigger);
1683 end;
1684 end;
1686 // Загружаем заголовок карты:
1687 Header := MapReader.GetMapHeader();
1689 gMapInfo.FileName := FileName;
1691 with gMapInfo do
1692 begin
1693 MapName := ResName;
1694 Name := win2utf(Header.MapName);
1695 Description := win2utf(Header.MapDescription);
1696 Author := win2utf(Header.MapAuthor);
1697 MusicName := win2utf(Header.MusicName);
1698 SkyName := win2utf(Header.SkyName);
1699 Height := Header.Height;
1700 Width := Header.Width;
1701 end;
1703 LoadSky(gMapInfo.SkyName);
1705 textures := nil;
1706 panels := nil;
1707 items := nil;
1708 areas := nil;
1709 triggers := nil;
1711 MapReader.Free();
1712 FreeMem(pData);
1714 Result := True;
1715 end;
1717 function LoadMapOld(_FileName: String): Boolean;
1718 const
1719 TexturePrefix = 'Standart.wad:STDTEXTURES\';
1720 DefaultMusRes = 'Standart.wad:STDMUS\MUS1';
1721 DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
1723 var
1724 map: TConfig;
1725 i, a: Integer;
1726 s, section: String;
1727 panel: TPanel;
1728 item: TItem;
1729 area: TArea;
1731 begin
1732 Result := False;
1734 if not FileExists(_FileName) then
1735 Exit;
1737 // Открытие карты:
1738 MainForm.pbLoad.Position := 0;
1739 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];;
1740 Application.ProcessMessages();
1742 map := TConfig.CreateFile(_FileName);
1744 // Чтение текстур:
1745 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1747 MainForm.pbLoad.Max := i;
1748 MainForm.pbLoad.Position := 0;
1749 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1751 for a := 1 to i do
1752 begin
1753 MainForm.pbLoad.StepIt();
1754 Application.ProcessMessages();
1756 s := TexturePrefix + UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1757 if s = TexturePrefix then
1758 Continue;
1760 // Нет такой текстуры - ищем в WAD карты:
1761 if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
1762 begin
1763 s := ExtractFileName(_FileName);
1764 Delete(s, Length(s)-3, 4);
1765 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
1767 if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
1768 Continue;
1769 end;
1771 MainForm.lbTextureList.Items.Add(s);
1772 end;
1774 // Чтение панелей:
1775 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1777 MainForm.pbLoad.Max := i;
1778 MainForm.pbLoad.Position := 0;
1779 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1781 for a := 1 to i do
1782 begin
1783 MainForm.pbLoad.StepIt();
1784 Application.ProcessMessages();
1786 section := 'Panel' + IntToStr(a);
1787 if not map.SectionExists(section) then
1788 Continue;
1790 panel.X := map.ReadInt(section, 'X1', 0);
1791 panel.Y := map.ReadInt(section, 'Y1', 0);
1792 panel.Height := map.ReadInt(section, 'Height', 16);
1793 panel.Width := map.ReadInt(section, 'Width', 16);
1795 case map.ReadInt(section, 'PanelType', 0) of
1796 0: panel.PanelType := PANEL_WALL;
1797 1: panel.PanelType := PANEL_BACK;
1798 2: panel.PanelType := PANEL_FORE;
1799 3: panel.PanelType := PANEL_STEP;
1800 4: panel.PanelType := PANEL_WATER;
1801 5: panel.PanelType := PANEL_ACID1;
1802 6: panel.PanelType := PANEL_ACID2;
1803 end;
1805 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1807 // Текстура панели:
1808 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_STEP] then
1809 begin
1810 s := TexturePrefix + UpperCase(map.ReadStr(section, 'TextureName', ''));
1812 if g_GetTexture(s, panel.TextureID) then
1813 begin
1814 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1815 panel.TextureName := s;
1816 end
1817 else // Нет такой текстуры - ищем в WAD карты:
1818 begin
1819 s := ExtractFileName(_FileName);
1820 Delete(s, Length(s)-3, 4);
1821 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
1823 if g_GetTexture(s, panel.TextureID) then
1824 begin
1825 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1826 panel.TextureName := s;
1827 end
1828 else
1829 Continue;
1830 end;
1831 end
1832 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1833 begin
1834 case panel.PanelType of
1835 PANEL_WATER:
1836 begin
1837 s := TEXTURE_NAME_WATER;
1838 panel.TextureID := TEXTURE_SPECIAL_WATER;
1839 end;
1840 PANEL_ACID1:
1841 begin
1842 s := TEXTURE_NAME_ACID2;
1843 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1844 end;
1845 PANEL_ACID2:
1846 begin
1847 s := TEXTURE_NAME_ACID1;
1848 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1849 end;
1850 end;
1852 with MainForm.lbTextureList.Items do
1853 if IndexOf(s) = -1 then
1854 Add(s);
1855 panel.TextureName := s;
1856 panel.TextureWidth := 1;
1857 panel.TextureHeight := 1;
1858 end;
1860 AddPanel(panel);
1861 end;
1863 // Чтение предметов:
1864 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1866 MainForm.pbLoad.Max := i;
1867 MainForm.pbLoad.Position := 0;
1868 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1870 for a := 1 to i do
1871 begin
1872 MainForm.pbLoad.StepIt();
1873 Application.ProcessMessages();
1875 section := 'Item' + IntToStr(a);
1876 if not map.SectionExists(section) then
1877 Continue;
1879 item.X := map.ReadInt(section, 'X', 0);
1880 item.Y := map.ReadInt(section, 'Y', 0);
1881 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1882 item.OnlyDM := False;
1883 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1885 // Размер предметов теперь другой:
1886 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1887 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1889 AddItem(item);
1890 end;
1892 // Чтение областей:
1893 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1895 MainForm.pbLoad.Max := i;
1896 MainForm.pbLoad.Position := 0;
1897 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1899 for a := 1 to i do
1900 begin
1901 MainForm.pbLoad.StepIt();
1902 Application.ProcessMessages();
1904 section := 'Area' + IntToStr(a);
1905 if not map.SectionExists(section) then
1906 Continue;
1908 area.X := map.ReadInt(section, 'X', 0);
1909 area.Y := map.ReadInt(section, 'Y', 0);
1910 area.AreaType := map.ReadInt(section, 'Type', 0);
1911 area.Direction := D_RIGHT;
1913 // Размер областей теперь другой:
1914 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1915 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1917 AddArea(area);
1918 end;
1920 // Чтение параметров карты:
1921 with gMapInfo do
1922 begin
1923 Name := map.ReadStr('MapOptions', 'MapName', '');
1924 Description := map.ReadStr('MapOptions', 'MapDescription', '');
1925 Author := '';
1926 MusicName := DefaultMusRes;
1927 SkyName := DefaultSkyRes;
1928 FileName := _FileName;
1929 Height := map.ReadInt('MapOptions', 'Height', 1600);
1930 Width := map.ReadInt('MapOptions', 'Width', 1600);
1932 if Length(Name) > 32 then
1933 SetLength(Name, 32);
1934 if Length(Description) > 256 then
1935 SetLength(Description, 256);
1936 end;
1938 map.Free();
1940 Result := True;
1941 end;
1943 procedure ClearMap();
1944 var
1945 a: Integer;
1947 begin
1948 if gPanels <> nil then
1949 for a := 0 to High(gPanels) do
1950 if gPanels[a].TextureName <> '' then
1951 g_DeleteTexture(gPanels[a].TextureName);
1953 SetLength(gPanels, 0);
1954 gPanels := nil;
1955 SetLength(gItems, 0);
1956 gItems := nil;
1957 SetLength(gAreas, 0);
1958 gAreas := nil;
1959 SetLength(gMonsters, 0);
1960 gMonsters := nil;
1961 SetLength(gTriggers, 0);
1962 gTriggers := nil;
1964 with gMapInfo do
1965 begin
1966 Name := '';
1967 Description := '';
1968 Author := '';
1969 MusicName := '';
1970 SkyName := '';
1971 FileName := '';
1972 Height := 1600;
1973 Width := 1600;
1974 end;
1976 with MainForm.lbTextureList do
1977 begin
1978 if Items.Count > 0 then
1979 for a := Items.Count-1 downto 0 do
1980 if not IsSpecialTexture(Items[a]) then
1981 g_DeleteTexture(Items[a]);
1983 Clear();
1984 end;
1986 MapOffset.X := 0;
1987 MapOffset.Y := 0;
1988 end;
1990 procedure DrawPanels(fPanelType: Word);
1992 procedure DrawTexture(a: Integer);
1993 var
1994 NoTextureID: DWORD;
1995 NW, NH: Word;
1996 begin
1997 NoTextureID := 0;
1998 NW := 0;
1999 NH := 0;
2000 with gPanels[a] do
2001 begin
2002 case TextureID of
2003 TEXTURE_SPECIAL_NONE:
2004 if PreviewMode = 0 then
2005 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2006 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2007 64, 64, 64, 127);
2009 TEXTURE_SPECIAL_NOTEXTURE:
2010 if g_GetTexture('NOTEXTURE', NoTextureID) then
2011 begin
2012 g_GetTextureSizeByID(NoTextureID, NW, NH);
2013 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
2014 Width div NW, Height div NH, 0, False, False);
2015 end;
2017 TEXTURE_SPECIAL_WATER:
2018 if PreviewMode > 0 then
2019 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2020 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2021 0, 0, 255, 0, B_FILTER)
2022 else
2023 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2024 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2025 0, 0, 255, 127);
2027 TEXTURE_SPECIAL_ACID1:
2028 if PreviewMode > 0 then
2029 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2030 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2031 0, 127, 0, 0, B_FILTER)
2032 else
2033 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2034 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2035 0, 255, 0, 127);
2037 TEXTURE_SPECIAL_ACID2:
2038 if PreviewMode > 0 then
2039 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2040 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2041 127, 0, 0, 0, B_FILTER)
2042 else
2043 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2044 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2045 255, 0, 0, 127);
2047 else
2048 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2049 Width div TextureWidth, Height div TextureHeight,
2050 Alpha, True, Blending);
2051 end;
2052 end;
2053 end;
2055 var
2056 a: Integer;
2057 begin
2058 if gPanels <> nil then
2059 for a := 0 to High(gPanels) do
2060 if (gPanels[a].PanelType <> 0) and
2061 WordBool(gPanels[a].PanelType and fPanelType) then
2062 with gPanels[a] do
2063 begin
2064 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2065 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2066 case PanelType of
2067 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2068 PANEL_STEP, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2069 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2070 DrawTexture(a);
2072 PANEL_LIFTUP:
2073 if PreviewMode = 0 then
2074 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2075 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2076 128, 64, 0, 0);
2077 PANEL_LIFTDOWN:
2078 if PreviewMode = 0 then
2079 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2080 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2081 90, 154, 138, 0);
2082 PANEL_LIFTLEFT:
2083 if PreviewMode = 0 then
2084 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2085 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2086 200, 80, 4, 0);
2087 PANEL_LIFTRIGHT:
2088 if PreviewMode = 0 then
2089 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2090 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2091 252, 140, 56, 0);
2092 PANEL_BLOCKMON:
2093 if PreviewMode = 0 then
2094 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2095 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2096 192, 0, 192, 0);
2097 end;
2098 end;
2099 end;
2101 procedure DrawMap();
2102 var
2103 a, w, h: Integer;
2104 ID: DWORD;
2105 xx, yy, dx, dy: Integer;
2106 ww, hh: Word;
2107 sel: Boolean;
2108 r: TRectWH;
2110 begin
2111 ID := 0;
2112 // В режиме Превью рисуем небо:
2113 if PreviewMode > 0 then
2114 begin
2115 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2116 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2117 w := Round(w*4/3);
2118 h := Round(w*3/4);
2120 if g_GetTexture(SKY_TEXTURE, ID) then
2121 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2122 else
2123 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2124 end;
2126 // Рисуем панели (если Превью или если включен слой):
2127 if LayerEnabled[LAYER_BACK] or (PreviewMode = 1) then
2128 DrawPanels(PANEL_BACK);
2129 if PreviewMode > 0 then
2130 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
2131 else
2132 if LayerEnabled[LAYER_WATER] then
2133 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
2134 PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
2135 if LayerEnabled[LAYER_WALLS] or (PreviewMode = 1) then
2136 DrawPanels(PANEL_WALL);
2137 if LayerEnabled[LAYER_STEPS] or (PreviewMode = 1) then
2138 DrawPanels(PANEL_STEP);
2140 // Рисуем предметы:
2141 if (LayerEnabled[LAYER_ITEMS] or (PreviewMode = 1)) and
2142 (gItems <> nil) then
2143 for a := 0 to High(gItems) do
2144 if gItems[a].ItemType <> ITEM_NONE then
2145 with gItems[a] do
2146 begin
2147 ID := DWORD(-1);
2149 case ItemType of
2150 0: Continue;
2151 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2152 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2153 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2154 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2155 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2156 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2157 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2158 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2159 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2160 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2161 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2162 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2163 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2164 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2165 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2166 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2167 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2168 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2169 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2170 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2171 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2172 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2173 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2174 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2175 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2176 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2177 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2178 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2179 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2180 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2181 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2182 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2183 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2184 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2185 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2186 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2187 end;
2189 if ID <> DWORD(-1) then
2190 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2191 end;
2193 // Рисуем монстров:
2194 if (LayerEnabled[LAYER_MONSTERS] or (PreviewMode = 1)) and
2195 (gMonsters <> nil) then
2196 for a := 0 to High(gMonsters) do
2197 if gMonsters[a].MonsterType <> MONSTER_NONE then
2198 with MonsterSize[gMonsters[a].MonsterType] do
2199 begin
2200 ID := DWORD(-1);
2202 case gMonsters[a].MonsterType of
2203 0: Continue;
2204 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2205 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2206 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2207 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2208 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2209 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2210 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2211 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2212 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2213 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2214 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2215 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2216 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2217 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2218 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2219 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2220 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2221 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2222 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2223 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2224 end;
2226 if ID <> DWORD(-1) then
2227 if gMonsters[a].Direction = D_LEFT then
2228 begin
2229 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2230 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2231 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2232 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2233 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2234 xx := (gMonsters[a].X - X) - xx;
2236 yy := (gMonsters[a].Y - Y) +
2237 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2239 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2240 0, True, False, M_HORIZONTAL);
2241 end
2242 else
2243 begin
2244 // Левый верхний угол текстуры + смещение анимации:
2245 xx := (gMonsters[a].X - X) +
2246 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2247 yy := (gMonsters[a].Y - Y) +
2248 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2250 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2251 0, True, False);
2252 end;
2254 // Рамка:
2255 if PreviewMode = 0 then
2256 begin
2257 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2258 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2259 255, 255, 255);
2260 end;
2261 end;
2263 // Рисуем закрытые двери после монстров:
2264 if ((PreviewMode = 2) and LayerEnabled[LAYER_WATER])
2265 or (PreviewMode = 1) then
2266 DrawPanels(PANEL_CLOSEDOOR);
2268 // Рисуем области:
2269 if (LayerEnabled[LAYER_AREAS] or (PreviewMode = 1)) and
2270 (gAreas <> nil) then
2271 for a := 0 to High(gAreas) do
2272 if gAreas[a].AreaType <> AREA_NONE then
2273 with AreaSize[gAreas[a].AreaType] do
2274 begin
2275 ID := DWORD(-1);
2277 case gAreas[a].AreaType of
2278 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2279 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2280 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2281 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2282 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2283 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2284 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2285 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2286 end;
2288 if (PreviewMode = 0) or
2289 (gAreas[a].AreaType = AREA_REDFLAG) or
2290 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2291 (gAreas[a].AreaType = AREA_DOMFLAG) then
2292 if ID <> DWORD(-1) then
2293 if gAreas[a].Direction = D_LEFT then
2294 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2295 0, True, False, M_HORIZONTAL)
2296 else
2297 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2298 0, True, False);
2300 // Рамка:
2301 if PreviewMode = 0 then
2302 begin
2303 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2304 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2305 255, 255, 255);
2307 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2308 end;
2309 end;
2311 // Рисуем жидкости и передний план после областей:
2312 if LayerEnabled[LAYER_WATER] or (PreviewMode = 1) then
2313 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2314 if LayerEnabled[LAYER_FOREGROUND] or (PreviewMode = 1) then
2315 DrawPanels(PANEL_FORE);
2317 // Рисуем триггеры:
2318 if LayerEnabled[LAYER_TRIGGERS] and
2319 (PreviewMode = 0) and (gTriggers <> nil) then
2320 for a := 0 to High(gTriggers) do
2321 with gTriggers[a] do
2322 if TriggerType <> TRIGGER_NONE then
2323 begin
2324 // Если выбран - рисуем красным, иначе - белым:
2325 sel := ObjectSelected(OBJECT_TRIGGER, a);
2327 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2328 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2329 0, 0, 0, 150);
2331 if TexturePanel <> -1 then
2332 begin
2333 with gPanels[TexturePanel] do
2334 begin
2335 xx := X;
2336 yy := Y;
2337 ww := Width;
2338 hh := Height;
2339 end;
2341 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2342 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2343 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2344 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2345 MapOffset.X+xx, MapOffset.Y+yy,
2346 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2347 end;
2349 case TriggerType of
2350 TRIGGER_EXIT: ;
2352 TRIGGER_TELEPORT:
2353 begin
2354 // Точка назначения Телепорта:
2355 if Data.d2d_teleport then
2356 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2357 MapOffset.Y+Data.TargetPoint.Y-1,
2358 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2359 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2360 else
2361 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2362 MapOffset.Y+Data.TargetPoint.Y,
2363 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2364 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2365 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2366 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2367 MapOffset.Y+Data.TargetPoint.Y,
2368 255, 0, 0);
2369 // Линия к точке назначения Телепорта:
2370 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2371 MapOffset.Y+Y+(Height div 2),
2372 MapOffset.X+Data.TargetPoint.X,
2373 MapOffset.Y+Data.TargetPoint.Y,
2374 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2375 end;
2377 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2378 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2379 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2380 TRIGGER_LIFT:
2381 if Data.PanelID <> -1 then
2382 begin
2383 // Дверь/Ловушка/Лифт:
2384 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2385 MapOffset.Y+gPanels[Data.PanelID].Y,
2386 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2387 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2388 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2389 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2390 MapOffset.Y+gPanels[Data.PanelID].Y,
2391 255, 0, 0);
2392 // Линия к Двери/Ловушке/Лифту:
2393 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2394 MapOffset.Y+Y+(Height div 2),
2395 MapOffset.X+gPanels[Data.PanelID].X,
2396 MapOffset.Y+gPanels[Data.PanelID].Y,
2397 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2398 end;
2400 TRIGGER_PRESS, TRIGGER_ON,
2401 TRIGGER_OFF, TRIGGER_ONOFF:
2402 begin
2403 if (Data.tWidth > 0) and
2404 (Data.tHeight > 0) then
2405 begin
2406 // Область Расширителя:
2407 e_DrawQuad(MapOffset.X+Data.tX,
2408 MapOffset.Y+Data.tY,
2409 MapOffset.X+Data.tX+Data.tWidth-1,
2410 MapOffset.Y+Data.tY+Data.tHeight-1,
2411 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2412 e_DrawPoint(2, MapOffset.X+Data.tX,
2413 MapOffset.Y+Data.tY,
2414 255, 0, 0);
2415 // Линия к области Расширителя:
2416 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2417 MapOffset.Y+Y+(Height div 2),
2418 MapOffset.X+Data.tX,
2419 MapOffset.Y+Data.tY,
2420 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2421 end;
2423 if Data.MonsterID <> 0 then
2424 if (gMonsters <> nil) and
2425 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2426 begin
2427 // Рамка вокруг Монстра - условия активации:
2428 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2429 e_DrawQuad(MapOffset.X+r.X,
2430 MapOffset.Y+r.Y,
2431 MapOffset.X+r.X+r.Width-1,
2432 MapOffset.Y+r.Y+r.Height-1,
2433 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2434 // Линия к Монстру - условию активации:
2435 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2436 MapOffset.Y+Y+(Height div 2),
2437 MapOffset.X+r.X,
2438 MapOffset.Y+r.Y,
2439 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2441 end;
2442 end;
2444 TRIGGER_SECRET: ;
2446 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2447 begin
2448 if TriggerType = TRIGGER_SPAWNMONSTER then
2449 begin
2450 xx := Data.MonPos.X;
2451 yy := Data.MonPos.Y;
2452 end
2453 else
2454 begin
2455 xx := Data.ItemPos.X;
2456 yy := Data.ItemPos.Y;
2457 end;
2458 // Точка появления Монстра/Предмета:
2459 e_DrawLine(2, MapOffset.X+xx-16,
2460 MapOffset.Y+yy-1,
2461 MapOffset.X+xx+16,
2462 MapOffset.Y+yy-1,
2463 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2464 e_DrawPoint(2, MapOffset.X+xx,
2465 MapOffset.Y+yy,
2466 255, 0, 0);
2467 // Линия к точке появления Монстра/Предмета:
2468 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2469 MapOffset.Y+Y+(Height div 2),
2470 MapOffset.X+xx,
2471 MapOffset.Y+yy,
2472 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2473 // Предпросмотр создаваемого объекта:
2474 if sel then
2475 begin
2476 // Монстр:
2477 if TriggerType = TRIGGER_SPAWNMONSTER then
2478 begin
2479 if Data.MonType <> MONSTER_NONE then
2480 with MonsterSize[Data.MonType] do
2481 begin
2482 ID := DWORD(-1);
2483 case Data.MonType of
2484 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2485 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2486 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2487 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2488 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2489 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2490 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2491 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2492 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2493 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2494 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2495 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2496 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2497 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2498 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2499 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2500 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2501 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2502 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2503 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2504 end;
2505 if ID <> DWORD(-1) then
2506 begin
2507 if Data.MonDir = Byte(D_LEFT) then
2508 begin
2509 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2510 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2511 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2513 yy := Data.TargetPoint.Y - Y +
2514 MonsterSizeDelta[Data.MonType].Y-Height;
2516 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2517 128, True, False, M_HORIZONTAL);
2518 end
2519 else
2520 begin
2521 xx := Data.TargetPoint.X - X +
2522 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2523 yy := Data.TargetPoint.Y - Y +
2524 MonsterSizeDelta[Data.MonType].Y-Height;
2526 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2527 128, True, False);
2528 end;
2529 // Рамка:
2530 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2531 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2532 255, 255, 0, 128);
2533 end;
2534 end;
2535 end
2536 else
2537 // Предмет:
2538 begin
2539 if Data.ItemType <> ITEM_NONE then
2540 begin
2541 ID := DWORD(-1);
2542 case Data.ItemType of
2543 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2544 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2545 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2546 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2547 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2548 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2549 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2550 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2551 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2552 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2553 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2554 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2555 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2556 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2557 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2558 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2559 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2560 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2561 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2562 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2563 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2564 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2565 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2566 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2567 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2568 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2569 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2570 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2571 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2572 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2573 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2574 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2575 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2576 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2577 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2578 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2579 end;
2580 if ID <> DWORD(-1) then
2581 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2582 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2583 128, True, False);
2584 // Рамка:
2585 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2586 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2587 255, 255, 0, 128);
2588 end;
2589 end;
2590 end;
2591 end;
2593 TRIGGER_PUSH:
2594 begin
2595 // Линия направления и силы ускорения:
2596 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2597 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2598 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2599 MapOffset.Y+Y+(Height div 2),
2600 MapOffset.X+xx,
2601 MapOffset.Y+yy,
2602 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2603 end;
2605 TRIGGER_SHOT:
2606 begin;
2607 xx := Data.ShotPos.X;
2608 yy := Data.ShotPos.Y;
2609 // Точка появления снаряда:
2610 e_DrawPoint(2, MapOffset.X+xx,
2611 MapOffset.Y+yy,
2612 255, 0, 0);
2613 // Линия к точке появления снаряда:
2614 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2615 MapOffset.Y+Y+(Height div 2),
2616 MapOffset.X+xx,
2617 MapOffset.Y+yy,
2618 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2619 // Линия направления выстрела:
2620 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2621 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2622 e_DrawLine(1, MapOffset.X+xx,
2623 MapOffset.Y+yy,
2624 MapOffset.X+xx+dx,
2625 MapOffset.Y+yy+dy,
2626 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2628 if (Data.ShotPanelID <> -1) and
2629 (Data.ShotPanelID <= High(gPanels)) then
2630 begin
2631 // Линия к панели индикации выстрела
2632 with gPanels[Data.ShotPanelID] do
2633 begin
2634 xx := X;
2635 yy := Y;
2636 ww := Width;
2637 hh := Height;
2638 end;
2640 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2641 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2642 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2643 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2644 MapOffset.X+xx, MapOffset.Y+yy,
2645 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2646 end;
2647 end;
2648 end;
2649 end;
2651 // Границы карты:
2652 if PreviewMode = 0 then
2653 begin
2654 e_DrawFillQuad(-32+MapOffset.X,
2655 -32+MapOffset.Y,
2656 gMapInfo.Width+31+MapOffset.X,
2657 -1+MapOffset.Y,
2658 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2659 e_DrawFillQuad(-32+MapOffset.X,
2660 gMapInfo.Height+MapOffset.Y,
2661 gMapInfo.Width+31+MapOffset.X,
2662 gMapInfo.Height+31+MapOffset.Y,
2663 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2664 e_DrawFillQuad(-32+MapOffset.X,
2665 MapOffset.Y,
2666 -1+MapOffset.X,
2667 gMapInfo.Height+MapOffset.Y-1,
2668 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2669 e_DrawFillQuad(gMapInfo.Width+MapOffset.X,
2670 MapOffset.Y,
2671 gMapInfo.Width+31+MapOffset.X,
2672 gMapInfo.Height+MapOffset.Y-1,
2673 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2674 end;
2675 end;
2677 procedure ShiftMapObjects(dx, dy: Integer);
2678 var
2679 i: Integer;
2680 begin
2681 if gPanels <> nil then
2682 for i := 0 to High(gPanels) do
2683 if gPanels[i].PanelType <> 0 then
2684 begin
2685 Inc(gPanels[i].X, dx);
2686 Inc(gPanels[i].Y, dy);
2687 end;
2689 if gItems <> nil then
2690 for i := 0 to High(gItems) do
2691 if gItems[i].ItemType <> 0 then
2692 begin
2693 Inc(gItems[i].X, dx);
2694 Inc(gItems[i].Y, dy);
2695 end;
2697 if gAreas <> nil then
2698 for i := 0 to High(gAreas) do
2699 if gAreas[i].AreaType <> 0 then
2700 begin
2701 Inc(gAreas[i].X, dx);
2702 Inc(gAreas[i].Y, dy);
2703 end;
2705 if gMonsters <> nil then
2706 for i := 0 to High(gMonsters) do
2707 if gMonsters[i].MonsterType <> 0 then
2708 begin
2709 Inc(gMonsters[i].X, dx);
2710 Inc(gMonsters[i].Y, dy);
2711 end;
2713 if gTriggers <> nil then
2714 for i := 0 to High(gTriggers) do
2715 if gTriggers[i].TriggerType <> 0 then
2716 begin
2717 Inc(gTriggers[i].X, dx);
2718 Inc(gTriggers[i].Y, dy);
2720 case gTriggers[i].TriggerType of
2721 TRIGGER_TELEPORT:
2722 begin
2723 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2724 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2725 end;
2727 TRIGGER_PRESS, TRIGGER_ON,
2728 TRIGGER_OFF, TRIGGER_ONOFF:
2729 begin
2730 Inc(gTriggers[i].Data.tX, dx);
2731 Inc(gTriggers[i].Data.tY, dy);
2732 end;
2734 TRIGGER_SPAWNMONSTER:
2735 begin
2736 Inc(gTriggers[i].Data.MonPos.X, dx);
2737 Inc(gTriggers[i].Data.MonPos.Y, dy);
2738 end;
2740 TRIGGER_SPAWNITEM:
2741 begin
2742 Inc(gTriggers[i].Data.ItemPos.X, dx);
2743 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2744 end;
2746 TRIGGER_SHOT:
2747 begin
2748 Inc(gTriggers[i].Data.ShotPos.X, dx);
2749 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2750 end;
2751 end;
2752 end;
2753 end;
2755 procedure LoadData();
2756 begin
2757 g_CreateTextureWAD('PREVIEW', EditorDir+'data/Editor.wad:TEXTURES\CHECKERS');
2758 g_CreateTextureWAD('NOTEXTURE', EditorDir+'data/Game.wad:TEXTURES\NOTEXTURE');
2760 g_CreateTextureWADSize('AREA_REDFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGRED', 0, 0, 64, 64);
2761 g_CreateTextureWADSize('AREA_BLUEFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2762 g_CreateTextureWADSize('AREA_DOMFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGDOM', 0, 0, 64, 64);
2764 g_CreateTextureWADSize('MONSTER_DEMON', EditorDir+'data/Game.wad:MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2765 g_CreateTextureWADSize('MONSTER_IMP', EditorDir+'data/Game.wad:MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2766 g_CreateTextureWADSize('MONSTER_ZOMBY', EditorDir+'data/Game.wad:MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2767 g_CreateTextureWADSize('MONSTER_SERG', EditorDir+'data/Game.wad:MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2768 g_CreateTextureWADSize('MONSTER_CYBER', EditorDir+'data/Game.wad:MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2769 g_CreateTextureWADSize('MONSTER_CGUN', EditorDir+'data/Game.wad:MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2770 g_CreateTextureWADSize('MONSTER_BARON', EditorDir+'data/Game.wad:MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2771 g_CreateTextureWADSize('MONSTER_KNIGHT', EditorDir+'data/Game.wad:MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2772 g_CreateTextureWADSize('MONSTER_CACO', EditorDir+'data/Game.wad:MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2773 g_CreateTextureWADSize('MONSTER_SOUL', EditorDir+'data/Game.wad:MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2774 g_CreateTextureWADSize('MONSTER_PAIN', EditorDir+'data/Game.wad:MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2775 g_CreateTextureWADSize('MONSTER_SPIDER', EditorDir+'data/Game.wad:MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2776 g_CreateTextureWADSize('MONSTER_BSP', EditorDir+'data/Game.wad:MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2777 g_CreateTextureWADSize('MONSTER_MANCUB', EditorDir+'data/Game.wad:MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2778 g_CreateTextureWADSize('MONSTER_SKEL', EditorDir+'data/Game.wad:MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2779 g_CreateTextureWADSize('MONSTER_VILE', EditorDir+'data/Game.wad:MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2780 g_CreateTextureWADSize('MONSTER_FISH', EditorDir+'data/Game.wad:MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2781 g_CreateTextureWADSize('MONSTER_BARREL', EditorDir+'data/Game.wad:MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2782 g_CreateTextureWADSize('MONSTER_ROBO', EditorDir+'data/Game.wad:MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2783 g_CreateTextureWADSize('MONSTER_MAN', EditorDir+'data/Game.wad:MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2785 g_CreateTextureWADSize('ITEM_BLUESPHERE', EditorDir+'data/Game.wad:TEXTURES\SBLUE', 0, 0, 32, 32);
2786 g_CreateTextureWADSize('ITEM_WHITESPHERE', EditorDir+'data/Game.wad:TEXTURES\SWHITE', 0, 0, 32, 32);
2787 g_CreateTextureWADSize('ITEM_ARMORGREEN', EditorDir+'data/Game.wad:TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2788 g_CreateTextureWADSize('ITEM_ARMORBLUE', EditorDir+'data/Game.wad:TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2789 g_CreateTextureWADSize('ITEM_INVUL', EditorDir+'data/Game.wad:TEXTURES\INVUL', 0, 0, 32, 32);
2790 g_CreateTextureWADSize('ITEM_BOTTLE', EditorDir+'data/Game.wad:TEXTURES\BOTTLE', 0, 0, 16, 32);
2791 g_CreateTextureWADSize('ITEM_HELMET', EditorDir+'data/Game.wad:TEXTURES\HELMET', 0, 0, 16, 16);
2792 g_CreateTextureWADSize('ITEM_INVIS', EditorDir+'data/Game.wad:TEXTURES\INVIS', 0, 0, 32, 32);
2793 g_CreateTextureWADSize('ITEM_WEAPON_FLAMETHROWER', EditorDir+'data/Game.wad:TEXTURES\FLAMETHROWER', 0, 0, 64, 32);
2794 g_CreateTextureWADSize('ITEM_AMMO_FUELCAN', EditorDir+'data/Game.wad:TEXTURES\FUELCAN', 0, 0, 16, 32);
2796 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', EditorDir+'data/Game.wad:TEXTURES\MED1');
2797 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', EditorDir+'data/Game.wad:TEXTURES\MED2');
2798 g_CreateTextureWAD('ITEM_WEAPON_SAW', EditorDir+'data/Game.wad:TEXTURES\SAW');
2799 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', EditorDir+'data/Game.wad:TEXTURES\PISTOL');
2800 g_CreateTextureWAD('ITEM_WEAPON_KASTET', EditorDir+'data/Game.wad:TEXTURES\KASTET');
2801 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', EditorDir+'data/Game.wad:TEXTURES\SHOTGUN1');
2802 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', EditorDir+'data/Game.wad:TEXTURES\SHOTGUN2');
2803 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', EditorDir+'data/Game.wad:TEXTURES\MGUN');
2804 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', EditorDir+'data/Game.wad:TEXTURES\RLAUNCHER');
2805 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', EditorDir+'data/Game.wad:TEXTURES\PGUN');
2806 g_CreateTextureWAD('ITEM_WEAPON_BFG', EditorDir+'data/Game.wad:TEXTURES\BFG');
2807 g_CreateTextureWAD('ITEM_WEAPON_SUPERPULEMET', EditorDir+'data/Game.wad:TEXTURES\SPULEMET');
2808 g_CreateTextureWAD('ITEM_AMMO_BULLETS', EditorDir+'data/Game.wad:TEXTURES\CLIP');
2809 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', EditorDir+'data/Game.wad:TEXTURES\AMMO');
2810 g_CreateTextureWAD('ITEM_AMMO_SHELLS', EditorDir+'data/Game.wad:TEXTURES\SHELL1');
2811 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', EditorDir+'data/Game.wad:TEXTURES\SHELL2');
2812 g_CreateTextureWAD('ITEM_AMMO_ROCKET', EditorDir+'data/Game.wad:TEXTURES\ROCKET');
2813 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', EditorDir+'data/Game.wad:TEXTURES\ROCKETS');
2814 g_CreateTextureWAD('ITEM_AMMO_CELL', EditorDir+'data/Game.wad:TEXTURES\CELL');
2815 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', EditorDir+'data/Game.wad:TEXTURES\CELL2');
2816 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', EditorDir+'data/Game.wad:TEXTURES\BPACK');
2817 g_CreateTextureWAD('ITEM_KEY_RED', EditorDir+'data/Game.wad:TEXTURES\KEYR');
2818 g_CreateTextureWAD('ITEM_KEY_GREEN', EditorDir+'data/Game.wad:TEXTURES\KEYG');
2819 g_CreateTextureWAD('ITEM_KEY_BLUE', EditorDir+'data/Game.wad:TEXTURES\KEYB');
2820 g_CreateTextureWAD('ITEM_OXYGEN', EditorDir+'data/Game.wad:TEXTURES\OXYGEN');
2821 g_CreateTextureWAD('ITEM_SUIT', EditorDir+'data/Game.wad:TEXTURES\SUIT');
2822 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', EditorDir+'data/Game.wad:TEXTURES\BMED');
2823 g_CreateTextureWAD('ITEM_JETPACK', EditorDir+'data/Game.wad:TEXTURES\JETPACK');
2825 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorDir+'data/Editor.wad:TEXTURES\P1POINT');
2826 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorDir+'data/Editor.wad:TEXTURES\P2POINT');
2827 g_CreateTextureWAD('AREA_DMPOINT', EditorDir+'data/Editor.wad:TEXTURES\DMPOINT');
2828 g_CreateTextureWAD('AREA_REDPOINT', EditorDir+'data/Editor.wad:TEXTURES\REDPOINT');
2829 g_CreateTextureWAD('AREA_BLUEPOINT', EditorDir+'data/Editor.wad:TEXTURES\BLUEPOINT');
2830 end;
2832 procedure FreeData();
2833 begin
2834 g_DeleteTexture('NOTEXTURE');
2836 g_DeleteTexture('ITEM_BLUESPHERE');
2837 g_DeleteTexture('ITEM_WHITESPHERE');
2838 g_DeleteTexture('ITEM_ARMORGREEN');
2839 g_DeleteTexture('ITEM_ARMORBLUE');
2840 g_DeleteTexture('ITEM_INVUL');
2841 g_DeleteTexture('ITEM_BOTTLE');
2842 g_DeleteTexture('ITEM_HELMET');
2843 g_DeleteTexture('AREA_REDFLAG');
2844 g_DeleteTexture('AREA_BLUEFLAG');
2845 g_DeleteTexture('AREA_DOMFLAG');
2847 g_DeleteTexture('MONSTER_DEMON');
2848 g_DeleteTexture('MONSTER_IMP');
2849 g_DeleteTexture('MONSTER_ZOMBY');
2850 g_DeleteTexture('MONSTER_SERG');
2851 g_DeleteTexture('MONSTER_CGUN');
2852 g_DeleteTexture('MONSTER_BARREL');
2853 g_DeleteTexture('MONSTER_MAN');
2855 g_DeleteTexture('MONSTER_DEMON');
2856 g_DeleteTexture('MONSTER_IMP');
2857 g_DeleteTexture('MONSTER_ZOMBY');
2858 g_DeleteTexture('MONSTER_SERG');
2859 g_DeleteTexture('MONSTER_CYBER');
2860 g_DeleteTexture('MONSTER_CGUN');
2861 g_DeleteTexture('MONSTER_BARON');
2862 g_DeleteTexture('MONSTER_KNIGHT');
2863 g_DeleteTexture('MONSTER_CACO');
2864 g_DeleteTexture('MONSTER_SOUL');
2865 g_DeleteTexture('MONSTER_PAIN');
2866 g_DeleteTexture('MONSTER_SPIDER');
2867 g_DeleteTexture('MONSTER_BSP');
2868 g_DeleteTexture('MONSTER_MANCUB');
2869 g_DeleteTexture('MONSTER_SKEL');
2870 g_DeleteTexture('MONSTER_VILE');
2871 g_DeleteTexture('MONSTER_FISH');
2872 g_DeleteTexture('MONSTER_BARREL');
2873 g_DeleteTexture('MONSTER_ROBO');
2874 g_DeleteTexture('MONSTER_MAN');
2876 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2877 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2878 g_DeleteTexture('ITEM_WEAPON_SAW');
2879 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2880 g_DeleteTexture('ITEM_WEAPON_KASTET');
2881 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2882 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2883 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2884 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
2885 g_DeleteTexture('ITEM_WEAPON_PLASMA');
2886 g_DeleteTexture('ITEM_WEAPON_BFG');
2887 g_DeleteTexture('ITEM_WEAPON_SUPERPULEMET');
2888 g_DeleteTexture('ITEM_AMMO_BULLETS');
2889 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
2890 g_DeleteTexture('ITEM_AMMO_SHELLS');
2891 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
2892 g_DeleteTexture('ITEM_AMMO_ROCKET');
2893 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
2894 g_DeleteTexture('ITEM_AMMO_CELL');
2895 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
2896 g_DeleteTexture('ITEM_AMMO_BACKPACK');
2897 g_DeleteTexture('ITEM_KEY_RED');
2898 g_DeleteTexture('ITEM_KEY_GREEN');
2899 g_DeleteTexture('ITEM_KEY_BLUE');
2900 g_DeleteTexture('ITEM_OXYGEN');
2901 g_DeleteTexture('ITEM_SUIT');
2902 g_DeleteTexture('ITEM_MEDKIT_BLACK');
2903 g_DeleteTexture('ITEM_JETPACK');
2904 g_DeleteTexture('ITEM_INVIS');
2905 g_DeleteTexture('ITEM_WEAPON_FLAMETHROWER');
2906 g_DeleteTexture('ITEM_AMMO_FUELCAN');
2908 g_DeleteTexture('AREA_PLAYERPOINT1');
2909 g_DeleteTexture('AREA_PLAYERPOINT2');
2910 g_DeleteTexture('AREA_DMPOINT');
2911 g_DeleteTexture('AREA_REDPOINT');
2912 g_DeleteTexture('AREA_BLUEPOINT');
2913 end;
2915 end.