DEADSOFTWARE

changed some backslashes to forward slashes
[d2df-editor.git] / src / editor / g_map.pas
1 Unit g_map;
3 {$MODE Delphi}
5 Interface
7 Uses
8 LCLIntf, LCLType, LMessages, g_basic, e_graphics, MAPREADER, MAPSTRUCT,
9 MAPWRITER, e_log, MAPDEF;
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;
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;
1069 // Открываем WAD, если надо:
1070 if Res <> '' then
1071 begin
1072 WAD := TWADEditor_1.Create();
1073 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1074 if not WAD.ReadFile(FileName) then
1075 WAD.FreeWAD();
1077 WAD.CreateImage();
1078 end;
1080 MapWriter := TMapWriter_1.Create();
1082 // Сохраняем заголовок:
1083 with header do
1084 begin
1085 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1087 if gMapInfo.Name <> '' then
1088 CopyMemory(@MapName[0], @gMapInfo.Name[1], Min(32, Length(gMapInfo.Name)));
1090 if gMapInfo.Description <> '' then
1091 CopyMemory(@MapDescription[0], @gMapInfo.Description[1], Min(256, Length(gMapInfo.Description)));
1093 if gMapInfo.Author <> '' then
1094 CopyMemory(@MapAuthor[0], @gMapInfo.Author[1], Min(32, Length(gMapInfo.Author)));
1096 if gMapInfo.MusicName <> '' then
1097 CopyMemory(@MusicName[0], @gMapInfo.MusicName[1], Min(64, Length(gMapInfo.MusicName)));
1099 if gMapInfo.SkyName <> '' then
1100 CopyMemory(@SkyName[0], @gMapInfo.SkyName[1], Min(64, Length(gMapInfo.SkyName)));
1102 Width := gMapInfo.Width;
1103 Height := gMapInfo.Height;
1104 end;
1106 MapWriter.AddHeader(header);
1108 // Сохраняем названия текстур:
1109 if MainForm.lbTextureList.Items.Count > 0 then
1110 begin
1111 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1112 begin
1113 SetLength(textures, Length(textures)+1);
1114 s := MainForm.lbTextureList.Items[a];
1115 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1116 if g_GetTextureFlagByName(s) = 1 then
1117 textures[High(textures)].Anim := 1
1118 else
1119 textures[High(textures)].Anim := 0;
1120 end;
1122 MapWriter.AddTextures(textures);
1123 end;
1125 // Сохраняем панели:
1126 if gPanels <> nil then
1127 begin
1128 c := 0;
1130 for a := 0 to High(gPanels) do
1131 if gPanels[a].PanelType <> 0 then
1132 begin
1133 SetLength(PanelTable, Length(PanelTable)+1);
1134 PanelTable[High(PanelTable)][0] := a;
1135 PanelTable[High(PanelTable)][1] := c;
1136 c := c + 1;
1138 SetLength(panels, Length(panels)+1);
1140 with panels[High(panels)] do
1141 begin
1142 X := gPanels[a].X;
1143 Y := gPanels[a].Y;
1144 Width := gPanels[a].Width;
1145 Height := gPanels[a].Height;
1146 PanelType := gPanels[a].PanelType;
1147 Alpha := gPanels[a].Alpha;
1149 TextureNum := 0;
1150 Flags := 0;
1152 if WordBool(gPanels[a].PanelType and
1153 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1154 Flags := PANEL_FLAG_WATERTEXTURES;
1156 // Может быть текстура:
1157 if not WordBool(gPanels[a].PanelType and
1158 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1159 begin
1160 if gPanels[a].Blending then
1161 Flags := Flags or PANEL_FLAG_BLENDING;
1162 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1163 Flags := Flags or PANEL_FLAG_HIDE;
1165 // Номер текстуры в списке текстур:
1166 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1167 for b := 0 to High(textures) do
1168 if gPanels[a].TextureName = textures[b].Resource then
1169 begin
1170 TextureNum := b;
1171 Break;
1172 end;
1173 end;
1174 end;
1175 end;
1177 MapWriter.AddPanels(panels);
1178 end;
1180 // Сохраняем предметы:
1181 if gItems <> nil then
1182 begin
1183 for a := 0 to High(gItems) do
1184 if gItems[a].ItemType <> 0 then
1185 begin
1186 SetLength(items, Length(items)+1);
1188 with items[High(items)] do
1189 begin
1190 X := gItems[a].X;
1191 Y := gItems[a].Y;
1192 ItemType := gItems[a].ItemType;
1193 if gItems[a].OnlyDM then
1194 Options := Options or ITEM_OPTION_ONLYDM;
1195 if gItems[a].Fall then
1196 Options := Options or ITEM_OPTION_FALL;
1197 end;
1198 end;
1200 MapWriter.AddItems(items);
1201 end;
1203 // Сохраняем монстров:
1204 if gMonsters <> nil then
1205 begin
1206 c := 0;
1208 for a := 0 to High(gMonsters) do
1209 if gMonsters[a].MonsterType <> 0 then
1210 begin
1211 SetLength(MonsterTable, Length(MonsterTable)+1);
1212 MonsterTable[High(MonsterTable)][0] := a;
1213 MonsterTable[High(MonsterTable)][1] := c;
1214 c := c + 1;
1216 SetLength(monsters, Length(monsters)+1);
1218 with monsters[High(monsters)] do
1219 begin
1220 X := gMonsters[a].X;
1221 Y := gMonsters[a].Y;
1222 MonsterType := gMonsters[a].MonsterType;
1223 Direction := Ord(gMonsters[a].Direction);
1224 end;
1225 end;
1227 MapWriter.AddMonsters(monsters);
1228 end;
1230 // Сохраняем области:
1231 if gAreas <> nil then
1232 begin
1233 for a := 0 to High(gAreas) do
1234 if gAreas[a].AreaType <> 0 then
1235 begin
1236 SetLength(areas, Length(areas)+1);
1238 with areas[High(areas)] do
1239 begin
1240 X := gAreas[a].X;
1241 Y := gAreas[a].Y;
1242 AreaType := gAreas[a].AreaType;
1243 Direction := Ord(gAreas[a].Direction);
1244 end;
1245 end;
1247 MapWriter.AddAreas(areas);
1248 end;
1250 // Сохраняем триггеры:
1251 if gTriggers <> nil then
1252 begin
1253 for a := 0 to High(gTriggers) do
1254 if gTriggers[a].TriggerType <> 0 then
1255 begin
1256 SetLength(triggers, Length(triggers)+1);
1258 with triggers[High(triggers)] do
1259 begin
1260 X := gTriggers[a].X;
1261 Y := gTriggers[a].Y;
1262 Width := gTriggers[a].Width;
1263 Height := gTriggers[a].Height;
1264 Enabled := Byte(gTriggers[a].Enabled);
1265 TexturePanel := -1;
1266 TriggerType := gTriggers[a].TriggerType;
1267 ActivateType := gTriggers[a].ActivateType;
1268 Keys := gTriggers[a].Key;
1269 DATA := gTriggers[a].Data.Default;
1271 if PanelTable <> nil then
1272 begin
1273 // Ищем номер панели, которой этот триггер меняет текстуру:
1274 if gTriggers[a].TexturePanel <> -1 then
1275 begin
1276 for c := 0 to High(PanelTable) do
1277 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1278 TexturePanel := PanelTable[c][1];
1279 end;
1281 // Ищем номер панели, которую меняет этот триггер:
1282 if gTriggers[a].TriggerType in [
1283 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1284 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1285 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1286 if TTriggerData(DATA).PanelID <> -1 then
1287 for c := 0 to High(PanelTable) do
1288 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1289 begin
1290 TTriggerData(DATA).PanelID := PanelTable[c][1];
1291 Break;
1292 end;
1294 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1295 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1296 (TTriggerData(DATA).ShotPanelID <> -1) then
1297 begin
1298 for c := 0 to High(PanelTable) do
1299 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1300 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1301 end;
1302 end;
1304 if MonsterTable <> nil then
1305 begin
1306 // Ищем номер монстра - условие активации триггера:
1307 if gTriggers[a].TriggerType in [
1308 TRIGGER_PRESS, TRIGGER_ON,
1309 TRIGGER_OFF, TRIGGER_ONOFF] then
1310 if TTriggerData(DATA).MonsterID <> 0 then
1311 for c := 0 to High(MonsterTable) do
1312 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1313 begin
1314 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1315 Break;
1316 end;
1317 end;
1318 end;
1319 end;
1321 MapWriter.AddTriggers(triggers);
1322 end;
1324 // Сохраняем карту в память:
1325 Len := MapWriter.SaveMap(Data);
1327 MapWriter.Free();
1329 // Записываем в WAD, если надо:
1330 if Res <> '' then
1331 begin
1332 WAD.RemoveResource('', ResName);
1333 WAD.AddResource(Data, Len, ResName, '');
1334 WAD.SaveTo(FileName);
1336 FreeMem(Data);
1337 WAD.Free();
1339 Result := nil;
1340 end
1341 else
1342 Result := Data;
1343 end;
1345 procedure AddTexture(res: String; Error: Boolean);
1346 var
1347 a: Integer;
1348 begin
1349 with MainForm.lbTextureList do
1350 begin
1351 for a := 0 to Count-1 do
1352 if Items[a] = res then
1353 Exit;
1355 if Error and (slInvalidTextures.IndexOf(res) = -1) then
1356 slInvalidTextures.Add(res);
1357 Items.Add(res);
1358 end;
1359 end;
1361 function LoadMap(Res: String): Boolean;
1362 var
1363 WAD: TWADEditor_1;
1364 MapReader: TMapReader_1;
1365 Header: TMapHeaderRec_1;
1366 textures: TTexturesRec1Array;
1367 panels: TPanelsRec1Array;
1368 items: TItemsRec1Array;
1369 monsters: TMonsterRec1Array;
1370 areas: TAreasRec1Array;
1371 triggers: TTriggersRec1Array;
1372 panel: TPanel;
1373 item: TItem;
1374 monster: TMonster;
1375 area: TArea;
1376 trigger: TTrigger;
1377 a: Integer;
1378 Data: Pointer;
1379 Width, Height, m: Word;
1380 FileName, SectionName, ResName, _fn: String;
1381 TextureRes: String;
1382 pData: Pointer;
1383 Len, FrameLen: Integer;
1384 Error: Boolean;
1385 NoTextureID: DWORD;
1386 NW, NH: Word;
1387 begin
1388 Result := False;
1390 MainForm.pbLoad.Position := 0;
1391 MainForm.lLoad.Caption := _lc[I_LOAD_WAD];
1392 Application.ProcessMessages();
1394 // Открываем WAD:
1395 WAD := TWADEditor_1.Create();
1396 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1398 if not WAD.ReadFile(FileName) then
1399 begin
1400 WAD.Free();
1401 Exit;
1402 end;
1404 // Читаем ресурс карты:
1405 if not WAD.GetResource('', ResName, pData, Len) then
1406 begin
1407 WAD.Free();
1408 Exit;
1409 end;
1411 WAD.Free();
1413 MapReader := TMapReader_1.Create();
1415 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];
1416 Application.ProcessMessages();
1418 MapReader.LoadMap(pData);
1420 // Загружаем текстуры:
1421 textures := MapReader.GetTextures();
1423 if textures <> nil then
1424 begin
1425 MainForm.pbLoad.Position := 0;
1426 MainForm.pbLoad.Max := Length(textures);
1427 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1429 for a := 0 to High(textures) do
1430 begin
1431 MainForm.pbLoad.StepIt();
1432 Application.ProcessMessages();
1434 if IsSpecialTexture(textures[a].Resource) then
1435 begin
1436 AddTexture(textures[a].Resource, False);
1437 Continue;
1438 end;
1440 g_ProcessResourceStr(textures[a].Resource, @_fn, nil, nil);
1442 if _fn = '' then
1443 TextureRes := FileName + textures[a].Resource
1444 else
1445 TextureRes := EditorDir+'wads/'+textures[a].Resource;
1447 Error := False;
1449 if not ByteBool(textures[a].Anim) then
1450 begin // Обычная текстура
1451 if not g_CreateTextureWAD(textures[a].Resource, TextureRes) then
1452 begin
1453 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s',
1454 [textures[a].Resource]), MSG_WARNING);
1455 Error := True;
1456 end;
1458 AddTexture(textures[a].Resource, Error);
1459 end
1460 else // Anim
1461 begin // Анимированная текстура
1462 if not GetFrame(TextureRes, Data, FrameLen, Width, Height) then
1463 begin // Кадры
1464 e_WriteLog(Format('GetFrame() error, res=%s',
1465 [textures[a].Resource]), MSG_WARNING);
1466 Error := True;
1467 end;
1469 if not g_CreateTextureMemorySize(Data, FrameLen, textures[a].Resource, 0, 0, Width, Height, 1) then
1470 begin // Сама текстура
1471 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s',
1472 [textures[a].Resource]), MSG_WARNING);
1473 Error := True;
1474 end;
1476 AddTexture(textures[a].Resource, Error);
1477 end;
1478 end;
1479 end;
1481 // Загружаем панели:
1482 panels := MapReader.GetPanels();
1484 if panels <> nil then
1485 begin
1486 MainForm.pbLoad.Position := 0;
1487 MainForm.pbLoad.Max := Length(panels);
1488 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1490 for a := 0 to High(panels) do
1491 begin
1492 MainForm.pbLoad.StepIt();
1493 Application.ProcessMessages();
1495 panel.X := panels[a].X;
1496 panel.Y := panels[a].Y;
1497 panel.Height := panels[a].Height;
1498 panel.Width := panels[a].Width;
1499 panel.PanelType := panels[a].PanelType;
1500 panel.Alpha := panels[a].Alpha;
1502 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1504 panel.TextureWidth := 0;
1505 panel.TextureHeight := 0;
1506 panel.TextureName := '';
1507 panel.TextureID := TEXTURE_SPECIAL_NONE;
1509 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_STEP or
1510 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1512 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1513 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1515 // Если панель видима:
1516 if WordBool(panel.PanelType and m) and
1517 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1518 begin
1519 if not IsSpecialTexture(textures[panels[a].TextureNum].Resource) then
1520 begin // Текстура
1521 if g_GetTexture(textures[panels[a].TextureNum].Resource, panel.TextureID) then
1522 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1523 else begin
1524 panel.TextureWidth := 1;
1525 panel.TextureHeight := 1;
1526 if g_GetTexture('NOTEXTURE', NoTextureID) then
1527 begin
1528 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1529 g_GetTextureSizeByID(NoTextureID, NW, NH);
1530 panel.TextureWidth := NW;
1531 panel.TextureHeight := NH;
1532 end;
1533 end;
1534 end
1535 else // Спец. текстура
1536 panel.TextureID := SpecialTextureID(textures[panels[a].TextureNum].Resource);
1538 panel.TextureName := textures[panels[a].TextureNum].Resource;
1539 end;
1541 // Жидкость без текстуры:
1542 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1543 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1544 begin
1545 case panel.PanelType of
1546 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1547 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1548 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1549 end;
1551 panel.TextureID := SpecialTextureID(panel.TextureName);
1552 AddTexture(panel.TextureName, False);
1553 end;
1555 AddPanel(panel);
1556 end;
1557 end;
1559 // Загружаем предметы:
1560 items := MapReader.GetItems();
1562 if items <> nil then
1563 begin
1564 MainForm.pbLoad.Position := 0;
1565 MainForm.pbLoad.Max := Length(items);
1566 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1568 for a := 0 to High(items) do
1569 begin
1570 MainForm.pbLoad.StepIt();
1571 Application.ProcessMessages();
1573 item.X := items[a].X;
1574 item.Y := items[a].Y;
1575 item.ItemType := items[a].ItemType;
1576 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1577 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1579 AddItem(item);
1580 end;
1581 end;
1583 // Загружаем монстров:
1584 monsters := MapReader.GetMonsters();
1586 if monsters <> nil then
1587 begin
1588 MainForm.pbLoad.Position := 0;
1589 MainForm.pbLoad.Max := Length(monsters);
1590 MainForm.lLoad.Caption := _lc[I_LOAD_MONSTERS];
1592 for a := 0 to High(monsters) do
1593 begin
1594 MainForm.pbLoad.StepIt();
1595 Application.ProcessMessages();
1597 monster.X := monsters[a].X;
1598 monster.Y := monsters[a].Y;
1599 monster.MonsterType := monsters[a].MonsterType;
1600 monster.Direction := TDirection(monsters[a].Direction);
1602 AddMonster(monster);
1603 end;
1604 end;
1606 // Загружаем области:
1607 areas := MapReader.GetAreas();
1609 if areas <> nil then
1610 begin
1611 MainForm.pbLoad.Position := 0;
1612 MainForm.pbLoad.Max := Length(areas);
1613 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1615 for a := 0 to High(areas) do
1616 begin
1617 MainForm.pbLoad.StepIt();
1618 Application.ProcessMessages();
1620 area.X := areas[a].X;
1621 area.Y := areas[a].Y;
1622 area.AreaType := areas[a].AreaType;
1623 area.Direction := TDirection(areas[a].Direction);
1625 AddArea(area);
1626 end;
1627 end;
1629 // Загружаем триггеры:
1630 triggers := MapReader.GetTriggers();
1632 if triggers <> nil then
1633 begin
1634 MainForm.pbLoad.Position := 0;
1635 MainForm.pbLoad.Max := Length(triggers);
1636 MainForm.lLoad.Caption := _lc[I_LOAD_TRIGGERS];
1638 for a := 0 to High(triggers) do
1639 begin
1640 MainForm.pbLoad.StepIt();
1641 Application.ProcessMessages();
1643 trigger.X := triggers[a].X;
1644 trigger.Y := triggers[a].Y;
1645 trigger.Width := triggers[a].Width;
1646 trigger.Height := triggers[a].Height;
1648 trigger.Enabled := ByteBool(triggers[a].Enabled);
1649 trigger.TexturePanel := triggers[a].TexturePanel;
1650 trigger.TriggerType := triggers[a].TriggerType;
1651 trigger.ActivateType := triggers[a].ActivateType;
1652 trigger.Key := triggers[a].Keys;
1653 trigger.Data.Default := triggers[a].DATA;
1655 AddTrigger(trigger);
1656 end;
1657 end;
1659 // Загружаем заголовок карты:
1660 Header := MapReader.GetMapHeader();
1662 gMapInfo.FileName := FileName;
1664 with gMapInfo do
1665 begin
1666 MapName := ResName;
1667 Name := Header.MapName;
1668 Description := Header.MapDescription;
1669 Author := Header.MapAuthor;
1670 MusicName := Header.MusicName;
1671 SkyName := Header.SkyName;
1672 Height := Header.Height;
1673 Width := Header.Width;
1674 end;
1676 LoadSky(gMapInfo.SkyName);
1678 textures := nil;
1679 panels := nil;
1680 items := nil;
1681 areas := nil;
1682 triggers := nil;
1684 MapReader.Free();
1685 FreeMem(pData);
1687 Result := True;
1688 end;
1690 function LoadMapOld(_FileName: String): Boolean;
1691 const
1692 TexturePrefix = 'Standart.wad:STDTEXTURES\';
1693 DefaultMusRes = 'Standart.wad:STDMUS\MUS1';
1694 DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
1696 var
1697 map: TConfig;
1698 i, a: Integer;
1699 s, section: String;
1700 panel: TPanel;
1701 item: TItem;
1702 area: TArea;
1704 begin
1705 Result := False;
1707 if not FileExists(_FileName) then
1708 Exit;
1710 // Открытие карты:
1711 MainForm.pbLoad.Position := 0;
1712 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];;
1713 Application.ProcessMessages();
1715 map := TConfig.CreateFile(_FileName);
1717 // Чтение текстур:
1718 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1720 MainForm.pbLoad.Max := i;
1721 MainForm.pbLoad.Position := 0;
1722 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1724 for a := 1 to i do
1725 begin
1726 MainForm.pbLoad.StepIt();
1727 Application.ProcessMessages();
1729 s := TexturePrefix + UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1730 if s = TexturePrefix then
1731 Continue;
1733 // Нет такой текстуры - ищем в WAD карты:
1734 if not g_CreateTextureWAD(s, EditorDir+'/wads/'+s) then
1735 begin
1736 s := ExtractFileName(_FileName);
1737 Delete(s, Length(s)-3, 4);
1738 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1740 if not g_CreateTextureWAD(s, EditorDir+'/wads/'+s) then
1741 Continue;
1742 end;
1744 MainForm.lbTextureList.Items.Add(s);
1745 end;
1747 // Чтение панелей:
1748 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1750 MainForm.pbLoad.Max := i;
1751 MainForm.pbLoad.Position := 0;
1752 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1754 for a := 1 to i do
1755 begin
1756 MainForm.pbLoad.StepIt();
1757 Application.ProcessMessages();
1759 section := 'Panel' + IntToStr(a);
1760 if not map.SectionExists(section) then
1761 Continue;
1763 panel.X := map.ReadInt(section, 'X1', 0);
1764 panel.Y := map.ReadInt(section, 'Y1', 0);
1765 panel.Height := map.ReadInt(section, 'Height', 16);
1766 panel.Width := map.ReadInt(section, 'Width', 16);
1768 case map.ReadInt(section, 'PanelType', 0) of
1769 0: panel.PanelType := PANEL_WALL;
1770 1: panel.PanelType := PANEL_BACK;
1771 2: panel.PanelType := PANEL_FORE;
1772 3: panel.PanelType := PANEL_STEP;
1773 4: panel.PanelType := PANEL_WATER;
1774 5: panel.PanelType := PANEL_ACID1;
1775 6: panel.PanelType := PANEL_ACID2;
1776 end;
1778 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1780 // Текстура панели:
1781 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_STEP] then
1782 begin
1783 s := TexturePrefix + UpperCase(map.ReadStr(section, 'TextureName', ''));
1785 if g_GetTexture(s, panel.TextureID) then
1786 begin
1787 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1788 panel.TextureName := s;
1789 end
1790 else // Нет такой текстуры - ищем в WAD карты:
1791 begin
1792 s := ExtractFileName(_FileName);
1793 Delete(s, Length(s)-3, 4);
1794 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(map.ReadStr(section, 'TextureName', ''));
1796 if g_GetTexture(s, panel.TextureID) then
1797 begin
1798 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1799 panel.TextureName := s;
1800 end
1801 else
1802 Continue;
1803 end;
1804 end
1805 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1806 begin
1807 case panel.PanelType of
1808 PANEL_WATER:
1809 begin
1810 s := TEXTURE_NAME_WATER;
1811 panel.TextureID := TEXTURE_SPECIAL_WATER;
1812 end;
1813 PANEL_ACID1:
1814 begin
1815 s := TEXTURE_NAME_ACID2;
1816 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1817 end;
1818 PANEL_ACID2:
1819 begin
1820 s := TEXTURE_NAME_ACID1;
1821 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1822 end;
1823 end;
1825 with MainForm.lbTextureList.Items do
1826 if IndexOf(s) = -1 then
1827 Add(s);
1828 panel.TextureName := s;
1829 panel.TextureWidth := 1;
1830 panel.TextureHeight := 1;
1831 end;
1833 AddPanel(panel);
1834 end;
1836 // Чтение предметов:
1837 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1839 MainForm.pbLoad.Max := i;
1840 MainForm.pbLoad.Position := 0;
1841 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1843 for a := 1 to i do
1844 begin
1845 MainForm.pbLoad.StepIt();
1846 Application.ProcessMessages();
1848 section := 'Item' + IntToStr(a);
1849 if not map.SectionExists(section) then
1850 Continue;
1852 item.X := map.ReadInt(section, 'X', 0);
1853 item.Y := map.ReadInt(section, 'Y', 0);
1854 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1855 item.OnlyDM := False;
1856 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1858 // Размер предметов теперь другой:
1859 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1860 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1862 AddItem(item);
1863 end;
1865 // Чтение областей:
1866 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1868 MainForm.pbLoad.Max := i;
1869 MainForm.pbLoad.Position := 0;
1870 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1872 for a := 1 to i do
1873 begin
1874 MainForm.pbLoad.StepIt();
1875 Application.ProcessMessages();
1877 section := 'Area' + IntToStr(a);
1878 if not map.SectionExists(section) then
1879 Continue;
1881 area.X := map.ReadInt(section, 'X', 0);
1882 area.Y := map.ReadInt(section, 'Y', 0);
1883 area.AreaType := map.ReadInt(section, 'Type', 0);
1884 area.Direction := D_RIGHT;
1886 // Размер областей теперь другой:
1887 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1888 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1890 AddArea(area);
1891 end;
1893 // Чтение параметров карты:
1894 with gMapInfo do
1895 begin
1896 Name := map.ReadStr('MapOptions', 'MapName', '');
1897 Description := map.ReadStr('MapOptions', 'MapDescription', '');
1898 Author := '';
1899 MusicName := DefaultMusRes;
1900 SkyName := DefaultSkyRes;
1901 FileName := _FileName;
1902 Height := map.ReadInt('MapOptions', 'Height', 1600);
1903 Width := map.ReadInt('MapOptions', 'Width', 1600);
1905 if Length(Name) > 32 then
1906 SetLength(Name, 32);
1907 if Length(Description) > 256 then
1908 SetLength(Description, 256);
1909 end;
1911 map.Free();
1913 Result := True;
1914 end;
1916 procedure ClearMap();
1917 var
1918 a: Integer;
1920 begin
1921 if gPanels <> nil then
1922 for a := 0 to High(gPanels) do
1923 if gPanels[a].TextureName <> '' then
1924 g_DeleteTexture(gPanels[a].TextureName);
1926 SetLength(gPanels, 0);
1927 gPanels := nil;
1928 SetLength(gItems, 0);
1929 gItems := nil;
1930 SetLength(gAreas, 0);
1931 gAreas := nil;
1932 SetLength(gMonsters, 0);
1933 gMonsters := nil;
1934 SetLength(gTriggers, 0);
1935 gTriggers := nil;
1937 with gMapInfo do
1938 begin
1939 Name := '';
1940 Description := '';
1941 Author := '';
1942 MusicName := '';
1943 SkyName := '';
1944 FileName := '';
1945 Height := 1600;
1946 Width := 1600;
1947 end;
1949 with MainForm.lbTextureList do
1950 begin
1951 if Items.Count > 0 then
1952 for a := Items.Count-1 downto 0 do
1953 if not IsSpecialTexture(Items[a]) then
1954 g_DeleteTexture(Items[a]);
1956 Clear();
1957 end;
1959 MapOffset.X := 0;
1960 MapOffset.Y := 0;
1961 end;
1963 procedure DrawPanels(fPanelType: Word);
1965 procedure DrawTexture(a: Integer);
1966 var
1967 NoTextureID: DWORD;
1968 NW, NH: Word;
1969 begin
1970 with gPanels[a] do
1971 begin
1972 case TextureID of
1973 TEXTURE_SPECIAL_NONE:
1974 if not PreviewMode then
1975 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1976 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1977 64, 64, 64, 127);
1979 TEXTURE_SPECIAL_NOTEXTURE:
1980 if g_GetTexture('NOTEXTURE', NoTextureID) then
1981 begin
1982 g_GetTextureSizeByID(NoTextureID, NW, NH);
1983 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
1984 Width div NW, Height div NH, 0, False, False);
1985 end;
1987 TEXTURE_SPECIAL_WATER:
1988 if PreviewMode then
1989 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1990 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1991 0, 0, 255, 0, B_FILTER)
1992 else
1993 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1994 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1995 0, 0, 255, 127);
1997 TEXTURE_SPECIAL_ACID1:
1998 if PreviewMode then
1999 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2000 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2001 0, 127, 0, 0, B_FILTER)
2002 else
2003 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2004 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2005 0, 255, 0, 127);
2007 TEXTURE_SPECIAL_ACID2:
2008 if PreviewMode then
2009 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2010 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2011 127, 0, 0, 0, B_FILTER)
2012 else
2013 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2014 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2015 255, 0, 0, 127);
2017 else
2018 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2019 Width div TextureWidth, Height div TextureHeight,
2020 Alpha, True, Blending);
2021 end;
2022 end;
2023 end;
2025 var
2026 a: Integer;
2027 begin
2028 if gPanels <> nil then
2029 for a := 0 to High(gPanels) do
2030 if (gPanels[a].PanelType <> 0) and
2031 WordBool(gPanels[a].PanelType and fPanelType) then
2032 with gPanels[a] do
2033 begin
2034 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2035 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2036 case PanelType of
2037 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2038 PANEL_STEP, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2039 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2040 DrawTexture(a);
2042 PANEL_LIFTUP:
2043 if not PreviewMode then
2044 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2045 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2046 128, 64, 0, 0);
2047 PANEL_LIFTDOWN:
2048 if not PreviewMode then
2049 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2050 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2051 90, 154, 138, 0);
2052 PANEL_LIFTLEFT:
2053 if not PreviewMode then
2054 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2055 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2056 200, 80, 4, 0);
2057 PANEL_LIFTRIGHT:
2058 if not PreviewMode then
2059 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2060 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2061 252, 140, 56, 0);
2062 PANEL_BLOCKMON:
2063 if not PreviewMode then
2064 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2065 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2066 192, 0, 192, 0);
2067 end;
2068 end;
2069 end;
2071 procedure DrawMap();
2072 var
2073 a, w, h: Integer;
2074 ID: DWORD;
2075 xx, yy, dx, dy: Integer;
2076 ww, hh: Word;
2077 sel: Boolean;
2078 r: TRectWH;
2080 begin
2081 // В режиме Превью рисуем небо:
2082 if PreviewMode then
2083 begin
2084 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2085 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2086 w := Round(w*4/3);
2087 h := Round(w*3/4);
2089 if g_GetTexture(SKY_TEXTURE, ID) then
2090 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2091 else
2092 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2093 end;
2095 // Рисуем панели (если Превью или если включен слой):
2096 if LayerEnabled[LAYER_BACK] or PreviewMode then
2097 DrawPanels(PANEL_BACK);
2098 if PreviewMode then
2099 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
2100 else
2101 if LayerEnabled[LAYER_WATER] then
2102 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
2103 PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
2104 if LayerEnabled[LAYER_WALLS] or PreviewMode then
2105 DrawPanels(PANEL_WALL);
2106 if LayerEnabled[LAYER_STEPS] or PreviewMode then
2107 DrawPanels(PANEL_STEP);
2109 // Рисуем предметы:
2110 if (LayerEnabled[LAYER_ITEMS] or PreviewMode) and
2111 (gItems <> nil) then
2112 for a := 0 to High(gItems) do
2113 if gItems[a].ItemType <> ITEM_NONE then
2114 with gItems[a] do
2115 begin
2116 ID := DWORD(-1);
2118 case ItemType of
2119 0: Continue;
2120 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2121 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2122 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2123 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2124 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2125 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2126 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2127 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2128 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2129 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2130 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2131 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2132 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2133 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2134 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2135 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2136 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2137 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2138 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2139 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2140 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2141 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2142 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2143 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2144 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2145 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2146 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2147 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2148 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2149 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2150 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2151 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2152 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2153 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2154 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2155 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2156 end;
2158 if ID <> DWORD(-1) then
2159 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2160 end;
2162 // Рисуем монстров:
2163 if (LayerEnabled[LAYER_MONSTERS] or PreviewMode) and
2164 (gMonsters <> nil) then
2165 for a := 0 to High(gMonsters) do
2166 if gMonsters[a].MonsterType <> MONSTER_NONE then
2167 with MonsterSize[gMonsters[a].MonsterType] do
2168 begin
2169 ID := DWORD(-1);
2171 case gMonsters[a].MonsterType of
2172 0: Continue;
2173 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2174 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2175 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2176 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2177 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2178 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2179 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2180 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2181 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2182 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2183 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2184 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2185 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2186 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2187 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2188 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2189 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2190 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2191 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2192 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2193 end;
2195 if ID <> DWORD(-1) then
2196 if gMonsters[a].Direction = D_LEFT then
2197 begin
2198 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2199 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2200 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2201 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2202 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2203 xx := (gMonsters[a].X - X) - xx;
2205 yy := (gMonsters[a].Y - Y) +
2206 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2208 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2209 0, True, False, M_HORIZONTAL);
2210 end
2211 else
2212 begin
2213 // Левый верхний угол текстуры + смещение анимации:
2214 xx := (gMonsters[a].X - X) +
2215 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2216 yy := (gMonsters[a].Y - Y) +
2217 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2219 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2220 0, True, False);
2221 end;
2223 // Рамка:
2224 if not PreviewMode then
2225 begin
2226 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2227 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2228 255, 255, 255);
2229 end;
2230 end;
2232 // Рисуем закрытые двери после монстров:
2233 if PreviewMode then
2234 DrawPanels(PANEL_CLOSEDOOR);
2236 // Рисуем области:
2237 if (LayerEnabled[LAYER_AREAS] or PreviewMode) and
2238 (gAreas <> nil) then
2239 for a := 0 to High(gAreas) do
2240 if gAreas[a].AreaType <> AREA_NONE then
2241 with AreaSize[gAreas[a].AreaType] do
2242 begin
2243 ID := DWORD(-1);
2245 case gAreas[a].AreaType of
2246 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2247 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2248 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2249 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2250 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2251 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2252 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2253 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2254 end;
2256 if (not PreviewMode) or
2257 (gAreas[a].AreaType = AREA_REDFLAG) or
2258 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2259 (gAreas[a].AreaType = AREA_DOMFLAG) then
2260 if ID <> DWORD(-1) then
2261 if gAreas[a].Direction = D_LEFT then
2262 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2263 0, True, False, M_HORIZONTAL)
2264 else
2265 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2266 0, True, False);
2268 // Рамка:
2269 if not PreviewMode then
2270 begin
2271 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2272 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2273 255, 255, 255);
2275 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2276 end;
2277 end;
2279 // Рисуем жидкости и передний план после областей:
2280 if LayerEnabled[LAYER_WATER] or PreviewMode then
2281 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2282 if LayerEnabled[LAYER_FOREGROUND] or PreviewMode then
2283 DrawPanels(PANEL_FORE);
2285 // Рисуем триггеры:
2286 if LayerEnabled[LAYER_TRIGGERS] and
2287 (not PreviewMode) and (gTriggers <> nil) then
2288 for a := 0 to High(gTriggers) do
2289 with gTriggers[a] do
2290 if TriggerType <> TRIGGER_NONE then
2291 begin
2292 // Если выбран - рисуем красным, иначе - белым:
2293 sel := ObjectSelected(OBJECT_TRIGGER, a);
2295 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2296 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2297 0, 0, 0, 150);
2299 if TexturePanel <> -1 then
2300 begin
2301 with gPanels[TexturePanel] do
2302 begin
2303 xx := X;
2304 yy := Y;
2305 ww := Width;
2306 hh := Height;
2307 end;
2309 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2310 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2311 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2312 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2313 MapOffset.X+xx, MapOffset.Y+yy,
2314 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2315 end;
2317 case TriggerType of
2318 TRIGGER_EXIT: ;
2320 TRIGGER_TELEPORT:
2321 begin
2322 // Точка назначения Телепорта:
2323 if Data.d2d_teleport then
2324 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2325 MapOffset.Y+Data.TargetPoint.Y-1,
2326 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2327 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2328 else
2329 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2330 MapOffset.Y+Data.TargetPoint.Y,
2331 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2332 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2333 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2334 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2335 MapOffset.Y+Data.TargetPoint.Y,
2336 255, 0, 0);
2337 // Линия к точке назначения Телепорта:
2338 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2339 MapOffset.Y+Y+(Height div 2),
2340 MapOffset.X+Data.TargetPoint.X,
2341 MapOffset.Y+Data.TargetPoint.Y,
2342 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2343 end;
2345 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2346 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2347 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2348 TRIGGER_LIFT:
2349 if Data.PanelID <> -1 then
2350 begin
2351 // Дверь/Ловушка/Лифт:
2352 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2353 MapOffset.Y+gPanels[Data.PanelID].Y,
2354 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2355 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2356 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2357 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2358 MapOffset.Y+gPanels[Data.PanelID].Y,
2359 255, 0, 0);
2360 // Линия к Двери/Ловушке/Лифту:
2361 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2362 MapOffset.Y+Y+(Height div 2),
2363 MapOffset.X+gPanels[Data.PanelID].X,
2364 MapOffset.Y+gPanels[Data.PanelID].Y,
2365 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2366 end;
2368 TRIGGER_PRESS, TRIGGER_ON,
2369 TRIGGER_OFF, TRIGGER_ONOFF:
2370 begin
2371 if (Data.tWidth > 0) and
2372 (Data.tHeight > 0) then
2373 begin
2374 // Область Расширителя:
2375 e_DrawQuad(MapOffset.X+Data.tX,
2376 MapOffset.Y+Data.tY,
2377 MapOffset.X+Data.tX+Data.tWidth-1,
2378 MapOffset.Y+Data.tY+Data.tHeight-1,
2379 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2380 e_DrawPoint(2, MapOffset.X+Data.tX,
2381 MapOffset.Y+Data.tY,
2382 255, 0, 0);
2383 // Линия к области Расширителя:
2384 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2385 MapOffset.Y+Y+(Height div 2),
2386 MapOffset.X+Data.tX,
2387 MapOffset.Y+Data.tY,
2388 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2389 end;
2391 if Data.MonsterID <> 0 then
2392 if (gMonsters <> nil) and
2393 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2394 begin
2395 // Рамка вокруг Монстра - условия активации:
2396 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2397 e_DrawQuad(MapOffset.X+r.X,
2398 MapOffset.Y+r.Y,
2399 MapOffset.X+r.X+r.Width-1,
2400 MapOffset.Y+r.Y+r.Height-1,
2401 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2402 // Линия к Монстру - условию активации:
2403 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2404 MapOffset.Y+Y+(Height div 2),
2405 MapOffset.X+r.X,
2406 MapOffset.Y+r.Y,
2407 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2409 end;
2410 end;
2412 TRIGGER_SECRET: ;
2414 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2415 begin
2416 if TriggerType = TRIGGER_SPAWNMONSTER then
2417 begin
2418 xx := Data.MonPos.X;
2419 yy := Data.MonPos.Y;
2420 end
2421 else
2422 begin
2423 xx := Data.ItemPos.X;
2424 yy := Data.ItemPos.Y;
2425 end;
2426 // Точка появления Монстра/Предмета:
2427 e_DrawLine(2, MapOffset.X+xx-16,
2428 MapOffset.Y+yy-1,
2429 MapOffset.X+xx+16,
2430 MapOffset.Y+yy-1,
2431 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2432 e_DrawPoint(2, MapOffset.X+xx,
2433 MapOffset.Y+yy,
2434 255, 0, 0);
2435 // Линия к точке появления Монстра/Предмета:
2436 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2437 MapOffset.Y+Y+(Height div 2),
2438 MapOffset.X+xx,
2439 MapOffset.Y+yy,
2440 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2441 // Предпросмотр создаваемого объекта:
2442 if sel then
2443 begin
2444 // Монстр:
2445 if TriggerType = TRIGGER_SPAWNMONSTER then
2446 begin
2447 if Data.MonType <> MONSTER_NONE then
2448 with MonsterSize[Data.MonType] do
2449 begin
2450 ID := DWORD(-1);
2451 case Data.MonType of
2452 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2453 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2454 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2455 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2456 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2457 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2458 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2459 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2460 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2461 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2462 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2463 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2464 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2465 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2466 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2467 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2468 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2469 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2470 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2471 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2472 end;
2473 if ID <> DWORD(-1) then
2474 begin
2475 if Data.MonDir = Byte(D_LEFT) then
2476 begin
2477 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2478 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2479 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2481 yy := Data.TargetPoint.Y - Y +
2482 MonsterSizeDelta[Data.MonType].Y-Height;
2484 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2485 128, True, False, M_HORIZONTAL);
2486 end
2487 else
2488 begin
2489 xx := Data.TargetPoint.X - X +
2490 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2491 yy := Data.TargetPoint.Y - Y +
2492 MonsterSizeDelta[Data.MonType].Y-Height;
2494 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2495 128, True, False);
2496 end;
2497 // Рамка:
2498 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2499 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2500 255, 255, 0, 128);
2501 end;
2502 end;
2503 end
2504 else
2505 // Предмет:
2506 begin
2507 if Data.ItemType <> ITEM_NONE then
2508 begin
2509 ID := DWORD(-1);
2510 case Data.ItemType of
2511 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2512 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2513 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2514 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2515 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2516 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2517 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2518 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2519 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2520 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2521 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2522 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2523 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2524 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2525 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2526 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2527 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2528 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2529 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2530 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2531 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2532 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2533 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2534 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2535 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2536 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2537 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2538 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2539 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2540 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2541 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2542 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2543 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2544 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2545 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2546 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2547 end;
2548 if ID <> DWORD(-1) then
2549 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2550 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2551 128, True, False);
2552 // Рамка:
2553 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2554 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2555 255, 255, 0, 128);
2556 end;
2557 end;
2558 end;
2559 end;
2561 TRIGGER_PUSH:
2562 begin
2563 // Линия направления и силы ускорения:
2564 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2565 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2566 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2567 MapOffset.Y+Y+(Height div 2),
2568 MapOffset.X+xx,
2569 MapOffset.Y+yy,
2570 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2571 end;
2573 TRIGGER_SHOT:
2574 begin;
2575 xx := Data.ShotPos.X;
2576 yy := Data.ShotPos.Y;
2577 // Точка появления снаряда:
2578 e_DrawPoint(2, MapOffset.X+xx,
2579 MapOffset.Y+yy,
2580 255, 0, 0);
2581 // Линия к точке появления снаряда:
2582 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2583 MapOffset.Y+Y+(Height div 2),
2584 MapOffset.X+xx,
2585 MapOffset.Y+yy,
2586 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2587 // Линия направления выстрела:
2588 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2589 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2590 e_DrawLine(1, MapOffset.X+xx,
2591 MapOffset.Y+yy,
2592 MapOffset.X+xx+dx,
2593 MapOffset.Y+yy+dy,
2594 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2596 if (Data.ShotPanelID <> -1) and
2597 (Data.ShotPanelID <= High(gPanels)) then
2598 begin
2599 // Линия к панели индикации выстрела
2600 with gPanels[Data.ShotPanelID] do
2601 begin
2602 xx := X;
2603 yy := Y;
2604 ww := Width;
2605 hh := Height;
2606 end;
2608 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2609 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2610 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2611 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2612 MapOffset.X+xx, MapOffset.Y+yy,
2613 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2614 end;
2615 end;
2616 end;
2617 end;
2619 // Границы карты:
2620 if not PreviewMode then
2621 begin
2622 e_DrawFillQuad(-32+MapOffset.X,
2623 -32+MapOffset.Y,
2624 gMapInfo.Width+31+MapOffset.X,
2625 -1+MapOffset.Y,
2626 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2627 e_DrawFillQuad(-32+MapOffset.X,
2628 gMapInfo.Height+MapOffset.Y,
2629 gMapInfo.Width+31+MapOffset.X,
2630 gMapInfo.Height+31+MapOffset.Y,
2631 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2632 e_DrawFillQuad(-32+MapOffset.X,
2633 MapOffset.Y,
2634 -1+MapOffset.X,
2635 gMapInfo.Height+MapOffset.Y-1,
2636 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2637 e_DrawFillQuad(gMapInfo.Width+MapOffset.X,
2638 MapOffset.Y,
2639 gMapInfo.Width+31+MapOffset.X,
2640 gMapInfo.Height+MapOffset.Y-1,
2641 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2642 end;
2643 end;
2645 procedure ShiftMapObjects(dx, dy: Integer);
2646 var
2647 i: Integer;
2648 begin
2649 if gPanels <> nil then
2650 for i := 0 to High(gPanels) do
2651 if gPanels[i].PanelType <> 0 then
2652 begin
2653 Inc(gPanels[i].X, dx);
2654 Inc(gPanels[i].Y, dy);
2655 end;
2657 if gItems <> nil then
2658 for i := 0 to High(gItems) do
2659 if gItems[i].ItemType <> 0 then
2660 begin
2661 Inc(gItems[i].X, dx);
2662 Inc(gItems[i].Y, dy);
2663 end;
2665 if gAreas <> nil then
2666 for i := 0 to High(gAreas) do
2667 if gAreas[i].AreaType <> 0 then
2668 begin
2669 Inc(gAreas[i].X, dx);
2670 Inc(gAreas[i].Y, dy);
2671 end;
2673 if gMonsters <> nil then
2674 for i := 0 to High(gMonsters) do
2675 if gMonsters[i].MonsterType <> 0 then
2676 begin
2677 Inc(gMonsters[i].X, dx);
2678 Inc(gMonsters[i].Y, dy);
2679 end;
2681 if gTriggers <> nil then
2682 for i := 0 to High(gTriggers) do
2683 if gTriggers[i].TriggerType <> 0 then
2684 begin
2685 Inc(gTriggers[i].X, dx);
2686 Inc(gTriggers[i].Y, dy);
2688 case gTriggers[i].TriggerType of
2689 TRIGGER_TELEPORT:
2690 begin
2691 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2692 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2693 end;
2695 TRIGGER_PRESS, TRIGGER_ON,
2696 TRIGGER_OFF, TRIGGER_ONOFF:
2697 begin
2698 Inc(gTriggers[i].Data.tX, dx);
2699 Inc(gTriggers[i].Data.tY, dy);
2700 end;
2702 TRIGGER_SPAWNMONSTER:
2703 begin
2704 Inc(gTriggers[i].Data.MonPos.X, dx);
2705 Inc(gTriggers[i].Data.MonPos.Y, dy);
2706 end;
2708 TRIGGER_SPAWNITEM:
2709 begin
2710 Inc(gTriggers[i].Data.ItemPos.X, dx);
2711 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2712 end;
2714 TRIGGER_SHOT:
2715 begin
2716 Inc(gTriggers[i].Data.ShotPos.X, dx);
2717 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2718 end;
2719 end;
2720 end;
2721 end;
2723 procedure LoadData();
2724 begin
2725 g_CreateTextureWAD('PREVIEW', EditorDir+'/data/Editor.wad:TEXTURES\CHECKERS');
2726 g_CreateTextureWAD('NOTEXTURE', EditorDir+'/data/Game.wad:TEXTURES\NOTEXTURE');
2728 g_CreateTextureWADSize('AREA_REDFLAG', EditorDir+'/data/Game.wad:TEXTURES\FLAGRED', 0, 0, 64, 64);
2729 g_CreateTextureWADSize('AREA_BLUEFLAG', EditorDir+'/data/Game.wad:TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2730 g_CreateTextureWADSize('AREA_DOMFLAG', EditorDir+'/data/Game.wad:TEXTURES\FLAGDOM', 0, 0, 64, 64);
2732 g_CreateTextureWADSize('MONSTER_DEMON', EditorDir+'/data/Game.wad:MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2733 g_CreateTextureWADSize('MONSTER_IMP', EditorDir+'/data/Game.wad:MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2734 g_CreateTextureWADSize('MONSTER_ZOMBY', EditorDir+'/data/Game.wad:MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2735 g_CreateTextureWADSize('MONSTER_SERG', EditorDir+'/data/Game.wad:MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2736 g_CreateTextureWADSize('MONSTER_CYBER', EditorDir+'/data/Game.wad:MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2737 g_CreateTextureWADSize('MONSTER_CGUN', EditorDir+'/data/Game.wad:MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2738 g_CreateTextureWADSize('MONSTER_BARON', EditorDir+'/data/Game.wad:MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2739 g_CreateTextureWADSize('MONSTER_KNIGHT', EditorDir+'/data/Game.wad:MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2740 g_CreateTextureWADSize('MONSTER_CACO', EditorDir+'/data/Game.wad:MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2741 g_CreateTextureWADSize('MONSTER_SOUL', EditorDir+'/data/Game.wad:MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2742 g_CreateTextureWADSize('MONSTER_PAIN', EditorDir+'/data/Game.wad:MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2743 g_CreateTextureWADSize('MONSTER_SPIDER', EditorDir+'/data/Game.wad:MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2744 g_CreateTextureWADSize('MONSTER_BSP', EditorDir+'/data/Game.wad:MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2745 g_CreateTextureWADSize('MONSTER_MANCUB', EditorDir+'/data/Game.wad:MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2746 g_CreateTextureWADSize('MONSTER_SKEL', EditorDir+'/data/Game.wad:MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2747 g_CreateTextureWADSize('MONSTER_VILE', EditorDir+'/data/Game.wad:MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2748 g_CreateTextureWADSize('MONSTER_FISH', EditorDir+'/data/Game.wad:MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2749 g_CreateTextureWADSize('MONSTER_BARREL', EditorDir+'/data/Game.wad:MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2750 g_CreateTextureWADSize('MONSTER_ROBO', EditorDir+'/data/Game.wad:MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2751 g_CreateTextureWADSize('MONSTER_MAN', EditorDir+'/data/Game.wad:MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2753 g_CreateTextureWADSize('ITEM_BLUESPHERE', EditorDir+'/data/Game.wad:TEXTURES\SBLUE', 0, 0, 32, 32);
2754 g_CreateTextureWADSize('ITEM_WHITESPHERE', EditorDir+'/data/Game.wad:TEXTURES\SWHITE', 0, 0, 32, 32);
2755 g_CreateTextureWADSize('ITEM_ARMORGREEN', EditorDir+'/data/Game.wad:TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2756 g_CreateTextureWADSize('ITEM_ARMORBLUE', EditorDir+'/data/Game.wad:TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2757 g_CreateTextureWADSize('ITEM_INVUL', EditorDir+'/data/Game.wad:TEXTURES\INVUL', 0, 0, 32, 32);
2758 g_CreateTextureWADSize('ITEM_BOTTLE', EditorDir+'/data/Game.wad:TEXTURES\BOTTLE', 0, 0, 16, 32);
2759 g_CreateTextureWADSize('ITEM_HELMET', EditorDir+'/data/Game.wad:TEXTURES\HELMET', 0, 0, 16, 16);
2760 g_CreateTextureWADSize('ITEM_INVIS', EditorDir+'/data/Game.wad:TEXTURES\INVIS', 0, 0, 32, 32);
2761 g_CreateTextureWADSize('ITEM_WEAPON_FLAMETHROWER', EditorDir+'/data/Game.wad:TEXTURES\FLAMETHROWER', 0, 0, 64, 32);
2762 g_CreateTextureWADSize('ITEM_AMMO_FUELCAN', EditorDir+'/data/Game.wad:TEXTURES\FUELCAN', 0, 0, 16, 32);
2764 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', EditorDir+'/data/Game.wad:TEXTURES\MED1');
2765 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', EditorDir+'/data/Game.wad:TEXTURES\MED2');
2766 g_CreateTextureWAD('ITEM_WEAPON_SAW', EditorDir+'/data/Game.wad:TEXTURES\SAW');
2767 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', EditorDir+'/data/Game.wad:TEXTURES\PISTOL');
2768 g_CreateTextureWAD('ITEM_WEAPON_KASTET', EditorDir+'/data/Game.wad:TEXTURES\KASTET');
2769 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', EditorDir+'/data/Game.wad:TEXTURES\SHOTGUN1');
2770 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', EditorDir+'/data/Game.wad:TEXTURES\SHOTGUN2');
2771 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', EditorDir+'/data/Game.wad:TEXTURES\MGUN');
2772 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', EditorDir+'/data/Game.wad:TEXTURES\RLAUNCHER');
2773 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', EditorDir+'/data/Game.wad:TEXTURES\PGUN');
2774 g_CreateTextureWAD('ITEM_WEAPON_BFG', EditorDir+'/data/Game.wad:TEXTURES\BFG');
2775 g_CreateTextureWAD('ITEM_WEAPON_SUPERPULEMET', EditorDir+'/data/Game.wad:TEXTURES\SPULEMET');
2776 g_CreateTextureWAD('ITEM_AMMO_BULLETS', EditorDir+'/data/Game.wad:TEXTURES\CLIP');
2777 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', EditorDir+'/data/Game.wad:TEXTURES\AMMO');
2778 g_CreateTextureWAD('ITEM_AMMO_SHELLS', EditorDir+'/data/Game.wad:TEXTURES\SHELL1');
2779 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', EditorDir+'/data/Game.wad:TEXTURES\SHELL2');
2780 g_CreateTextureWAD('ITEM_AMMO_ROCKET', EditorDir+'/data/Game.wad:TEXTURES\ROCKET');
2781 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', EditorDir+'/data/Game.wad:TEXTURES\ROCKETS');
2782 g_CreateTextureWAD('ITEM_AMMO_CELL', EditorDir+'/data/Game.wad:TEXTURES\CELL');
2783 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', EditorDir+'/data/Game.wad:TEXTURES\CELL2');
2784 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', EditorDir+'/data/Game.wad:TEXTURES\BPACK');
2785 g_CreateTextureWAD('ITEM_KEY_RED', EditorDir+'/data/Game.wad:TEXTURES\KEYR');
2786 g_CreateTextureWAD('ITEM_KEY_GREEN', EditorDir+'/data/Game.wad:TEXTURES\KEYG');
2787 g_CreateTextureWAD('ITEM_KEY_BLUE', EditorDir+'/data/Game.wad:TEXTURES\KEYB');
2788 g_CreateTextureWAD('ITEM_OXYGEN', EditorDir+'/data/Game.wad:TEXTURES\OXYGEN');
2789 g_CreateTextureWAD('ITEM_SUIT', EditorDir+'/data/Game.wad:TEXTURES\SUIT');
2790 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', EditorDir+'/data/Game.wad:TEXTURES\BMED');
2791 g_CreateTextureWAD('ITEM_JETPACK', EditorDir+'/data/Game.wad:TEXTURES\JETPACK');
2793 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorDir+'/data/Editor.wad:TEXTURES\P1POINT');
2794 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorDir+'/data/Editor.wad:TEXTURES\P2POINT');
2795 g_CreateTextureWAD('AREA_DMPOINT', EditorDir+'/data/Editor.wad:TEXTURES\DMPOINT');
2796 g_CreateTextureWAD('AREA_REDPOINT', EditorDir+'/data/Editor.wad:TEXTURES\REDPOINT');
2797 g_CreateTextureWAD('AREA_BLUEPOINT', EditorDir+'/data/Editor.wad:TEXTURES\BLUEPOINT');
2798 end;
2800 procedure FreeData();
2801 begin
2802 g_DeleteTexture('NOTEXTURE');
2804 g_DeleteTexture('ITEM_BLUESPHERE');
2805 g_DeleteTexture('ITEM_WHITESPHERE');
2806 g_DeleteTexture('ITEM_ARMORGREEN');
2807 g_DeleteTexture('ITEM_ARMORBLUE');
2808 g_DeleteTexture('ITEM_INVUL');
2809 g_DeleteTexture('ITEM_BOTTLE');
2810 g_DeleteTexture('ITEM_HELMET');
2811 g_DeleteTexture('AREA_REDFLAG');
2812 g_DeleteTexture('AREA_BLUEFLAG');
2813 g_DeleteTexture('AREA_DOMFLAG');
2815 g_DeleteTexture('MONSTER_DEMON');
2816 g_DeleteTexture('MONSTER_IMP');
2817 g_DeleteTexture('MONSTER_ZOMBY');
2818 g_DeleteTexture('MONSTER_SERG');
2819 g_DeleteTexture('MONSTER_CGUN');
2820 g_DeleteTexture('MONSTER_BARREL');
2821 g_DeleteTexture('MONSTER_MAN');
2823 g_DeleteTexture('MONSTER_DEMON');
2824 g_DeleteTexture('MONSTER_IMP');
2825 g_DeleteTexture('MONSTER_ZOMBY');
2826 g_DeleteTexture('MONSTER_SERG');
2827 g_DeleteTexture('MONSTER_CYBER');
2828 g_DeleteTexture('MONSTER_CGUN');
2829 g_DeleteTexture('MONSTER_BARON');
2830 g_DeleteTexture('MONSTER_KNIGHT');
2831 g_DeleteTexture('MONSTER_CACO');
2832 g_DeleteTexture('MONSTER_SOUL');
2833 g_DeleteTexture('MONSTER_PAIN');
2834 g_DeleteTexture('MONSTER_SPIDER');
2835 g_DeleteTexture('MONSTER_BSP');
2836 g_DeleteTexture('MONSTER_MANCUB');
2837 g_DeleteTexture('MONSTER_SKEL');
2838 g_DeleteTexture('MONSTER_VILE');
2839 g_DeleteTexture('MONSTER_FISH');
2840 g_DeleteTexture('MONSTER_BARREL');
2841 g_DeleteTexture('MONSTER_ROBO');
2842 g_DeleteTexture('MONSTER_MAN');
2844 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2845 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2846 g_DeleteTexture('ITEM_WEAPON_SAW');
2847 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2848 g_DeleteTexture('ITEM_WEAPON_KASTET');
2849 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2850 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2851 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2852 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
2853 g_DeleteTexture('ITEM_WEAPON_PLASMA');
2854 g_DeleteTexture('ITEM_WEAPON_BFG');
2855 g_DeleteTexture('ITEM_WEAPON_SUPERPULEMET');
2856 g_DeleteTexture('ITEM_AMMO_BULLETS');
2857 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
2858 g_DeleteTexture('ITEM_AMMO_SHELLS');
2859 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
2860 g_DeleteTexture('ITEM_AMMO_ROCKET');
2861 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
2862 g_DeleteTexture('ITEM_AMMO_CELL');
2863 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
2864 g_DeleteTexture('ITEM_AMMO_BACKPACK');
2865 g_DeleteTexture('ITEM_KEY_RED');
2866 g_DeleteTexture('ITEM_KEY_GREEN');
2867 g_DeleteTexture('ITEM_KEY_BLUE');
2868 g_DeleteTexture('ITEM_OXYGEN');
2869 g_DeleteTexture('ITEM_SUIT');
2870 g_DeleteTexture('ITEM_MEDKIT_BLACK');
2871 g_DeleteTexture('ITEM_JETPACK');
2872 g_DeleteTexture('ITEM_INVIS');
2873 g_DeleteTexture('ITEM_WEAPON_FLAMETHROWER');
2874 g_DeleteTexture('ITEM_AMMO_FUELCAN');
2876 g_DeleteTexture('AREA_PLAYERPOINT1');
2877 g_DeleteTexture('AREA_PLAYERPOINT2');
2878 g_DeleteTexture('AREA_DMPOINT');
2879 g_DeleteTexture('AREA_REDPOINT');
2880 g_DeleteTexture('AREA_BLUEPOINT');
2881 end;
2883 end.