DEADSOFTWARE

Map: Jetpack have animated texture now
[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 gAlphaMonsterRect: Byte;
198 gAlphaAreaRect: Byte;
199 drEdge: Array[0..3] of Byte;
200 gPanels: Array of TPanel;
201 gItems: Array of TItem;
202 gAreas: Array of TArea;
203 gMonsters: Array of TMonster;
204 gTriggers: Array of TTrigger;
205 gMapInfo: TMapInfo;
206 MapOffset: TPoint = (X: 0; Y: 0);
207 SelectedObjects: Array of TMapObject = nil;
209 procedure LoadSky(Res: String);
211 function AddItem(Item: TItem): DWORD;
212 function AddPanel(Panel: TPanel): DWORD;
213 function AddArea(Area: TArea): DWORD;
214 function AddMonster(Monster: TMonster): DWORD;
215 function AddTrigger(Trigger: TTrigger): DWORD;
217 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
218 function PanelInShownLayer(PanelType: Word): Boolean;
219 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
220 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
221 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
222 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
223 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
224 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
225 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
227 function GetPanelName(PanelType: Word): String;
228 function GetPanelType(PanelName: String): Word;
229 function GetTriggerName(TriggerType: Byte): String;
230 function GetTriggerType(TriggerName: String): Byte;
232 function IsSpecialTexture(TextureName: String): Boolean;
233 function SpecialTextureID(TextureName: String): DWORD;
235 procedure ClearMap();
236 function SaveMap(Res: String): Pointer;
237 function LoadMap(Res: String): Boolean;
238 function LoadMapOld(_FileName: String): Boolean;
239 procedure DrawMap();
240 procedure LoadData();
241 procedure FreeData();
243 procedure ShiftMapObjects(dx, dy: Integer);
245 implementation
247 uses
248 BinEditor, g_textures, Dialogs, SysUtils, CONFIG, f_main,
249 Forms, Math, f_addresource_texture, WADEDITOR, g_language;
251 const
252 OLD_ITEM_MEDKIT_SMALL = 1;
253 OLD_ITEM_MEDKIT_LARGE = 2;
254 OLD_ITEM_ARMOR_GREEN = 3;
255 OLD_ITEM_ARMOR_BLUE = 4;
256 OLD_ITEM_SPHERE_BLUE = 5;
257 OLD_ITEM_SPHERE_WHITE = 6;
258 OLD_ITEM_WEAPON_SAW = 7;
259 OLD_ITEM_WEAPON_SHOTGUN1 = 8;
260 OLD_ITEM_WEAPON_SHOTGUN2 = 9;
261 OLD_ITEM_WEAPON_CHAINGUN = 10;
262 OLD_ITEM_WEAPON_ROCKETLAUNCHER = 11;
263 OLD_ITEM_WEAPON_PLASMA = 12;
264 OLD_ITEM_WEAPON_BFG = 13;
265 OLD_ITEM_WEAPON_SUPERPULEMET = 14;
266 OLD_ITEM_AMMO_BULLETS = 15;
267 OLD_ITEM_AMMO_BULLETS_BOX = 16;
268 OLD_ITEM_AMMO_SHELLS = 17;
269 OLD_ITEM_AMMO_SHELLS_BOX = 18;
270 OLD_ITEM_AMMO_ROCKET = 19;
271 OLD_ITEM_AMMO_ROCKET_BOX = 20;
272 OLD_ITEM_AMMO_CELL = 21;
273 OLD_ITEM_AMMO_CELL_BIG = 22;
274 OLD_ITEM_AMMO_BACKPACK = 23;
275 OLD_ITEM_KEY_RED = 24;
276 OLD_ITEM_KEY_GREEN = 25;
277 OLD_ITEM_KEY_BLUE = 26;
278 OLD_ITEM_SUIT = 27;
279 OLD_ITEM_OXYGEN = 28;
280 OLD_ITEM_MEDKIT_BLACK = 29;
281 OLD_ITEM_INVUL = 30;
283 ITEMSCONVERT: Array [OLD_ITEM_MEDKIT_SMALL..OLD_ITEM_INVUL] of Integer =
284 ((ITEM_MEDKIT_SMALL),
285 (ITEM_MEDKIT_LARGE),
286 (ITEM_ARMOR_GREEN),
287 (ITEM_ARMOR_BLUE),
288 (ITEM_SPHERE_BLUE),
289 (ITEM_SPHERE_WHITE),
290 (ITEM_WEAPON_SAW),
291 (ITEM_WEAPON_SHOTGUN1),
292 (ITEM_WEAPON_SHOTGUN2),
293 (ITEM_WEAPON_CHAINGUN),
294 (ITEM_WEAPON_ROCKETLAUNCHER),
295 (ITEM_WEAPON_PLASMA),
296 (ITEM_WEAPON_BFG),
297 (ITEM_WEAPON_SUPERPULEMET),
298 (ITEM_AMMO_BULLETS),
299 (ITEM_AMMO_BULLETS_BOX),
300 (ITEM_AMMO_SHELLS),
301 (ITEM_AMMO_SHELLS_BOX),
302 (ITEM_AMMO_ROCKET),
303 (ITEM_AMMO_ROCKET_BOX),
304 (ITEM_AMMO_CELL),
305 (ITEM_AMMO_CELL_BIG),
306 (ITEM_AMMO_BACKPACK),
307 (ITEM_KEY_RED),
308 (ITEM_KEY_GREEN),
309 (ITEM_KEY_BLUE),
310 (ITEM_SUIT),
311 (ITEM_OXYGEN),
312 (ITEM_MEDKIT_BLACK),
313 (ITEM_INVUL));
315 OldItemSize: Array [ITEM_MEDKIT_SMALL..ITEM_KEY_BLUE] of Array [0..1] of Byte =
316 (((14), (15)), // MEDKIT_SMALL
317 ((28), (19)), // MEDKIT_LARGE
318 ((28), (19)), // MEDKIT_BLACK - not in map generator
319 ((30), (16)), // ARMOR_GREEN
320 ((30), (16)), // ARMOR_BLUE
321 ((24), (24)), // SPHERE_BLUE
322 ((24), (24)), // SPHERE_WHITE
323 ((24), (46)), // SUIT
324 ((14), (27)), // OXYGEN
325 ((25), (25)), // INVUL - not in map generator
326 ((61), (23)), // WEAPON_SAW
327 ((62), (10)), // WEAPON_SHOTGUN1
328 ((52), (12)), // WEAPON_SHOTGUN2
329 ((53), (15)), // WEAPON_CHAINGUN
330 ((61), (15)), // WEAPON_ROCKETLAUNCHER
331 ((53), (14)), // WEAPON_PLASMA
332 ((61), (34)), // WEAPON_BFG
333 ((53), (16)), // WEAPON_SUPERPULEMET
334 (( 9), (10)), // AMMO_BULLETS
335 ((28), (16)), // AMMO_BULLETS_BOX
336 ((15), ( 7)), // AMMO_SHELLS
337 ((32), (12)), // AMMO_SHELLS_BOX
338 ((12), (26)), // AMMO_ROCKET
339 ((54), (21)), // AMMO_ROCKET_BOX
340 ((15), (12)), // AMMO_CELL
341 ((32), (21)), // AMMO_CELL_BIG
342 ((22), (29)), // AMMO_BACKPACK
343 ((16), (16)), // KEY_RED
344 ((16), (16)), // KEY_GREEN
345 ((16), (16))); // KEY_BLUE
347 OldAreaSize: Array [0..1] of Byte = ((34), (56));
349 SKY_TEXTURE = 'SKY';
351 procedure LoadSky(Res: String);
352 var
353 fn: String;
355 begin
356 g_DeleteTexture(SKY_TEXTURE);
358 if Res = '' then
359 Exit;
361 g_ProcessResourceStr(Res, @fn, nil, nil);
363 if fn = '' then
364 begin
365 g_ProcessResourceStr(OpenedMap, @fn, nil, nil);
366 fn := fn + Res;
367 end
368 else
369 fn := EditorDir + 'wads/' + Res;
371 g_CreateTextureWAD(SKY_TEXTURE, fn);
372 end;
374 function AddItem(Item: TItem): DWORD;
375 var
376 a: Integer;
377 ok: Boolean;
379 begin
380 ok := False;
381 a := 0;
383 if gItems <> nil then
384 for a := 0 to High(gItems) do
385 if gItems[a].ItemType = ITEM_NONE then
386 begin
387 ok := True;
388 Break;
389 end;
391 if not ok then
392 begin
393 a := Length(gItems);
394 SetLength(gItems, a + 128);
395 end;
397 gItems[a] := Item;
399 Result := a;
400 end;
402 function AddPanel(Panel: TPanel): DWORD;
403 var
404 a, b: Integer;
405 ok: Boolean;
407 begin
408 ok := False;
409 a := 0;
410 b := -1;
412 if gPanels <> nil then
413 for a := High(gPanels) downto 0 do
414 if gPanels[a].PanelType = PANEL_NONE then
415 b := a
416 else
417 Break;
419 if b <> -1 then
420 begin
421 a := b;
422 ok := True;
423 end;
425 if not ok then
426 begin
427 a := Length(gPanels);
428 SetLength(gPanels, a + 512);
429 end;
431 gPanels[a] := Panel;
433 Result := a;
434 end;
436 function AddArea(Area: TArea): DWORD;
437 var
438 a: Integer;
439 ok: Boolean;
441 begin
442 ok := False;
443 a := 0;
445 if gAreas <> nil then
446 for a := 0 to High(gAreas) do
447 if gAreas[a].AreaType = AREA_NONE then
448 begin
449 ok := True;
450 Break;
451 end;
453 if not ok then
454 begin
455 a := Length(gAreas);
456 SetLength(gAreas, a + 64);
457 end;
459 gAreas[a] := Area;
461 Result := a;
462 end;
464 function AddMonster(Monster: TMonster): DWORD;
465 var
466 a: Integer;
467 ok: Boolean;
469 begin
470 ok := False;
471 a := 0;
473 if gMonsters <> nil then
474 for a := 0 to High(gMonsters) do
475 if gMonsters[a].MonsterType = MONSTER_NONE then
476 begin
477 ok := True;
478 Break;
479 end;
481 if not ok then
482 begin
483 a := Length(gMonsters);
484 SetLength(gMonsters, a + 128);
485 end;
487 gMonsters[a] := Monster;
489 Result := a;
490 end;
492 function AddTrigger(Trigger: TTrigger): DWORD;
493 var
494 a: Integer;
495 ok: Boolean;
497 begin
498 ok := False;
499 a := 0;
501 if gTriggers <> nil then
502 for a := 0 to High(gTriggers) do
503 if gTriggers[a].TriggerType = TRIGGER_NONE then
504 begin
505 ok := True;
506 Break;
507 end;
509 if not ok then
510 begin
511 a := Length(gTriggers);
512 SetLength(gTriggers, a + 64);
513 end;
515 gTriggers[a] := Trigger;
517 Result := a;
518 end;
520 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
521 var
522 a: Integer;
524 begin
525 case ObjectType of
526 OBJECT_PANEL:
527 begin
528 // Убираем ссылки триггеров на эту панель:
529 if gTriggers <> nil then
530 for a := 0 to High(gTriggers) do
531 if gTriggers[a].TriggerType <> 0 then
532 begin
533 if gTriggers[a].TexturePanel = Integer(ID) then
534 gTriggers[a].TexturePanel := -1;
536 if gTriggers[a].TriggerType in [
537 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
538 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
539 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
540 TRIGGER_LIFT] then
541 if gTriggers[a].Data.PanelID = Integer(ID) then
542 gTriggers[a].Data.PanelID := -1;
544 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
545 (gTriggers[a].Data.ShotPanelID = Integer(ID)) then
546 gTriggers[a].Data.ShotPanelID := -1;
547 end;
549 gPanels[ID].PanelType := 0;
550 end;
552 OBJECT_ITEM:
553 gItems[ID].ItemType := 0;
555 OBJECT_MONSTER:
556 begin
557 // Убираем ссылки триггеров на этого монстра:
558 if gTriggers <> nil then
559 for a := 0 to High(gTriggers) do
560 if gTriggers[a].TriggerType <> 0 then
561 begin
562 if gTriggers[a].TriggerType in [TRIGGER_PRESS,
563 TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
564 if (gTriggers[a].Data.MonsterID-1 = Integer(ID)) then
565 gTriggers[a].Data.MonsterID := 0;
566 end;
568 gMonsters[ID].MonsterType := 0;
569 end;
571 OBJECT_AREA:
572 gAreas[ID].AreaType := 0;
574 OBJECT_TRIGGER:
575 gTriggers[ID].TriggerType := 0;
576 end;
577 end;
579 function PanelInShownLayer(PanelType: Word): Boolean;
580 begin
581 case PanelType of
582 PANEL_WALL:
583 Result := LayerEnabled[LAYER_WALLS];
585 PANEL_BACK:
586 Result := LayerEnabled[LAYER_BACK];
588 PANEL_FORE:
589 Result := LayerEnabled[LAYER_FOREGROUND];
591 PANEL_STEP:
592 Result := LayerEnabled[LAYER_STEPS];
594 PANEL_WATER, PANEL_ACID1, PANEL_ACID2,
595 PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT,
596 PANEL_OPENDOOR, PANEL_CLOSEDOOR,
597 PANEL_BLOCKMON:
598 Result := LayerEnabled[LAYER_WATER];
600 else
601 Result := False;
602 end;
603 end;
605 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
606 var
607 a: Integer;
609 begin
610 Result := nil;
612 case ObjectType of
613 OBJECT_PANEL:
614 if gPanels <> nil then
615 for a := High(gPanels) downto 0 do
616 with gPanels[a] do
617 begin
618 if not PanelInShownLayer(gPanels[a].PanelType) then
619 Continue;
621 if g_Collide(X, Y, Width, Height,
622 fX, fY, fWidth, fHeight) then
623 begin
624 SetLength(Result, Length(Result)+1);
625 Result[High(Result)] := a;
627 if not All then
628 Break;
629 end;
630 end;
632 OBJECT_ITEM:
633 if LayerEnabled[LAYER_ITEMS] and (gItems <> nil) then
634 for a := High(gItems) downto 0 do
635 with gItems[a] do
636 if (ItemType <> ITEM_NONE) and
637 g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
638 fX, fY, fWidth, fHeight) then
639 begin
640 SetLength(Result, Length(Result)+1);
641 Result[High(Result)] := a;
643 if not All then
644 Break;
645 end;
647 OBJECT_MONSTER:
648 if LayerEnabled[LAYER_MONSTERS] and (gMonsters <> nil) then
649 for a := High(gMonsters) downto 0 do
650 if gMonsters[a].MonsterType <> MONSTER_NONE then
651 with MonsterSize[gMonsters[a].MonsterType] do
652 if (gMonsters[a].MonsterType <> 0) and
653 g_Collide(gMonsters[a].X, gMonsters[a].Y, Width, Height,
654 fX, fY, fWidth, fHeight) then
655 begin
656 SetLength(Result, Length(Result)+1);
657 Result[High(Result)] := a;
659 if not All then
660 Break;
661 end;
663 OBJECT_AREA:
664 if LayerEnabled[LAYER_AREAS] and (gAreas <> nil) then
665 for a := High(gAreas) downto 0 do
666 if gAreas[a].AreaType <> AREA_NONE then
667 with AreaSize[gAreas[a].AreaType] do
668 if (gAreas[a].AreaType <> 0) and
669 g_Collide(gAreas[a].X, gAreas[a].Y, Width, Height,
670 fX, fY, fWidth, fHeight) then
671 begin
672 SetLength(Result, Length(Result)+1);
673 Result[High(Result)] := a;
675 if not All then
676 Break;
677 end;
679 OBJECT_TRIGGER:
680 if LayerEnabled[LAYER_TRIGGERS] and (gTriggers <> nil) then
681 for a := High(gTriggers) downto 0 do
682 if gTriggers[a].TriggerType <> TRIGGER_NONE then
683 with gTriggers[a] do
684 begin
685 if (TriggerType <> 0) and
686 g_Collide(X, Y, Width, Height,
687 fX, fY, fWidth, fHeight) then
688 begin
689 SetLength(Result, Length(Result)+1);
690 Result[High(Result)] := a;
692 if not All then
693 Break;
694 end;
695 end;
696 end;
697 end;
699 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
700 var
701 PanelID: DWORD;
703 begin
704 Result := False;
705 PanelID := DWORD(-1);
707 case ObjectType of
708 OBJECT_PANEL:
709 with gPanels[fID] do
710 Result := (PanelID <> fID) and
711 g_CollideLevel2(X+dX, Y+dY,
712 Width, Height,
713 fID, PanelID);
715 OBJECT_ITEM:
716 with gItems[fID] do
717 Result := g_CollideLevel(X+dX, Y+dY,
718 ItemSize[ItemType][0], ItemSize[ItemType][1]);
720 OBJECT_MONSTER:
721 with MonsterSize[gMonsters[fID].MonsterType] do
722 Result := g_CollideLevel(gMonsters[fID].X+dX, gMonsters[fID].Y+dY,
723 Width, Height);
725 OBJECT_AREA:
726 with AreaSize[gAreas[fID].AreaType] do
727 Result := g_CollideLevel(gAreas[fID].X+dX, gAreas[fID].Y+dY,
728 Width, Height);
730 OBJECT_TRIGGER:
731 with gTriggers[fID] do
732 Result := g_CollideLevel(X+dX, Y+dY,
733 Width, Height);
734 end;
735 end;
737 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
738 begin
739 Result := False;
741 case ObjectType of
742 OBJECT_PANEL:
743 with gPanels[ID] do
744 Result := g_Collide(X, Y, Width, Height,
745 fX, fY, fWidth, fHeight);
747 OBJECT_ITEM:
748 with gItems[ID] do
749 Result := g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
750 fX, fY, fWidth, fHeight);
752 OBJECT_MONSTER:
753 with MonsterSize[gMonsters[ID].MonsterType] do
754 Result := g_Collide(gMonsters[ID].X, gMonsters[ID].Y, Width, Height,
755 fX, fY, fWidth, fHeight);
757 OBJECT_AREA:
758 with AreaSize[gAreas[ID].AreaType] do
759 Result := g_Collide(gAreas[ID].X, gAreas[ID].Y, Width, Height,
760 fX, fY, fWidth, fHeight);
762 OBJECT_TRIGGER:
763 with gTriggers[ID] do
764 Result := g_Collide(X, Y, Width, Height,
765 fX, fY, fWidth, fHeight);
766 end;
767 end;
769 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
770 begin
771 case ObjectType of
772 OBJECT_PANEL:
773 with gPanels[ID] do
774 begin
775 Result.X := X;
776 Result.Y := Y;
777 Result.Width := Width;
778 Result.Height := Height;
779 end;
781 OBJECT_ITEM:
782 with gItems[ID] do
783 begin
784 Result.X := X;
785 Result.Y := Y;
786 Result.Width := ItemSize[ItemType][0];
787 Result.Height := ItemSize[ItemType][1];
788 end;
790 OBJECT_MONSTER:
791 with MonsterSize[gMonsters[ID].MonsterType] do
792 begin
793 Result.X := gMonsters[ID].X;
794 Result.Y := gMonsters[ID].Y;
795 Result.Width := Width;
796 Result.Height := Height;
797 end;
799 OBJECT_AREA:
800 with AreaSize[gAreas[ID].AreaType] do
801 begin
802 Result.X := gAreas[ID].X;
803 Result.Y := gAreas[ID].Y;
804 Result.Width := Width;
805 Result.Height := Height;
806 end;
808 OBJECT_TRIGGER:
809 with gTriggers[ID] do
810 begin
811 Result.X := X;
812 Result.Y := Y;
813 Result.Width := Width;
814 Result.Height := Height;
815 end;
817 else
818 begin
819 Result.X := 0;
820 Result.Y := 0;
821 Result.Width := 0;
822 Result.Height := 0;
823 end;
824 end;
825 end;
827 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
828 begin
829 case ObjectType of
830 OBJECT_PANEL:
831 with gPanels[ID] do
832 begin
833 X := X + dX;
834 Y := Y + dY;
835 end;
837 OBJECT_ITEM:
838 with gItems[ID] do
839 begin
840 X := X + dX;
841 Y := Y + dY;
842 end;
844 OBJECT_MONSTER:
845 with gMonsters[ID] do
846 begin
847 X := X + dX;
848 Y := Y + dY;
849 end;
851 OBJECT_AREA:
852 with gAreas[ID] do
853 begin
854 X := X + dX;
855 Y := Y + dY;
856 end;
858 OBJECT_TRIGGER:
859 with gTriggers[ID] do
860 begin
861 X := X + dX;
862 Y := Y + dY;
863 end;
864 end;
865 end;
867 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
868 begin
869 case ObjectType of
870 OBJECT_PANEL:
871 with gPanels[ID] do
872 begin
873 if Width >= -dWidth then
874 Width := Width+dWidth
875 else
876 begin
877 Width := 0;
878 Exit;
879 end;
881 if Height >= -dHeight then
882 Height := Height+dHeight
883 else
884 begin
885 Height := 0;
886 Exit;
887 end;
889 case ResizeDir of
890 2: Y := Y - dHeight;
891 4: X := X - dWidth;
892 end;
893 end;
895 OBJECT_ITEM, OBJECT_MONSTER, OBJECT_AREA:
896 Exit;
898 OBJECT_TRIGGER:
899 with gTriggers[ID] do
900 begin
901 if Width >= -dWidth then
902 Width := Width+dWidth
903 else
904 begin
905 Width := 0;
906 Exit;
907 end;
909 if Height >= -dHeight then
910 Height := Height+dHeight
911 else
912 begin
913 Height := 0;
914 Exit;
915 end;
917 case ResizeDir of
918 2: Y := Y - dHeight;
919 4: X := X - dWidth;
920 end;
921 end;
922 end;
923 end;
925 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
926 var
927 a: Integer;
929 begin
930 Result := False;
932 if SelectedObjects <> nil then
933 for a := 0 to High(SelectedObjects) do
934 if SelectedObjects[a].Live and
935 (SelectedObjects[a].ObjectType = ObjectType) and
936 (SelectedObjects[a].ID = ID) then
937 begin
938 Result := True;
939 Break;
940 end;
941 end;
943 function GetPanelName(PanelType: Word): String;
944 begin
945 Result := '';
947 case PanelType of
948 PANEL_WALL: Result := PANELNAMES[0];
949 PANEL_BACK: Result := PANELNAMES[1];
950 PANEL_FORE: Result := PANELNAMES[2];
951 PANEL_OPENDOOR: Result := PANELNAMES[3];
952 PANEL_CLOSEDOOR: Result := PANELNAMES[4];
953 PANEL_STEP: Result := PANELNAMES[5];
954 PANEL_WATER: Result := PANELNAMES[6];
955 PANEL_ACID1: Result := PANELNAMES[7];
956 PANEL_ACID2: Result := PANELNAMES[8];
957 PANEL_LIFTUP: Result := PANELNAMES[9];
958 PANEL_LIFTDOWN: Result := PANELNAMES[10];
959 PANEL_LIFTLEFT: Result := PANELNAMES[11];
960 PANEL_LIFTRIGHT: Result := PANELNAMES[12];
961 PANEL_BLOCKMON: Result := PANELNAMES[13];
962 else Assert(False);
963 end;
964 end;
966 function GetPanelType(PanelName: String): Word;
967 begin
968 Result := 0;
970 if PanelName = PANELNAMES[0] then
971 Result := PANEL_WALL
972 else if PanelName = PANELNAMES[1] then
973 Result := PANEL_BACK
974 else if PanelName = PANELNAMES[2] then
975 Result := PANEL_FORE
976 else if PanelName = PANELNAMES[3] then
977 Result := PANEL_OPENDOOR
978 else if PanelName = PANELNAMES[4] then
979 Result := PANEL_CLOSEDOOR
980 else if PanelName = PANELNAMES[5] then
981 Result := PANEL_STEP
982 else if PanelName = PANELNAMES[6] then
983 Result := PANEL_WATER
984 else if PanelName = PANELNAMES[7] then
985 Result := PANEL_ACID1
986 else if PanelName = PANELNAMES[8] then
987 Result := PANEL_ACID2
988 else if PanelName = PANELNAMES[9] then
989 Result := PANEL_LIFTUP
990 else if PanelName = PANELNAMES[10] then
991 Result := PANEL_LIFTDOWN
992 else if PanelName = PANELNAMES[11] then
993 Result := PANEL_LIFTLEFT
994 else if PanelName = PANELNAMES[12] then
995 Result := PANEL_LIFTRIGHT
996 else if PanelName = PANELNAMES[13] then
997 Result := PANEL_BLOCKMON;
999 Assert(Result <> 0);
1000 end;
1002 function GetTriggerName(TriggerType: Byte): String;
1003 begin
1004 if TriggerType in [TRIGGER_EXIT..TRIGGER_MAX] then
1005 Result := TriggerNames[TriggerType]
1006 else
1007 Assert(False);
1008 end;
1010 function GetTriggerType(TriggerName: String): Byte;
1011 var
1012 i: Integer;
1014 begin
1015 Result := TRIGGER_NONE;
1016 for i := TRIGGER_EXIT to TRIGGER_MAX do
1017 if TriggerNames[i] = TriggerName then
1018 begin
1019 Result := i;
1020 Exit;
1021 end;
1023 Assert(False);
1024 end;
1026 function IsSpecialTexture(TextureName: string): Boolean;
1027 begin
1028 Result := (TextureName = TEXTURE_NAME_WATER) or
1029 (TextureName = TEXTURE_NAME_ACID1) or
1030 (TextureName = TEXTURE_NAME_ACID2);
1031 end;
1033 function SpecialTextureID(TextureName: string): DWORD;
1034 begin
1035 Assert(IsSpecialTexture(TextureName));
1037 Result := 0;
1039 if TextureName = TEXTURE_NAME_WATER then
1040 Result := TEXTURE_SPECIAL_WATER
1041 else
1042 if TextureName = TEXTURE_NAME_ACID1 then
1043 Result := TEXTURE_SPECIAL_ACID1
1044 else
1045 if TextureName = TEXTURE_NAME_ACID2 then
1046 Result := TEXTURE_SPECIAL_ACID2;
1047 end;
1049 function SaveMap(Res: String): Pointer;
1050 var
1051 WAD: TWADEditor_1;
1052 MapWriter: TMapWriter_1;
1053 textures: TTexturesRec1Array;
1054 panels: TPanelsRec1Array;
1055 items: TItemsRec1Array;
1056 areas: TAreasRec1Array;
1057 monsters: TMonsterRec1Array;
1058 triggers: TTriggersRec1Array;
1059 header: TMapHeaderRec_1;
1060 a, b, c: Integer;
1061 s: String;
1062 PanelTable: Array of Array [0..1] of Word;
1063 MonsterTable: Array of Array [0..1] of Word;
1064 Data: Pointer;
1065 FileName, SectionName, ResName: String;
1066 Len: LongWord;
1068 begin
1069 WAD := nil;
1070 textures := nil;
1071 panels := nil;
1072 items := nil;
1073 areas := nil;
1074 monsters := nil;
1075 triggers := nil;
1076 PanelTable := nil;
1077 MonsterTable := nil;
1078 Data := nil;
1079 Len := 0;
1081 // Открываем WAD, если надо:
1082 if Res <> '' then
1083 begin
1084 WAD := TWADEditor_1.Create();
1085 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1086 if not WAD.ReadFile(FileName) then
1087 WAD.FreeWAD();
1089 WAD.CreateImage();
1090 end;
1092 MapWriter := TMapWriter_1.Create();
1094 // Сохраняем заголовок:
1095 with header do
1096 begin
1097 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1099 s := utf2win(gMapInfo.Name);
1100 if s <> '' then
1101 CopyMemory(@MapName[0], @s[1], Min(32, Length(s)));
1103 s := utf2win(gMapInfo.Description);
1104 if s <> '' then
1105 CopyMemory(@MapDescription[0], @s[1], Min(256, Length(s)));
1107 s := utf2win(gMapInfo.Author);
1108 if s <> '' then
1109 CopyMemory(@MapAuthor[0], @s[1], Min(32, Length(s)));
1111 s := utf2win(gMapInfo.MusicName);
1112 if s <> '' then
1113 CopyMemory(@MusicName[0], @s[1], Min(64, Length(s)));
1115 s := utf2win(gMapInfo.SkyName);
1116 if s <> '' then
1117 CopyMemory(@SkyName[0], @s[1], Min(64, Length(s)));
1119 Width := gMapInfo.Width;
1120 Height := gMapInfo.Height;
1121 end;
1123 MapWriter.AddHeader(header);
1125 // Сохраняем названия текстур:
1126 if MainForm.lbTextureList.Items.Count > 0 then
1127 begin
1128 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1129 begin
1130 SetLength(textures, Length(textures)+1);
1131 s := utf2win(MainForm.lbTextureList.Items[a]);
1132 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1133 if g_GetTextureFlagByName(MainForm.lbTextureList.Items[a]) = 1 then
1134 textures[High(textures)].Anim := 1
1135 else
1136 textures[High(textures)].Anim := 0;
1137 end;
1139 MapWriter.AddTextures(textures);
1140 end;
1142 // Сохраняем панели:
1143 if gPanels <> nil then
1144 begin
1145 c := 0;
1147 for a := 0 to High(gPanels) do
1148 if gPanels[a].PanelType <> 0 then
1149 begin
1150 SetLength(PanelTable, Length(PanelTable)+1);
1151 PanelTable[High(PanelTable)][0] := a;
1152 PanelTable[High(PanelTable)][1] := c;
1153 c := c + 1;
1155 SetLength(panels, Length(panels)+1);
1157 with panels[High(panels)] do
1158 begin
1159 X := gPanels[a].X;
1160 Y := gPanels[a].Y;
1161 Width := gPanels[a].Width;
1162 Height := gPanels[a].Height;
1163 PanelType := gPanels[a].PanelType;
1164 Alpha := gPanels[a].Alpha;
1166 TextureNum := 0;
1167 Flags := 0;
1169 if WordBool(gPanels[a].PanelType and
1170 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1171 Flags := PANEL_FLAG_WATERTEXTURES;
1173 // Может быть текстура:
1174 if not WordBool(gPanels[a].PanelType and
1175 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1176 begin
1177 if gPanels[a].Blending then
1178 Flags := Flags or PANEL_FLAG_BLENDING;
1179 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1180 Flags := Flags or PANEL_FLAG_HIDE;
1182 // Номер текстуры в списке текстур:
1183 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1184 for b := 0 to High(textures) do
1185 if utf2win(gPanels[a].TextureName) = textures[b].Resource then
1186 begin
1187 TextureNum := b;
1188 Break;
1189 end;
1190 end;
1191 end;
1192 end;
1194 MapWriter.AddPanels(panels);
1195 end;
1197 // Сохраняем предметы:
1198 if gItems <> nil then
1199 begin
1200 for a := 0 to High(gItems) do
1201 if gItems[a].ItemType <> 0 then
1202 begin
1203 SetLength(items, Length(items)+1);
1205 with items[High(items)] do
1206 begin
1207 X := gItems[a].X;
1208 Y := gItems[a].Y;
1209 ItemType := gItems[a].ItemType;
1210 if gItems[a].OnlyDM then
1211 Options := Options or ITEM_OPTION_ONLYDM;
1212 if gItems[a].Fall then
1213 Options := Options or ITEM_OPTION_FALL;
1214 end;
1215 end;
1217 MapWriter.AddItems(items);
1218 end;
1220 // Сохраняем монстров:
1221 if gMonsters <> nil then
1222 begin
1223 c := 0;
1225 for a := 0 to High(gMonsters) do
1226 if gMonsters[a].MonsterType <> 0 then
1227 begin
1228 SetLength(MonsterTable, Length(MonsterTable)+1);
1229 MonsterTable[High(MonsterTable)][0] := a;
1230 MonsterTable[High(MonsterTable)][1] := c;
1231 c := c + 1;
1233 SetLength(monsters, Length(monsters)+1);
1235 with monsters[High(monsters)] do
1236 begin
1237 X := gMonsters[a].X;
1238 Y := gMonsters[a].Y;
1239 MonsterType := gMonsters[a].MonsterType;
1240 Direction := Ord(gMonsters[a].Direction);
1241 end;
1242 end;
1244 MapWriter.AddMonsters(monsters);
1245 end;
1247 // Сохраняем области:
1248 if gAreas <> nil then
1249 begin
1250 for a := 0 to High(gAreas) do
1251 if gAreas[a].AreaType <> 0 then
1252 begin
1253 SetLength(areas, Length(areas)+1);
1255 with areas[High(areas)] do
1256 begin
1257 X := gAreas[a].X;
1258 Y := gAreas[a].Y;
1259 AreaType := gAreas[a].AreaType;
1260 Direction := Ord(gAreas[a].Direction);
1261 end;
1262 end;
1264 MapWriter.AddAreas(areas);
1265 end;
1267 // Сохраняем триггеры:
1268 if gTriggers <> nil then
1269 begin
1270 for a := 0 to High(gTriggers) do
1271 if gTriggers[a].TriggerType <> 0 then
1272 begin
1273 SetLength(triggers, Length(triggers)+1);
1275 with triggers[High(triggers)] do
1276 begin
1277 X := gTriggers[a].X;
1278 Y := gTriggers[a].Y;
1279 Width := gTriggers[a].Width;
1280 Height := gTriggers[a].Height;
1281 Enabled := Byte(gTriggers[a].Enabled);
1282 TexturePanel := -1;
1283 TriggerType := gTriggers[a].TriggerType;
1284 ActivateType := gTriggers[a].ActivateType;
1285 Keys := gTriggers[a].Key;
1286 DATA := gTriggers[a].Data.Default;
1288 if PanelTable <> nil then
1289 begin
1290 // Ищем номер панели, которой этот триггер меняет текстуру:
1291 if gTriggers[a].TexturePanel <> -1 then
1292 begin
1293 for c := 0 to High(PanelTable) do
1294 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1295 TexturePanel := PanelTable[c][1];
1296 end;
1298 // Ищем номер панели, которую меняет этот триггер:
1299 if gTriggers[a].TriggerType in [
1300 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1301 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1302 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1303 if TTriggerData(DATA).PanelID <> -1 then
1304 for c := 0 to High(PanelTable) do
1305 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1306 begin
1307 TTriggerData(DATA).PanelID := PanelTable[c][1];
1308 Break;
1309 end;
1311 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1312 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1313 (TTriggerData(DATA).ShotPanelID <> -1) then
1314 begin
1315 for c := 0 to High(PanelTable) do
1316 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1317 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1318 end;
1319 end;
1321 if MonsterTable <> nil then
1322 begin
1323 // Ищем номер монстра - условие активации триггера:
1324 if gTriggers[a].TriggerType in [
1325 TRIGGER_PRESS, TRIGGER_ON,
1326 TRIGGER_OFF, TRIGGER_ONOFF] then
1327 if TTriggerData(DATA).MonsterID <> 0 then
1328 for c := 0 to High(MonsterTable) do
1329 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1330 begin
1331 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1332 Break;
1333 end;
1334 end;
1335 end;
1336 end;
1338 MapWriter.AddTriggers(triggers);
1339 end;
1341 // Сохраняем карту в память:
1342 Len := MapWriter.SaveMap(Data);
1344 MapWriter.Free();
1346 // Записываем в WAD, если надо:
1347 if Res <> '' then
1348 begin
1349 s := utf2win(ResName);
1350 WAD.RemoveResource('', s);
1351 WAD.AddResource(Data, Len, s, '');
1352 WAD.SaveTo(FileName);
1354 FreeMem(Data);
1355 WAD.Free();
1357 Result := nil;
1358 end
1359 else
1360 Result := Data;
1361 end;
1363 procedure AddTexture(res: String; Error: Boolean);
1364 var
1365 a: Integer;
1366 begin
1367 with MainForm.lbTextureList do
1368 begin
1369 for a := 0 to Count-1 do
1370 if Items[a] = res then
1371 Exit;
1373 if Error and (slInvalidTextures.IndexOf(res) = -1) then
1374 slInvalidTextures.Add(res);
1375 Items.Add(res);
1376 end;
1377 end;
1379 function LoadMap(Res: String): Boolean;
1380 var
1381 WAD: TWADEditor_1;
1382 MapReader: TMapReader_1;
1383 Header: TMapHeaderRec_1;
1384 textures: TTexturesRec1Array;
1385 panels: TPanelsRec1Array;
1386 items: TItemsRec1Array;
1387 monsters: TMonsterRec1Array;
1388 areas: TAreasRec1Array;
1389 triggers: TTriggersRec1Array;
1390 panel: TPanel;
1391 item: TItem;
1392 monster: TMonster;
1393 area: TArea;
1394 trigger: TTrigger;
1395 a: Integer;
1396 Data: Pointer;
1397 Width, Height, m: Word;
1398 FileName, SectionName, ResName, _fn: String;
1399 TextureRes, ustr: String;
1400 pData: Pointer;
1401 Len, FrameLen: Integer;
1402 Error: Boolean;
1403 NoTextureID: DWORD;
1404 NW, NH: Word;
1405 begin
1406 Result := False;
1407 pData := nil;
1408 Len := 0;
1409 Data := nil;
1410 FrameLen := 0;
1411 Width := 0;
1412 Height := 0;
1413 NoTextureID := 0;
1414 NW := 0;
1415 NH := 0;
1417 MainForm.pbLoad.Position := 0;
1418 MainForm.lLoad.Caption := _lc[I_LOAD_WAD];
1419 Application.ProcessMessages();
1421 // Открываем WAD:
1422 WAD := TWADEditor_1.Create();
1423 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1425 if not WAD.ReadFile(FileName) then
1426 begin
1427 WAD.Free();
1428 Exit;
1429 end;
1431 // Читаем ресурс карты:
1432 if not WAD.GetResource('', utf2win(ResName), pData, Len) then
1433 begin
1434 WAD.Free();
1435 Exit;
1436 end;
1438 WAD.Free();
1440 MapReader := TMapReader_1.Create();
1442 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];
1443 Application.ProcessMessages();
1445 MapReader.LoadMap(pData);
1447 // Загружаем текстуры:
1448 textures := MapReader.GetTextures();
1450 if textures <> nil then
1451 begin
1452 MainForm.pbLoad.Position := 0;
1453 MainForm.pbLoad.Max := Length(textures);
1454 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1456 for a := 0 to High(textures) do
1457 begin
1458 MainForm.pbLoad.StepIt();
1459 Application.ProcessMessages();
1460 ustr := win2utf(textures[a].Resource);
1462 if IsSpecialTexture(ustr) then
1463 begin
1464 AddTexture(ustr, False);
1465 Continue;
1466 end;
1468 g_ProcessResourceStr(ustr, @_fn, nil, nil);
1470 if _fn = '' then
1471 TextureRes := FileName + ustr
1472 else
1473 TextureRes := EditorDir+'wads/'+ustr;
1475 Error := False;
1477 if not ByteBool(textures[a].Anim) then
1478 begin // Обычная текстура
1479 if not g_CreateTextureWAD(ustr, TextureRes) then
1480 begin
1481 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s',
1482 [ustr]), MSG_WARNING);
1483 Error := True;
1484 end;
1486 AddTexture(ustr, Error);
1487 end
1488 else // Anim
1489 begin // Анимированная текстура
1490 if not GetFrame(TextureRes, Data, FrameLen, Width, Height) then
1491 begin // Кадры
1492 e_WriteLog(Format('GetFrame() error, res=%s',
1493 [ustr]), MSG_WARNING);
1494 Error := True;
1495 end;
1497 if not g_CreateTextureMemorySize(Data, FrameLen, ustr, 0, 0, Width, Height, 1) then
1498 begin // Сама текстура
1499 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s',
1500 [ustr]), MSG_WARNING);
1501 Error := True;
1502 end;
1504 AddTexture(ustr, Error);
1505 end;
1506 end;
1507 end;
1509 // Загружаем панели:
1510 panels := MapReader.GetPanels();
1512 if panels <> nil then
1513 begin
1514 MainForm.pbLoad.Position := 0;
1515 MainForm.pbLoad.Max := Length(panels);
1516 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1518 for a := 0 to High(panels) do
1519 begin
1520 MainForm.pbLoad.StepIt();
1521 Application.ProcessMessages();
1523 panel.X := panels[a].X;
1524 panel.Y := panels[a].Y;
1525 panel.Height := panels[a].Height;
1526 panel.Width := panels[a].Width;
1527 panel.PanelType := panels[a].PanelType;
1528 panel.Alpha := panels[a].Alpha;
1530 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1532 panel.TextureWidth := 0;
1533 panel.TextureHeight := 0;
1534 panel.TextureName := '';
1535 panel.TextureID := TEXTURE_SPECIAL_NONE;
1537 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_STEP or
1538 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1540 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1541 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1543 // Если панель видима:
1544 if WordBool(panel.PanelType and m) and
1545 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1546 begin
1547 ustr := win2utf(textures[panels[a].TextureNum].Resource);
1548 if not IsSpecialTexture(ustr) then
1549 begin // Текстура
1550 if g_GetTexture(ustr, panel.TextureID) then
1551 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1552 else begin
1553 panel.TextureWidth := 1;
1554 panel.TextureHeight := 1;
1555 if g_GetTexture('NOTEXTURE', NoTextureID) then
1556 begin
1557 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1558 g_GetTextureSizeByID(NoTextureID, NW, NH);
1559 panel.TextureWidth := NW;
1560 panel.TextureHeight := NH;
1561 end;
1562 end;
1563 end
1564 else // Спец. текстура
1565 panel.TextureID := SpecialTextureID(ustr);
1567 panel.TextureName := ustr;
1568 end;
1570 // Жидкость без текстуры:
1571 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1572 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1573 begin
1574 case panel.PanelType of
1575 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1576 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1577 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1578 end;
1580 panel.TextureID := SpecialTextureID(panel.TextureName);
1581 AddTexture(panel.TextureName, False);
1582 end;
1584 AddPanel(panel);
1585 end;
1586 end;
1588 // Загружаем предметы:
1589 items := MapReader.GetItems();
1591 if items <> nil then
1592 begin
1593 MainForm.pbLoad.Position := 0;
1594 MainForm.pbLoad.Max := Length(items);
1595 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1597 for a := 0 to High(items) do
1598 begin
1599 MainForm.pbLoad.StepIt();
1600 Application.ProcessMessages();
1602 item.X := items[a].X;
1603 item.Y := items[a].Y;
1604 item.ItemType := items[a].ItemType;
1605 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1606 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1608 AddItem(item);
1609 end;
1610 end;
1612 // Загружаем монстров:
1613 monsters := MapReader.GetMonsters();
1615 if monsters <> nil then
1616 begin
1617 MainForm.pbLoad.Position := 0;
1618 MainForm.pbLoad.Max := Length(monsters);
1619 MainForm.lLoad.Caption := _lc[I_LOAD_MONSTERS];
1621 for a := 0 to High(monsters) do
1622 begin
1623 MainForm.pbLoad.StepIt();
1624 Application.ProcessMessages();
1626 monster.X := monsters[a].X;
1627 monster.Y := monsters[a].Y;
1628 monster.MonsterType := monsters[a].MonsterType;
1629 monster.Direction := TDirection(monsters[a].Direction);
1631 AddMonster(monster);
1632 end;
1633 end;
1635 // Загружаем области:
1636 areas := MapReader.GetAreas();
1638 if areas <> nil then
1639 begin
1640 MainForm.pbLoad.Position := 0;
1641 MainForm.pbLoad.Max := Length(areas);
1642 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1644 for a := 0 to High(areas) do
1645 begin
1646 MainForm.pbLoad.StepIt();
1647 Application.ProcessMessages();
1649 area.X := areas[a].X;
1650 area.Y := areas[a].Y;
1651 area.AreaType := areas[a].AreaType;
1652 area.Direction := TDirection(areas[a].Direction);
1654 AddArea(area);
1655 end;
1656 end;
1658 // Загружаем триггеры:
1659 triggers := MapReader.GetTriggers();
1661 if triggers <> nil then
1662 begin
1663 MainForm.pbLoad.Position := 0;
1664 MainForm.pbLoad.Max := Length(triggers);
1665 MainForm.lLoad.Caption := _lc[I_LOAD_TRIGGERS];
1667 for a := 0 to High(triggers) do
1668 begin
1669 MainForm.pbLoad.StepIt();
1670 Application.ProcessMessages();
1672 trigger.X := triggers[a].X;
1673 trigger.Y := triggers[a].Y;
1674 trigger.Width := triggers[a].Width;
1675 trigger.Height := triggers[a].Height;
1677 trigger.Enabled := ByteBool(triggers[a].Enabled);
1678 trigger.TexturePanel := triggers[a].TexturePanel;
1679 trigger.TriggerType := triggers[a].TriggerType;
1680 trigger.ActivateType := triggers[a].ActivateType;
1681 trigger.Key := triggers[a].Keys;
1682 trigger.Data.Default := triggers[a].DATA;
1684 AddTrigger(trigger);
1685 end;
1686 end;
1688 // Загружаем заголовок карты:
1689 Header := MapReader.GetMapHeader();
1691 gMapInfo.FileName := FileName;
1693 with gMapInfo do
1694 begin
1695 MapName := ResName;
1696 Name := win2utf(Header.MapName);
1697 Description := win2utf(Header.MapDescription);
1698 Author := win2utf(Header.MapAuthor);
1699 MusicName := win2utf(Header.MusicName);
1700 SkyName := win2utf(Header.SkyName);
1701 Height := Header.Height;
1702 Width := Header.Width;
1703 end;
1705 LoadSky(gMapInfo.SkyName);
1707 textures := nil;
1708 panels := nil;
1709 items := nil;
1710 areas := nil;
1711 triggers := nil;
1713 MapReader.Free();
1714 FreeMem(pData);
1716 Result := True;
1717 end;
1719 function LoadMapOld(_FileName: String): Boolean;
1720 const
1721 TexturePrefix = 'Standart.wad:STDTEXTURES\';
1722 DefaultMusRes = 'Standart.wad:STDMUS\MUS1';
1723 DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
1725 var
1726 map: TConfig;
1727 i, a: Integer;
1728 s, section: String;
1729 panel: TPanel;
1730 item: TItem;
1731 area: TArea;
1733 begin
1734 Result := False;
1736 if not FileExists(_FileName) then
1737 Exit;
1739 // Открытие карты:
1740 MainForm.pbLoad.Position := 0;
1741 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];;
1742 Application.ProcessMessages();
1744 map := TConfig.CreateFile(_FileName);
1746 // Чтение текстур:
1747 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1749 MainForm.pbLoad.Max := i;
1750 MainForm.pbLoad.Position := 0;
1751 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1753 for a := 1 to i do
1754 begin
1755 MainForm.pbLoad.StepIt();
1756 Application.ProcessMessages();
1758 s := TexturePrefix + UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1759 if s = TexturePrefix then
1760 Continue;
1762 // Нет такой текстуры - ищем в WAD карты:
1763 if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
1764 begin
1765 s := ExtractFileName(_FileName);
1766 Delete(s, Length(s)-3, 4);
1767 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
1769 if not g_CreateTextureWAD(s, EditorDir+'wads/'+s) then
1770 Continue;
1771 end;
1773 MainForm.lbTextureList.Items.Add(s);
1774 end;
1776 // Чтение панелей:
1777 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1779 MainForm.pbLoad.Max := i;
1780 MainForm.pbLoad.Position := 0;
1781 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1783 for a := 1 to i do
1784 begin
1785 MainForm.pbLoad.StepIt();
1786 Application.ProcessMessages();
1788 section := 'Panel' + IntToStr(a);
1789 if not map.SectionExists(section) then
1790 Continue;
1792 panel.X := map.ReadInt(section, 'X1', 0);
1793 panel.Y := map.ReadInt(section, 'Y1', 0);
1794 panel.Height := map.ReadInt(section, 'Height', 16);
1795 panel.Width := map.ReadInt(section, 'Width', 16);
1797 case map.ReadInt(section, 'PanelType', 0) of
1798 0: panel.PanelType := PANEL_WALL;
1799 1: panel.PanelType := PANEL_BACK;
1800 2: panel.PanelType := PANEL_FORE;
1801 3: panel.PanelType := PANEL_STEP;
1802 4: panel.PanelType := PANEL_WATER;
1803 5: panel.PanelType := PANEL_ACID1;
1804 6: panel.PanelType := PANEL_ACID2;
1805 end;
1807 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1809 // Текстура панели:
1810 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_STEP] then
1811 begin
1812 s := TexturePrefix + UpperCase(map.ReadStr(section, 'TextureName', ''));
1814 if g_GetTexture(s, panel.TextureID) then
1815 begin
1816 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1817 panel.TextureName := s;
1818 end
1819 else // Нет такой текстуры - ищем в WAD карты:
1820 begin
1821 s := ExtractFileName(_FileName);
1822 Delete(s, Length(s)-3, 4);
1823 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
1825 if g_GetTexture(s, panel.TextureID) then
1826 begin
1827 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1828 panel.TextureName := s;
1829 end
1830 else
1831 Continue;
1832 end;
1833 end
1834 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1835 begin
1836 case panel.PanelType of
1837 PANEL_WATER:
1838 begin
1839 s := TEXTURE_NAME_WATER;
1840 panel.TextureID := TEXTURE_SPECIAL_WATER;
1841 end;
1842 PANEL_ACID1:
1843 begin
1844 s := TEXTURE_NAME_ACID2;
1845 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1846 end;
1847 PANEL_ACID2:
1848 begin
1849 s := TEXTURE_NAME_ACID1;
1850 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1851 end;
1852 end;
1854 with MainForm.lbTextureList.Items do
1855 if IndexOf(s) = -1 then
1856 Add(s);
1857 panel.TextureName := s;
1858 panel.TextureWidth := 1;
1859 panel.TextureHeight := 1;
1860 end;
1862 AddPanel(panel);
1863 end;
1865 // Чтение предметов:
1866 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1868 MainForm.pbLoad.Max := i;
1869 MainForm.pbLoad.Position := 0;
1870 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1872 for a := 1 to i do
1873 begin
1874 MainForm.pbLoad.StepIt();
1875 Application.ProcessMessages();
1877 section := 'Item' + IntToStr(a);
1878 if not map.SectionExists(section) then
1879 Continue;
1881 item.X := map.ReadInt(section, 'X', 0);
1882 item.Y := map.ReadInt(section, 'Y', 0);
1883 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1884 item.OnlyDM := False;
1885 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1887 // Размер предметов теперь другой:
1888 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1889 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1891 AddItem(item);
1892 end;
1894 // Чтение областей:
1895 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1897 MainForm.pbLoad.Max := i;
1898 MainForm.pbLoad.Position := 0;
1899 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1901 for a := 1 to i do
1902 begin
1903 MainForm.pbLoad.StepIt();
1904 Application.ProcessMessages();
1906 section := 'Area' + IntToStr(a);
1907 if not map.SectionExists(section) then
1908 Continue;
1910 area.X := map.ReadInt(section, 'X', 0);
1911 area.Y := map.ReadInt(section, 'Y', 0);
1912 area.AreaType := map.ReadInt(section, 'Type', 0);
1913 area.Direction := D_RIGHT;
1915 // Размер областей теперь другой:
1916 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1917 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1919 AddArea(area);
1920 end;
1922 // Чтение параметров карты:
1923 with gMapInfo do
1924 begin
1925 Name := map.ReadStr('MapOptions', 'MapName', '');
1926 Description := map.ReadStr('MapOptions', 'MapDescription', '');
1927 Author := '';
1928 MusicName := DefaultMusRes;
1929 SkyName := DefaultSkyRes;
1930 FileName := _FileName;
1931 Height := map.ReadInt('MapOptions', 'Height', 1600);
1932 Width := map.ReadInt('MapOptions', 'Width', 1600);
1934 if Length(Name) > 32 then
1935 SetLength(Name, 32);
1936 if Length(Description) > 256 then
1937 SetLength(Description, 256);
1938 end;
1940 map.Free();
1942 Result := True;
1943 end;
1945 procedure ClearMap();
1946 var
1947 a: Integer;
1949 begin
1950 if gPanels <> nil then
1951 for a := 0 to High(gPanels) do
1952 if gPanels[a].TextureName <> '' then
1953 g_DeleteTexture(gPanels[a].TextureName);
1955 SetLength(gPanels, 0);
1956 gPanels := nil;
1957 SetLength(gItems, 0);
1958 gItems := nil;
1959 SetLength(gAreas, 0);
1960 gAreas := nil;
1961 SetLength(gMonsters, 0);
1962 gMonsters := nil;
1963 SetLength(gTriggers, 0);
1964 gTriggers := nil;
1966 with gMapInfo do
1967 begin
1968 Name := '';
1969 Description := '';
1970 Author := '';
1971 MusicName := '';
1972 SkyName := '';
1973 FileName := '';
1974 Height := 1600;
1975 Width := 1600;
1976 end;
1978 with MainForm.lbTextureList do
1979 begin
1980 if Items.Count > 0 then
1981 for a := Items.Count-1 downto 0 do
1982 if not IsSpecialTexture(Items[a]) then
1983 g_DeleteTexture(Items[a]);
1985 Clear();
1986 end;
1988 MapOffset.X := 0;
1989 MapOffset.Y := 0;
1990 end;
1992 procedure DrawPanels(fPanelType: Word);
1994 procedure DrawTexture(a: Integer);
1995 var
1996 NoTextureID: DWORD;
1997 NW, NH: Word;
1998 begin
1999 NoTextureID := 0;
2000 NW := 0;
2001 NH := 0;
2002 with gPanels[a] do
2003 begin
2004 case TextureID of
2005 TEXTURE_SPECIAL_NONE:
2006 if PreviewMode = 0 then
2007 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2008 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2009 64, 64, 64, 127);
2011 TEXTURE_SPECIAL_NOTEXTURE:
2012 if g_GetTexture('NOTEXTURE', NoTextureID) then
2013 begin
2014 g_GetTextureSizeByID(NoTextureID, NW, NH);
2015 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
2016 Width div NW, Height div NH, 0, False, False);
2017 end;
2019 TEXTURE_SPECIAL_WATER:
2020 if PreviewMode > 0 then
2021 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2022 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2023 0, 0, 255, 0, B_FILTER)
2024 else
2025 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2026 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2027 0, 0, 255, 127);
2029 TEXTURE_SPECIAL_ACID1:
2030 if PreviewMode > 0 then
2031 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2032 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2033 0, 127, 0, 0, B_FILTER)
2034 else
2035 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2036 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2037 0, 255, 0, 127);
2039 TEXTURE_SPECIAL_ACID2:
2040 if PreviewMode > 0 then
2041 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2042 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2043 127, 0, 0, 0, B_FILTER)
2044 else
2045 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2046 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2047 255, 0, 0, 127);
2049 else
2050 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2051 Width div TextureWidth, Height div TextureHeight,
2052 Alpha, True, Blending);
2053 end;
2054 end;
2055 end;
2057 var
2058 a: Integer;
2059 begin
2060 if gPanels <> nil then
2061 for a := 0 to High(gPanels) do
2062 if (gPanels[a].PanelType <> 0) and
2063 WordBool(gPanels[a].PanelType and fPanelType) then
2064 with gPanels[a] do
2065 begin
2066 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2067 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2068 case PanelType of
2069 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2070 PANEL_STEP, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2071 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2072 DrawTexture(a);
2074 PANEL_LIFTUP:
2075 if PreviewMode = 0 then
2076 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2077 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2078 128, 64, 0, 0);
2079 PANEL_LIFTDOWN:
2080 if PreviewMode = 0 then
2081 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2082 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2083 90, 154, 138, 0);
2084 PANEL_LIFTLEFT:
2085 if PreviewMode = 0 then
2086 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2087 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2088 200, 80, 4, 0);
2089 PANEL_LIFTRIGHT:
2090 if PreviewMode = 0 then
2091 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2092 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2093 252, 140, 56, 0);
2094 PANEL_BLOCKMON:
2095 if PreviewMode = 0 then
2096 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2097 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2098 192, 0, 192, 0);
2099 end;
2100 end;
2101 end;
2103 procedure DrawMap();
2104 var
2105 a, w, h: Integer;
2106 ID: DWORD;
2107 xx, yy, dx, dy: Integer;
2108 ww, hh: Word;
2109 sel: Boolean;
2110 r: TRectWH;
2112 begin
2113 ID := 0;
2114 // В режиме Превью рисуем небо:
2115 if PreviewMode > 0 then
2116 begin
2117 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2118 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2119 w := Round(w*4/3);
2120 h := Round(w*3/4);
2122 if g_GetTexture(SKY_TEXTURE, ID) then
2123 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2124 else
2125 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2126 end;
2128 // Рисуем панели (если Превью или если включен слой):
2129 if LayerEnabled[LAYER_BACK] or (PreviewMode = 1) then
2130 DrawPanels(PANEL_BACK);
2131 if PreviewMode > 0 then
2132 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
2133 else
2134 if LayerEnabled[LAYER_WATER] then
2135 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
2136 PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
2137 if LayerEnabled[LAYER_WALLS] or (PreviewMode = 1) then
2138 DrawPanels(PANEL_WALL);
2139 if LayerEnabled[LAYER_STEPS] or (PreviewMode = 1) then
2140 DrawPanels(PANEL_STEP);
2142 // Рисуем предметы:
2143 if (LayerEnabled[LAYER_ITEMS] or (PreviewMode = 1)) and
2144 (gItems <> nil) then
2145 for a := 0 to High(gItems) do
2146 if gItems[a].ItemType <> ITEM_NONE then
2147 with gItems[a] do
2148 begin
2149 ID := DWORD(-1);
2151 case ItemType of
2152 0: Continue;
2153 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2154 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2155 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2156 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2157 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2158 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2159 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2160 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2161 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2162 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2163 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2164 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2165 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2166 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2167 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2168 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2169 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2170 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2171 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2172 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2173 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2174 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2175 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2176 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2177 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2178 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2179 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2180 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2181 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2182 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2183 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2184 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2185 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2186 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2187 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2188 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2189 end;
2191 if ID <> DWORD(-1) then
2192 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2193 end;
2195 // Рисуем монстров:
2196 if (LayerEnabled[LAYER_MONSTERS] or (PreviewMode = 1)) and
2197 (gMonsters <> nil) then
2198 for a := 0 to High(gMonsters) do
2199 if gMonsters[a].MonsterType <> MONSTER_NONE then
2200 with MonsterSize[gMonsters[a].MonsterType] do
2201 begin
2202 ID := DWORD(-1);
2203 sel := ObjectSelected(OBJECT_MONSTER, a);
2205 case gMonsters[a].MonsterType of
2206 0: Continue;
2207 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2208 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2209 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2210 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2211 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2212 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2213 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2214 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2215 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2216 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2217 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2218 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2219 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2220 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2221 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2222 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2223 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2224 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2225 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2226 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2227 end;
2229 if ID <> DWORD(-1) then
2230 if gMonsters[a].Direction = D_LEFT then
2231 begin
2232 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2233 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2234 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2235 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2236 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2237 xx := (gMonsters[a].X - X) - xx;
2239 yy := (gMonsters[a].Y - Y) +
2240 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2242 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2243 0, True, False, M_HORIZONTAL);
2244 end
2245 else
2246 begin
2247 // Левый верхний угол текстуры + смещение анимации:
2248 xx := (gMonsters[a].X - X) +
2249 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2250 yy := (gMonsters[a].Y - Y) +
2251 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2253 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2254 0, True, False);
2255 end;
2257 // Рамка:
2258 if PreviewMode = 0 then
2259 begin
2260 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2261 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2262 255, 255, 255, IfThen(sel, 0, gAlphaMonsterRect));
2263 end;
2264 end;
2266 // Рисуем закрытые двери после монстров:
2267 if ((PreviewMode = 2) and LayerEnabled[LAYER_WATER])
2268 or (PreviewMode = 1) then
2269 DrawPanels(PANEL_CLOSEDOOR);
2271 // Рисуем области:
2272 if (LayerEnabled[LAYER_AREAS] or (PreviewMode = 1)) and
2273 (gAreas <> nil) then
2274 for a := 0 to High(gAreas) do
2275 if gAreas[a].AreaType <> AREA_NONE then
2276 with AreaSize[gAreas[a].AreaType] do
2277 begin
2278 ID := DWORD(-1);
2279 sel := ObjectSelected(OBJECT_AREA, a);
2281 case gAreas[a].AreaType of
2282 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2283 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2284 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2285 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2286 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2287 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2288 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2289 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2290 end;
2292 if (PreviewMode = 0) or
2293 (gAreas[a].AreaType = AREA_REDFLAG) or
2294 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2295 (gAreas[a].AreaType = AREA_DOMFLAG) then
2296 if ID <> DWORD(-1) then
2297 if gAreas[a].Direction = D_LEFT then
2298 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2299 0, True, False, M_HORIZONTAL)
2300 else
2301 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2302 0, True, False);
2304 // Рамка:
2305 if PreviewMode = 0 then
2306 begin
2307 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2308 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2309 255, 255, 255, IfThen(sel, 0, gAlphaAreaRect));
2311 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2312 end;
2313 end;
2315 // Рисуем жидкости и передний план после областей:
2316 if LayerEnabled[LAYER_WATER] or (PreviewMode = 1) then
2317 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2318 if LayerEnabled[LAYER_FOREGROUND] or (PreviewMode = 1) then
2319 DrawPanels(PANEL_FORE);
2321 // Рисуем триггеры:
2322 if LayerEnabled[LAYER_TRIGGERS] and
2323 (PreviewMode = 0) and (gTriggers <> nil) then
2324 for a := 0 to High(gTriggers) do
2325 with gTriggers[a] do
2326 if TriggerType <> TRIGGER_NONE then
2327 begin
2328 // Если выбран - рисуем красным, иначе - белым:
2329 sel := ObjectSelected(OBJECT_TRIGGER, a);
2331 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2332 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2333 0, 0, 0, 150);
2335 if TexturePanel <> -1 then
2336 begin
2337 with gPanels[TexturePanel] do
2338 begin
2339 xx := X;
2340 yy := Y;
2341 ww := Width;
2342 hh := Height;
2343 end;
2345 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2346 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2347 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2348 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2349 MapOffset.X+xx, MapOffset.Y+yy,
2350 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2351 end;
2353 case TriggerType of
2354 TRIGGER_EXIT: ;
2356 TRIGGER_TELEPORT:
2357 begin
2358 // Точка назначения Телепорта:
2359 if Data.d2d_teleport then
2360 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2361 MapOffset.Y+Data.TargetPoint.Y-1,
2362 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2363 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2364 else
2365 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2366 MapOffset.Y+Data.TargetPoint.Y,
2367 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2368 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2369 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2370 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2371 MapOffset.Y+Data.TargetPoint.Y,
2372 255, 0, 0);
2373 // Линия к точке назначения Телепорта:
2374 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2375 MapOffset.Y+Y+(Height div 2),
2376 MapOffset.X+Data.TargetPoint.X,
2377 MapOffset.Y+Data.TargetPoint.Y,
2378 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2379 end;
2381 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2382 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2383 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2384 TRIGGER_LIFT:
2385 if Data.PanelID <> -1 then
2386 begin
2387 // Дверь/Ловушка/Лифт:
2388 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2389 MapOffset.Y+gPanels[Data.PanelID].Y,
2390 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2391 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2392 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2393 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2394 MapOffset.Y+gPanels[Data.PanelID].Y,
2395 255, 0, 0);
2396 // Линия к Двери/Ловушке/Лифту:
2397 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2398 MapOffset.Y+Y+(Height div 2),
2399 MapOffset.X+gPanels[Data.PanelID].X,
2400 MapOffset.Y+gPanels[Data.PanelID].Y,
2401 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2402 end;
2404 TRIGGER_PRESS, TRIGGER_ON,
2405 TRIGGER_OFF, TRIGGER_ONOFF:
2406 begin
2407 if (Data.tWidth > 0) and
2408 (Data.tHeight > 0) then
2409 begin
2410 // Область Расширителя:
2411 e_DrawQuad(MapOffset.X+Data.tX,
2412 MapOffset.Y+Data.tY,
2413 MapOffset.X+Data.tX+Data.tWidth-1,
2414 MapOffset.Y+Data.tY+Data.tHeight-1,
2415 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2416 e_DrawPoint(2, MapOffset.X+Data.tX,
2417 MapOffset.Y+Data.tY,
2418 255, 0, 0);
2419 // Линия к области Расширителя:
2420 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2421 MapOffset.Y+Y+(Height div 2),
2422 MapOffset.X+Data.tX,
2423 MapOffset.Y+Data.tY,
2424 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2425 end;
2427 if Data.MonsterID <> 0 then
2428 if (gMonsters <> nil) and
2429 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2430 begin
2431 // Рамка вокруг Монстра - условия активации:
2432 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2433 e_DrawQuad(MapOffset.X+r.X,
2434 MapOffset.Y+r.Y,
2435 MapOffset.X+r.X+r.Width-1,
2436 MapOffset.Y+r.Y+r.Height-1,
2437 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2438 // Линия к Монстру - условию активации:
2439 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2440 MapOffset.Y+Y+(Height div 2),
2441 MapOffset.X+r.X,
2442 MapOffset.Y+r.Y,
2443 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2445 end;
2446 end;
2448 TRIGGER_SECRET: ;
2450 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2451 begin
2452 if TriggerType = TRIGGER_SPAWNMONSTER then
2453 begin
2454 xx := Data.MonPos.X;
2455 yy := Data.MonPos.Y;
2456 end
2457 else
2458 begin
2459 xx := Data.ItemPos.X;
2460 yy := Data.ItemPos.Y;
2461 end;
2462 // Точка появления Монстра/Предмета:
2463 e_DrawLine(2, MapOffset.X+xx-16,
2464 MapOffset.Y+yy-1,
2465 MapOffset.X+xx+16,
2466 MapOffset.Y+yy-1,
2467 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2468 e_DrawPoint(2, MapOffset.X+xx,
2469 MapOffset.Y+yy,
2470 255, 0, 0);
2471 // Линия к точке появления Монстра/Предмета:
2472 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2473 MapOffset.Y+Y+(Height div 2),
2474 MapOffset.X+xx,
2475 MapOffset.Y+yy,
2476 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2477 // Предпросмотр создаваемого объекта:
2478 if sel then
2479 begin
2480 // Монстр:
2481 if TriggerType = TRIGGER_SPAWNMONSTER then
2482 begin
2483 if Data.MonType <> MONSTER_NONE then
2484 with MonsterSize[Data.MonType] do
2485 begin
2486 ID := DWORD(-1);
2487 case Data.MonType of
2488 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2489 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2490 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2491 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2492 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2493 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2494 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2495 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2496 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2497 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2498 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2499 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2500 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2501 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2502 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2503 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2504 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2505 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2506 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2507 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2508 end;
2509 if ID <> DWORD(-1) then
2510 begin
2511 if Data.MonDir = Byte(D_LEFT) then
2512 begin
2513 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2514 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2515 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2517 yy := Data.TargetPoint.Y - Y +
2518 MonsterSizeDelta[Data.MonType].Y-Height;
2520 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2521 128, True, False, M_HORIZONTAL);
2522 end
2523 else
2524 begin
2525 xx := Data.TargetPoint.X - X +
2526 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2527 yy := Data.TargetPoint.Y - Y +
2528 MonsterSizeDelta[Data.MonType].Y-Height;
2530 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2531 128, True, False);
2532 end;
2533 // Рамка:
2534 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2535 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2536 255, 255, 0, 128);
2537 end;
2538 end;
2539 end
2540 else
2541 // Предмет:
2542 begin
2543 if Data.ItemType <> ITEM_NONE then
2544 begin
2545 ID := DWORD(-1);
2546 case Data.ItemType of
2547 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2548 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2549 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2550 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2551 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2552 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2553 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2554 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2555 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2556 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2557 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2558 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2559 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2560 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2561 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2562 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2563 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2564 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2565 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2566 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2567 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2568 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2569 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2570 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2571 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2572 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2573 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2574 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2575 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2576 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2577 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2578 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2579 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2580 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2581 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2582 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2583 end;
2584 if ID <> DWORD(-1) then
2585 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2586 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2587 128, True, False);
2588 // Рамка:
2589 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2590 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2591 255, 255, 0, 128);
2592 end;
2593 end;
2594 end;
2595 end;
2597 TRIGGER_PUSH:
2598 begin
2599 // Линия направления и силы ускорения:
2600 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2601 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2602 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2603 MapOffset.Y+Y+(Height div 2),
2604 MapOffset.X+xx,
2605 MapOffset.Y+yy,
2606 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2607 end;
2609 TRIGGER_SHOT:
2610 begin;
2611 xx := Data.ShotPos.X;
2612 yy := Data.ShotPos.Y;
2613 // Точка появления снаряда:
2614 e_DrawPoint(2, MapOffset.X+xx,
2615 MapOffset.Y+yy,
2616 255, 0, 0);
2617 // Линия к точке появления снаряда:
2618 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2619 MapOffset.Y+Y+(Height div 2),
2620 MapOffset.X+xx,
2621 MapOffset.Y+yy,
2622 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2623 // Линия направления выстрела:
2624 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2625 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2626 e_DrawLine(1, MapOffset.X+xx,
2627 MapOffset.Y+yy,
2628 MapOffset.X+xx+dx,
2629 MapOffset.Y+yy+dy,
2630 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2632 if (Data.ShotPanelID <> -1) and
2633 (Data.ShotPanelID <= High(gPanels)) then
2634 begin
2635 // Линия к панели индикации выстрела
2636 with gPanels[Data.ShotPanelID] do
2637 begin
2638 xx := X;
2639 yy := Y;
2640 ww := Width;
2641 hh := Height;
2642 end;
2644 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2645 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2646 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2647 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2648 MapOffset.X+xx, MapOffset.Y+yy,
2649 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2650 end;
2651 end;
2652 end;
2653 end;
2655 // Границы карты:
2656 if PreviewMode = 0 then
2657 begin
2658 e_DrawFillQuad(-32+MapOffset.X,
2659 -32+MapOffset.Y,
2660 gMapInfo.Width+31+MapOffset.X,
2661 -1+MapOffset.Y,
2662 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2663 e_DrawFillQuad(-32+MapOffset.X,
2664 gMapInfo.Height+MapOffset.Y,
2665 gMapInfo.Width+31+MapOffset.X,
2666 gMapInfo.Height+31+MapOffset.Y,
2667 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2668 e_DrawFillQuad(-32+MapOffset.X,
2669 MapOffset.Y,
2670 -1+MapOffset.X,
2671 gMapInfo.Height+MapOffset.Y-1,
2672 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2673 e_DrawFillQuad(gMapInfo.Width+MapOffset.X,
2674 MapOffset.Y,
2675 gMapInfo.Width+31+MapOffset.X,
2676 gMapInfo.Height+MapOffset.Y-1,
2677 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2678 end;
2679 end;
2681 procedure ShiftMapObjects(dx, dy: Integer);
2682 var
2683 i: Integer;
2684 begin
2685 if gPanels <> nil then
2686 for i := 0 to High(gPanels) do
2687 if gPanels[i].PanelType <> 0 then
2688 begin
2689 Inc(gPanels[i].X, dx);
2690 Inc(gPanels[i].Y, dy);
2691 end;
2693 if gItems <> nil then
2694 for i := 0 to High(gItems) do
2695 if gItems[i].ItemType <> 0 then
2696 begin
2697 Inc(gItems[i].X, dx);
2698 Inc(gItems[i].Y, dy);
2699 end;
2701 if gAreas <> nil then
2702 for i := 0 to High(gAreas) do
2703 if gAreas[i].AreaType <> 0 then
2704 begin
2705 Inc(gAreas[i].X, dx);
2706 Inc(gAreas[i].Y, dy);
2707 end;
2709 if gMonsters <> nil then
2710 for i := 0 to High(gMonsters) do
2711 if gMonsters[i].MonsterType <> 0 then
2712 begin
2713 Inc(gMonsters[i].X, dx);
2714 Inc(gMonsters[i].Y, dy);
2715 end;
2717 if gTriggers <> nil then
2718 for i := 0 to High(gTriggers) do
2719 if gTriggers[i].TriggerType <> 0 then
2720 begin
2721 Inc(gTriggers[i].X, dx);
2722 Inc(gTriggers[i].Y, dy);
2724 case gTriggers[i].TriggerType of
2725 TRIGGER_TELEPORT:
2726 begin
2727 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2728 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2729 end;
2731 TRIGGER_PRESS, TRIGGER_ON,
2732 TRIGGER_OFF, TRIGGER_ONOFF:
2733 begin
2734 Inc(gTriggers[i].Data.tX, dx);
2735 Inc(gTriggers[i].Data.tY, dy);
2736 end;
2738 TRIGGER_SPAWNMONSTER:
2739 begin
2740 Inc(gTriggers[i].Data.MonPos.X, dx);
2741 Inc(gTriggers[i].Data.MonPos.Y, dy);
2742 end;
2744 TRIGGER_SPAWNITEM:
2745 begin
2746 Inc(gTriggers[i].Data.ItemPos.X, dx);
2747 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2748 end;
2750 TRIGGER_SHOT:
2751 begin
2752 Inc(gTriggers[i].Data.ShotPos.X, dx);
2753 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2754 end;
2755 end;
2756 end;
2757 end;
2759 procedure LoadData();
2760 begin
2761 g_CreateTextureWAD('PREVIEW', EditorDir+'data/Editor.wad:TEXTURES\CHECKERS');
2762 g_CreateTextureWAD('NOTEXTURE', EditorDir+'data/Game.wad:TEXTURES\NOTEXTURE');
2764 g_CreateTextureWADSize('AREA_REDFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGRED', 0, 0, 64, 64);
2765 g_CreateTextureWADSize('AREA_BLUEFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2766 g_CreateTextureWADSize('AREA_DOMFLAG', EditorDir+'data/Game.wad:TEXTURES\FLAGDOM', 0, 0, 64, 64);
2768 g_CreateTextureWADSize('MONSTER_DEMON', EditorDir+'data/Game.wad:MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2769 g_CreateTextureWADSize('MONSTER_IMP', EditorDir+'data/Game.wad:MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2770 g_CreateTextureWADSize('MONSTER_ZOMBY', EditorDir+'data/Game.wad:MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2771 g_CreateTextureWADSize('MONSTER_SERG', EditorDir+'data/Game.wad:MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2772 g_CreateTextureWADSize('MONSTER_CYBER', EditorDir+'data/Game.wad:MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2773 g_CreateTextureWADSize('MONSTER_CGUN', EditorDir+'data/Game.wad:MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2774 g_CreateTextureWADSize('MONSTER_BARON', EditorDir+'data/Game.wad:MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2775 g_CreateTextureWADSize('MONSTER_KNIGHT', EditorDir+'data/Game.wad:MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2776 g_CreateTextureWADSize('MONSTER_CACO', EditorDir+'data/Game.wad:MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2777 g_CreateTextureWADSize('MONSTER_SOUL', EditorDir+'data/Game.wad:MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2778 g_CreateTextureWADSize('MONSTER_PAIN', EditorDir+'data/Game.wad:MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2779 g_CreateTextureWADSize('MONSTER_SPIDER', EditorDir+'data/Game.wad:MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2780 g_CreateTextureWADSize('MONSTER_BSP', EditorDir+'data/Game.wad:MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2781 g_CreateTextureWADSize('MONSTER_MANCUB', EditorDir+'data/Game.wad:MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2782 g_CreateTextureWADSize('MONSTER_SKEL', EditorDir+'data/Game.wad:MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2783 g_CreateTextureWADSize('MONSTER_VILE', EditorDir+'data/Game.wad:MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2784 g_CreateTextureWADSize('MONSTER_FISH', EditorDir+'data/Game.wad:MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2785 g_CreateTextureWADSize('MONSTER_BARREL', EditorDir+'data/Game.wad:MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2786 g_CreateTextureWADSize('MONSTER_ROBO', EditorDir+'data/Game.wad:MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2787 g_CreateTextureWADSize('MONSTER_MAN', EditorDir+'data/Game.wad:MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2789 g_CreateTextureWADSize('ITEM_BLUESPHERE', EditorDir+'data/Game.wad:TEXTURES\SBLUE', 0, 0, 32, 32);
2790 g_CreateTextureWADSize('ITEM_WHITESPHERE', EditorDir+'data/Game.wad:TEXTURES\SWHITE', 0, 0, 32, 32);
2791 g_CreateTextureWADSize('ITEM_ARMORGREEN', EditorDir+'data/Game.wad:TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2792 g_CreateTextureWADSize('ITEM_ARMORBLUE', EditorDir+'data/Game.wad:TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2793 g_CreateTextureWADSize('ITEM_INVUL', EditorDir+'data/Game.wad:TEXTURES\INVUL', 0, 0, 32, 32);
2794 g_CreateTextureWADSize('ITEM_BOTTLE', EditorDir+'data/Game.wad:TEXTURES\BOTTLE', 0, 0, 16, 32);
2795 g_CreateTextureWADSize('ITEM_HELMET', EditorDir+'data/Game.wad:TEXTURES\HELMET', 0, 0, 16, 16);
2796 g_CreateTextureWADSize('ITEM_JETPACK', EditorDir+'data/Game.wad:TEXTURES\JETPACK', 0, 0, 32, 32);
2797 g_CreateTextureWADSize('ITEM_INVIS', EditorDir+'data/Game.wad:TEXTURES\INVIS', 0, 0, 32, 32);
2798 g_CreateTextureWADSize('ITEM_WEAPON_FLAMETHROWER', EditorDir+'data/Game.wad:TEXTURES\FLAMETHROWER', 0, 0, 64, 32);
2799 g_CreateTextureWADSize('ITEM_AMMO_FUELCAN', EditorDir+'data/Game.wad:TEXTURES\FUELCAN', 0, 0, 16, 32);
2801 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', EditorDir+'data/Game.wad:TEXTURES\MED1');
2802 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', EditorDir+'data/Game.wad:TEXTURES\MED2');
2803 g_CreateTextureWAD('ITEM_WEAPON_SAW', EditorDir+'data/Game.wad:TEXTURES\SAW');
2804 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', EditorDir+'data/Game.wad:TEXTURES\PISTOL');
2805 g_CreateTextureWAD('ITEM_WEAPON_KASTET', EditorDir+'data/Game.wad:TEXTURES\KASTET');
2806 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', EditorDir+'data/Game.wad:TEXTURES\SHOTGUN1');
2807 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', EditorDir+'data/Game.wad:TEXTURES\SHOTGUN2');
2808 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', EditorDir+'data/Game.wad:TEXTURES\MGUN');
2809 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', EditorDir+'data/Game.wad:TEXTURES\RLAUNCHER');
2810 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', EditorDir+'data/Game.wad:TEXTURES\PGUN');
2811 g_CreateTextureWAD('ITEM_WEAPON_BFG', EditorDir+'data/Game.wad:TEXTURES\BFG');
2812 g_CreateTextureWAD('ITEM_WEAPON_SUPERPULEMET', EditorDir+'data/Game.wad:TEXTURES\SPULEMET');
2813 g_CreateTextureWAD('ITEM_AMMO_BULLETS', EditorDir+'data/Game.wad:TEXTURES\CLIP');
2814 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', EditorDir+'data/Game.wad:TEXTURES\AMMO');
2815 g_CreateTextureWAD('ITEM_AMMO_SHELLS', EditorDir+'data/Game.wad:TEXTURES\SHELL1');
2816 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', EditorDir+'data/Game.wad:TEXTURES\SHELL2');
2817 g_CreateTextureWAD('ITEM_AMMO_ROCKET', EditorDir+'data/Game.wad:TEXTURES\ROCKET');
2818 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', EditorDir+'data/Game.wad:TEXTURES\ROCKETS');
2819 g_CreateTextureWAD('ITEM_AMMO_CELL', EditorDir+'data/Game.wad:TEXTURES\CELL');
2820 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', EditorDir+'data/Game.wad:TEXTURES\CELL2');
2821 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', EditorDir+'data/Game.wad:TEXTURES\BPACK');
2822 g_CreateTextureWAD('ITEM_KEY_RED', EditorDir+'data/Game.wad:TEXTURES\KEYR');
2823 g_CreateTextureWAD('ITEM_KEY_GREEN', EditorDir+'data/Game.wad:TEXTURES\KEYG');
2824 g_CreateTextureWAD('ITEM_KEY_BLUE', EditorDir+'data/Game.wad:TEXTURES\KEYB');
2825 g_CreateTextureWAD('ITEM_OXYGEN', EditorDir+'data/Game.wad:TEXTURES\OXYGEN');
2826 g_CreateTextureWAD('ITEM_SUIT', EditorDir+'data/Game.wad:TEXTURES\SUIT');
2827 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', EditorDir+'data/Game.wad:TEXTURES\BMED');
2829 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorDir+'data/Editor.wad:TEXTURES\P1POINT');
2830 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorDir+'data/Editor.wad:TEXTURES\P2POINT');
2831 g_CreateTextureWAD('AREA_DMPOINT', EditorDir+'data/Editor.wad:TEXTURES\DMPOINT');
2832 g_CreateTextureWAD('AREA_REDPOINT', EditorDir+'data/Editor.wad:TEXTURES\REDPOINT');
2833 g_CreateTextureWAD('AREA_BLUEPOINT', EditorDir+'data/Editor.wad:TEXTURES\BLUEPOINT');
2834 end;
2836 procedure FreeData();
2837 begin
2838 g_DeleteTexture('NOTEXTURE');
2840 g_DeleteTexture('ITEM_BLUESPHERE');
2841 g_DeleteTexture('ITEM_WHITESPHERE');
2842 g_DeleteTexture('ITEM_ARMORGREEN');
2843 g_DeleteTexture('ITEM_ARMORBLUE');
2844 g_DeleteTexture('ITEM_INVUL');
2845 g_DeleteTexture('ITEM_BOTTLE');
2846 g_DeleteTexture('ITEM_HELMET');
2847 g_DeleteTexture('AREA_REDFLAG');
2848 g_DeleteTexture('AREA_BLUEFLAG');
2849 g_DeleteTexture('AREA_DOMFLAG');
2851 g_DeleteTexture('MONSTER_DEMON');
2852 g_DeleteTexture('MONSTER_IMP');
2853 g_DeleteTexture('MONSTER_ZOMBY');
2854 g_DeleteTexture('MONSTER_SERG');
2855 g_DeleteTexture('MONSTER_CGUN');
2856 g_DeleteTexture('MONSTER_BARREL');
2857 g_DeleteTexture('MONSTER_MAN');
2859 g_DeleteTexture('MONSTER_DEMON');
2860 g_DeleteTexture('MONSTER_IMP');
2861 g_DeleteTexture('MONSTER_ZOMBY');
2862 g_DeleteTexture('MONSTER_SERG');
2863 g_DeleteTexture('MONSTER_CYBER');
2864 g_DeleteTexture('MONSTER_CGUN');
2865 g_DeleteTexture('MONSTER_BARON');
2866 g_DeleteTexture('MONSTER_KNIGHT');
2867 g_DeleteTexture('MONSTER_CACO');
2868 g_DeleteTexture('MONSTER_SOUL');
2869 g_DeleteTexture('MONSTER_PAIN');
2870 g_DeleteTexture('MONSTER_SPIDER');
2871 g_DeleteTexture('MONSTER_BSP');
2872 g_DeleteTexture('MONSTER_MANCUB');
2873 g_DeleteTexture('MONSTER_SKEL');
2874 g_DeleteTexture('MONSTER_VILE');
2875 g_DeleteTexture('MONSTER_FISH');
2876 g_DeleteTexture('MONSTER_BARREL');
2877 g_DeleteTexture('MONSTER_ROBO');
2878 g_DeleteTexture('MONSTER_MAN');
2880 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2881 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2882 g_DeleteTexture('ITEM_WEAPON_SAW');
2883 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2884 g_DeleteTexture('ITEM_WEAPON_KASTET');
2885 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2886 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2887 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2888 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
2889 g_DeleteTexture('ITEM_WEAPON_PLASMA');
2890 g_DeleteTexture('ITEM_WEAPON_BFG');
2891 g_DeleteTexture('ITEM_WEAPON_SUPERPULEMET');
2892 g_DeleteTexture('ITEM_AMMO_BULLETS');
2893 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
2894 g_DeleteTexture('ITEM_AMMO_SHELLS');
2895 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
2896 g_DeleteTexture('ITEM_AMMO_ROCKET');
2897 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
2898 g_DeleteTexture('ITEM_AMMO_CELL');
2899 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
2900 g_DeleteTexture('ITEM_AMMO_BACKPACK');
2901 g_DeleteTexture('ITEM_KEY_RED');
2902 g_DeleteTexture('ITEM_KEY_GREEN');
2903 g_DeleteTexture('ITEM_KEY_BLUE');
2904 g_DeleteTexture('ITEM_OXYGEN');
2905 g_DeleteTexture('ITEM_SUIT');
2906 g_DeleteTexture('ITEM_MEDKIT_BLACK');
2907 g_DeleteTexture('ITEM_JETPACK');
2908 g_DeleteTexture('ITEM_INVIS');
2909 g_DeleteTexture('ITEM_WEAPON_FLAMETHROWER');
2910 g_DeleteTexture('ITEM_AMMO_FUELCAN');
2912 g_DeleteTexture('AREA_PLAYERPOINT1');
2913 g_DeleteTexture('AREA_PLAYERPOINT2');
2914 g_DeleteTexture('AREA_DMPOINT');
2915 g_DeleteTexture('AREA_REDPOINT');
2916 g_DeleteTexture('AREA_BLUEPOINT');
2917 end;
2919 end.