DEADSOFTWARE

get rid of "kastet" and "pulemet" in symbols
[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_SUPERCHAINGUN
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_IRONFIST
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 function ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte): Boolean;
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, ArchiveFormat: 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, g_options;
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_SUPERCHAINGUN = 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_SUPERCHAINGUN),
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_SUPERCHAINGUN
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 := WadsDir + DirectorySeparator + 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 function ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte): Boolean;
868 begin
869 Result := True;
870 case ObjectType of
871 OBJECT_PANEL:
872 with gPanels[ID] do
873 begin
874 if Width >= -dWidth then
875 Width := Width+dWidth
876 else
877 begin
878 Width := 0;
879 Result := False;
880 Exit;
881 end;
883 if Height >= -dHeight then
884 Height := Height+dHeight
885 else
886 begin
887 Height := 0;
888 Result := False;
889 Exit;
890 end;
892 case ResizeDir of
893 2: Y := Y - dHeight;
894 4: X := X - dWidth;
895 end;
896 end;
898 OBJECT_ITEM, OBJECT_MONSTER, OBJECT_AREA:
899 Exit;
901 OBJECT_TRIGGER:
902 with gTriggers[ID] do
903 begin
904 if Width >= -dWidth then
905 Width := Width+dWidth
906 else
907 begin
908 Width := 0;
909 Result := False;
910 Exit;
911 end;
913 if Height >= -dHeight then
914 Height := Height+dHeight
915 else
916 begin
917 Height := 0;
918 Result := False;
919 Exit;
920 end;
922 case ResizeDir of
923 2: Y := Y - dHeight;
924 4: X := X - dWidth;
925 end;
926 end;
927 end;
928 end;
930 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
931 var
932 a: Integer;
934 begin
935 Result := False;
937 if SelectedObjects <> nil then
938 for a := 0 to High(SelectedObjects) do
939 if SelectedObjects[a].Live and
940 (SelectedObjects[a].ObjectType = ObjectType) and
941 (SelectedObjects[a].ID = ID) then
942 begin
943 Result := True;
944 Break;
945 end;
946 end;
948 function GetPanelName(PanelType: Word): String;
949 begin
950 Result := '';
952 case PanelType of
953 PANEL_WALL: Result := PANELNAMES[0];
954 PANEL_BACK: Result := PANELNAMES[1];
955 PANEL_FORE: Result := PANELNAMES[2];
956 PANEL_OPENDOOR: Result := PANELNAMES[3];
957 PANEL_CLOSEDOOR: Result := PANELNAMES[4];
958 PANEL_STEP: Result := PANELNAMES[5];
959 PANEL_WATER: Result := PANELNAMES[6];
960 PANEL_ACID1: Result := PANELNAMES[7];
961 PANEL_ACID2: Result := PANELNAMES[8];
962 PANEL_LIFTUP: Result := PANELNAMES[9];
963 PANEL_LIFTDOWN: Result := PANELNAMES[10];
964 PANEL_LIFTLEFT: Result := PANELNAMES[11];
965 PANEL_LIFTRIGHT: Result := PANELNAMES[12];
966 PANEL_BLOCKMON: Result := PANELNAMES[13];
967 else Assert(False);
968 end;
969 end;
971 function GetPanelType(PanelName: String): Word;
972 begin
973 Result := 0;
975 if PanelName = PANELNAMES[0] then
976 Result := PANEL_WALL
977 else if PanelName = PANELNAMES[1] then
978 Result := PANEL_BACK
979 else if PanelName = PANELNAMES[2] then
980 Result := PANEL_FORE
981 else if PanelName = PANELNAMES[3] then
982 Result := PANEL_OPENDOOR
983 else if PanelName = PANELNAMES[4] then
984 Result := PANEL_CLOSEDOOR
985 else if PanelName = PANELNAMES[5] then
986 Result := PANEL_STEP
987 else if PanelName = PANELNAMES[6] then
988 Result := PANEL_WATER
989 else if PanelName = PANELNAMES[7] then
990 Result := PANEL_ACID1
991 else if PanelName = PANELNAMES[8] then
992 Result := PANEL_ACID2
993 else if PanelName = PANELNAMES[9] then
994 Result := PANEL_LIFTUP
995 else if PanelName = PANELNAMES[10] then
996 Result := PANEL_LIFTDOWN
997 else if PanelName = PANELNAMES[11] then
998 Result := PANEL_LIFTLEFT
999 else if PanelName = PANELNAMES[12] then
1000 Result := PANEL_LIFTRIGHT
1001 else if PanelName = PANELNAMES[13] then
1002 Result := PANEL_BLOCKMON;
1004 Assert(Result <> 0);
1005 end;
1007 function GetTriggerName(TriggerType: Byte): String;
1008 begin
1009 if TriggerType in [TRIGGER_EXIT..TRIGGER_MAX] then
1010 Result := TriggerNames[TriggerType]
1011 else
1012 Assert(False);
1013 end;
1015 function GetTriggerType(TriggerName: String): Byte;
1016 var
1017 i: Integer;
1019 begin
1020 Result := TRIGGER_NONE;
1021 for i := TRIGGER_EXIT to TRIGGER_MAX do
1022 if TriggerNames[i] = TriggerName then
1023 begin
1024 Result := i;
1025 Exit;
1026 end;
1028 Assert(False);
1029 end;
1031 function IsSpecialTexture(TextureName: string): Boolean;
1032 begin
1033 Result := (TextureName = TEXTURE_NAME_WATER) or
1034 (TextureName = TEXTURE_NAME_ACID1) or
1035 (TextureName = TEXTURE_NAME_ACID2);
1036 end;
1038 function SpecialTextureID(TextureName: string): DWORD;
1039 begin
1040 Assert(IsSpecialTexture(TextureName));
1042 Result := 0;
1044 if TextureName = TEXTURE_NAME_WATER then
1045 Result := TEXTURE_SPECIAL_WATER
1046 else
1047 if TextureName = TEXTURE_NAME_ACID1 then
1048 Result := TEXTURE_SPECIAL_ACID1
1049 else
1050 if TextureName = TEXTURE_NAME_ACID2 then
1051 Result := TEXTURE_SPECIAL_ACID2;
1052 end;
1054 function SaveMap(Res, ArchiveFormat: String): Pointer;
1055 var
1056 WAD: TWADEditor;
1057 MapWriter: TMapWriter_1;
1058 textures: TTexturesRec1Array;
1059 panels: TPanelsRec1Array;
1060 items: TItemsRec1Array;
1061 areas: TAreasRec1Array;
1062 monsters: TMonsterRec1Array;
1063 triggers: TTriggersRec1Array;
1064 header: TMapHeaderRec_1;
1065 a, b, c: Integer;
1066 s: String;
1067 PanelTable: Array of Array [0..1] of Word;
1068 MonsterTable: Array of Array [0..1] of Word;
1069 Data: Pointer;
1070 FileName, SectionName, ResName: String;
1071 Len: LongWord;
1073 begin
1074 WAD := nil;
1075 textures := nil;
1076 panels := nil;
1077 items := nil;
1078 areas := nil;
1079 monsters := nil;
1080 triggers := nil;
1081 PanelTable := nil;
1082 MonsterTable := nil;
1083 Data := nil;
1084 Len := 0;
1086 // Открываем WAD, если надо:
1087 if Res <> '' then
1088 begin
1089 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1091 if ArchiveFormat = '' then
1092 begin
1093 // format not specified -> try open automatically and append to it (or create new default)
1094 WAD := gWADEditorFactory.OpenFile(FileName);
1095 if WAD = nil then
1096 WAD := gWADEditorFactory.CreateDefaultEditor();
1097 end
1098 else
1099 begin
1100 // format specified -> append using exactly this format (overwrite if not compatible)
1101 WAD := gWADEditorFactory.CreateEditor(ArchiveFormat);
1102 if WAD.ReadFile(FileName) = False then
1103 WAD.FreeWAD();
1104 end;
1105 WAD.CreateImage();
1106 end;
1108 MapWriter := TMapWriter_1.Create();
1110 // Сохраняем заголовок:
1111 with header do
1112 begin
1113 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1115 s := utf2win(gMapInfo.Name);
1116 if s <> '' then
1117 CopyMemory(@MapName[0], @s[1], Min(32, Length(s)));
1119 s := utf2win(gMapInfo.Description);
1120 if s <> '' then
1121 CopyMemory(@MapDescription[0], @s[1], Min(256, Length(s)));
1123 s := utf2win(gMapInfo.Author);
1124 if s <> '' then
1125 CopyMemory(@MapAuthor[0], @s[1], Min(32, Length(s)));
1127 s := utf2win(gMapInfo.MusicName);
1128 if s <> '' then
1129 CopyMemory(@MusicName[0], @s[1], Min(64, Length(s)));
1131 s := utf2win(gMapInfo.SkyName);
1132 if s <> '' then
1133 CopyMemory(@SkyName[0], @s[1], Min(64, Length(s)));
1135 Width := gMapInfo.Width;
1136 Height := gMapInfo.Height;
1137 end;
1139 MapWriter.AddHeader(header);
1141 // Сохраняем названия текстур:
1142 if MainForm.lbTextureList.Items.Count > 0 then
1143 begin
1144 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1145 begin
1146 SetLength(textures, Length(textures)+1);
1147 s := utf2win(MainForm.lbTextureList.Items[a]);
1148 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1149 if g_GetTextureFlagByName(MainForm.lbTextureList.Items[a]) = 1 then
1150 textures[High(textures)].Anim := 1
1151 else
1152 textures[High(textures)].Anim := 0;
1153 end;
1155 MapWriter.AddTextures(textures);
1156 end;
1158 // Сохраняем панели:
1159 if gPanels <> nil then
1160 begin
1161 c := 0;
1163 for a := 0 to High(gPanels) do
1164 if gPanels[a].PanelType <> 0 then
1165 begin
1166 SetLength(PanelTable, Length(PanelTable)+1);
1167 PanelTable[High(PanelTable)][0] := a;
1168 PanelTable[High(PanelTable)][1] := c;
1169 c := c + 1;
1171 SetLength(panels, Length(panels)+1);
1173 with panels[High(panels)] do
1174 begin
1175 X := gPanels[a].X;
1176 Y := gPanels[a].Y;
1177 Width := gPanels[a].Width;
1178 Height := gPanels[a].Height;
1179 PanelType := gPanels[a].PanelType;
1180 Alpha := gPanels[a].Alpha;
1182 TextureNum := 0;
1183 Flags := 0;
1185 if WordBool(gPanels[a].PanelType and
1186 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1187 Flags := PANEL_FLAG_WATERTEXTURES;
1189 // Может быть текстура:
1190 if not WordBool(gPanels[a].PanelType and
1191 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1192 begin
1193 if gPanels[a].Blending then
1194 Flags := Flags or PANEL_FLAG_BLENDING;
1195 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1196 Flags := Flags or PANEL_FLAG_HIDE;
1198 // Номер текстуры в списке текстур:
1199 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1200 for b := 0 to High(textures) do
1201 if utf2win(gPanels[a].TextureName) = textures[b].Resource then
1202 begin
1203 TextureNum := b;
1204 Break;
1205 end;
1206 end;
1207 end;
1208 end;
1210 MapWriter.AddPanels(panels);
1211 end;
1213 // Сохраняем предметы:
1214 if gItems <> nil then
1215 begin
1216 for a := 0 to High(gItems) do
1217 if gItems[a].ItemType <> 0 then
1218 begin
1219 SetLength(items, Length(items)+1);
1221 with items[High(items)] do
1222 begin
1223 X := gItems[a].X;
1224 Y := gItems[a].Y;
1225 ItemType := gItems[a].ItemType;
1226 if gItems[a].OnlyDM then
1227 Options := Options or ITEM_OPTION_ONLYDM;
1228 if gItems[a].Fall then
1229 Options := Options or ITEM_OPTION_FALL;
1230 end;
1231 end;
1233 MapWriter.AddItems(items);
1234 end;
1236 // Сохраняем монстров:
1237 if gMonsters <> nil then
1238 begin
1239 c := 0;
1241 for a := 0 to High(gMonsters) do
1242 if gMonsters[a].MonsterType <> 0 then
1243 begin
1244 SetLength(MonsterTable, Length(MonsterTable)+1);
1245 MonsterTable[High(MonsterTable)][0] := a;
1246 MonsterTable[High(MonsterTable)][1] := c;
1247 c := c + 1;
1249 SetLength(monsters, Length(monsters)+1);
1251 with monsters[High(monsters)] do
1252 begin
1253 X := gMonsters[a].X;
1254 Y := gMonsters[a].Y;
1255 MonsterType := gMonsters[a].MonsterType;
1256 Direction := Ord(gMonsters[a].Direction);
1257 end;
1258 end;
1260 MapWriter.AddMonsters(monsters);
1261 end;
1263 // Сохраняем области:
1264 if gAreas <> nil then
1265 begin
1266 for a := 0 to High(gAreas) do
1267 if gAreas[a].AreaType <> 0 then
1268 begin
1269 SetLength(areas, Length(areas)+1);
1271 with areas[High(areas)] do
1272 begin
1273 X := gAreas[a].X;
1274 Y := gAreas[a].Y;
1275 AreaType := gAreas[a].AreaType;
1276 Direction := Ord(gAreas[a].Direction);
1277 end;
1278 end;
1280 MapWriter.AddAreas(areas);
1281 end;
1283 // Сохраняем триггеры:
1284 if gTriggers <> nil then
1285 begin
1286 for a := 0 to High(gTriggers) do
1287 if gTriggers[a].TriggerType <> 0 then
1288 begin
1289 SetLength(triggers, Length(triggers)+1);
1291 with triggers[High(triggers)] do
1292 begin
1293 X := gTriggers[a].X;
1294 Y := gTriggers[a].Y;
1295 Width := gTriggers[a].Width;
1296 Height := gTriggers[a].Height;
1297 Enabled := Byte(gTriggers[a].Enabled);
1298 TexturePanel := -1;
1299 TriggerType := gTriggers[a].TriggerType;
1300 ActivateType := gTriggers[a].ActivateType;
1301 Keys := gTriggers[a].Key;
1302 DATA := gTriggers[a].Data.Default;
1304 if PanelTable <> nil then
1305 begin
1306 // Ищем номер панели, которой этот триггер меняет текстуру:
1307 if gTriggers[a].TexturePanel <> -1 then
1308 begin
1309 for c := 0 to High(PanelTable) do
1310 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1311 TexturePanel := PanelTable[c][1];
1312 end;
1314 // Ищем номер панели, которую меняет этот триггер:
1315 if gTriggers[a].TriggerType in [
1316 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1317 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1318 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1319 if TTriggerData(DATA).PanelID <> -1 then
1320 for c := 0 to High(PanelTable) do
1321 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1322 begin
1323 TTriggerData(DATA).PanelID := PanelTable[c][1];
1324 Break;
1325 end;
1327 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1328 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1329 (TTriggerData(DATA).ShotPanelID <> -1) then
1330 begin
1331 for c := 0 to High(PanelTable) do
1332 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1333 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1334 end;
1335 end;
1337 if MonsterTable <> nil then
1338 begin
1339 // Ищем номер монстра - условие активации триггера:
1340 if gTriggers[a].TriggerType in [
1341 TRIGGER_PRESS, TRIGGER_ON,
1342 TRIGGER_OFF, TRIGGER_ONOFF] then
1343 if TTriggerData(DATA).MonsterID <> 0 then
1344 for c := 0 to High(MonsterTable) do
1345 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1346 begin
1347 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1348 Break;
1349 end;
1350 end;
1351 end;
1352 end;
1354 MapWriter.AddTriggers(triggers);
1355 end;
1357 // Сохраняем карту в память:
1358 Len := MapWriter.SaveMap(Data);
1360 MapWriter.Free();
1362 // Записываем в WAD, если надо:
1363 if Res <> '' then
1364 begin
1365 s := utf2win(ResName);
1366 WAD.RemoveResource('', s);
1367 WAD.AddResource(Data, Len, s, '');
1368 WAD.SaveTo(FileName);
1370 FreeMem(Data);
1371 WAD.Free();
1373 Result := nil;
1374 end
1375 else
1376 Result := Data;
1377 end;
1379 procedure AddTexture(res: String; Error: Boolean);
1380 var
1381 a: Integer;
1382 begin
1383 with MainForm.lbTextureList do
1384 begin
1385 for a := 0 to Count-1 do
1386 if Items[a] = res then
1387 Exit;
1389 if Error and (slInvalidTextures.IndexOf(res) = -1) then
1390 slInvalidTextures.Add(res);
1391 Items.Add(res);
1392 end;
1393 end;
1395 function map_CreateAnimTexture(TextureName, Resource: String): Boolean;
1396 var
1397 Data: Pointer = nil;
1398 FrameLen: Integer = 0;
1399 Width: Word = 0;
1400 Height: Word = 0;
1401 begin
1402 Result := GetFrame(Resource, Data, FrameLen, Width, Height);
1403 if not Result then // Кадры
1404 e_WriteLog(Format('GetFrame() error, res=%s', [TextureName]), MSG_WARNING)
1405 else
1406 begin
1407 Result := g_CreateTextureMemorySize(Data, FrameLen, TextureName, 0, 0, Width, Height, 1);
1408 if not Result then // Сама текстура
1409 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s', [TextureName]), MSG_WARNING);
1410 end;
1411 end;
1413 function LoadMap(Res: String): Boolean;
1414 var
1415 WAD: TWADEditor_1;
1416 MapReader: TMapReader_1;
1417 Header: TMapHeaderRec_1;
1418 textures: TTexturesRec1Array;
1419 panels: TPanelsRec1Array;
1420 items: TItemsRec1Array;
1421 monsters: TMonsterRec1Array;
1422 areas: TAreasRec1Array;
1423 triggers: TTriggersRec1Array;
1424 panel: TPanel;
1425 item: TItem;
1426 monster: TMonster;
1427 area: TArea;
1428 trigger: TTrigger;
1429 a: Integer;
1430 m: Word;
1431 FileName, SectionName, ResName, _fn: String;
1432 TextureRes, ustr: String;
1433 pData: Pointer;
1434 Len: Integer;
1435 Success: Boolean;
1436 NoTextureID: DWORD;
1437 NW, NH: Word;
1438 begin
1439 Result := False;
1440 pData := nil;
1441 Len := 0;
1442 NoTextureID := 0;
1443 NW := 0;
1444 NH := 0;
1446 MainForm.pbLoad.Position := 0;
1447 MainForm.lLoad.Caption := MsgLoadWad;
1448 Application.ProcessMessages();
1450 // Открываем WAD:
1451 WAD := TWADEditor_1.Create();
1452 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1454 if not WAD.ReadFile(FileName) then
1455 begin
1456 WAD.Free();
1457 Exit;
1458 end;
1460 // Читаем ресурс карты:
1461 if not WAD.GetResource('', utf2win(ResName), pData, Len) then
1462 begin
1463 WAD.Free();
1464 Exit;
1465 end;
1467 WAD.Free();
1469 MapReader := TMapReader_1.Create();
1471 MainForm.lLoad.Caption := MsgLoadMap;
1472 Application.ProcessMessages();
1474 MapReader.LoadMap(pData);
1476 // Загружаем текстуры:
1477 textures := MapReader.GetTextures();
1479 if textures <> nil then
1480 begin
1481 MainForm.pbLoad.Position := 0;
1482 MainForm.pbLoad.Max := Length(textures);
1483 MainForm.lLoad.Caption := MsgLoadTextures;
1485 for a := 0 to High(textures) do
1486 begin
1487 MainForm.pbLoad.StepIt();
1488 Application.ProcessMessages();
1489 ustr := win2utf(textures[a].Resource);
1491 Success := True;
1492 if not IsSpecialTexture(ustr) then
1493 begin
1494 g_ProcessResourceStr(ustr, @_fn, nil, nil);
1496 if _fn = ''
1497 then TextureRes := FileName + ustr
1498 else TextureRes := WadsDir + DirectorySeparator + ustr;
1500 if not Boolean(textures[a].Anim) then
1501 begin // Обычная текстура
1502 if not g_CreateTextureWAD(ustr, TextureRes) then
1503 begin
1504 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s', [ustr]), MSG_WARNING);
1505 Success := map_CreateAnimTexture(ustr, TextureRes);
1506 if Success then
1507 begin
1508 textures[a].Anim := Byte(ByteBool(True));
1509 e_WriteLog(Format(' wrong (outdated?) anim flag hint - texture #%d is actually animated: %s', [a, ustr]), MSG_WARNING);
1510 end;
1511 end;
1512 end
1513 else
1514 begin // Анимированная текстура
1515 if not map_CreateAnimTexture(ustr, TextureRes) then
1516 begin
1517 Success := g_CreateTextureWAD(ustr, TextureRes);
1518 if Success then
1519 begin
1520 textures[a].Anim := Byte(ByteBool(False));
1521 e_WriteLog(Format(' wrong (outdated?) anim flag hint - texture #%d is actually static: %s', [a, ustr]), MSG_WARNING);
1522 end;
1523 end;
1524 end;
1525 end;
1527 AddTexture(ustr, not Success);
1528 end;
1529 end;
1531 // Загружаем панели:
1532 panels := MapReader.GetPanels();
1534 if panels <> nil then
1535 begin
1536 MainForm.pbLoad.Position := 0;
1537 MainForm.pbLoad.Max := Length(panels);
1538 MainForm.lLoad.Caption := MsgLoadPanels;
1540 for a := 0 to High(panels) do
1541 begin
1542 MainForm.pbLoad.StepIt();
1543 Application.ProcessMessages();
1545 panel.X := panels[a].X;
1546 panel.Y := panels[a].Y;
1547 panel.Height := panels[a].Height;
1548 panel.Width := panels[a].Width;
1549 panel.PanelType := panels[a].PanelType;
1550 panel.Alpha := panels[a].Alpha;
1552 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1554 panel.TextureWidth := 0;
1555 panel.TextureHeight := 0;
1556 panel.TextureName := '';
1557 panel.TextureID := TEXTURE_SPECIAL_NONE;
1559 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_STEP or
1560 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1562 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1563 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1565 // Если панель видима:
1566 if WordBool(panel.PanelType and m) and
1567 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1568 begin
1569 ustr := win2utf(textures[panels[a].TextureNum].Resource);
1570 if not IsSpecialTexture(ustr) then
1571 begin // Текстура
1572 if g_GetTexture(ustr, panel.TextureID) then
1573 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1574 else begin
1575 panel.TextureWidth := 1;
1576 panel.TextureHeight := 1;
1577 if g_GetTexture('NOTEXTURE', NoTextureID) then
1578 begin
1579 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1580 g_GetTextureSizeByID(NoTextureID, NW, NH);
1581 panel.TextureWidth := NW;
1582 panel.TextureHeight := NH;
1583 end;
1584 end;
1585 end
1586 else // Спец. текстура
1587 panel.TextureID := SpecialTextureID(ustr);
1589 panel.TextureName := ustr;
1590 end;
1592 // Жидкость без текстуры:
1593 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1594 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1595 begin
1596 case panel.PanelType of
1597 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1598 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1599 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1600 end;
1602 panel.TextureID := SpecialTextureID(panel.TextureName);
1603 AddTexture(panel.TextureName, False);
1604 end;
1606 AddPanel(panel);
1607 end;
1608 end;
1610 // Загружаем предметы:
1611 items := MapReader.GetItems();
1613 if items <> nil then
1614 begin
1615 MainForm.pbLoad.Position := 0;
1616 MainForm.pbLoad.Max := Length(items);
1617 MainForm.lLoad.Caption := MsgLoadItems;
1619 for a := 0 to High(items) do
1620 begin
1621 MainForm.pbLoad.StepIt();
1622 Application.ProcessMessages();
1624 item.X := items[a].X;
1625 item.Y := items[a].Y;
1626 item.ItemType := items[a].ItemType;
1627 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1628 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1630 AddItem(item);
1631 end;
1632 end;
1634 // Загружаем монстров:
1635 monsters := MapReader.GetMonsters();
1637 if monsters <> nil then
1638 begin
1639 MainForm.pbLoad.Position := 0;
1640 MainForm.pbLoad.Max := Length(monsters);
1641 MainForm.lLoad.Caption := MsgLoadMonsters;
1643 for a := 0 to High(monsters) do
1644 begin
1645 MainForm.pbLoad.StepIt();
1646 Application.ProcessMessages();
1648 monster.X := monsters[a].X;
1649 monster.Y := monsters[a].Y;
1650 monster.MonsterType := monsters[a].MonsterType;
1651 monster.Direction := TDirection(monsters[a].Direction);
1653 AddMonster(monster);
1654 end;
1655 end;
1657 // Загружаем области:
1658 areas := MapReader.GetAreas();
1660 if areas <> nil then
1661 begin
1662 MainForm.pbLoad.Position := 0;
1663 MainForm.pbLoad.Max := Length(areas);
1664 MainForm.lLoad.Caption := MsgLoadAreas;
1666 for a := 0 to High(areas) do
1667 begin
1668 MainForm.pbLoad.StepIt();
1669 Application.ProcessMessages();
1671 area.X := areas[a].X;
1672 area.Y := areas[a].Y;
1673 area.AreaType := areas[a].AreaType;
1674 area.Direction := TDirection(areas[a].Direction);
1676 AddArea(area);
1677 end;
1678 end;
1680 // Загружаем триггеры:
1681 triggers := MapReader.GetTriggers();
1683 if triggers <> nil then
1684 begin
1685 MainForm.pbLoad.Position := 0;
1686 MainForm.pbLoad.Max := Length(triggers);
1687 MainForm.lLoad.Caption := MsgLoadTriggers;
1689 for a := 0 to High(triggers) do
1690 begin
1691 MainForm.pbLoad.StepIt();
1692 Application.ProcessMessages();
1694 trigger.X := triggers[a].X;
1695 trigger.Y := triggers[a].Y;
1696 trigger.Width := triggers[a].Width;
1697 trigger.Height := triggers[a].Height;
1699 trigger.Enabled := ByteBool(triggers[a].Enabled);
1700 trigger.TexturePanel := triggers[a].TexturePanel;
1701 trigger.TriggerType := triggers[a].TriggerType;
1702 trigger.ActivateType := triggers[a].ActivateType;
1703 trigger.Key := triggers[a].Keys;
1704 trigger.Data.Default := triggers[a].DATA;
1706 AddTrigger(trigger);
1707 end;
1708 end;
1710 // Загружаем заголовок карты:
1711 Header := MapReader.GetMapHeader();
1713 gMapInfo.FileName := FileName;
1715 with gMapInfo do
1716 begin
1717 MapName := ResName;
1718 Name := win2utf(Header.MapName);
1719 Description := win2utf(Header.MapDescription);
1720 Author := win2utf(Header.MapAuthor);
1721 MusicName := win2utf(Header.MusicName);
1722 SkyName := win2utf(Header.SkyName);
1723 Height := Header.Height;
1724 Width := Header.Width;
1725 end;
1727 LoadSky(gMapInfo.SkyName);
1729 textures := nil;
1730 panels := nil;
1731 items := nil;
1732 areas := nil;
1733 triggers := nil;
1735 MapReader.Free();
1736 FreeMem(pData);
1738 Result := True;
1739 end;
1741 function LoadMapOld(_FileName: String): Boolean;
1742 const
1743 TexturePrefix = 'standart.wad:STDTEXTURES\';
1744 DefaultMusRes = 'standart.wad:STDMUS\MUS1';
1745 DefaultSkyRes = 'standart.wad:STDSKY\SKY0';
1747 var
1748 map: TConfig;
1749 i, a: Integer;
1750 s, section: String;
1751 panel: TPanel;
1752 item: TItem;
1753 area: TArea;
1755 begin
1756 Result := False;
1758 if not FileExists(_FileName) then
1759 Exit;
1761 // Открытие карты:
1762 MainForm.pbLoad.Position := 0;
1763 MainForm.lLoad.Caption := MsgLoadMap;;
1764 Application.ProcessMessages();
1766 map := TConfig.CreateFile(_FileName);
1768 // Чтение текстур:
1769 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1771 MainForm.pbLoad.Max := i;
1772 MainForm.pbLoad.Position := 0;
1773 MainForm.lLoad.Caption := MsgLoadTextures;
1775 for a := 1 to i do
1776 begin
1777 MainForm.pbLoad.StepIt();
1778 Application.ProcessMessages();
1780 s := TexturePrefix + UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
1781 if s = TexturePrefix then
1782 Continue;
1784 // Нет такой текстуры - ищем в WAD карты:
1785 if not g_CreateTextureWAD(s, WadsDir + DirectorySeparator + s) then
1786 begin
1787 s := ExtractFileName(_FileName);
1788 Delete(s, Length(s)-3, 4);
1789 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
1791 if not g_CreateTextureWAD(s, WadsDir + DirectorySeparator + s) then
1792 Continue;
1793 end;
1795 MainForm.lbTextureList.Items.Add(s);
1796 end;
1798 // Чтение панелей:
1799 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1801 MainForm.pbLoad.Max := i;
1802 MainForm.pbLoad.Position := 0;
1803 MainForm.lLoad.Caption := MsgLoadPanels;
1805 for a := 1 to i do
1806 begin
1807 MainForm.pbLoad.StepIt();
1808 Application.ProcessMessages();
1810 section := 'Panel' + IntToStr(a);
1811 if not map.SectionExists(section) then
1812 Continue;
1814 panel := Default(TPanel);
1815 panel.X := map.ReadInt(section, 'X1', 0);
1816 panel.Y := map.ReadInt(section, 'Y1', 0);
1817 panel.Height := map.ReadInt(section, 'Height', 16);
1818 panel.Width := map.ReadInt(section, 'Width', 16);
1820 case map.ReadInt(section, 'PanelType', 0) of
1821 0: panel.PanelType := PANEL_WALL;
1822 1: panel.PanelType := PANEL_BACK;
1823 2: panel.PanelType := PANEL_FORE;
1824 3: panel.PanelType := PANEL_STEP;
1825 4: panel.PanelType := PANEL_WATER;
1826 5: panel.PanelType := PANEL_ACID1;
1827 6: panel.PanelType := PANEL_ACID2;
1828 end;
1830 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1831 panel.Blending := false;
1833 // Текстура панели:
1834 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_STEP] then
1835 begin
1836 s := TexturePrefix + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
1838 if g_GetTexture(s, panel.TextureID) then
1839 begin
1840 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1841 panel.TextureName := s;
1842 end
1843 else // Нет такой текстуры - ищем в WAD карты:
1844 begin
1845 s := ExtractFileName(_FileName);
1846 Delete(s, Length(s)-3, 4);
1847 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
1849 if g_GetTexture(s, panel.TextureID) then
1850 begin
1851 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1852 panel.TextureName := s;
1853 end
1854 else
1855 Continue;
1856 end;
1857 end
1858 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1859 begin
1860 case panel.PanelType of
1861 PANEL_WATER:
1862 begin
1863 s := TEXTURE_NAME_WATER;
1864 panel.TextureID := TEXTURE_SPECIAL_WATER;
1865 end;
1866 PANEL_ACID1:
1867 begin
1868 s := TEXTURE_NAME_ACID2;
1869 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1870 end;
1871 PANEL_ACID2:
1872 begin
1873 s := TEXTURE_NAME_ACID1;
1874 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1875 end;
1876 end;
1878 with MainForm.lbTextureList.Items do
1879 if IndexOf(s) = -1 then
1880 Add(s);
1881 panel.TextureName := s;
1882 panel.TextureWidth := 1;
1883 panel.TextureHeight := 1;
1884 end;
1886 AddPanel(panel);
1887 end;
1889 // Чтение предметов:
1890 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1892 MainForm.pbLoad.Max := i;
1893 MainForm.pbLoad.Position := 0;
1894 MainForm.lLoad.Caption := MsgLoadItems;
1896 for a := 1 to i do
1897 begin
1898 MainForm.pbLoad.StepIt();
1899 Application.ProcessMessages();
1901 section := 'Item' + IntToStr(a);
1902 if not map.SectionExists(section) then
1903 Continue;
1905 item := Default(TItem);
1906 item.X := map.ReadInt(section, 'X', 0);
1907 item.Y := map.ReadInt(section, 'Y', 0);
1908 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1909 item.OnlyDM := False;
1910 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1912 // Размер предметов теперь другой:
1913 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1914 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1916 AddItem(item);
1917 end;
1919 // Чтение областей:
1920 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1922 MainForm.pbLoad.Max := i;
1923 MainForm.pbLoad.Position := 0;
1924 MainForm.lLoad.Caption := MsgLoadAreas;
1926 for a := 1 to i do
1927 begin
1928 MainForm.pbLoad.StepIt();
1929 Application.ProcessMessages();
1931 section := 'Area' + IntToStr(a);
1932 if not map.SectionExists(section) then
1933 Continue;
1935 area := Default(TArea);
1936 area.X := map.ReadInt(section, 'X', 0);
1937 area.Y := map.ReadInt(section, 'Y', 0);
1938 area.AreaType := map.ReadInt(section, 'Type', 0);
1939 area.Direction := D_RIGHT;
1941 // Размер областей теперь другой:
1942 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1943 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1945 AddArea(area);
1946 end;
1948 // Чтение параметров карты:
1949 gMapInfo := Default(TMapInfo);
1950 with gMapInfo do
1951 begin
1952 Name := win2utf(map.ReadStr('MapOptions', 'MapName', ''));
1953 Description := win2utf(map.ReadStr('MapOptions', 'MapDescription', ''));
1954 Author := '';
1955 MusicName := DefaultMusRes;
1956 SkyName := DefaultSkyRes;
1957 FileName := _FileName;
1958 Height := map.ReadInt('MapOptions', 'Height', 1600);
1959 Width := map.ReadInt('MapOptions', 'Width', 1600);
1961 if Length(Name) > 32 then
1962 SetLength(Name, 32);
1963 if Length(Description) > 256 then
1964 SetLength(Description, 256);
1965 end;
1967 LoadSky(gMapInfo.SkyName);
1969 map.Free();
1971 Result := True;
1972 end;
1974 procedure ClearMap();
1975 var
1976 a: Integer;
1978 begin
1979 if gPanels <> nil then
1980 for a := 0 to High(gPanels) do
1981 if gPanels[a].TextureName <> '' then
1982 g_DeleteTexture(gPanels[a].TextureName);
1984 SetLength(gPanels, 0);
1985 gPanels := nil;
1986 SetLength(gItems, 0);
1987 gItems := nil;
1988 SetLength(gAreas, 0);
1989 gAreas := nil;
1990 SetLength(gMonsters, 0);
1991 gMonsters := nil;
1992 SetLength(gTriggers, 0);
1993 gTriggers := nil;
1995 gMapInfo := Default(TMapInfo);
1996 gMapInfo.Width := 1600;
1997 gMapInfo.Height := 1600;
1999 with MainForm.lbTextureList do
2000 begin
2001 if Items.Count > 0 then
2002 for a := Items.Count-1 downto 0 do
2003 if not IsSpecialTexture(Items[a]) then
2004 g_DeleteTexture(Items[a]);
2006 Clear();
2007 end;
2009 MapOffset.X := 0;
2010 MapOffset.Y := 0;
2011 end;
2013 procedure DrawPanels(fPanelType: Word);
2015 procedure DrawTexture(a: Integer);
2016 var
2017 NoTextureID: DWORD;
2018 NW, NH: Word;
2019 begin
2020 NoTextureID := 0;
2021 NW := 0;
2022 NH := 0;
2023 with gPanels[a] do
2024 begin
2025 case TextureID of
2026 TEXTURE_SPECIAL_NONE:
2027 if PreviewMode = 0 then
2028 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2029 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2030 64, 64, 64, 127);
2032 TEXTURE_SPECIAL_NOTEXTURE:
2033 if g_GetTexture('NOTEXTURE', NoTextureID) then
2034 begin
2035 g_GetTextureSizeByID(NoTextureID, NW, NH);
2036 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
2037 Width div NW, Height div NH, 0, False, False);
2038 end;
2040 TEXTURE_SPECIAL_WATER:
2041 if PreviewMode > 0 then
2042 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2043 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2044 0, 0, 255, 0, B_FILTER)
2045 else
2046 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2047 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2048 0, 0, 255, 127);
2050 TEXTURE_SPECIAL_ACID1:
2051 if PreviewMode > 0 then
2052 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2053 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2054 0, 127, 0, 0, B_FILTER)
2055 else
2056 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2057 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2058 0, 255, 0, 127);
2060 TEXTURE_SPECIAL_ACID2:
2061 if PreviewMode > 0 then
2062 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2063 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2064 127, 0, 0, 0, B_FILTER)
2065 else
2066 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2067 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2068 255, 0, 0, 127);
2070 else
2071 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2072 Width div TextureWidth, Height div TextureHeight,
2073 Alpha, True, Blending);
2074 end;
2075 end;
2076 end;
2078 var
2079 a: Integer;
2080 begin
2081 if gPanels <> nil then
2082 for a := 0 to High(gPanels) do
2083 if (gPanels[a].PanelType <> 0) and
2084 WordBool(gPanels[a].PanelType and fPanelType) then
2085 with gPanels[a] do
2086 begin
2087 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2088 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2089 case PanelType of
2090 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2091 PANEL_STEP, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2092 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2093 DrawTexture(a);
2095 PANEL_LIFTUP:
2096 if PreviewMode = 0 then
2097 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2098 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2099 128, 64, 0, 0);
2100 PANEL_LIFTDOWN:
2101 if PreviewMode = 0 then
2102 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2103 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2104 90, 154, 138, 0);
2105 PANEL_LIFTLEFT:
2106 if PreviewMode = 0 then
2107 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2108 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2109 200, 80, 4, 0);
2110 PANEL_LIFTRIGHT:
2111 if PreviewMode = 0 then
2112 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2113 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2114 252, 140, 56, 0);
2115 PANEL_BLOCKMON:
2116 if PreviewMode = 0 then
2117 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2118 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2119 192, 0, 192, 0);
2120 end;
2121 end;
2122 end;
2124 procedure DrawContours (fPanelType: Word);
2125 var i, xx, yy, ww, hh: Integer;
2126 begin
2127 if gPanels <> nil then
2128 for i := 0 to High(gPanels) do
2129 if (gPanels[i].PanelType <> 0) and WordBool(gPanels[i].PanelType and fPanelType) then
2130 begin
2131 xx := gPanels[i].X + MapOffset.X;
2132 yy := gPanels[i].Y + MapOffset.Y;
2133 ww := gPanels[i].X + MapOffset.X + gPanels[i].Width - 1;
2134 hh := gPanels[i].Y + MapOffset.Y + gPanels[i].Height - 1;
2135 case gPanels[i].PanelType of
2136 PANEL_NONE: ;
2137 PANEL_WALL: e_DrawQuad(xx, yy, ww, hh, 208, 208, 208, 0);
2138 PANEL_BACK: e_DrawQuad(xx, yy, ww, hh, 64, 64, 64, 0);
2139 PANEL_FORE: e_DrawQuad(xx, yy, ww, hh, 128, 128, 128, 0);
2140 PANEL_WATER: e_DrawQuad(xx, yy, ww, hh, 0, 0, 192, 0);
2141 PANEL_ACID1: e_DrawQuad(xx, yy, ww, hh, 0, 176, 0, 0);
2142 PANEL_ACID2: e_DrawQuad(xx, yy, ww, hh, 176, 0, 0, 0);
2143 PANEL_STEP: e_DrawQuad(xx, yy, ww, hh, 128, 128, 128, 0);
2144 PANEL_LIFTUP: e_DrawQuad(xx, yy, ww, hh, 116, 72, 36, 0);
2145 PANEL_LIFTDOWN: e_DrawQuad(xx, yy, ww, hh, 116, 124, 96, 0);
2146 PANEL_OPENDOOR: e_DrawQuad(xx, yy, ww, hh, 100, 220, 92, 0);
2147 PANEL_CLOSEDOOR: e_DrawQuad(xx, yy, ww, hh, 212, 184, 64, 0);
2148 PANEL_BLOCKMON: e_DrawQuad(xx, yy, ww, hh, 192, 0, 192, 0);
2149 PANEL_LIFTLEFT: e_DrawQuad(xx, yy, ww, hh, 200, 80, 4, 0);
2150 PANEL_LIFTRIGHT: e_DrawQuad(xx, yy, ww, hh, 252, 140, 56, 0);
2151 else
2152 assert(false)
2153 end;
2154 end;
2155 end;
2157 procedure DrawMap();
2158 var
2159 a, w, h: Integer;
2160 ID: DWORD;
2161 xx, yy, dx, dy: Integer;
2162 ww, hh: Word;
2163 sel: Boolean;
2164 r: TRectWH;
2165 mask: Word;
2166 begin
2167 ID := 0;
2168 // В режиме Превью рисуем небо:
2169 if PreviewMode > 0 then
2170 begin
2171 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2172 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2173 w := Round(w*4/3);
2174 h := Round(w*3/4);
2176 if g_GetTexture(SKY_TEXTURE, ID) then
2177 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2178 else
2179 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2180 end;
2182 // Рисуем панели (если Превью или если включен слой):
2183 if LayerEnabled[LAYER_BACK] or (PreviewMode = 1) then
2184 DrawPanels(PANEL_BACK);
2185 if PreviewMode > 0 then
2186 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)
2187 else
2188 if LayerEnabled[LAYER_WATER] then
2189 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or
2190 PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON);
2191 if LayerEnabled[LAYER_WALLS] or (PreviewMode = 1) then
2192 DrawPanels(PANEL_WALL);
2193 if LayerEnabled[LAYER_STEPS] or (PreviewMode = 1) then
2194 DrawPanels(PANEL_STEP);
2196 // Рисуем предметы:
2197 if (LayerEnabled[LAYER_ITEMS] or (PreviewMode = 1)) and
2198 (gItems <> nil) then
2199 for a := 0 to High(gItems) do
2200 if gItems[a].ItemType <> ITEM_NONE then
2201 with gItems[a] do
2202 begin
2203 ID := DWORD(-1);
2205 case ItemType of
2206 0: Continue;
2207 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2208 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2209 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2210 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2211 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2212 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2213 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2214 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2215 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2216 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2217 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2218 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2219 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2220 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2221 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2222 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2223 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2224 ITEM_WEAPON_SUPERCHAINGUN: g_GetTexture('ITEM_WEAPON_SUPERCHAINGUN', ID);
2225 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2226 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2227 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2228 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2229 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2230 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2231 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2232 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2233 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2234 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2235 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2236 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2237 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2238 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2239 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2240 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2241 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2242 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2243 end;
2245 if ID <> DWORD(-1) then
2246 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2247 end;
2249 // Рисуем монстров:
2250 if (LayerEnabled[LAYER_MONSTERS] or (PreviewMode = 1)) and
2251 (gMonsters <> nil) then
2252 for a := 0 to High(gMonsters) do
2253 if gMonsters[a].MonsterType <> MONSTER_NONE then
2254 with MonsterSize[gMonsters[a].MonsterType] do
2255 begin
2256 ID := DWORD(-1);
2257 sel := ObjectSelected(OBJECT_MONSTER, a);
2259 case gMonsters[a].MonsterType of
2260 0: Continue;
2261 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2262 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2263 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2264 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2265 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2266 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2267 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2268 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2269 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2270 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2271 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2272 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2273 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2274 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2275 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2276 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2277 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2278 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2279 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2280 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2281 end;
2283 if ID <> DWORD(-1) then
2284 if gMonsters[a].Direction = D_LEFT then
2285 begin
2286 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2287 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2288 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2289 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2290 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2291 xx := (gMonsters[a].X - X) - xx;
2293 yy := (gMonsters[a].Y - Y) +
2294 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2296 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2297 0, True, False, M_HORIZONTAL);
2298 end
2299 else
2300 begin
2301 // Левый верхний угол текстуры + смещение анимации:
2302 xx := (gMonsters[a].X - X) +
2303 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2304 yy := (gMonsters[a].Y - Y) +
2305 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2307 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2308 0, True, False);
2309 end;
2311 // Рамка:
2312 if PreviewMode = 0 then
2313 begin
2314 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2315 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2316 255, 255, 255, IfThen(sel, 0, gAlphaMonsterRect));
2317 end;
2318 end;
2320 // Рисуем закрытые двери после монстров:
2321 if ((PreviewMode = 2) and LayerEnabled[LAYER_WATER])
2322 or (PreviewMode = 1) then
2323 DrawPanels(PANEL_CLOSEDOOR);
2325 // Рисуем области:
2326 if (LayerEnabled[LAYER_AREAS] or (PreviewMode = 1)) and
2327 (gAreas <> nil) then
2328 for a := 0 to High(gAreas) do
2329 if gAreas[a].AreaType <> AREA_NONE then
2330 with AreaSize[gAreas[a].AreaType] do
2331 begin
2332 ID := DWORD(-1);
2333 sel := ObjectSelected(OBJECT_AREA, a);
2335 case gAreas[a].AreaType of
2336 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2337 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2338 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2339 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2340 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2341 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2342 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2343 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2344 end;
2346 if (PreviewMode = 0) or
2347 (gAreas[a].AreaType = AREA_REDFLAG) or
2348 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2349 (gAreas[a].AreaType = AREA_DOMFLAG) then
2350 if ID <> DWORD(-1) then
2351 if gAreas[a].Direction = D_LEFT then
2352 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2353 0, True, False, M_HORIZONTAL)
2354 else
2355 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2356 0, True, False);
2358 // Рамка:
2359 if PreviewMode = 0 then
2360 begin
2361 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2362 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2363 255, 255, 255, IfThen(sel, 0, gAlphaAreaRect));
2365 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2366 end;
2367 end;
2369 // Рисуем жидкости и передний план после областей:
2370 if LayerEnabled[LAYER_WATER] or (PreviewMode = 1) then
2371 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2372 if LayerEnabled[LAYER_FOREGROUND] or (PreviewMode = 1) then
2373 DrawPanels(PANEL_FORE);
2375 // Рисуем триггеры:
2376 if LayerEnabled[LAYER_TRIGGERS] and
2377 (PreviewMode = 0) and (gTriggers <> nil) then
2378 for a := 0 to High(gTriggers) do
2379 with gTriggers[a] do
2380 if TriggerType <> TRIGGER_NONE then
2381 begin
2382 // Если выбран - рисуем красным, иначе - белым:
2383 sel := ObjectSelected(OBJECT_TRIGGER, a);
2385 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2386 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2387 0, 0, 0, 150);
2389 if TexturePanel <> -1 then
2390 begin
2391 with gPanels[TexturePanel] do
2392 begin
2393 xx := X;
2394 yy := Y;
2395 ww := Width;
2396 hh := Height;
2397 end;
2399 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2400 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2401 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2402 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2403 MapOffset.X+xx, MapOffset.Y+yy,
2404 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2405 end;
2407 case TriggerType of
2408 TRIGGER_EXIT: ;
2410 TRIGGER_TELEPORT:
2411 begin
2412 // Точка назначения Телепорта:
2413 if Data.d2d_teleport then
2414 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2415 MapOffset.Y+Data.TargetPoint.Y-1,
2416 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2417 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2418 else
2419 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2420 MapOffset.Y+Data.TargetPoint.Y,
2421 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2422 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2423 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2424 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2425 MapOffset.Y+Data.TargetPoint.Y,
2426 255, 0, 0);
2427 // Линия к точке назначения Телепорта:
2428 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2429 MapOffset.Y+Y+(Height div 2),
2430 MapOffset.X+Data.TargetPoint.X,
2431 MapOffset.Y+Data.TargetPoint.Y,
2432 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2433 end;
2435 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2436 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2437 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2438 TRIGGER_LIFT:
2439 if Data.PanelID <> -1 then
2440 begin
2441 // Дверь/Ловушка/Лифт:
2442 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2443 MapOffset.Y+gPanels[Data.PanelID].Y,
2444 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2445 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2446 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2447 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2448 MapOffset.Y+gPanels[Data.PanelID].Y,
2449 255, 0, 0);
2450 // Линия к Двери/Ловушке/Лифту:
2451 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2452 MapOffset.Y+Y+(Height div 2),
2453 MapOffset.X+gPanels[Data.PanelID].X,
2454 MapOffset.Y+gPanels[Data.PanelID].Y,
2455 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2456 end;
2458 TRIGGER_PRESS, TRIGGER_ON,
2459 TRIGGER_OFF, TRIGGER_ONOFF:
2460 begin
2461 if (Data.tWidth > 0) and
2462 (Data.tHeight > 0) then
2463 begin
2464 // Область Расширителя:
2465 e_DrawQuad(MapOffset.X+Data.tX,
2466 MapOffset.Y+Data.tY,
2467 MapOffset.X+Data.tX+Data.tWidth-1,
2468 MapOffset.Y+Data.tY+Data.tHeight-1,
2469 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2470 e_DrawPoint(2, MapOffset.X+Data.tX,
2471 MapOffset.Y+Data.tY,
2472 255, 0, 0);
2473 // Линия к области Расширителя:
2474 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2475 MapOffset.Y+Y+(Height div 2),
2476 MapOffset.X+Data.tX,
2477 MapOffset.Y+Data.tY,
2478 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2479 end;
2481 if Data.MonsterID <> 0 then
2482 if (gMonsters <> nil) and
2483 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2484 begin
2485 // Рамка вокруг Монстра - условия активации:
2486 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2487 e_DrawQuad(MapOffset.X+r.X,
2488 MapOffset.Y+r.Y,
2489 MapOffset.X+r.X+r.Width-1,
2490 MapOffset.Y+r.Y+r.Height-1,
2491 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2492 // Линия к Монстру - условию активации:
2493 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2494 MapOffset.Y+Y+(Height div 2),
2495 MapOffset.X+r.X,
2496 MapOffset.Y+r.Y,
2497 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2499 end;
2500 end;
2502 TRIGGER_SECRET: ;
2504 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2505 begin
2506 if TriggerType = TRIGGER_SPAWNMONSTER then
2507 begin
2508 xx := Data.MonPos.X;
2509 yy := Data.MonPos.Y;
2510 end
2511 else
2512 begin
2513 xx := Data.ItemPos.X;
2514 yy := Data.ItemPos.Y;
2515 end;
2516 // Точка появления Монстра/Предмета:
2517 e_DrawLine(2, MapOffset.X+xx-16,
2518 MapOffset.Y+yy-1,
2519 MapOffset.X+xx+16,
2520 MapOffset.Y+yy-1,
2521 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2522 e_DrawPoint(2, MapOffset.X+xx,
2523 MapOffset.Y+yy,
2524 255, 0, 0);
2525 // Линия к точке появления Монстра/Предмета:
2526 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2527 MapOffset.Y+Y+(Height div 2),
2528 MapOffset.X+xx,
2529 MapOffset.Y+yy,
2530 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2531 // Предпросмотр создаваемого объекта:
2532 if sel then
2533 begin
2534 // Монстр:
2535 if TriggerType = TRIGGER_SPAWNMONSTER then
2536 begin
2537 if Data.MonType <> MONSTER_NONE then
2538 with MonsterSize[Data.MonType] do
2539 begin
2540 ID := DWORD(-1);
2541 case Data.MonType of
2542 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2543 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2544 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2545 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2546 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2547 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2548 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2549 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2550 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2551 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2552 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2553 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2554 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2555 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2556 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2557 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2558 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2559 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2560 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2561 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2562 end;
2563 if ID <> DWORD(-1) then
2564 begin
2565 if Data.MonDir = Byte(D_LEFT) then
2566 begin
2567 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2568 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2569 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2571 yy := Data.TargetPoint.Y - Y +
2572 MonsterSizeDelta[Data.MonType].Y-Height;
2574 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2575 128, True, False, M_HORIZONTAL);
2576 end
2577 else
2578 begin
2579 xx := Data.TargetPoint.X - X +
2580 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2581 yy := Data.TargetPoint.Y - Y +
2582 MonsterSizeDelta[Data.MonType].Y-Height;
2584 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2585 128, True, False);
2586 end;
2587 // Рамка:
2588 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2589 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2590 255, 255, 0, 128);
2591 end;
2592 end;
2593 end
2594 else
2595 // Предмет:
2596 begin
2597 if Data.ItemType <> ITEM_NONE then
2598 begin
2599 ID := DWORD(-1);
2600 case Data.ItemType of
2601 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2602 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2603 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2604 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2605 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2606 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2607 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2608 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2609 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2610 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2611 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2612 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2613 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2614 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2615 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2616 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2617 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2618 ITEM_WEAPON_SUPERCHAINGUN: g_GetTexture('ITEM_WEAPON_SUPERCHAINGUN', ID);
2619 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2620 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2621 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2622 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2623 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2624 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2625 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2626 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2627 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2628 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2629 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2630 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2631 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2632 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2633 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2634 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2635 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2636 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2637 end;
2638 if ID <> DWORD(-1) then
2639 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2640 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2641 128, True, False);
2642 // Рамка:
2643 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2644 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2645 255, 255, 0, 128);
2646 end;
2647 end;
2648 end;
2649 end;
2651 TRIGGER_PUSH:
2652 begin
2653 // Линия направления и силы ускорения:
2654 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2655 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2656 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2657 MapOffset.Y+Y+(Height div 2),
2658 MapOffset.X+xx,
2659 MapOffset.Y+yy,
2660 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2661 end;
2663 TRIGGER_SHOT:
2664 begin;
2665 xx := Data.ShotPos.X;
2666 yy := Data.ShotPos.Y;
2667 // Точка появления снаряда:
2668 e_DrawPoint(2, MapOffset.X+xx,
2669 MapOffset.Y+yy,
2670 255, 0, 0);
2671 // Линия к точке появления снаряда:
2672 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2673 MapOffset.Y+Y+(Height div 2),
2674 MapOffset.X+xx,
2675 MapOffset.Y+yy,
2676 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2677 // Линия направления выстрела:
2678 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2679 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2680 e_DrawLine(1, MapOffset.X+xx,
2681 MapOffset.Y+yy,
2682 MapOffset.X+xx+dx,
2683 MapOffset.Y+yy+dy,
2684 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2686 if (Data.ShotPanelID <> -1) and
2687 (Data.ShotPanelID <= High(gPanels)) then
2688 begin
2689 // Линия к панели индикации выстрела
2690 with gPanels[Data.ShotPanelID] do
2691 begin
2692 xx := X;
2693 yy := Y;
2694 ww := Width;
2695 hh := Height;
2696 end;
2698 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2699 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2700 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2701 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2702 MapOffset.X+xx, MapOffset.Y+yy,
2703 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2704 end;
2705 end;
2706 end;
2707 end;
2709 // Draw panel contours
2710 mask := 0;
2711 if ContourEnabled[LAYER_BACK] then
2712 mask := mask or PANEL_BACK;
2713 if ContourEnabled[LAYER_WALLS] then
2714 mask := mask or PANEL_WALL;
2715 if ContourEnabled[LAYER_FOREGROUND] then
2716 mask := mask or PANEL_FORE;
2717 if ContourEnabled[LAYER_STEPS] then
2718 mask := mask or PANEL_STEP;
2719 if ContourEnabled[LAYER_WATER] then
2720 mask := mask or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2
2721 or PANEL_OPENDOOR or PANEL_CLOSEDOOR or PANEL_BLOCKMON
2722 or PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT;
2723 if mask <> 0 then
2724 DrawContours(mask);
2725 if ContourEnabled[LAYER_ITEMS] and (gItems <> nil) then
2726 for a := 0 to High(gItems) do
2727 if gItems[a].ItemType <> ITEM_NONE then
2728 e_DrawQuad(
2729 MapOffset.X + gItems[a].X,
2730 MapOffset.Y + gItems[a].Y,
2731 MapOffset.X + gItems[a].X + ItemSize[gItems[a].ItemType, 0] - 1,
2732 MapOffset.Y + gItems[a].Y + ItemSize[gItems[a].ItemType, 1] - 1,
2733 0, 255, 255
2734 );
2735 if ContourEnabled[LAYER_MONSTERS] and (gMonsters <> nil) then
2736 for a := 0 to High(gMonsters) do
2737 if gMonsters[a].MonsterType <> MONSTER_NONE then
2738 e_DrawQuad(
2739 MapOffset.X + gMonsters[a].X,
2740 MapOffset.Y + gMonsters[a].Y,
2741 MapOffset.X + gMonsters[a].X + MonsterSize[gMonsters[a].MonsterType].Width - 1,
2742 MapOffset.Y + gMonsters[a].Y + MonsterSize[gMonsters[a].MonsterType].Height - 1,
2743 200, 0, 0
2744 );
2745 if ContourEnabled[LAYER_AREAS] and (gAreas <> nil) then
2746 for a := 0 to High(gAreas) do
2747 if gAreas[a].AreaType <> AREA_NONE then
2748 e_DrawQuad(
2749 MapOffset.X + gAreas[a].X,
2750 MapOffset.Y + gAreas[a].Y,
2751 MapOffset.X + gAreas[a].X + AreaSize[gAreas[a].AreaType].Width - 1,
2752 MapOffset.Y + gAreas[a].Y + AreaSize[gAreas[a].AreaType].Height - 1,
2753 0, 255, 255
2754 );
2755 if ContourEnabled[LAYER_TRIGGERS] and (gTriggers <> nil) then
2756 for a := 0 to High(gTriggers) do
2757 if gTriggers[a].TriggerType <> TRIGGER_NONE then
2758 e_DrawQuad(
2759 MapOffset.X + gTriggers[a].X,
2760 MapOffset.Y + gTriggers[a].Y,
2761 MapOffset.X + gTriggers[a].X + gTriggers[a].Width - 1,
2762 MapOffset.Y + gTriggers[a].Y + gTriggers[a].Height - 1,
2763 255, 255, 0
2764 );
2766 // Границы карты:
2767 if PreviewMode = 0 then
2768 begin
2769 e_DrawFillQuad(0,
2770 0,
2771 MainForm.RenderPanel.Width,
2772 -1 + MapOffset.Y,
2773 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2774 e_DrawFillQuad(0,
2775 gMapInfo.Height + MapOffset.Y,
2776 MainForm.RenderPanel.Width,
2777 MainForm.RenderPanel.Height,
2778 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2779 e_DrawFillQuad(0,
2780 MapOffset.Y,
2781 -1 + MapOffset.X,
2782 gMapInfo.Height + MapOffset.Y - 1,
2783 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2784 e_DrawFillQuad(gMapInfo.Width + MapOffset.X,
2785 MapOffset.Y,
2786 MainForm.RenderPanel.Width,
2787 gMapInfo.Height + MapOffset.Y - 1,
2788 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2789 end;
2790 end;
2792 procedure ShiftMapObjects(dx, dy: Integer);
2793 var
2794 i: Integer;
2795 begin
2796 if gPanels <> nil then
2797 for i := 0 to High(gPanels) do
2798 if gPanels[i].PanelType <> 0 then
2799 begin
2800 Inc(gPanels[i].X, dx);
2801 Inc(gPanels[i].Y, dy);
2802 end;
2804 if gItems <> nil then
2805 for i := 0 to High(gItems) do
2806 if gItems[i].ItemType <> 0 then
2807 begin
2808 Inc(gItems[i].X, dx);
2809 Inc(gItems[i].Y, dy);
2810 end;
2812 if gAreas <> nil then
2813 for i := 0 to High(gAreas) do
2814 if gAreas[i].AreaType <> 0 then
2815 begin
2816 Inc(gAreas[i].X, dx);
2817 Inc(gAreas[i].Y, dy);
2818 end;
2820 if gMonsters <> nil then
2821 for i := 0 to High(gMonsters) do
2822 if gMonsters[i].MonsterType <> 0 then
2823 begin
2824 Inc(gMonsters[i].X, dx);
2825 Inc(gMonsters[i].Y, dy);
2826 end;
2828 if gTriggers <> nil then
2829 for i := 0 to High(gTriggers) do
2830 if gTriggers[i].TriggerType <> 0 then
2831 begin
2832 Inc(gTriggers[i].X, dx);
2833 Inc(gTriggers[i].Y, dy);
2835 case gTriggers[i].TriggerType of
2836 TRIGGER_TELEPORT:
2837 begin
2838 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2839 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2840 end;
2842 TRIGGER_PRESS, TRIGGER_ON,
2843 TRIGGER_OFF, TRIGGER_ONOFF:
2844 begin
2845 Inc(gTriggers[i].Data.tX, dx);
2846 Inc(gTriggers[i].Data.tY, dy);
2847 end;
2849 TRIGGER_SPAWNMONSTER:
2850 begin
2851 Inc(gTriggers[i].Data.MonPos.X, dx);
2852 Inc(gTriggers[i].Data.MonPos.Y, dy);
2853 end;
2855 TRIGGER_SPAWNITEM:
2856 begin
2857 Inc(gTriggers[i].Data.ItemPos.X, dx);
2858 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2859 end;
2861 TRIGGER_SHOT:
2862 begin
2863 Inc(gTriggers[i].Data.ShotPos.X, dx);
2864 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2865 end;
2866 end;
2867 end;
2868 end;
2870 procedure LoadData();
2871 begin
2872 g_CreateTextureWAD('PREVIEW', EditorWad + ':TEXTURES\CHECKERS');
2873 g_CreateTextureWAD('NOTEXTURE', GameWad + ':TEXTURES\NOTEXTURE');
2875 g_CreateTextureWADSize('AREA_REDFLAG', GameWad + ':TEXTURES\FLAGRED', 0, 0, 64, 64);
2876 g_CreateTextureWADSize('AREA_BLUEFLAG', GameWad + ':TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2877 g_CreateTextureWADSize('AREA_DOMFLAG', GameWad + ':TEXTURES\FLAGDOM', 0, 0, 64, 64);
2879 g_CreateTextureWADSize('MONSTER_DEMON', GameWad + ':MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2880 g_CreateTextureWADSize('MONSTER_IMP', GameWad + ':MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2881 g_CreateTextureWADSize('MONSTER_ZOMBY', GameWad + ':MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2882 g_CreateTextureWADSize('MONSTER_SERG', GameWad + ':MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2883 g_CreateTextureWADSize('MONSTER_CYBER', GameWad + ':MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2884 g_CreateTextureWADSize('MONSTER_CGUN', GameWad + ':MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2885 g_CreateTextureWADSize('MONSTER_BARON', GameWad + ':MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2886 g_CreateTextureWADSize('MONSTER_KNIGHT', GameWad + ':MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2887 g_CreateTextureWADSize('MONSTER_CACO', GameWad + ':MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2888 g_CreateTextureWADSize('MONSTER_SOUL', GameWad + ':MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2889 g_CreateTextureWADSize('MONSTER_PAIN', GameWad + ':MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2890 g_CreateTextureWADSize('MONSTER_SPIDER', GameWad + ':MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2891 g_CreateTextureWADSize('MONSTER_BSP', GameWad + ':MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2892 g_CreateTextureWADSize('MONSTER_MANCUB', GameWad + ':MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2893 g_CreateTextureWADSize('MONSTER_SKEL', GameWad + ':MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2894 g_CreateTextureWADSize('MONSTER_VILE', GameWad + ':MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2895 g_CreateTextureWADSize('MONSTER_FISH', GameWad + ':MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2896 g_CreateTextureWADSize('MONSTER_BARREL', GameWad + ':MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2897 g_CreateTextureWADSize('MONSTER_ROBO', GameWad + ':MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2898 g_CreateTextureWADSize('MONSTER_MAN', GameWad + ':MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2900 g_CreateTextureWADSize('ITEM_BLUESPHERE', GameWad + ':TEXTURES\SBLUE', 0, 0, 32, 32);
2901 g_CreateTextureWADSize('ITEM_WHITESPHERE', GameWad + ':TEXTURES\SWHITE', 0, 0, 32, 32);
2902 g_CreateTextureWADSize('ITEM_ARMORGREEN', GameWad + ':TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2903 g_CreateTextureWADSize('ITEM_ARMORBLUE', GameWad + ':TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2904 g_CreateTextureWADSize('ITEM_INVUL', GameWad + ':TEXTURES\INVUL', 0, 0, 32, 32);
2905 g_CreateTextureWADSize('ITEM_BOTTLE', GameWad + ':TEXTURES\BOTTLE', 0, 0, 16, 32);
2906 g_CreateTextureWADSize('ITEM_HELMET', GameWad + ':TEXTURES\HELMET', 0, 0, 16, 16);
2907 g_CreateTextureWADSize('ITEM_JETPACK', GameWad + ':TEXTURES\JETPACK', 0, 0, 32, 32);
2908 g_CreateTextureWADSize('ITEM_INVIS', GameWad + ':TEXTURES\INVIS', 0, 0, 32, 32);
2909 g_CreateTextureWADSize('ITEM_WEAPON_FLAMETHROWER', GameWad + ':TEXTURES\FLAMETHROWER', 0, 0, 64, 32);
2910 g_CreateTextureWADSize('ITEM_AMMO_FUELCAN', GameWad + ':TEXTURES\FUELCAN', 0, 0, 16, 32);
2912 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', GameWad + ':TEXTURES\MED1');
2913 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', GameWad + ':TEXTURES\MED2');
2914 g_CreateTextureWAD('ITEM_WEAPON_SAW', GameWad + ':TEXTURES\SAW');
2915 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', GameWad + ':TEXTURES\PISTOL');
2916 g_CreateTextureWAD('ITEM_WEAPON_IRONFIST', GameWad + ':TEXTURES\IRONFIST');
2917 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', GameWad + ':TEXTURES\SHOTGUN1');
2918 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', GameWad + ':TEXTURES\SHOTGUN2');
2919 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', GameWad + ':TEXTURES\MGUN');
2920 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', GameWad + ':TEXTURES\RLAUNCHER');
2921 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', GameWad + ':TEXTURES\PGUN');
2922 g_CreateTextureWAD('ITEM_WEAPON_BFG', GameWad + ':TEXTURES\BFG');
2923 g_CreateTextureWAD('ITEM_WEAPON_SUPERCHAINGUN', GameWad + ':TEXTURES\SCHAINGUN');
2924 g_CreateTextureWAD('ITEM_AMMO_BULLETS', GameWad + ':TEXTURES\CLIP');
2925 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', GameWad + ':TEXTURES\AMMO');
2926 g_CreateTextureWAD('ITEM_AMMO_SHELLS', GameWad + ':TEXTURES\SHELL1');
2927 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', GameWad + ':TEXTURES\SHELL2');
2928 g_CreateTextureWAD('ITEM_AMMO_ROCKET', GameWad + ':TEXTURES\ROCKET');
2929 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', GameWad + ':TEXTURES\ROCKETS');
2930 g_CreateTextureWAD('ITEM_AMMO_CELL', GameWad + ':TEXTURES\CELL');
2931 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', GameWad + ':TEXTURES\CELL2');
2932 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', GameWad + ':TEXTURES\BPACK');
2933 g_CreateTextureWAD('ITEM_KEY_RED', GameWad + ':TEXTURES\KEYR');
2934 g_CreateTextureWAD('ITEM_KEY_GREEN', GameWad + ':TEXTURES\KEYG');
2935 g_CreateTextureWAD('ITEM_KEY_BLUE', GameWad + ':TEXTURES\KEYB');
2936 g_CreateTextureWAD('ITEM_OXYGEN', GameWad + ':TEXTURES\OXYGEN');
2937 g_CreateTextureWAD('ITEM_SUIT', GameWad + ':TEXTURES\SUIT');
2938 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', GameWad + ':TEXTURES\BMED');
2940 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorWad + ':TEXTURES\P1POINT');
2941 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorWad + ':TEXTURES\P2POINT');
2942 g_CreateTextureWAD('AREA_DMPOINT', EditorWad + ':TEXTURES\DMPOINT');
2943 g_CreateTextureWAD('AREA_REDPOINT', EditorWad + ':TEXTURES\REDPOINT');
2944 g_CreateTextureWAD('AREA_BLUEPOINT', EditorWad + ':TEXTURES\BLUEPOINT');
2945 end;
2947 procedure FreeData();
2948 begin
2949 g_DeleteTexture('NOTEXTURE');
2951 g_DeleteTexture('ITEM_BLUESPHERE');
2952 g_DeleteTexture('ITEM_WHITESPHERE');
2953 g_DeleteTexture('ITEM_ARMORGREEN');
2954 g_DeleteTexture('ITEM_ARMORBLUE');
2955 g_DeleteTexture('ITEM_INVUL');
2956 g_DeleteTexture('ITEM_BOTTLE');
2957 g_DeleteTexture('ITEM_HELMET');
2958 g_DeleteTexture('AREA_REDFLAG');
2959 g_DeleteTexture('AREA_BLUEFLAG');
2960 g_DeleteTexture('AREA_DOMFLAG');
2962 g_DeleteTexture('MONSTER_DEMON');
2963 g_DeleteTexture('MONSTER_IMP');
2964 g_DeleteTexture('MONSTER_ZOMBY');
2965 g_DeleteTexture('MONSTER_SERG');
2966 g_DeleteTexture('MONSTER_CGUN');
2967 g_DeleteTexture('MONSTER_BARREL');
2968 g_DeleteTexture('MONSTER_MAN');
2970 g_DeleteTexture('MONSTER_DEMON');
2971 g_DeleteTexture('MONSTER_IMP');
2972 g_DeleteTexture('MONSTER_ZOMBY');
2973 g_DeleteTexture('MONSTER_SERG');
2974 g_DeleteTexture('MONSTER_CYBER');
2975 g_DeleteTexture('MONSTER_CGUN');
2976 g_DeleteTexture('MONSTER_BARON');
2977 g_DeleteTexture('MONSTER_KNIGHT');
2978 g_DeleteTexture('MONSTER_CACO');
2979 g_DeleteTexture('MONSTER_SOUL');
2980 g_DeleteTexture('MONSTER_PAIN');
2981 g_DeleteTexture('MONSTER_SPIDER');
2982 g_DeleteTexture('MONSTER_BSP');
2983 g_DeleteTexture('MONSTER_MANCUB');
2984 g_DeleteTexture('MONSTER_SKEL');
2985 g_DeleteTexture('MONSTER_VILE');
2986 g_DeleteTexture('MONSTER_FISH');
2987 g_DeleteTexture('MONSTER_BARREL');
2988 g_DeleteTexture('MONSTER_ROBO');
2989 g_DeleteTexture('MONSTER_MAN');
2991 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2992 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2993 g_DeleteTexture('ITEM_WEAPON_SAW');
2994 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2995 g_DeleteTexture('ITEM_WEAPON_IRONFIST');
2996 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2997 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2998 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2999 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
3000 g_DeleteTexture('ITEM_WEAPON_PLASMA');
3001 g_DeleteTexture('ITEM_WEAPON_BFG');
3002 g_DeleteTexture('ITEM_WEAPON_SUPERCHAINGUN');
3003 g_DeleteTexture('ITEM_AMMO_BULLETS');
3004 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
3005 g_DeleteTexture('ITEM_AMMO_SHELLS');
3006 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
3007 g_DeleteTexture('ITEM_AMMO_ROCKET');
3008 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
3009 g_DeleteTexture('ITEM_AMMO_CELL');
3010 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
3011 g_DeleteTexture('ITEM_AMMO_BACKPACK');
3012 g_DeleteTexture('ITEM_KEY_RED');
3013 g_DeleteTexture('ITEM_KEY_GREEN');
3014 g_DeleteTexture('ITEM_KEY_BLUE');
3015 g_DeleteTexture('ITEM_OXYGEN');
3016 g_DeleteTexture('ITEM_SUIT');
3017 g_DeleteTexture('ITEM_MEDKIT_BLACK');
3018 g_DeleteTexture('ITEM_JETPACK');
3019 g_DeleteTexture('ITEM_INVIS');
3020 g_DeleteTexture('ITEM_WEAPON_FLAMETHROWER');
3021 g_DeleteTexture('ITEM_AMMO_FUELCAN');
3023 g_DeleteTexture('AREA_PLAYERPOINT1');
3024 g_DeleteTexture('AREA_PLAYERPOINT2');
3025 g_DeleteTexture('AREA_DMPOINT');
3026 g_DeleteTexture('AREA_REDPOINT');
3027 g_DeleteTexture('AREA_BLUEPOINT');
3028 end;
3030 end.