DEADSOFTWARE

d61a0e2c2fc57d1617ca4b2220de416176c749b2
[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
136 AreaSize: Array [AREA_PLAYERPOINT1..AREA_BLUETEAMPOINT] of TRectWH =
137 ((X:15; Y:12; Width:34; Height:52), // PLAYERPOINT1
138 (X:15; Y:12; Width:34; Height:52), // PLAYERPOINT2
139 (X:15; Y:12; Width:34; Height:52), // DMPOINT
140 (X:15; Y:11; Width:34; Height:52), // REDFLAG
141 (X:15; Y:11; Width:34; Height:52), // BLUEFLAG
142 (X:15; Y:11; Width:34; Height:52), // DOMFLAG
143 (X:15; Y:12; Width:34; Height:52), // REDTEAMPOINT
144 (X:15; Y:12; Width:34; Height:52)); // BLUETEAMPOINT
146 MonsterSize: Array [MONSTER_DEMON..MONSTER_MAN] of TRectWH =
147 ((X: 7; Y: 8; Width: 50; Height: 52), // DEMON
148 (X: 15; Y: 10; Width: 34; Height: 50), // IMP
149 (X: 15; Y: 8; Width: 34; Height: 52), // ZOMBY
150 (X: 15; Y: 8; Width: 34; Height: 52), // SERG
151 (X: 24; Y: 9; Width: 80; Height: 110), // CYBER
152 (X: 15; Y: 4; Width: 34; Height: 56), // CGUN
153 (X: 39; Y: 32; Width: 50; Height: 64), // BARON
154 (X: 39; Y: 32; Width: 50; Height: 64), // KNIGHT
155 (X: 34; Y: 36; Width: 60; Height: 56), // CACO
156 (X: 16; Y: 14; Width: 32; Height: 36), // SOUL
157 (X: 34; Y: 36; Width: 60; Height: 56), // PAIN
158 (X: 23; Y: 14; Width: 210; Height: 100), // SPIDER
159 (X: 14; Y: 17; Width: 100; Height: 42), // BSP
160 (X: 28; Y: 34; Width: 72; Height: 60), // MANCUB
161 (X: 30; Y: 28; Width: 68; Height: 72), // SKEL
162 (X: 30; Y: 28; Width: 68; Height: 72), // VILE
163 (X: 6; Y: 11; Width: 20; Height: 10), // FISH
164 (X: 20; Y: 13; Width: 24; Height: 36), // BARREL
165 (X: 30; Y: 26; Width: 68; Height: 76), // ROBO
166 (X: 15; Y: 6; Width: 34; Height: 52)); // MAN
168 MonsterSizeDelta: Array [MONSTER_DEMON..MONSTER_MAN] of TMonsterSizeDelta =
169 ((X: 1; Y: 4; Width: 64), // DEMON
170 (X: 8; Y: -4; Width: 64), // IMP
171 (X: 1; Y: -4; Width: 64), // ZOMBY
172 (X: 0; Y: -4; Width: 64), // SERG
173 (X: 2; Y: -6; Width: 128), // CYBER
174 (X: -1; Y: -2; Width: 64), // CGUN
175 (X: 4; Y: 0; Width: 128), // BARON
176 (X: 4; Y: 0; Width: 128), // KNIGHT
177 (X: 0; Y: -4; Width: 128), // CACO
178 (X: 1; Y: -10; Width: 64), // SOUL
179 (X: -1; Y: -3; Width: 128), // PAIN
180 (X: -4; Y: -4; Width: 256), // SPIDER
181 (X: 0; Y: -1; Width: 128), // BSP
182 (X: -2; Y: -7; Width: 128), // MANCUB
183 (X: -1; Y: 4; Width: 128), // SKEL
184 (X: 5; Y: -21; Width: 128), // VILE
185 (X: -1; Y: 0; Width: 32), // FISH
186 (X: 0; Y: -15; Width: 64), // BARREL
187 (X: -2; Y: -26; Width: 128), // ROBO
188 (X: 0; Y: -6; Width: 64)); // MAN
190 var
191 gColorEdge: Integer;
192 gAlphaEdge: Byte;
193 gAlphaTriggerLine: Byte;
194 gAlphaTriggerArea: Byte;
195 drEdge: Array[0..3] of Byte;
196 gPanels: Array of TPanel;
197 gItems: Array of TItem;
198 gAreas: Array of TArea;
199 gMonsters: Array of TMonster;
200 gTriggers: Array of TTrigger;
201 gMapInfo: TMapInfo;
202 MapOffset: TPoint = (X: 0; Y: 0);
203 SelectedObjects: Array of TMapObject = nil;
205 procedure LoadSky(Res: String);
207 function AddItem(Item: TItem): DWORD;
208 function AddPanel(Panel: TPanel): DWORD;
209 function AddArea(Area: TArea): DWORD;
210 function AddMonster(Monster: TMonster): DWORD;
211 function AddTrigger(Trigger: TTrigger): DWORD;
213 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
214 function PanelInShownLayer(PanelType: Word): Boolean;
215 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
216 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
217 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
218 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
219 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
220 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
221 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
223 function GetPanelName(PanelType: Word): String;
224 function GetPanelType(PanelName: String): Word;
225 function GetTriggerName(TriggerType: Byte): String;
226 function GetTriggerType(TriggerName: String): Byte;
228 function IsSpecialTexture(TextureName: String): Boolean;
229 function SpecialTextureID(TextureName: String): DWORD;
231 procedure ClearMap();
232 function SaveMap(Res: String): Pointer;
233 function LoadMap(Res: String): Boolean;
234 function LoadMapOld(_FileName: String): Boolean;
235 procedure DrawMap();
236 procedure LoadData();
237 procedure FreeData();
239 procedure ShiftMapObjects(dx, dy: Integer);
241 Implementation
243 Uses
244 BinEditor, g_textures, Dialogs, SysUtils, CONFIG, f_main,
245 Forms, Math, f_addresource_texture, WADEDITOR,
246 Masks, g_Language;
248 const
249 OLD_ITEM_MEDKIT_SMALL = 1;
250 OLD_ITEM_MEDKIT_LARGE = 2;
251 OLD_ITEM_ARMOR_GREEN = 3;
252 OLD_ITEM_ARMOR_BLUE = 4;
253 OLD_ITEM_SPHERE_BLUE = 5;
254 OLD_ITEM_SPHERE_WHITE = 6;
255 OLD_ITEM_WEAPON_SAW = 7;
256 OLD_ITEM_WEAPON_SHOTGUN1 = 8;
257 OLD_ITEM_WEAPON_SHOTGUN2 = 9;
258 OLD_ITEM_WEAPON_CHAINGUN = 10;
259 OLD_ITEM_WEAPON_ROCKETLAUNCHER = 11;
260 OLD_ITEM_WEAPON_PLASMA = 12;
261 OLD_ITEM_WEAPON_BFG = 13;
262 OLD_ITEM_WEAPON_SUPERPULEMET = 14;
263 OLD_ITEM_AMMO_BULLETS = 15;
264 OLD_ITEM_AMMO_BULLETS_BOX = 16;
265 OLD_ITEM_AMMO_SHELLS = 17;
266 OLD_ITEM_AMMO_SHELLS_BOX = 18;
267 OLD_ITEM_AMMO_ROCKET = 19;
268 OLD_ITEM_AMMO_ROCKET_BOX = 20;
269 OLD_ITEM_AMMO_CELL = 21;
270 OLD_ITEM_AMMO_CELL_BIG = 22;
271 OLD_ITEM_AMMO_BACKPACK = 23;
272 OLD_ITEM_KEY_RED = 24;
273 OLD_ITEM_KEY_GREEN = 25;
274 OLD_ITEM_KEY_BLUE = 26;
275 OLD_ITEM_SUIT = 27;
276 OLD_ITEM_OXYGEN = 28;
277 OLD_ITEM_MEDKIT_BLACK = 29;
278 OLD_ITEM_INVUL = 30;
280 ITEMSCONVERT: Array [OLD_ITEM_MEDKIT_SMALL..OLD_ITEM_INVUL] of Integer =
281 ((ITEM_MEDKIT_SMALL),
282 (ITEM_MEDKIT_LARGE),
283 (ITEM_ARMOR_GREEN),
284 (ITEM_ARMOR_BLUE),
285 (ITEM_SPHERE_BLUE),
286 (ITEM_SPHERE_WHITE),
287 (ITEM_WEAPON_SAW),
288 (ITEM_WEAPON_SHOTGUN1),
289 (ITEM_WEAPON_SHOTGUN2),
290 (ITEM_WEAPON_CHAINGUN),
291 (ITEM_WEAPON_ROCKETLAUNCHER),
292 (ITEM_WEAPON_PLASMA),
293 (ITEM_WEAPON_BFG),
294 (ITEM_WEAPON_SUPERPULEMET),
295 (ITEM_AMMO_BULLETS),
296 (ITEM_AMMO_BULLETS_BOX),
297 (ITEM_AMMO_SHELLS),
298 (ITEM_AMMO_SHELLS_BOX),
299 (ITEM_AMMO_ROCKET),
300 (ITEM_AMMO_ROCKET_BOX),
301 (ITEM_AMMO_CELL),
302 (ITEM_AMMO_CELL_BIG),
303 (ITEM_AMMO_BACKPACK),
304 (ITEM_KEY_RED),
305 (ITEM_KEY_GREEN),
306 (ITEM_KEY_BLUE),
307 (ITEM_SUIT),
308 (ITEM_OXYGEN),
309 (ITEM_MEDKIT_BLACK),
310 (ITEM_INVUL));
312 OldItemSize: Array [ITEM_MEDKIT_SMALL..ITEM_KEY_BLUE] of Array [0..1] of Byte =
313 (((14), (15)), // MEDKIT_SMALL
314 ((28), (19)), // MEDKIT_LARGE
315 ((28), (19)), // MEDKIT_BLACK - not in map generator
316 ((30), (16)), // ARMOR_GREEN
317 ((30), (16)), // ARMOR_BLUE
318 ((24), (24)), // SPHERE_BLUE
319 ((24), (24)), // SPHERE_WHITE
320 ((24), (46)), // SUIT
321 ((14), (27)), // OXYGEN
322 ((25), (25)), // INVUL - not in map generator
323 ((61), (23)), // WEAPON_SAW
324 ((62), (10)), // WEAPON_SHOTGUN1
325 ((52), (12)), // WEAPON_SHOTGUN2
326 ((53), (15)), // WEAPON_CHAINGUN
327 ((61), (15)), // WEAPON_ROCKETLAUNCHER
328 ((53), (14)), // WEAPON_PLASMA
329 ((61), (34)), // WEAPON_BFG
330 ((53), (16)), // WEAPON_SUPERPULEMET
331 (( 9), (10)), // AMMO_BULLETS
332 ((28), (16)), // AMMO_BULLETS_BOX
333 ((15), ( 7)), // AMMO_SHELLS
334 ((32), (12)), // AMMO_SHELLS_BOX
335 ((12), (26)), // AMMO_ROCKET
336 ((54), (21)), // AMMO_ROCKET_BOX
337 ((15), (12)), // AMMO_CELL
338 ((32), (21)), // AMMO_CELL_BIG
339 ((22), (29)), // AMMO_BACKPACK
340 ((16), (16)), // KEY_RED
341 ((16), (16)), // KEY_GREEN
342 ((16), (16))); // KEY_BLUE
344 OldAreaSize: Array [0..1] of Byte = ((34), (56));
346 SKY_TEXTURE = 'SKY';
348 procedure LoadSky(Res: String);
349 var
350 fn: String;
352 begin
353 g_DeleteTexture(SKY_TEXTURE);
355 if Res = '' then
356 Exit;
358 g_ProcessResourceStr(Res, @fn, nil, nil);
360 if fn = '' then
361 begin
362 g_ProcessResourceStr(OpenedMap, @fn, nil, nil);
363 fn := fn + Res;
364 end
365 else
366 fn := EditorDir + 'wads\' + Res;
368 g_CreateTextureWAD(SKY_TEXTURE, fn);
369 end;
371 function AddItem(Item: TItem): DWORD;
372 var
373 a: Integer;
374 ok: Boolean;
376 begin
377 ok := False;
378 a := 0;
380 if gItems <> nil then
381 for a := 0 to High(gItems) do
382 if gItems[a].ItemType = ITEM_NONE then
383 begin
384 ok := True;
385 Break;
386 end;
388 if not ok then
389 begin
390 a := Length(gItems);
391 SetLength(gItems, a + 128);
392 end;
394 gItems[a] := Item;
396 Result := a;
397 end;
399 function AddPanel(Panel: TPanel): DWORD;
400 var
401 a, b: Integer;
402 ok: Boolean;
404 begin
405 ok := False;
406 a := 0;
407 b := -1;
409 if gPanels <> nil then
410 for a := High(gPanels) downto 0 do
411 if gPanels[a].PanelType = PANEL_NONE then
412 b := a
413 else
414 Break;
416 if b <> -1 then
417 begin
418 a := b;
419 ok := True;
420 end;
422 if not ok then
423 begin
424 a := Length(gPanels);
425 SetLength(gPanels, a + 512);
426 end;
428 gPanels[a] := Panel;
430 Result := a;
431 end;
433 function AddArea(Area: TArea): DWORD;
434 var
435 a: Integer;
436 ok: Boolean;
438 begin
439 ok := False;
440 a := 0;
442 if gAreas <> nil then
443 for a := 0 to High(gAreas) do
444 if gAreas[a].AreaType = AREA_NONE then
445 begin
446 ok := True;
447 Break;
448 end;
450 if not ok then
451 begin
452 a := Length(gAreas);
453 SetLength(gAreas, a + 64);
454 end;
456 gAreas[a] := Area;
458 Result := a;
459 end;
461 function AddMonster(Monster: TMonster): DWORD;
462 var
463 a: Integer;
464 ok: Boolean;
466 begin
467 ok := False;
468 a := 0;
470 if gMonsters <> nil then
471 for a := 0 to High(gMonsters) do
472 if gMonsters[a].MonsterType = MONSTER_NONE then
473 begin
474 ok := True;
475 Break;
476 end;
478 if not ok then
479 begin
480 a := Length(gMonsters);
481 SetLength(gMonsters, a + 128);
482 end;
484 gMonsters[a] := Monster;
486 Result := a;
487 end;
489 function AddTrigger(Trigger: TTrigger): DWORD;
490 var
491 a: Integer;
492 ok: Boolean;
494 begin
495 ok := False;
496 a := 0;
498 if gTriggers <> nil then
499 for a := 0 to High(gTriggers) do
500 if gTriggers[a].TriggerType = TRIGGER_NONE then
501 begin
502 ok := True;
503 Break;
504 end;
506 if not ok then
507 begin
508 a := Length(gTriggers);
509 SetLength(gTriggers, a + 64);
510 end;
512 gTriggers[a] := Trigger;
514 Result := a;
515 end;
517 procedure RemoveObject(ID: DWORD; ObjectType: Byte);
518 var
519 a: Integer;
521 begin
522 case ObjectType of
523 OBJECT_PANEL:
524 begin
525 // Убираем ссылки триггеров на эту панель:
526 if gTriggers <> nil then
527 for a := 0 to High(gTriggers) do
528 if gTriggers[a].TriggerType <> 0 then
529 begin
530 if gTriggers[a].TexturePanel = Integer(ID) then
531 gTriggers[a].TexturePanel := -1;
533 if gTriggers[a].TriggerType in [
534 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
535 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
536 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
537 TRIGGER_LIFT] then
538 if gTriggers[a].Data.PanelID = Integer(ID) then
539 gTriggers[a].Data.PanelID := -1;
541 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
542 (gTriggers[a].Data.ShotPanelID = Integer(ID)) then
543 gTriggers[a].Data.ShotPanelID := -1;
544 end;
546 gPanels[ID].PanelType := 0;
547 end;
549 OBJECT_ITEM:
550 gItems[ID].ItemType := 0;
552 OBJECT_MONSTER:
553 begin
554 // Убираем ссылки триггеров на этого монстра:
555 if gTriggers <> nil then
556 for a := 0 to High(gTriggers) do
557 if gTriggers[a].TriggerType <> 0 then
558 begin
559 if gTriggers[a].TriggerType in [TRIGGER_PRESS,
560 TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
561 if (gTriggers[a].Data.MonsterID-1 = Integer(ID)) then
562 gTriggers[a].Data.MonsterID := 0;
563 end;
565 gMonsters[ID].MonsterType := 0;
566 end;
568 OBJECT_AREA:
569 gAreas[ID].AreaType := 0;
571 OBJECT_TRIGGER:
572 gTriggers[ID].TriggerType := 0;
573 end;
574 end;
576 function PanelInShownLayer(PanelType: Word): Boolean;
577 begin
578 case PanelType of
579 PANEL_WALL:
580 Result := LayerEnabled[LAYER_WALLS];
582 PANEL_BACK:
583 Result := LayerEnabled[LAYER_BACK];
585 PANEL_FORE:
586 Result := LayerEnabled[LAYER_FOREGROUND];
588 PANEL_STEP:
589 Result := LayerEnabled[LAYER_STEPS];
591 PANEL_WATER, PANEL_ACID1, PANEL_ACID2,
592 PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT,
593 PANEL_OPENDOOR, PANEL_CLOSEDOOR,
594 PANEL_BLOCKMON:
595 Result := LayerEnabled[LAYER_WATER];
597 else
598 Result := False;
599 end;
600 end;
602 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
603 var
604 a: Integer;
606 begin
607 Result := nil;
609 case ObjectType of
610 OBJECT_PANEL:
611 if gPanels <> nil then
612 for a := High(gPanels) downto 0 do
613 with gPanels[a] do
614 begin
615 if not PanelInShownLayer(gPanels[a].PanelType) then
616 Continue;
618 if g_Collide(X, Y, Width, Height,
619 fX, fY, fWidth, fHeight) then
620 begin
621 SetLength(Result, Length(Result)+1);
622 Result[High(Result)] := a;
624 if not All then
625 Break;
626 end;
627 end;
629 OBJECT_ITEM:
630 if LayerEnabled[LAYER_ITEMS] and (gItems <> nil) then
631 for a := High(gItems) downto 0 do
632 with gItems[a] do
633 if (ItemType <> ITEM_NONE) and
634 g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
635 fX, fY, fWidth, fHeight) then
636 begin
637 SetLength(Result, Length(Result)+1);
638 Result[High(Result)] := a;
640 if not All then
641 Break;
642 end;
644 OBJECT_MONSTER:
645 if LayerEnabled[LAYER_MONSTERS] and (gMonsters <> nil) then
646 for a := High(gMonsters) downto 0 do
647 if gMonsters[a].MonsterType <> MONSTER_NONE then
648 with MonsterSize[gMonsters[a].MonsterType] do
649 if (gMonsters[a].MonsterType <> 0) and
650 g_Collide(gMonsters[a].X, gMonsters[a].Y, Width, Height,
651 fX, fY, fWidth, fHeight) then
652 begin
653 SetLength(Result, Length(Result)+1);
654 Result[High(Result)] := a;
656 if not All then
657 Break;
658 end;
660 OBJECT_AREA:
661 if LayerEnabled[LAYER_AREAS] and (gAreas <> nil) then
662 for a := High(gAreas) downto 0 do
663 if gAreas[a].AreaType <> AREA_NONE then
664 with AreaSize[gAreas[a].AreaType] do
665 if (gAreas[a].AreaType <> 0) and
666 g_Collide(gAreas[a].X, gAreas[a].Y, Width, Height,
667 fX, fY, fWidth, fHeight) then
668 begin
669 SetLength(Result, Length(Result)+1);
670 Result[High(Result)] := a;
672 if not All then
673 Break;
674 end;
676 OBJECT_TRIGGER:
677 if LayerEnabled[LAYER_TRIGGERS] and (gTriggers <> nil) then
678 for a := High(gTriggers) downto 0 do
679 if gTriggers[a].TriggerType <> TRIGGER_NONE then
680 with gTriggers[a] do
681 begin
682 if (TriggerType <> 0) and
683 g_Collide(X, Y, Width, Height,
684 fX, fY, fWidth, fHeight) then
685 begin
686 SetLength(Result, Length(Result)+1);
687 Result[High(Result)] := a;
689 if not All then
690 Break;
691 end;
692 end;
693 end;
694 end;
696 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
697 var
698 PanelID: DWORD;
700 begin
701 Result := False;
703 case ObjectType of
704 OBJECT_PANEL:
705 with gPanels[fID] do
706 Result := (PanelID <> fID) and
707 g_CollideLevel2(X+dX, Y+dY,
708 Width, Height,
709 fID, PanelID);
711 OBJECT_ITEM:
712 with gItems[fID] do
713 Result := g_CollideLevel(X+dX, Y+dY,
714 ItemSize[ItemType][0], ItemSize[ItemType][1]);
716 OBJECT_MONSTER:
717 with MonsterSize[gMonsters[fID].MonsterType] do
718 Result := g_CollideLevel(gMonsters[fID].X+dX, gMonsters[fID].Y+dY,
719 Width, Height);
721 OBJECT_AREA:
722 with AreaSize[gAreas[fID].AreaType] do
723 Result := g_CollideLevel(gAreas[fID].X+dX, gAreas[fID].Y+dY,
724 Width, Height);
726 OBJECT_TRIGGER:
727 with gTriggers[fID] do
728 Result := g_CollideLevel(X+dX, Y+dY,
729 Width, Height);
730 end;
731 end;
733 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
734 begin
735 Result := False;
737 case ObjectType of
738 OBJECT_PANEL:
739 with gPanels[ID] do
740 Result := g_Collide(X, Y, Width, Height,
741 fX, fY, fWidth, fHeight);
743 OBJECT_ITEM:
744 with gItems[ID] do
745 Result := g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
746 fX, fY, fWidth, fHeight);
748 OBJECT_MONSTER:
749 with MonsterSize[gMonsters[ID].MonsterType] do
750 Result := g_Collide(gMonsters[ID].X, gMonsters[ID].Y, Width, Height,
751 fX, fY, fWidth, fHeight);
753 OBJECT_AREA:
754 with AreaSize[gAreas[ID].AreaType] do
755 Result := g_Collide(gAreas[ID].X, gAreas[ID].Y, Width, Height,
756 fX, fY, fWidth, fHeight);
758 OBJECT_TRIGGER:
759 with gTriggers[ID] do
760 Result := g_Collide(X, Y, Width, Height,
761 fX, fY, fWidth, fHeight);
762 end;
763 end;
765 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
766 begin
767 case ObjectType of
768 OBJECT_PANEL:
769 with gPanels[ID] do
770 begin
771 Result.X := X;
772 Result.Y := Y;
773 Result.Width := Width;
774 Result.Height := Height;
775 end;
777 OBJECT_ITEM:
778 with gItems[ID] do
779 begin
780 Result.X := X;
781 Result.Y := Y;
782 Result.Width := ItemSize[ItemType][0];
783 Result.Height := ItemSize[ItemType][1];
784 end;
786 OBJECT_MONSTER:
787 with MonsterSize[gMonsters[ID].MonsterType] do
788 begin
789 Result.X := gMonsters[ID].X;
790 Result.Y := gMonsters[ID].Y;
791 Result.Width := Width;
792 Result.Height := Height;
793 end;
795 OBJECT_AREA:
796 with AreaSize[gAreas[ID].AreaType] do
797 begin
798 Result.X := gAreas[ID].X;
799 Result.Y := gAreas[ID].Y;
800 Result.Width := Width;
801 Result.Height := Height;
802 end;
804 OBJECT_TRIGGER:
805 with gTriggers[ID] do
806 begin
807 Result.X := X;
808 Result.Y := Y;
809 Result.Width := Width;
810 Result.Height := Height;
811 end;
813 else
814 begin
815 Result.X := 0;
816 Result.Y := 0;
817 Result.Width := 0;
818 Result.Height := 0;
819 end;
820 end;
821 end;
823 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
824 begin
825 case ObjectType of
826 OBJECT_PANEL:
827 with gPanels[ID] do
828 begin
829 X := X + dX;
830 Y := Y + dY;
831 end;
833 OBJECT_ITEM:
834 with gItems[ID] do
835 begin
836 X := X + dX;
837 Y := Y + dY;
838 end;
840 OBJECT_MONSTER:
841 with gMonsters[ID] do
842 begin
843 X := X + dX;
844 Y := Y + dY;
845 end;
847 OBJECT_AREA:
848 with gAreas[ID] do
849 begin
850 X := X + dX;
851 Y := Y + dY;
852 end;
854 OBJECT_TRIGGER:
855 with gTriggers[ID] do
856 begin
857 X := X + dX;
858 Y := Y + dY;
859 end;
860 end;
861 end;
863 procedure ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte);
864 begin
865 case ObjectType of
866 OBJECT_PANEL:
867 with gPanels[ID] do
868 begin
869 if Width >= -dWidth then
870 Width := Width+dWidth
871 else
872 begin
873 Width := 0;
874 Exit;
875 end;
877 if Height >= -dHeight then
878 Height := Height+dHeight
879 else
880 begin
881 Height := 0;
882 Exit;
883 end;
885 case ResizeDir of
886 2: Y := Y - dHeight;
887 4: X := X - dWidth;
888 end;
889 end;
891 OBJECT_ITEM, OBJECT_MONSTER, OBJECT_AREA:
892 Exit;
894 OBJECT_TRIGGER:
895 with gTriggers[ID] do
896 begin
897 if Width >= -dWidth then
898 Width := Width+dWidth
899 else
900 begin
901 Width := 0;
902 Exit;
903 end;
905 if Height >= -dHeight then
906 Height := Height+dHeight
907 else
908 begin
909 Height := 0;
910 Exit;
911 end;
913 case ResizeDir of
914 2: Y := Y - dHeight;
915 4: X := X - dWidth;
916 end;
917 end;
918 end;
919 end;
921 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
922 var
923 a: Integer;
925 begin
926 Result := False;
928 if SelectedObjects <> nil then
929 for a := 0 to High(SelectedObjects) do
930 if SelectedObjects[a].Live and
931 (SelectedObjects[a].ObjectType = ObjectType) and
932 (SelectedObjects[a].ID = ID) then
933 begin
934 Result := True;
935 Break;
936 end;
937 end;
939 function GetPanelName(PanelType: Word): String;
940 begin
941 Result := '';
943 case PanelType of
944 PANEL_WALL: Result := PANELNAMES[0];
945 PANEL_BACK: Result := PANELNAMES[1];
946 PANEL_FORE: Result := PANELNAMES[2];
947 PANEL_OPENDOOR: Result := PANELNAMES[3];
948 PANEL_CLOSEDOOR: Result := PANELNAMES[4];
949 PANEL_STEP: Result := PANELNAMES[5];
950 PANEL_WATER: Result := PANELNAMES[6];
951 PANEL_ACID1: Result := PANELNAMES[7];
952 PANEL_ACID2: Result := PANELNAMES[8];
953 PANEL_LIFTUP: Result := PANELNAMES[9];
954 PANEL_LIFTDOWN: Result := PANELNAMES[10];
955 PANEL_LIFTLEFT: Result := PANELNAMES[11];
956 PANEL_LIFTRIGHT: Result := PANELNAMES[12];
957 PANEL_BLOCKMON: Result := PANELNAMES[13];
958 else Assert(False);
959 end;
960 end;
962 function GetPanelType(PanelName: String): Word;
963 begin
964 Result := 0;
966 if PanelName = PANELNAMES[0] then
967 Result := PANEL_WALL
968 else if PanelName = PANELNAMES[1] then
969 Result := PANEL_BACK
970 else if PanelName = PANELNAMES[2] then
971 Result := PANEL_FORE
972 else if PanelName = PANELNAMES[3] then
973 Result := PANEL_OPENDOOR
974 else if PanelName = PANELNAMES[4] then
975 Result := PANEL_CLOSEDOOR
976 else if PanelName = PANELNAMES[5] then
977 Result := PANEL_STEP
978 else if PanelName = PANELNAMES[6] then
979 Result := PANEL_WATER
980 else if PanelName = PANELNAMES[7] then
981 Result := PANEL_ACID1
982 else if PanelName = PANELNAMES[8] then
983 Result := PANEL_ACID2
984 else if PanelName = PANELNAMES[9] then
985 Result := PANEL_LIFTUP
986 else if PanelName = PANELNAMES[10] then
987 Result := PANEL_LIFTDOWN
988 else if PanelName = PANELNAMES[11] then
989 Result := PANEL_LIFTLEFT
990 else if PanelName = PANELNAMES[12] then
991 Result := PANEL_LIFTRIGHT
992 else if PanelName = PANELNAMES[13] then
993 Result := PANEL_BLOCKMON;
995 Assert(Result <> 0);
996 end;
998 function GetTriggerName(TriggerType: Byte): String;
999 begin
1000 if TriggerType in [TRIGGER_EXIT..TRIGGER_MAX] then
1001 Result := TriggerNames[TriggerType]
1002 else
1003 Assert(False);
1004 end;
1006 function GetTriggerType(TriggerName: String): Byte;
1007 var
1008 i: Integer;
1010 begin
1011 Result := TRIGGER_NONE;
1012 for i := TRIGGER_EXIT to TRIGGER_MAX do
1013 if TriggerNames[i] = TriggerName then
1014 begin
1015 Result := i;
1016 Exit;
1017 end;
1019 Assert(False);
1020 end;
1022 function IsSpecialTexture(TextureName: string): Boolean;
1023 begin
1024 Result := (TextureName = TEXTURE_NAME_WATER) or
1025 (TextureName = TEXTURE_NAME_ACID1) or
1026 (TextureName = TEXTURE_NAME_ACID2);
1027 end;
1029 function SpecialTextureID(TextureName: string): DWORD;
1030 begin
1031 Assert(IsSpecialTexture(TextureName));
1033 Result := 0;
1035 if TextureName = TEXTURE_NAME_WATER then
1036 Result := TEXTURE_SPECIAL_WATER
1037 else
1038 if TextureName = TEXTURE_NAME_ACID1 then
1039 Result := TEXTURE_SPECIAL_ACID1
1040 else
1041 if TextureName = TEXTURE_NAME_ACID2 then
1042 Result := TEXTURE_SPECIAL_ACID2;
1043 end;
1045 function SaveMap(Res: String): Pointer;
1046 var
1047 WAD: TWADEditor_1;
1048 MapWriter: TMapWriter_1;
1049 textures: TTexturesRec1Array;
1050 panels: TPanelsRec1Array;
1051 items: TItemsRec1Array;
1052 areas: TAreasRec1Array;
1053 monsters: TMonsterRec1Array;
1054 triggers: TTriggersRec1Array;
1055 header: TMapHeaderRec_1;
1056 a, b, c: Integer;
1057 s: String;
1058 PanelTable: Array of Array [0..1] of Word;
1059 MonsterTable: Array of Array [0..1] of Word;
1060 Data: Pointer;
1061 FileName, SectionName, ResName: String;
1062 Len: LongWord;
1064 begin
1065 WAD := nil;
1067 // Открываем WAD, если надо:
1068 if Res <> '' then
1069 begin
1070 WAD := TWADEditor_1.Create();
1071 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1072 if not WAD.ReadFile(FileName) then
1073 WAD.FreeWAD();
1075 WAD.CreateImage();
1076 end;
1078 MapWriter := TMapWriter_1.Create();
1080 // Сохраняем заголовок:
1081 with header do
1082 begin
1083 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1085 if gMapInfo.Name <> '' then
1086 CopyMemory(@MapName[0], @gMapInfo.Name[1], Min(32, Length(gMapInfo.Name)));
1088 if gMapInfo.Description <> '' then
1089 CopyMemory(@MapDescription[0], @gMapInfo.Description[1], Min(256, Length(gMapInfo.Description)));
1091 if gMapInfo.Author <> '' then
1092 CopyMemory(@MapAuthor[0], @gMapInfo.Author[1], Min(32, Length(gMapInfo.Author)));
1094 if gMapInfo.MusicName <> '' then
1095 CopyMemory(@MusicName[0], @gMapInfo.MusicName[1], Min(64, Length(gMapInfo.MusicName)));
1097 if gMapInfo.SkyName <> '' then
1098 CopyMemory(@SkyName[0], @gMapInfo.SkyName[1], Min(64, Length(gMapInfo.SkyName)));
1100 Width := gMapInfo.Width;
1101 Height := gMapInfo.Height;
1102 end;
1104 MapWriter.AddHeader(header);
1106 // Сохраняем названия текстур:
1107 if MainForm.lbTextureList.Items.Count > 0 then
1108 begin
1109 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1110 begin
1111 SetLength(textures, Length(textures)+1);
1112 s := MainForm.lbTextureList.Items[a];
1113 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1114 if g_GetTextureFlagByName(s) = 1 then
1115 textures[High(textures)].Anim := 1
1116 else
1117 textures[High(textures)].Anim := 0;
1118 end;
1120 MapWriter.AddTextures(textures);
1121 end;
1123 // Сохраняем панели:
1124 if gPanels <> nil then
1125 begin
1126 c := 0;
1128 for a := 0 to High(gPanels) do
1129 if gPanels[a].PanelType <> 0 then
1130 begin
1131 SetLength(PanelTable, Length(PanelTable)+1);
1132 PanelTable[High(PanelTable)][0] := a;
1133 PanelTable[High(PanelTable)][1] := c;
1134 c := c + 1;
1136 SetLength(panels, Length(panels)+1);
1138 with panels[High(panels)] do
1139 begin
1140 X := gPanels[a].X;
1141 Y := gPanels[a].Y;
1142 Width := gPanels[a].Width;
1143 Height := gPanels[a].Height;
1144 PanelType := gPanels[a].PanelType;
1145 Alpha := gPanels[a].Alpha;
1147 TextureNum := 0;
1148 Flags := 0;
1150 if WordBool(gPanels[a].PanelType and
1151 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1152 Flags := PANEL_FLAG_WATERTEXTURES;
1154 // Может быть текстура:
1155 if not WordBool(gPanels[a].PanelType and
1156 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1157 begin
1158 if gPanels[a].Blending then
1159 Flags := Flags or PANEL_FLAG_BLENDING;
1160 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1161 Flags := Flags or PANEL_FLAG_HIDE;
1163 // Номер текстуры в списке текстур:
1164 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1165 for b := 0 to High(textures) do
1166 if gPanels[a].TextureName = textures[b].Resource then
1167 begin
1168 TextureNum := b;
1169 Break;
1170 end;
1171 end;
1172 end;
1173 end;
1175 MapWriter.AddPanels(panels);
1176 end;
1178 // Сохраняем предметы:
1179 if gItems <> nil then
1180 begin
1181 for a := 0 to High(gItems) do
1182 if gItems[a].ItemType <> 0 then
1183 begin
1184 SetLength(items, Length(items)+1);
1186 with items[High(items)] do
1187 begin
1188 X := gItems[a].X;
1189 Y := gItems[a].Y;
1190 ItemType := gItems[a].ItemType;
1191 if gItems[a].OnlyDM then
1192 Options := Options or ITEM_OPTION_ONLYDM;
1193 if gItems[a].Fall then
1194 Options := Options or ITEM_OPTION_FALL;
1195 end;
1196 end;
1198 MapWriter.AddItems(items);
1199 end;
1201 // Сохраняем монстров:
1202 if gMonsters <> nil then
1203 begin
1204 c := 0;
1206 for a := 0 to High(gMonsters) do
1207 if gMonsters[a].MonsterType <> 0 then
1208 begin
1209 SetLength(MonsterTable, Length(MonsterTable)+1);
1210 MonsterTable[High(MonsterTable)][0] := a;
1211 MonsterTable[High(MonsterTable)][1] := c;
1212 c := c + 1;
1214 SetLength(monsters, Length(monsters)+1);
1216 with monsters[High(monsters)] do
1217 begin
1218 X := gMonsters[a].X;
1219 Y := gMonsters[a].Y;
1220 MonsterType := gMonsters[a].MonsterType;
1221 Direction := Ord(gMonsters[a].Direction);
1222 end;
1223 end;
1225 MapWriter.AddMonsters(monsters);
1226 end;
1228 // Сохраняем области:
1229 if gAreas <> nil then
1230 begin
1231 for a := 0 to High(gAreas) do
1232 if gAreas[a].AreaType <> 0 then
1233 begin
1234 SetLength(areas, Length(areas)+1);
1236 with areas[High(areas)] do
1237 begin
1238 X := gAreas[a].X;
1239 Y := gAreas[a].Y;
1240 AreaType := gAreas[a].AreaType;
1241 Direction := Ord(gAreas[a].Direction);
1242 end;
1243 end;
1245 MapWriter.AddAreas(areas);
1246 end;
1248 // Сохраняем триггеры:
1249 if gTriggers <> nil then
1250 begin
1251 for a := 0 to High(gTriggers) do
1252 if gTriggers[a].TriggerType <> 0 then
1253 begin
1254 SetLength(triggers, Length(triggers)+1);
1256 with triggers[High(triggers)] do
1257 begin
1258 X := gTriggers[a].X;
1259 Y := gTriggers[a].Y;
1260 Width := gTriggers[a].Width;
1261 Height := gTriggers[a].Height;
1262 Enabled := Byte(gTriggers[a].Enabled);
1263 TexturePanel := -1;
1264 TriggerType := gTriggers[a].TriggerType;
1265 ActivateType := gTriggers[a].ActivateType;
1266 Keys := gTriggers[a].Key;
1267 DATA := gTriggers[a].Data.Default;
1269 if PanelTable <> nil then
1270 begin
1271 // Ищем номер панели, которой этот триггер меняет текстуру:
1272 if gTriggers[a].TexturePanel <> -1 then
1273 begin
1274 for c := 0 to High(PanelTable) do
1275 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1276 TexturePanel := PanelTable[c][1];
1277 end;
1279 // Ищем номер панели, которую меняет этот триггер:
1280 if gTriggers[a].TriggerType in [
1281 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1282 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1283 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1284 if TTriggerData(DATA).PanelID <> -1 then
1285 for c := 0 to High(PanelTable) do
1286 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1287 begin
1288 TTriggerData(DATA).PanelID := PanelTable[c][1];
1289 Break;
1290 end;
1292 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1293 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1294 (TTriggerData(DATA).ShotPanelID <> -1) then
1295 begin
1296 for c := 0 to High(PanelTable) do
1297 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1298 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1299 end;
1300 end;
1302 if MonsterTable <> nil then
1303 begin
1304 // Ищем номер монстра - условие активации триггера:
1305 if gTriggers[a].TriggerType in [
1306 TRIGGER_PRESS, TRIGGER_ON,
1307 TRIGGER_OFF, TRIGGER_ONOFF] then
1308 if TTriggerData(DATA).MonsterID <> 0 then
1309 for c := 0 to High(MonsterTable) do
1310 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1311 begin
1312 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1313 Break;
1314 end;
1315 end;
1316 end;
1317 end;
1319 MapWriter.AddTriggers(triggers);
1320 end;
1322 // Сохраняем карту в память:
1323 Len := MapWriter.SaveMap(Data);
1325 MapWriter.Free();
1327 // Записываем в WAD, если надо:
1328 if Res <> '' then
1329 begin
1330 WAD.RemoveResource('', ResName);
1331 WAD.AddResource(Data, Len, ResName, '');
1332 WAD.SaveTo(FileName);
1334 FreeMem(Data);
1335 WAD.Free();
1337 Result := nil;
1338 end
1339 else
1340 Result := Data;
1341 end;
1343 procedure AddTexture(res: String; Error: Boolean);
1344 var
1345 a: Integer;
1346 begin
1347 with MainForm.lbTextureList do
1348 begin
1349 for a := 0 to Count-1 do
1350 if Items[a] = res then
1351 Exit;
1353 if Error and (slInvalidTextures.IndexOf(res) = -1) then
1354 slInvalidTextures.Add(res);
1355 Items.Add(res);
1356 end;
1357 end;
1359 function LoadMap(Res: String): Boolean;
1360 var
1361 WAD: TWADEditor_1;
1362 MapReader: TMapReader_1;
1363 Header: TMapHeaderRec_1;
1364 textures: TTexturesRec1Array;
1365 panels: TPanelsRec1Array;
1366 items: TItemsRec1Array;
1367 monsters: TMonsterRec1Array;
1368 areas: TAreasRec1Array;
1369 triggers: TTriggersRec1Array;
1370 panel: TPanel;
1371 item: TItem;
1372 monster: TMonster;
1373 area: TArea;
1374 trigger: TTrigger;
1375 a: Integer;
1376 Data: Pointer;
1377 Width, Height, m: Word;
1378 FileName, SectionName, ResName, _fn: String;
1379 TextureRes: String;
1380 pData: Pointer;
1381 Len: Integer;
1382 Error: Boolean;
1383 NoTextureID: DWORD;
1384 NW, NH: Word;
1385 begin
1386 Result := False;
1388 MainForm.pbLoad.Position := 0;
1389 MainForm.lLoad.Caption := _lc[I_LOAD_WAD];
1390 Application.ProcessMessages();
1392 // Открываем WAD:
1393 WAD := TWADEditor_1.Create();
1394 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1396 if not WAD.ReadFile(FileName) then
1397 begin
1398 WAD.Free();
1399 Exit;
1400 end;
1402 // Читаем ресурс карты:
1403 if not WAD.GetResource('', ResName, pData, Len) then
1404 begin
1405 WAD.Free();
1406 Exit;
1407 end;
1409 WAD.Free();
1411 MapReader := TMapReader_1.Create();
1413 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];
1414 Application.ProcessMessages();
1416 MapReader.LoadMap(pData);
1418 // Загружаем текстуры:
1419 textures := MapReader.GetTextures();
1421 if textures <> nil then
1422 begin
1423 MainForm.pbLoad.Position := 0;
1424 MainForm.pbLoad.Max := Length(textures);
1425 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1427 for a := 0 to High(textures) do
1428 begin
1429 MainForm.pbLoad.StepIt();
1430 Application.ProcessMessages();
1432 if IsSpecialTexture(textures[a].Resource) then
1433 begin
1434 AddTexture(textures[a].Resource, False);
1435 Continue;
1436 end;
1438 g_ProcessResourceStr(textures[a].Resource, @_fn, nil, nil);
1440 if _fn = '' then
1441 TextureRes := FileName + textures[a].Resource
1442 else
1443 TextureRes := EditorDir+'wads\'+textures[a].Resource;
1445 Error := False;
1447 if not ByteBool(textures[a].Anim) then
1448 begin // Обычная текстура
1449 if not g_CreateTextureWAD(textures[a].Resource, TextureRes) then
1450 begin
1451 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s',
1452 [textures[a].Resource]), MSG_WARNING);
1453 Error := True;
1454 end;
1456 AddTexture(textures[a].Resource, Error);
1457 end
1458 else // Anim
1459 begin // Анимированная текстура
1460 if not GetFrame(TextureRes, Data, Width, Height) then
1461 begin // Кадры
1462 e_WriteLog(Format('GetFrame() error, res=%s',
1463 [textures[a].Resource]), MSG_WARNING);
1464 Error := True;
1465 end;
1467 if not g_CreateTextureMemorySize(Data, textures[a].Resource, 0, 0, Width, Height, 1) then
1468 begin // Сама текстура
1469 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s',
1470 [textures[a].Resource]), MSG_WARNING);
1471 Error := True;
1472 end;
1474 AddTexture(textures[a].Resource, Error);
1475 end;
1476 end;
1477 end;
1479 // Загружаем панели:
1480 panels := MapReader.GetPanels();
1482 if panels <> nil then
1483 begin
1484 MainForm.pbLoad.Position := 0;
1485 MainForm.pbLoad.Max := Length(panels);
1486 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1488 for a := 0 to High(panels) do
1489 begin
1490 MainForm.pbLoad.StepIt();
1491 Application.ProcessMessages();
1493 panel.X := panels[a].X;
1494 panel.Y := panels[a].Y;
1495 panel.Height := panels[a].Height;
1496 panel.Width := panels[a].Width;
1497 panel.PanelType := panels[a].PanelType;
1498 panel.Alpha := panels[a].Alpha;
1500 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1502 panel.TextureWidth := 0;
1503 panel.TextureHeight := 0;
1504 panel.TextureName := '';
1505 panel.TextureID := TEXTURE_SPECIAL_NONE;
1507 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_STEP or
1508 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1510 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1511 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1513 // Если панель видима:
1514 if WordBool(panel.PanelType and m) and
1515 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1516 begin
1517 if not IsSpecialTexture(textures[panels[a].TextureNum].Resource) then
1518 begin // Текстура
1519 if g_GetTexture(textures[panels[a].TextureNum].Resource, panel.TextureID) then
1520 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1521 else begin
1522 panel.TextureWidth := 1;
1523 panel.TextureHeight := 1;
1524 if g_GetTexture('NOTEXTURE', NoTextureID) then
1525 begin
1526 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1527 g_GetTextureSizeByID(NoTextureID, NW, NH);
1528 panel.TextureWidth := NW;
1529 panel.TextureHeight := NH;
1530 end;
1531 end;
1532 end
1533 else // Спец. текстура
1534 panel.TextureID := SpecialTextureID(textures[panels[a].TextureNum].Resource);
1536 panel.TextureName := textures[panels[a].TextureNum].Resource;
1537 end;
1539 // Жидкость без текстуры:
1540 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1541 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1542 begin
1543 case panel.PanelType of
1544 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1545 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1546 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1547 end;
1549 panel.TextureID := SpecialTextureID(panel.TextureName);
1550 AddTexture(panel.TextureName, False);
1551 end;
1553 AddPanel(panel);
1554 end;
1555 end;
1557 // Загружаем предметы:
1558 items := MapReader.GetItems();
1560 if items <> nil then
1561 begin
1562 MainForm.pbLoad.Position := 0;
1563 MainForm.pbLoad.Max := Length(items);
1564 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1566 for a := 0 to High(items) do
1567 begin
1568 MainForm.pbLoad.StepIt();
1569 Application.ProcessMessages();
1571 item.X := items[a].X;
1572 item.Y := items[a].Y;
1573 item.ItemType := items[a].ItemType;
1574 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1575 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1577 AddItem(item);
1578 end;
1579 end;
1581 // Загружаем монстров:
1582 monsters := MapReader.GetMonsters();
1584 if monsters <> nil then
1585 begin
1586 MainForm.pbLoad.Position := 0;
1587 MainForm.pbLoad.Max := Length(monsters);
1588 MainForm.lLoad.Caption := _lc[I_LOAD_MONSTERS];
1590 for a := 0 to High(monsters) do
1591 begin
1592 MainForm.pbLoad.StepIt();
1593 Application.ProcessMessages();
1595 monster.X := monsters[a].X;
1596 monster.Y := monsters[a].Y;
1597 monster.MonsterType := monsters[a].MonsterType;
1598 monster.Direction := TDirection(monsters[a].Direction);
1600 AddMonster(monster);
1601 end;
1602 end;
1604 // Загружаем области:
1605 areas := MapReader.GetAreas();
1607 if areas <> nil then
1608 begin
1609 MainForm.pbLoad.Position := 0;
1610 MainForm.pbLoad.Max := Length(areas);
1611 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1613 for a := 0 to High(areas) do
1614 begin
1615 MainForm.pbLoad.StepIt();
1616 Application.ProcessMessages();
1618 area.X := areas[a].X;
1619 area.Y := areas[a].Y;
1620 area.AreaType := areas[a].AreaType;
1621 area.Direction := TDirection(areas[a].Direction);
1623 AddArea(area);
1624 end;
1625 end;
1627 // Загружаем триггеры:
1628 triggers := MapReader.GetTriggers();
1630 if triggers <> nil then
1631 begin
1632 MainForm.pbLoad.Position := 0;
1633 MainForm.pbLoad.Max := Length(triggers);
1634 MainForm.lLoad.Caption := _lc[I_LOAD_TRIGGERS];
1636 for a := 0 to High(triggers) do
1637 begin
1638 MainForm.pbLoad.StepIt();
1639 Application.ProcessMessages();
1641 trigger.X := triggers[a].X;
1642 trigger.Y := triggers[a].Y;
1643 trigger.Width := triggers[a].Width;
1644 trigger.Height := triggers[a].Height;
1646 trigger.Enabled := ByteBool(triggers[a].Enabled);
1647 trigger.TexturePanel := triggers[a].TexturePanel;
1648 trigger.TriggerType := triggers[a].TriggerType;
1649 trigger.ActivateType := triggers[a].ActivateType;
1650 trigger.Key := triggers[a].Keys;
1651 trigger.Data.Default := triggers[a].DATA;
1653 AddTrigger(trigger);
1654 end;
1655 end;
1657 // Загружаем заголовок карты:
1658 Header := MapReader.GetMapHeader();
1660 gMapInfo.FileName := FileName;
1662 with gMapInfo do
1663 begin
1664 MapName := ResName;
1665 Name := Header.MapName;
1666 Description := Header.MapDescription;
1667 Author := Header.MapAuthor;
1668 MusicName := Header.MusicName;
1669 SkyName := Header.SkyName;
1670 Height := Header.Height;
1671 Width := Header.Width;
1672 end;
1674 LoadSky(gMapInfo.SkyName);
1676 textures := nil;
1677 panels := nil;
1678 items := nil;
1679 areas := nil;
1680 triggers := nil;
1682 MapReader.Free();
1683 FreeMem(pData);
1685 Result := True;
1686 end;
1688 function LoadMapOld(_FileName: String): Boolean;
1689 const
1690 TexturePrefix = 'Standart.wad:STDTEXTURES\';
1691 DefaultMusRes = 'Standart.wad:STDMUS\MUS1';
1692 DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
1694 var
1695 map: TConfig;
1696 i, a: Integer;
1697 s, section: String;
1698 panel: TPanel;
1699 item: TItem;
1700 area: TArea;
1702 begin
1703 Result := False;
1705 if not FileExists(_FileName) then
1706 Exit;
1708 // Открытие карты:
1709 MainForm.pbLoad.Position := 0;
1710 MainForm.lLoad.Caption := _lc[I_LOAD_MAP];;
1711 Application.ProcessMessages();
1713 map := TConfig.CreateFile(_FileName);
1715 // Чтение текстур:
1716 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1718 MainForm.pbLoad.Max := i;
1719 MainForm.pbLoad.Position := 0;
1720 MainForm.lLoad.Caption := _lc[I_LOAD_TEXTURES];
1722 for a := 1 to i do
1723 begin
1724 MainForm.pbLoad.StepIt();
1725 Application.ProcessMessages();
1727 s := TexturePrefix + UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1728 if s = TexturePrefix then
1729 Continue;
1731 // Нет такой текстуры - ищем в WAD карты:
1732 if not g_CreateTextureWAD(s, EditorDir+'\wads\'+s) then
1733 begin
1734 s := ExtractFileName(_FileName);
1735 Delete(s, Length(s)-3, 4);
1736 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(map.ReadStr('Textures', 'TextureName'+IntToStr(a), ''));
1738 if not g_CreateTextureWAD(s, EditorDir+'\wads\'+s) then
1739 Continue;
1740 end;
1742 MainForm.lbTextureList.Items.Add(s);
1743 end;
1745 // Чтение панелей:
1746 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1748 MainForm.pbLoad.Max := i;
1749 MainForm.pbLoad.Position := 0;
1750 MainForm.lLoad.Caption := _lc[I_LOAD_PANELS];
1752 for a := 1 to i do
1753 begin
1754 MainForm.pbLoad.StepIt();
1755 Application.ProcessMessages();
1757 section := 'Panel' + IntToStr(a);
1758 if not map.SectionExists(section) then
1759 Continue;
1761 panel.X := map.ReadInt(section, 'X1', 0);
1762 panel.Y := map.ReadInt(section, 'Y1', 0);
1763 panel.Height := map.ReadInt(section, 'Height', 16);
1764 panel.Width := map.ReadInt(section, 'Width', 16);
1766 case map.ReadInt(section, 'PanelType', 0) of
1767 0: panel.PanelType := PANEL_WALL;
1768 1: panel.PanelType := PANEL_BACK;
1769 2: panel.PanelType := PANEL_FORE;
1770 3: panel.PanelType := PANEL_STEP;
1771 4: panel.PanelType := PANEL_WATER;
1772 5: panel.PanelType := PANEL_ACID1;
1773 6: panel.PanelType := PANEL_ACID2;
1774 end;
1776 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1778 // Текстура панели:
1779 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_STEP] then
1780 begin
1781 s := TexturePrefix + UpperCase(map.ReadStr(section, 'TextureName', ''));
1783 if g_GetTexture(s, panel.TextureID) then
1784 begin
1785 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1786 panel.TextureName := s;
1787 end
1788 else // Нет такой текстуры - ищем в WAD карты:
1789 begin
1790 s := ExtractFileName(_FileName);
1791 Delete(s, Length(s)-3, 4);
1792 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(map.ReadStr(section, 'TextureName', ''));
1794 if g_GetTexture(s, panel.TextureID) then
1795 begin
1796 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1797 panel.TextureName := s;
1798 end
1799 else
1800 Continue;
1801 end;
1802 end
1803 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1804 begin
1805 case panel.PanelType of
1806 PANEL_WATER:
1807 begin
1808 s := TEXTURE_NAME_WATER;
1809 panel.TextureID := TEXTURE_SPECIAL_WATER;
1810 end;
1811 PANEL_ACID1:
1812 begin
1813 s := TEXTURE_NAME_ACID2;
1814 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1815 end;
1816 PANEL_ACID2:
1817 begin
1818 s := TEXTURE_NAME_ACID1;
1819 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1820 end;
1821 end;
1823 with MainForm.lbTextureList.Items do
1824 if IndexOf(s) = -1 then
1825 Add(s);
1826 panel.TextureName := s;
1827 panel.TextureWidth := 1;
1828 panel.TextureHeight := 1;
1829 end;
1831 AddPanel(panel);
1832 end;
1834 // Чтение предметов:
1835 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1837 MainForm.pbLoad.Max := i;
1838 MainForm.pbLoad.Position := 0;
1839 MainForm.lLoad.Caption := _lc[I_LOAD_ITEMS];
1841 for a := 1 to i do
1842 begin
1843 MainForm.pbLoad.StepIt();
1844 Application.ProcessMessages();
1846 section := 'Item' + IntToStr(a);
1847 if not map.SectionExists(section) then
1848 Continue;
1850 item.X := map.ReadInt(section, 'X', 0);
1851 item.Y := map.ReadInt(section, 'Y', 0);
1852 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1853 item.OnlyDM := False;
1854 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1856 // Размер предметов теперь другой:
1857 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1858 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1860 AddItem(item);
1861 end;
1863 // Чтение областей:
1864 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1866 MainForm.pbLoad.Max := i;
1867 MainForm.pbLoad.Position := 0;
1868 MainForm.lLoad.Caption := _lc[I_LOAD_AREAS];
1870 for a := 1 to i do
1871 begin
1872 MainForm.pbLoad.StepIt();
1873 Application.ProcessMessages();
1875 section := 'Area' + IntToStr(a);
1876 if not map.SectionExists(section) then
1877 Continue;
1879 area.X := map.ReadInt(section, 'X', 0);
1880 area.Y := map.ReadInt(section, 'Y', 0);
1881 area.AreaType := map.ReadInt(section, 'Type', 0);
1882 area.Direction := D_RIGHT;
1884 // Размер областей теперь другой:
1885 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1886 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1888 AddArea(area);
1889 end;
1891 // Чтение параметров карты:
1892 with gMapInfo do
1893 begin
1894 Name := map.ReadStr('MapOptions', 'MapName', '');
1895 Description := map.ReadStr('MapOptions', 'MapDescription', '');
1896 Author := '';
1897 MusicName := DefaultMusRes;
1898 SkyName := DefaultSkyRes;
1899 FileName := _FileName;
1900 Height := map.ReadInt('MapOptions', 'Height', 1600);
1901 Width := map.ReadInt('MapOptions', 'Width', 1600);
1903 if Length(Name) > 32 then
1904 SetLength(Name, 32);
1905 if Length(Description) > 256 then
1906 SetLength(Description, 256);
1907 end;
1909 map.Free();
1911 Result := True;
1912 end;
1914 procedure ClearMap();
1915 var
1916 a: Integer;
1918 begin
1919 if gPanels <> nil then
1920 for a := 0 to High(gPanels) do
1921 if gPanels[a].TextureName <> '' then
1922 g_DeleteTexture(gPanels[a].TextureName);
1924 SetLength(gPanels, 0);
1925 gPanels := nil;
1926 SetLength(gItems, 0);
1927 gItems := nil;
1928 SetLength(gAreas, 0);
1929 gAreas := nil;
1930 SetLength(gMonsters, 0);
1931 gMonsters := nil;
1932 SetLength(gTriggers, 0);
1933 gTriggers := nil;
1935 with gMapInfo do
1936 begin
1937 Name := '';
1938 Description := '';
1939 Author := '';
1940 MusicName := '';
1941 SkyName := '';
1942 FileName := '';
1943 Height := 1600;
1944 Width := 1600;
1945 end;
1947 with MainForm.lbTextureList do
1948 begin
1949 if Items.Count > 0 then
1950 for a := Items.Count-1 downto 0 do
1951 if not IsSpecialTexture(Items[a]) then
1952 g_DeleteTexture(Items[a]);
1954 Clear();
1955 end;
1957 MapOffset.X := 0;
1958 MapOffset.Y := 0;
1959 end;
1961 procedure DrawPanels(fPanelType: Word);
1963 procedure DrawTexture(a: Integer);
1964 var
1965 NoTextureID: DWORD;
1966 NW, NH: Word;
1967 begin
1968 with gPanels[a] do
1969 begin
1970 case TextureID of
1971 TEXTURE_SPECIAL_NONE:
1972 if not PreviewMode then
1973 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1974 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1975 64, 64, 64, 127);
1977 TEXTURE_SPECIAL_NOTEXTURE:
1978 if g_GetTexture('NOTEXTURE', NoTextureID) then
1979 begin
1980 g_GetTextureSizeByID(NoTextureID, NW, NH);
1981 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
1982 Width div NW, Height div NH, 0, False, False);
1983 end;
1985 TEXTURE_SPECIAL_WATER:
1986 if PreviewMode then
1987 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1988 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1989 0, 0, 255, 0, B_FILTER)
1990 else
1991 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1992 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1993 0, 0, 255, 127);
1995 TEXTURE_SPECIAL_ACID1:
1996 if PreviewMode then
1997 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
1998 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
1999 0, 127, 0, 0, B_FILTER)
2000 else
2001 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2002 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2003 0, 255, 0, 127);
2005 TEXTURE_SPECIAL_ACID2:
2006 if PreviewMode then
2007 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2008 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2009 127, 0, 0, 0, B_FILTER)
2010 else
2011 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2012 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2013 255, 0, 0, 127);
2015 else
2016 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2017 Width div TextureWidth, Height div TextureHeight,
2018 Alpha, True, Blending);
2019 end;
2020 end;
2021 end;
2023 var
2024 a: Integer;
2025 begin
2026 if gPanels <> nil then
2027 for a := 0 to High(gPanels) do
2028 if (gPanels[a].PanelType <> 0) and
2029 WordBool(gPanels[a].PanelType and fPanelType) then
2030 with gPanels[a] do
2031 begin
2032 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2033 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2034 case PanelType of
2035 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2036 PANEL_STEP, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2037 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2038 DrawTexture(a);
2040 PANEL_LIFTUP:
2041 if not PreviewMode then
2042 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2043 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2044 128, 64, 0, 0);
2045 PANEL_LIFTDOWN:
2046 if not PreviewMode then
2047 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2048 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2049 90, 154, 138, 0);
2050 PANEL_LIFTLEFT:
2051 if not PreviewMode then
2052 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2053 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2054 200, 80, 4, 0);
2055 PANEL_LIFTRIGHT:
2056 if not PreviewMode then
2057 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2058 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2059 252, 140, 56, 0);
2060 PANEL_BLOCKMON:
2061 if not PreviewMode then
2062 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2063 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2064 192, 0, 192, 0);
2065 end;
2066 end;
2067 end;
2069 procedure DrawMap();
2070 var
2071 a, w, h: Integer;
2072 ID: DWORD;
2073 xx, yy, dx, dy: Integer;
2074 ww, hh: Word;
2075 sel: Boolean;
2076 r: TRectWH;
2078 begin
2079 // В режиме Превью рисуем небо:
2080 if PreviewMode then
2081 begin
2082 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2083 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2084 w := Round(w*4/3);
2085 h := Round(w*3/4);
2087 if g_GetTexture(SKY_TEXTURE, ID) then
2088 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2089 else
2090 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2091 end;
2093 // Рисуем панели (если Превью или если включен слой):
2094 if LayerEnabled[LAYER_BACK] or PreviewMode then
2095 DrawPanels(PANEL_BACK);
2096 if PreviewMode then
2097 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
2098 else
2099 if LayerEnabled[LAYER_WATER] then
2100 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
2101 PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
2102 if LayerEnabled[LAYER_WALLS] or PreviewMode then
2103 DrawPanels(PANEL_WALL);
2104 if LayerEnabled[LAYER_STEPS] or PreviewMode then
2105 DrawPanels(PANEL_STEP);
2107 // Рисуем предметы:
2108 if (LayerEnabled[LAYER_ITEMS] or PreviewMode) and
2109 (gItems <> nil) then
2110 for a := 0 to High(gItems) do
2111 if gItems[a].ItemType <> ITEM_NONE then
2112 with gItems[a] do
2113 begin
2114 ID := DWORD(-1);
2116 case ItemType of
2117 0: Continue;
2118 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2119 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2120 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2121 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2122 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2123 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2124 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2125 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2126 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2127 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2128 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2129 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2130 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2131 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2132 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2133 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2134 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2135 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2136 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2137 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2138 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2139 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2140 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2141 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2142 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2143 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2144 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2145 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2146 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2147 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2148 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2149 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2150 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2151 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2152 end;
2154 if ID <> DWORD(-1) then
2155 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2156 end;
2158 // Рисуем монстров:
2159 if (LayerEnabled[LAYER_MONSTERS] or PreviewMode) and
2160 (gMonsters <> nil) then
2161 for a := 0 to High(gMonsters) do
2162 if gMonsters[a].MonsterType <> MONSTER_NONE then
2163 with MonsterSize[gMonsters[a].MonsterType] do
2164 begin
2165 ID := DWORD(-1);
2167 case gMonsters[a].MonsterType of
2168 0: Continue;
2169 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2170 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2171 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2172 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2173 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2174 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2175 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2176 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2177 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2178 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2179 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2180 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2181 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2182 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2183 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2184 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2185 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2186 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2187 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2188 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2189 end;
2191 if ID <> DWORD(-1) then
2192 if gMonsters[a].Direction = D_LEFT then
2193 begin
2194 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2195 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2196 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2197 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2198 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2199 xx := (gMonsters[a].X - X) - xx;
2201 yy := (gMonsters[a].Y - Y) +
2202 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2204 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2205 0, True, False, M_HORIZONTAL);
2206 end
2207 else
2208 begin
2209 // Левый верхний угол текстуры + смещение анимации:
2210 xx := (gMonsters[a].X - X) +
2211 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2212 yy := (gMonsters[a].Y - Y) +
2213 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2215 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2216 0, True, False);
2217 end;
2219 // Рамка:
2220 if not PreviewMode then
2221 begin
2222 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2223 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2224 255, 255, 255);
2225 end;
2226 end;
2228 // Рисуем закрытые двери после монстров:
2229 if PreviewMode then
2230 DrawPanels(PANEL_CLOSEDOOR);
2232 // Рисуем области:
2233 if (LayerEnabled[LAYER_AREAS] or PreviewMode) and
2234 (gAreas <> nil) then
2235 for a := 0 to High(gAreas) do
2236 if gAreas[a].AreaType <> AREA_NONE then
2237 with AreaSize[gAreas[a].AreaType] do
2238 begin
2239 ID := DWORD(-1);
2241 case gAreas[a].AreaType of
2242 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2243 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2244 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2245 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2246 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2247 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2248 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2249 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2250 end;
2252 if (not PreviewMode) or
2253 (gAreas[a].AreaType = AREA_REDFLAG) or
2254 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2255 (gAreas[a].AreaType = AREA_DOMFLAG) then
2256 if ID <> DWORD(-1) then
2257 if gAreas[a].Direction = D_LEFT then
2258 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2259 0, True, False, M_HORIZONTAL)
2260 else
2261 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2262 0, True, False);
2264 // Рамка:
2265 if not PreviewMode then
2266 begin
2267 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2268 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2269 255, 255, 255);
2271 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2272 end;
2273 end;
2275 // Рисуем жидкости и передний план после областей:
2276 if LayerEnabled[LAYER_WATER] or PreviewMode then
2277 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2278 if LayerEnabled[LAYER_FOREGROUND] or PreviewMode then
2279 DrawPanels(PANEL_FORE);
2281 // Рисуем триггеры:
2282 if LayerEnabled[LAYER_TRIGGERS] and
2283 (not PreviewMode) and (gTriggers <> nil) then
2284 for a := 0 to High(gTriggers) do
2285 with gTriggers[a] do
2286 if TriggerType <> TRIGGER_NONE then
2287 begin
2288 // Если выбран - рисуем красным, иначе - белым:
2289 sel := ObjectSelected(OBJECT_TRIGGER, a);
2291 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2292 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2293 0, 0, 0, 150);
2295 if TexturePanel <> -1 then
2296 begin
2297 with gPanels[TexturePanel] do
2298 begin
2299 xx := X;
2300 yy := Y;
2301 ww := Width;
2302 hh := Height;
2303 end;
2305 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2306 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2307 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2308 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2309 MapOffset.X+xx, MapOffset.Y+yy,
2310 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2311 end;
2313 case TriggerType of
2314 TRIGGER_EXIT: ;
2316 TRIGGER_TELEPORT:
2317 begin
2318 // Точка назначения Телепорта:
2319 if Data.d2d_teleport then
2320 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2321 MapOffset.Y+Data.TargetPoint.Y-1,
2322 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2323 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2324 else
2325 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2326 MapOffset.Y+Data.TargetPoint.Y,
2327 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2328 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2329 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2330 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2331 MapOffset.Y+Data.TargetPoint.Y,
2332 255, 0, 0);
2333 // Линия к точке назначения Телепорта:
2334 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2335 MapOffset.Y+Y+(Height div 2),
2336 MapOffset.X+Data.TargetPoint.X,
2337 MapOffset.Y+Data.TargetPoint.Y,
2338 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2339 end;
2341 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2342 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2343 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2344 TRIGGER_LIFT:
2345 if Data.PanelID <> -1 then
2346 begin
2347 // Дверь/Ловушка/Лифт:
2348 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2349 MapOffset.Y+gPanels[Data.PanelID].Y,
2350 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2351 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2352 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2353 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2354 MapOffset.Y+gPanels[Data.PanelID].Y,
2355 255, 0, 0);
2356 // Линия к Двери/Ловушке/Лифту:
2357 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2358 MapOffset.Y+Y+(Height div 2),
2359 MapOffset.X+gPanels[Data.PanelID].X,
2360 MapOffset.Y+gPanels[Data.PanelID].Y,
2361 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2362 end;
2364 TRIGGER_PRESS, TRIGGER_ON,
2365 TRIGGER_OFF, TRIGGER_ONOFF:
2366 begin
2367 if (Data.tWidth > 0) and
2368 (Data.tHeight > 0) then
2369 begin
2370 // Область Расширителя:
2371 e_DrawQuad(MapOffset.X+Data.tX,
2372 MapOffset.Y+Data.tY,
2373 MapOffset.X+Data.tX+Data.tWidth-1,
2374 MapOffset.Y+Data.tY+Data.tHeight-1,
2375 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2376 e_DrawPoint(2, MapOffset.X+Data.tX,
2377 MapOffset.Y+Data.tY,
2378 255, 0, 0);
2379 // Линия к области Расширителя:
2380 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2381 MapOffset.Y+Y+(Height div 2),
2382 MapOffset.X+Data.tX,
2383 MapOffset.Y+Data.tY,
2384 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2385 end;
2387 if Data.MonsterID <> 0 then
2388 if (gMonsters <> nil) and
2389 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2390 begin
2391 // Рамка вокруг Монстра - условия активации:
2392 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2393 e_DrawQuad(MapOffset.X+r.X,
2394 MapOffset.Y+r.Y,
2395 MapOffset.X+r.X+r.Width-1,
2396 MapOffset.Y+r.Y+r.Height-1,
2397 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2398 // Линия к Монстру - условию активации:
2399 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2400 MapOffset.Y+Y+(Height div 2),
2401 MapOffset.X+r.X,
2402 MapOffset.Y+r.Y,
2403 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2405 end;
2406 end;
2408 TRIGGER_SECRET: ;
2410 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2411 begin
2412 if TriggerType = TRIGGER_SPAWNMONSTER then
2413 begin
2414 xx := Data.MonPos.X;
2415 yy := Data.MonPos.Y;
2416 end
2417 else
2418 begin
2419 xx := Data.ItemPos.X;
2420 yy := Data.ItemPos.Y;
2421 end;
2422 // Точка появления Монстра/Предмета:
2423 e_DrawLine(2, MapOffset.X+xx-16,
2424 MapOffset.Y+yy-1,
2425 MapOffset.X+xx+16,
2426 MapOffset.Y+yy-1,
2427 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2428 e_DrawPoint(2, MapOffset.X+xx,
2429 MapOffset.Y+yy,
2430 255, 0, 0);
2431 // Линия к точке появления Монстра/Предмета:
2432 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2433 MapOffset.Y+Y+(Height div 2),
2434 MapOffset.X+xx,
2435 MapOffset.Y+yy,
2436 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2437 // Предпросмотр создаваемого объекта:
2438 if sel then
2439 begin
2440 // Монстр:
2441 if TriggerType = TRIGGER_SPAWNMONSTER then
2442 begin
2443 if Data.MonType <> MONSTER_NONE then
2444 with MonsterSize[Data.MonType] do
2445 begin
2446 ID := DWORD(-1);
2447 case Data.MonType of
2448 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2449 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2450 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2451 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2452 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2453 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2454 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2455 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2456 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2457 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2458 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2459 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2460 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2461 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2462 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2463 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2464 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2465 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2466 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2467 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2468 end;
2469 if ID <> DWORD(-1) then
2470 begin
2471 if Data.MonDir = Byte(D_LEFT) then
2472 begin
2473 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2474 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2475 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2477 yy := Data.TargetPoint.Y - Y +
2478 MonsterSizeDelta[Data.MonType].Y-Height;
2480 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2481 128, True, False, M_HORIZONTAL);
2482 end
2483 else
2484 begin
2485 xx := Data.TargetPoint.X - X +
2486 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2487 yy := Data.TargetPoint.Y - Y +
2488 MonsterSizeDelta[Data.MonType].Y-Height;
2490 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2491 128, True, False);
2492 end;
2493 // Рамка:
2494 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2495 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2496 255, 255, 0, 128);
2497 end;
2498 end;
2499 end
2500 else
2501 // Предмет:
2502 begin
2503 if Data.ItemType <> ITEM_NONE then
2504 begin
2505 ID := DWORD(-1);
2506 case Data.ItemType of
2507 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2508 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2509 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2510 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2511 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2512 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2513 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2514 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2515 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2516 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2517 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2518 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2519 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2520 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2521 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2522 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2523 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2524 ITEM_WEAPON_SUPERPULEMET: g_GetTexture('ITEM_WEAPON_SUPERPULEMET', ID);
2525 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2526 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2527 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2528 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2529 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2530 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2531 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2532 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2533 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2534 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2535 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2536 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2537 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2538 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2539 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2540 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2541 end;
2542 if ID <> DWORD(-1) then
2543 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2544 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2545 128, True, False);
2546 // Рамка:
2547 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2548 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2549 255, 255, 0, 128);
2550 end;
2551 end;
2552 end;
2553 end;
2555 TRIGGER_PUSH:
2556 begin
2557 // Линия направления и силы ускорения:
2558 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2559 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2560 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2561 MapOffset.Y+Y+(Height div 2),
2562 MapOffset.X+xx,
2563 MapOffset.Y+yy,
2564 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2565 end;
2567 TRIGGER_SHOT:
2568 begin;
2569 xx := Data.ShotPos.X;
2570 yy := Data.ShotPos.Y;
2571 // Точка появления снаряда:
2572 e_DrawPoint(2, MapOffset.X+xx,
2573 MapOffset.Y+yy,
2574 255, 0, 0);
2575 // Линия к точке появления снаряда:
2576 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2577 MapOffset.Y+Y+(Height div 2),
2578 MapOffset.X+xx,
2579 MapOffset.Y+yy,
2580 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2581 // Линия направления выстрела:
2582 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2583 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2584 e_DrawLine(1, MapOffset.X+xx,
2585 MapOffset.Y+yy,
2586 MapOffset.X+xx+dx,
2587 MapOffset.Y+yy+dy,
2588 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2590 if (Data.ShotPanelID <> -1) and
2591 (Data.ShotPanelID <= High(gPanels)) then
2592 begin
2593 // Линия к панели индикации выстрела
2594 with gPanels[Data.ShotPanelID] do
2595 begin
2596 xx := X;
2597 yy := Y;
2598 ww := Width;
2599 hh := Height;
2600 end;
2602 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2603 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2604 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2605 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2606 MapOffset.X+xx, MapOffset.Y+yy,
2607 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2608 end;
2609 end;
2610 end;
2611 end;
2613 // Границы карты:
2614 if not PreviewMode then
2615 begin
2616 e_DrawFillQuad(-32+MapOffset.X,
2617 -32+MapOffset.Y,
2618 gMapInfo.Width+31+MapOffset.X,
2619 -1+MapOffset.Y,
2620 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2621 e_DrawFillQuad(-32+MapOffset.X,
2622 gMapInfo.Height+MapOffset.Y,
2623 gMapInfo.Width+31+MapOffset.X,
2624 gMapInfo.Height+31+MapOffset.Y,
2625 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2626 e_DrawFillQuad(-32+MapOffset.X,
2627 MapOffset.Y,
2628 -1+MapOffset.X,
2629 gMapInfo.Height+MapOffset.Y-1,
2630 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2631 e_DrawFillQuad(gMapInfo.Width+MapOffset.X,
2632 MapOffset.Y,
2633 gMapInfo.Width+31+MapOffset.X,
2634 gMapInfo.Height+MapOffset.Y-1,
2635 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2636 end;
2637 end;
2639 procedure ShiftMapObjects(dx, dy: Integer);
2640 var
2641 i: Integer;
2642 begin
2643 if gPanels <> nil then
2644 for i := 0 to High(gPanels) do
2645 if gPanels[i].PanelType <> 0 then
2646 begin
2647 Inc(gPanels[i].X, dx);
2648 Inc(gPanels[i].Y, dy);
2649 end;
2651 if gItems <> nil then
2652 for i := 0 to High(gItems) do
2653 if gItems[i].ItemType <> 0 then
2654 begin
2655 Inc(gItems[i].X, dx);
2656 Inc(gItems[i].Y, dy);
2657 end;
2659 if gAreas <> nil then
2660 for i := 0 to High(gAreas) do
2661 if gAreas[i].AreaType <> 0 then
2662 begin
2663 Inc(gAreas[i].X, dx);
2664 Inc(gAreas[i].Y, dy);
2665 end;
2667 if gMonsters <> nil then
2668 for i := 0 to High(gMonsters) do
2669 if gMonsters[i].MonsterType <> 0 then
2670 begin
2671 Inc(gMonsters[i].X, dx);
2672 Inc(gMonsters[i].Y, dy);
2673 end;
2675 if gTriggers <> nil then
2676 for i := 0 to High(gTriggers) do
2677 if gTriggers[i].TriggerType <> 0 then
2678 begin
2679 Inc(gTriggers[i].X, dx);
2680 Inc(gTriggers[i].Y, dy);
2682 case gTriggers[i].TriggerType of
2683 TRIGGER_TELEPORT:
2684 begin
2685 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2686 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2687 end;
2689 TRIGGER_PRESS, TRIGGER_ON,
2690 TRIGGER_OFF, TRIGGER_ONOFF:
2691 begin
2692 Inc(gTriggers[i].Data.tX, dx);
2693 Inc(gTriggers[i].Data.tY, dy);
2694 end;
2696 TRIGGER_SPAWNMONSTER:
2697 begin
2698 Inc(gTriggers[i].Data.MonPos.X, dx);
2699 Inc(gTriggers[i].Data.MonPos.Y, dy);
2700 end;
2702 TRIGGER_SPAWNITEM:
2703 begin
2704 Inc(gTriggers[i].Data.ItemPos.X, dx);
2705 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2706 end;
2708 TRIGGER_SHOT:
2709 begin
2710 Inc(gTriggers[i].Data.ShotPos.X, dx);
2711 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2712 end;
2713 end;
2714 end;
2715 end;
2717 procedure LoadData();
2718 begin
2719 g_CreateTextureWAD('NOTEXTURE', EditorDir+'\data\Game.wad:TEXTURES\NOTEXTURE');
2721 g_CreateTextureWADSize('AREA_REDFLAG', EditorDir+'\data\Game.wad:TEXTURES\FLAGRED', 0, 0, 64, 64);
2722 g_CreateTextureWADSize('AREA_BLUEFLAG', EditorDir+'\data\Game.wad:TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2723 g_CreateTextureWADSize('AREA_DOMFLAG', EditorDir+'\data\Game.wad:TEXTURES\FLAGDOM', 0, 0, 64, 64);
2725 g_CreateTextureWADSize('MONSTER_DEMON', EditorDir+'\data\Game.wad:MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2726 g_CreateTextureWADSize('MONSTER_IMP', EditorDir+'\data\Game.wad:MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2727 g_CreateTextureWADSize('MONSTER_ZOMBY', EditorDir+'\data\Game.wad:MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2728 g_CreateTextureWADSize('MONSTER_SERG', EditorDir+'\data\Game.wad:MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2729 g_CreateTextureWADSize('MONSTER_CYBER', EditorDir+'\data\Game.wad:MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2730 g_CreateTextureWADSize('MONSTER_CGUN', EditorDir+'\data\Game.wad:MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2731 g_CreateTextureWADSize('MONSTER_BARON', EditorDir+'\data\Game.wad:MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2732 g_CreateTextureWADSize('MONSTER_KNIGHT', EditorDir+'\data\Game.wad:MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2733 g_CreateTextureWADSize('MONSTER_CACO', EditorDir+'\data\Game.wad:MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2734 g_CreateTextureWADSize('MONSTER_SOUL', EditorDir+'\data\Game.wad:MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2735 g_CreateTextureWADSize('MONSTER_PAIN', EditorDir+'\data\Game.wad:MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2736 g_CreateTextureWADSize('MONSTER_SPIDER', EditorDir+'\data\Game.wad:MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2737 g_CreateTextureWADSize('MONSTER_BSP', EditorDir+'\data\Game.wad:MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2738 g_CreateTextureWADSize('MONSTER_MANCUB', EditorDir+'\data\Game.wad:MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2739 g_CreateTextureWADSize('MONSTER_SKEL', EditorDir+'\data\Game.wad:MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2740 g_CreateTextureWADSize('MONSTER_VILE', EditorDir+'\data\Game.wad:MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2741 g_CreateTextureWADSize('MONSTER_FISH', EditorDir+'\data\Game.wad:MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2742 g_CreateTextureWADSize('MONSTER_BARREL', EditorDir+'\data\Game.wad:MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2743 g_CreateTextureWADSize('MONSTER_ROBO', EditorDir+'\data\Game.wad:MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2744 g_CreateTextureWADSize('MONSTER_MAN', EditorDir+'\data\Game.wad:MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2746 g_CreateTextureWADSize('ITEM_BLUESPHERE', EditorDir+'\data\Game.wad:TEXTURES\SBLUE', 0, 0, 32, 32);
2747 g_CreateTextureWADSize('ITEM_WHITESPHERE', EditorDir+'\data\Game.wad:TEXTURES\SWHITE', 0, 0, 32, 32);
2748 g_CreateTextureWADSize('ITEM_ARMORGREEN', EditorDir+'\data\Game.wad:TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2749 g_CreateTextureWADSize('ITEM_ARMORBLUE', EditorDir+'\data\Game.wad:TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2750 g_CreateTextureWADSize('ITEM_INVUL', EditorDir+'\data\Game.wad:TEXTURES\INVUL', 0, 0, 32, 32);
2751 g_CreateTextureWADSize('ITEM_BOTTLE', EditorDir+'\data\Game.wad:TEXTURES\BOTTLE', 0, 0, 16, 32);
2752 g_CreateTextureWADSize('ITEM_HELMET', EditorDir+'\data\Game.wad:TEXTURES\HELMET', 0, 0, 16, 16);
2753 g_CreateTextureWADSize('ITEM_INVIS', EditorDir+'\data\Game.wad:TEXTURES\INVIS', 0, 0, 32, 32);
2755 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', EditorDir+'\data\Game.wad:TEXTURES\MED1');
2756 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', EditorDir+'\data\Game.wad:TEXTURES\MED2');
2757 g_CreateTextureWAD('ITEM_WEAPON_SAW', EditorDir+'\data\Game.wad:TEXTURES\SAW');
2758 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', EditorDir+'\data\Game.wad:TEXTURES\PISTOL');
2759 g_CreateTextureWAD('ITEM_WEAPON_KASTET', EditorDir+'\data\Game.wad:TEXTURES\KASTET');
2760 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', EditorDir+'\data\Game.wad:TEXTURES\SHOTGUN1');
2761 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', EditorDir+'\data\Game.wad:TEXTURES\SHOTGUN2');
2762 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', EditorDir+'\data\Game.wad:TEXTURES\MGUN');
2763 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', EditorDir+'\data\Game.wad:TEXTURES\RLAUNCHER');
2764 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', EditorDir+'\data\Game.wad:TEXTURES\PGUN');
2765 g_CreateTextureWAD('ITEM_WEAPON_BFG', EditorDir+'\data\Game.wad:TEXTURES\BFG');
2766 g_CreateTextureWAD('ITEM_WEAPON_SUPERPULEMET', EditorDir+'\data\Game.wad:TEXTURES\SPULEMET');
2767 g_CreateTextureWAD('ITEM_AMMO_BULLETS', EditorDir+'\data\Game.wad:TEXTURES\CLIP');
2768 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', EditorDir+'\data\Game.wad:TEXTURES\AMMO');
2769 g_CreateTextureWAD('ITEM_AMMO_SHELLS', EditorDir+'\data\Game.wad:TEXTURES\SHELL1');
2770 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', EditorDir+'\data\Game.wad:TEXTURES\SHELL2');
2771 g_CreateTextureWAD('ITEM_AMMO_ROCKET', EditorDir+'\data\Game.wad:TEXTURES\ROCKET');
2772 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', EditorDir+'\data\Game.wad:TEXTURES\ROCKETS');
2773 g_CreateTextureWAD('ITEM_AMMO_CELL', EditorDir+'\data\Game.wad:TEXTURES\CELL');
2774 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', EditorDir+'\data\Game.wad:TEXTURES\CELL2');
2775 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', EditorDir+'\data\Game.wad:TEXTURES\BPACK');
2776 g_CreateTextureWAD('ITEM_KEY_RED', EditorDir+'\data\Game.wad:TEXTURES\KEYR');
2777 g_CreateTextureWAD('ITEM_KEY_GREEN', EditorDir+'\data\Game.wad:TEXTURES\KEYG');
2778 g_CreateTextureWAD('ITEM_KEY_BLUE', EditorDir+'\data\Game.wad:TEXTURES\KEYB');
2779 g_CreateTextureWAD('ITEM_OXYGEN', EditorDir+'\data\Game.wad:TEXTURES\OXYGEN');
2780 g_CreateTextureWAD('ITEM_SUIT', EditorDir+'\data\Game.wad:TEXTURES\SUIT');
2781 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', EditorDir+'\data\Game.wad:TEXTURES\BMED');
2782 g_CreateTextureWAD('ITEM_JETPACK', EditorDir+'\data\Game.wad:TEXTURES\JETPACK');
2784 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorDir+'\data\Editor.wad:TEXTURES\P1POINT');
2785 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorDir+'\data\Editor.wad:TEXTURES\P2POINT');
2786 g_CreateTextureWAD('AREA_DMPOINT', EditorDir+'\data\Editor.wad:TEXTURES\DMPOINT');
2787 g_CreateTextureWAD('AREA_REDPOINT', EditorDir+'\data\Editor.wad:TEXTURES\REDPOINT');
2788 g_CreateTextureWAD('AREA_BLUEPOINT', EditorDir+'\data\Editor.wad:TEXTURES\BLUEPOINT');
2789 end;
2791 procedure FreeData();
2792 begin
2793 g_DeleteTexture('NOTEXTURE');
2795 g_DeleteTexture('ITEM_BLUESPHERE');
2796 g_DeleteTexture('ITEM_WHITESPHERE');
2797 g_DeleteTexture('ITEM_ARMORGREEN');
2798 g_DeleteTexture('ITEM_ARMORBLUE');
2799 g_DeleteTexture('ITEM_INVUL');
2800 g_DeleteTexture('ITEM_BOTTLE');
2801 g_DeleteTexture('ITEM_HELMET');
2802 g_DeleteTexture('AREA_REDFLAG');
2803 g_DeleteTexture('AREA_BLUEFLAG');
2804 g_DeleteTexture('AREA_DOMFLAG');
2806 g_DeleteTexture('MONSTER_DEMON');
2807 g_DeleteTexture('MONSTER_IMP');
2808 g_DeleteTexture('MONSTER_ZOMBY');
2809 g_DeleteTexture('MONSTER_SERG');
2810 g_DeleteTexture('MONSTER_CGUN');
2811 g_DeleteTexture('MONSTER_BARREL');
2812 g_DeleteTexture('MONSTER_MAN');
2814 g_DeleteTexture('MONSTER_DEMON');
2815 g_DeleteTexture('MONSTER_IMP');
2816 g_DeleteTexture('MONSTER_ZOMBY');
2817 g_DeleteTexture('MONSTER_SERG');
2818 g_DeleteTexture('MONSTER_CYBER');
2819 g_DeleteTexture('MONSTER_CGUN');
2820 g_DeleteTexture('MONSTER_BARON');
2821 g_DeleteTexture('MONSTER_KNIGHT');
2822 g_DeleteTexture('MONSTER_CACO');
2823 g_DeleteTexture('MONSTER_SOUL');
2824 g_DeleteTexture('MONSTER_PAIN');
2825 g_DeleteTexture('MONSTER_SPIDER');
2826 g_DeleteTexture('MONSTER_BSP');
2827 g_DeleteTexture('MONSTER_MANCUB');
2828 g_DeleteTexture('MONSTER_SKEL');
2829 g_DeleteTexture('MONSTER_VILE');
2830 g_DeleteTexture('MONSTER_FISH');
2831 g_DeleteTexture('MONSTER_BARREL');
2832 g_DeleteTexture('MONSTER_ROBO');
2833 g_DeleteTexture('MONSTER_MAN');
2835 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2836 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2837 g_DeleteTexture('ITEM_WEAPON_SAW');
2838 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2839 g_DeleteTexture('ITEM_WEAPON_KASTET');
2840 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2841 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2842 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2843 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
2844 g_DeleteTexture('ITEM_WEAPON_PLASMA');
2845 g_DeleteTexture('ITEM_WEAPON_BFG');
2846 g_DeleteTexture('ITEM_WEAPON_SUPERPULEMET');
2847 g_DeleteTexture('ITEM_AMMO_BULLETS');
2848 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
2849 g_DeleteTexture('ITEM_AMMO_SHELLS');
2850 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
2851 g_DeleteTexture('ITEM_AMMO_ROCKET');
2852 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
2853 g_DeleteTexture('ITEM_AMMO_CELL');
2854 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
2855 g_DeleteTexture('ITEM_AMMO_BACKPACK');
2856 g_DeleteTexture('ITEM_KEY_RED');
2857 g_DeleteTexture('ITEM_KEY_GREEN');
2858 g_DeleteTexture('ITEM_KEY_BLUE');
2859 g_DeleteTexture('ITEM_OXYGEN');
2860 g_DeleteTexture('ITEM_SUIT');
2861 g_DeleteTexture('ITEM_MEDKIT_BLACK');
2862 g_DeleteTexture('ITEM_JETPACK');
2863 g_DeleteTexture('ITEM_INVIS');
2865 g_DeleteTexture('AREA_PLAYERPOINT1');
2866 g_DeleteTexture('AREA_PLAYERPOINT2');
2867 g_DeleteTexture('AREA_DMPOINT');
2868 g_DeleteTexture('AREA_REDPOINT');
2869 g_DeleteTexture('AREA_BLUEPOINT');
2870 end;
2872 end.