lang: ru: fix translation Enable Monsters -> Включить монстров
[d2df-editor.git] / src / editor / g_map.pas
blob2a42a4a72e090c4f502990f5190eed1fcf900ed1
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, f_main;
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
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(Sender: TMainForm);
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, StrUtils, CONFIG,
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);
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;
368 else
369 fn := WadsDir + DirectorySeparator + Res;
371 g_CreateTextureWAD(SKY_TEXTURE, fn);
372 end;
374 function AddItem(Item: TItem): DWORD;
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;
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;
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;
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;
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);
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_BACK: Result := MainForm.miLayerBackground.Checked;
583 PANEL_FORE: Result := MainForm.miLayerForeground.Checked;
584 PANEL_WALL: Result := MainForm.miLayerWalls.Checked;
585 PANEL_LADDER: Result := MainForm.miLayerLadders.Checked;
586 PANEL_BLOCKMON: Result := MainForm.miLayerZones.Checked;
588 PANEL_OPENDOOR, PANEL_CLOSEDOOR:
589 Result := MainForm.miLayerDoors.Checked;
591 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
592 Result := MainForm.miLayerLiquids.Checked;
594 PANEL_LIFTUP, PANEL_LIFTDOWN,
595 PANEL_LIFTLEFT, PANEL_LIFTRIGHT:
596 Result := MainForm.miLayerStreams.Checked;
598 else
599 Result := False;
600 end;
601 end;
603 function ObjectInRect(fX, fY: Integer; fWidth, fHeight: Word; ObjectType: Byte; All: Boolean): DWArray;
605 a: Integer;
607 begin
608 Result := nil;
610 case ObjectType of
611 OBJECT_PANEL:
612 if gPanels <> nil then
613 for a := High(gPanels) downto 0 do
614 with gPanels[a] do
615 begin
616 if not PanelInShownLayer(gPanels[a].PanelType) then
617 Continue;
619 if g_Collide(X, Y, Width, Height,
620 fX, fY, fWidth, fHeight) then
621 begin
622 SetLength(Result, Length(Result)+1);
623 Result[High(Result)] := a;
625 if not All then
626 Break;
627 end;
628 end;
630 OBJECT_ITEM:
631 if MainForm.miLayerItems.Checked and (gItems <> nil) then
632 for a := High(gItems) downto 0 do
633 with gItems[a] do
634 if (ItemType <> ITEM_NONE) and
635 g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
636 fX, fY, fWidth, fHeight) then
637 begin
638 SetLength(Result, Length(Result)+1);
639 Result[High(Result)] := a;
641 if not All then
642 Break;
643 end;
645 OBJECT_MONSTER:
646 if MainForm.miLayerMonsters.Checked and (gMonsters <> nil) then
647 for a := High(gMonsters) downto 0 do
648 if gMonsters[a].MonsterType <> MONSTER_NONE then
649 with MonsterSize[gMonsters[a].MonsterType] do
650 if (gMonsters[a].MonsterType <> 0) and
651 g_Collide(gMonsters[a].X, gMonsters[a].Y, Width, Height,
652 fX, fY, fWidth, fHeight) then
653 begin
654 SetLength(Result, Length(Result)+1);
655 Result[High(Result)] := a;
657 if not All then
658 Break;
659 end;
661 OBJECT_AREA:
662 if MainForm.miLayerAreas.Checked and (gAreas <> nil) then
663 for a := High(gAreas) downto 0 do
664 if gAreas[a].AreaType <> AREA_NONE then
665 with AreaSize[gAreas[a].AreaType] do
666 if (gAreas[a].AreaType <> 0) and
667 g_Collide(gAreas[a].X, gAreas[a].Y, Width, Height,
668 fX, fY, fWidth, fHeight) then
669 begin
670 SetLength(Result, Length(Result)+1);
671 Result[High(Result)] := a;
673 if not All then
674 Break;
675 end;
677 OBJECT_TRIGGER:
678 if MainForm.miLayerTriggers.Checked and (gTriggers <> nil) then
679 for a := High(gTriggers) downto 0 do
680 if gTriggers[a].TriggerType <> TRIGGER_NONE then
681 with gTriggers[a] do
682 begin
683 if (TriggerType <> 0) and
684 g_Collide(X, Y, Width, Height,
685 fX, fY, fWidth, fHeight) then
686 begin
687 SetLength(Result, Length(Result)+1);
688 Result[High(Result)] := a;
690 if not All then
691 Break;
692 end;
693 end;
694 end;
695 end;
697 function ObjectCollideLevel(fID: DWORD; ObjectType: Byte; dX, dY: Integer): Boolean;
699 PanelID: DWORD;
701 begin
702 Result := False;
703 PanelID := DWORD(-1);
705 case ObjectType of
706 OBJECT_PANEL:
707 with gPanels[fID] do
708 Result := (PanelID <> fID) and
709 g_CollideLevel2(X+dX, Y+dY,
710 Width, Height,
711 fID, PanelID);
713 OBJECT_ITEM:
714 with gItems[fID] do
715 Result := g_CollideLevel(X+dX, Y+dY,
716 ItemSize[ItemType][0], ItemSize[ItemType][1]);
718 OBJECT_MONSTER:
719 with MonsterSize[gMonsters[fID].MonsterType] do
720 Result := g_CollideLevel(gMonsters[fID].X+dX, gMonsters[fID].Y+dY,
721 Width, Height);
723 OBJECT_AREA:
724 with AreaSize[gAreas[fID].AreaType] do
725 Result := g_CollideLevel(gAreas[fID].X+dX, gAreas[fID].Y+dY,
726 Width, Height);
728 OBJECT_TRIGGER:
729 with gTriggers[fID] do
730 Result := g_CollideLevel(X+dX, Y+dY,
731 Width, Height);
732 end;
733 end;
735 function ObjectCollide(ObjectType: Byte; ID: DWORD; fX, fY: Integer; fWidth, fHeight: Word): Boolean;
736 begin
737 Result := False;
739 case ObjectType of
740 OBJECT_PANEL:
741 with gPanels[ID] do
742 Result := g_Collide(X, Y, Width, Height,
743 fX, fY, fWidth, fHeight);
745 OBJECT_ITEM:
746 with gItems[ID] do
747 Result := g_Collide(X, Y, ItemSize[ItemType][0], ItemSize[ItemType][1],
748 fX, fY, fWidth, fHeight);
750 OBJECT_MONSTER:
751 with MonsterSize[gMonsters[ID].MonsterType] do
752 Result := g_Collide(gMonsters[ID].X, gMonsters[ID].Y, Width, Height,
753 fX, fY, fWidth, fHeight);
755 OBJECT_AREA:
756 with AreaSize[gAreas[ID].AreaType] do
757 Result := g_Collide(gAreas[ID].X, gAreas[ID].Y, Width, Height,
758 fX, fY, fWidth, fHeight);
760 OBJECT_TRIGGER:
761 with gTriggers[ID] do
762 Result := g_Collide(X, Y, Width, Height,
763 fX, fY, fWidth, fHeight);
764 end;
765 end;
767 function ObjectGetRect(ObjectType: Byte; ID: DWORD): TRectWH;
768 begin
769 case ObjectType of
770 OBJECT_PANEL:
771 with gPanels[ID] do
772 begin
773 Result.X := X;
774 Result.Y := Y;
775 Result.Width := Width;
776 Result.Height := Height;
777 end;
779 OBJECT_ITEM:
780 with gItems[ID] do
781 begin
782 Result.X := X;
783 Result.Y := Y;
784 Result.Width := ItemSize[ItemType][0];
785 Result.Height := ItemSize[ItemType][1];
786 end;
788 OBJECT_MONSTER:
789 with MonsterSize[gMonsters[ID].MonsterType] do
790 begin
791 Result.X := gMonsters[ID].X;
792 Result.Y := gMonsters[ID].Y;
793 Result.Width := Width;
794 Result.Height := Height;
795 end;
797 OBJECT_AREA:
798 with AreaSize[gAreas[ID].AreaType] do
799 begin
800 Result.X := gAreas[ID].X;
801 Result.Y := gAreas[ID].Y;
802 Result.Width := Width;
803 Result.Height := Height;
804 end;
806 OBJECT_TRIGGER:
807 with gTriggers[ID] do
808 begin
809 Result.X := X;
810 Result.Y := Y;
811 Result.Width := Width;
812 Result.Height := Height;
813 end;
815 else
816 begin
817 Result.X := 0;
818 Result.Y := 0;
819 Result.Width := 0;
820 Result.Height := 0;
821 end;
822 end;
823 end;
825 procedure MoveObject(ObjectType: Byte; ID: DWORD; dX, dY: Integer);
826 begin
827 case ObjectType of
828 OBJECT_PANEL:
829 with gPanels[ID] do
830 begin
831 X := X + dX;
832 Y := Y + dY;
833 end;
835 OBJECT_ITEM:
836 with gItems[ID] do
837 begin
838 X := X + dX;
839 Y := Y + dY;
840 end;
842 OBJECT_MONSTER:
843 with gMonsters[ID] do
844 begin
845 X := X + dX;
846 Y := Y + dY;
847 end;
849 OBJECT_AREA:
850 with gAreas[ID] do
851 begin
852 X := X + dX;
853 Y := Y + dY;
854 end;
856 OBJECT_TRIGGER:
857 with gTriggers[ID] do
858 begin
859 X := X + dX;
860 Y := Y + dY;
861 end;
862 end;
863 end;
865 function ResizeObject(ObjectType: Byte; ID: DWORD; dWidth, dHeight: Integer; ResizeDir: Byte): Boolean;
866 begin
867 Result := True;
868 case ObjectType of
869 OBJECT_PANEL:
870 with gPanels[ID] do
871 begin
872 if Width >= -dWidth then
873 Width := Width+dWidth
874 else
875 begin
876 Width := 0;
877 Result := False;
878 Exit;
879 end;
881 if Height >= -dHeight then
882 Height := Height+dHeight
883 else
884 begin
885 Height := 0;
886 Result := False;
887 Exit;
888 end;
890 case ResizeDir of
891 2: Y := Y - dHeight;
892 4: X := X - dWidth;
893 end;
894 end;
896 OBJECT_ITEM, OBJECT_MONSTER, OBJECT_AREA:
897 Exit;
899 OBJECT_TRIGGER:
900 with gTriggers[ID] do
901 begin
902 if Width >= -dWidth then
903 Width := Width+dWidth
904 else
905 begin
906 Width := 0;
907 Result := False;
908 Exit;
909 end;
911 if Height >= -dHeight then
912 Height := Height+dHeight
913 else
914 begin
915 Height := 0;
916 Result := False;
917 Exit;
918 end;
920 case ResizeDir of
921 2: Y := Y - dHeight;
922 4: X := X - dWidth;
923 end;
924 end;
925 end;
926 end;
928 function ObjectSelected(ObjectType: Byte; ID: DWORD): Boolean;
930 a: Integer;
932 begin
933 Result := False;
935 if SelectedObjects <> nil then
936 for a := 0 to High(SelectedObjects) do
937 if SelectedObjects[a].Live and
938 (SelectedObjects[a].ObjectType = ObjectType) and
939 (SelectedObjects[a].ID = ID) then
940 begin
941 Result := True;
942 Break;
943 end;
944 end;
946 function GetPanelName(PanelType: Word): String;
947 begin
948 Result := '';
950 case PanelType of
951 PANEL_WALL: Result := PANELNAMES[0];
952 PANEL_BACK: Result := PANELNAMES[1];
953 PANEL_FORE: Result := PANELNAMES[2];
954 PANEL_OPENDOOR: Result := PANELNAMES[3];
955 PANEL_CLOSEDOOR: Result := PANELNAMES[4];
956 PANEL_LADDER: Result := PANELNAMES[5];
957 PANEL_WATER: Result := PANELNAMES[6];
958 PANEL_ACID1: Result := PANELNAMES[7];
959 PANEL_ACID2: Result := PANELNAMES[8];
960 PANEL_LIFTUP: Result := PANELNAMES[9];
961 PANEL_LIFTDOWN: Result := PANELNAMES[10];
962 PANEL_LIFTLEFT: Result := PANELNAMES[11];
963 PANEL_LIFTRIGHT: Result := PANELNAMES[12];
964 PANEL_BLOCKMON: Result := PANELNAMES[13];
965 else Assert(False);
966 end;
967 end;
969 function GetPanelType(PanelName: String): Word;
970 begin
971 Result := PANEL_NONE;
973 case AnsiIndexStr(PanelName, PANELNAMES) of
974 0: Result := PANEL_WALL;
975 1: Result := PANEL_BACK;
976 2: Result := PANEL_FORE;
977 3: Result := PANEL_OPENDOOR;
978 4: Result := PANEL_CLOSEDOOR;
979 5: Result := PANEL_LADDER;
980 6: Result := PANEL_WATER;
981 7: Result := PANEL_ACID1;
982 8: Result := PANEL_ACID2;
983 9: Result := PANEL_LIFTUP;
984 10: Result := PANEL_LIFTDOWN;
985 11: Result := PANEL_LIFTLEFT;
986 12: Result := PANEL_LIFTRIGHT;
987 13: Result := PANEL_BLOCKMON;
988 else Assert(False);
989 end;
990 end;
992 function GetTriggerName(TriggerType: Byte): String;
993 begin
994 if TriggerType in [TRIGGER_EXIT..TRIGGER_MAX] then
995 Result := TriggerNames[TriggerType]
996 else
997 Assert(False);
998 end;
1000 function GetTriggerType(TriggerName: String): Byte;
1002 i: Integer;
1004 begin
1005 Result := TRIGGER_NONE;
1006 for i := TRIGGER_EXIT to TRIGGER_MAX do
1007 if TriggerNames[i] = TriggerName then
1008 begin
1009 Result := i;
1010 Exit;
1011 end;
1013 Assert(False);
1014 end;
1016 function IsSpecialTexture(TextureName: string): Boolean;
1017 begin
1018 Result := (TextureName = TEXTURE_NAME_WATER) or
1019 (TextureName = TEXTURE_NAME_ACID1) or
1020 (TextureName = TEXTURE_NAME_ACID2);
1021 end;
1023 function SpecialTextureID(TextureName: string): DWORD;
1024 begin
1025 Assert(IsSpecialTexture(TextureName));
1027 Result := 0;
1029 if TextureName = TEXTURE_NAME_WATER then
1030 Result := TEXTURE_SPECIAL_WATER
1031 else
1032 if TextureName = TEXTURE_NAME_ACID1 then
1033 Result := TEXTURE_SPECIAL_ACID1
1034 else
1035 if TextureName = TEXTURE_NAME_ACID2 then
1036 Result := TEXTURE_SPECIAL_ACID2;
1037 end;
1039 function SaveMap(Res, ArchiveFormat: String): Pointer;
1041 WAD: TWADEditor;
1042 MapWriter: TMapWriter_1;
1043 textures: TTexturesRec1Array;
1044 panels: TPanelsRec1Array;
1045 items: TItemsRec1Array;
1046 areas: TAreasRec1Array;
1047 monsters: TMonsterRec1Array;
1048 triggers: TTriggersRec1Array;
1049 header: TMapHeaderRec_1;
1050 a, b, c: Integer;
1051 s: String;
1052 PanelTable: Array of Array [0..1] of Word;
1053 MonsterTable: Array of Array [0..1] of Word;
1054 Data: Pointer;
1055 FileName, SectionName, ResName: String;
1056 Len: LongWord;
1058 begin
1059 WAD := nil;
1060 textures := nil;
1061 panels := nil;
1062 items := nil;
1063 areas := nil;
1064 monsters := nil;
1065 triggers := nil;
1066 PanelTable := nil;
1067 MonsterTable := nil;
1068 Data := nil;
1069 Len := 0;
1071 // Открываем WAD, если надо:
1072 if Res <> '' then
1073 begin
1074 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1076 if ArchiveFormat = '' then
1077 begin
1078 // format not specified -> try open automatically and append to it (or create new default)
1079 WAD := gWADEditorFactory.OpenFile(FileName);
1080 if WAD = nil then
1081 WAD := gWADEditorFactory.CreateDefaultEditor();
1083 else
1084 begin
1085 // format specified -> append using exactly this format (overwrite if not compatible)
1086 WAD := gWADEditorFactory.CreateEditor(ArchiveFormat);
1087 if WAD.ReadFile(FileName) = False then
1088 WAD.FreeWAD();
1089 end;
1090 WAD.CreateImage();
1091 end;
1093 MapWriter := TMapWriter_1.Create();
1095 // Сохраняем заголовок:
1096 with header do
1097 begin
1098 ZeroMemory(@header, SizeOf(TMapHeaderRec_1));
1100 s := utf2win(gMapInfo.Name);
1101 if s <> '' then
1102 CopyMemory(@MapName[0], @s[1], Min(32, Length(s)));
1104 s := utf2win(gMapInfo.Description);
1105 if s <> '' then
1106 CopyMemory(@MapDescription[0], @s[1], Min(256, Length(s)));
1108 s := utf2win(gMapInfo.Author);
1109 if s <> '' then
1110 CopyMemory(@MapAuthor[0], @s[1], Min(32, Length(s)));
1112 s := utf2win(gMapInfo.MusicName);
1113 if s <> '' then
1114 CopyMemory(@MusicName[0], @s[1], Min(64, Length(s)));
1116 s := utf2win(gMapInfo.SkyName);
1117 if s <> '' then
1118 CopyMemory(@SkyName[0], @s[1], Min(64, Length(s)));
1120 Width := gMapInfo.Width;
1121 Height := gMapInfo.Height;
1122 end;
1124 MapWriter.AddHeader(header);
1126 // Сохраняем названия текстур:
1127 if MainForm.lbTextureList.Items.Count > 0 then
1128 begin
1129 for a := 0 to MainForm.lbTextureList.Items.Count-1 do
1130 begin
1131 SetLength(textures, Length(textures)+1);
1132 s := utf2win(MainForm.lbTextureList.Items[a]);
1133 CopyMemory(@textures[High(textures)].Resource[0], @s[1], Min(64, Length(s)));
1134 if g_GetTextureFlagByName(MainForm.lbTextureList.Items[a]) = 1 then
1135 textures[High(textures)].Anim := 1
1136 else
1137 textures[High(textures)].Anim := 0;
1138 end;
1140 MapWriter.AddTextures(textures);
1141 end;
1143 // Сохраняем панели:
1144 if gPanels <> nil then
1145 begin
1146 c := 0;
1148 for a := 0 to High(gPanels) do
1149 if gPanels[a].PanelType <> 0 then
1150 begin
1151 SetLength(PanelTable, Length(PanelTable)+1);
1152 PanelTable[High(PanelTable)][0] := a;
1153 PanelTable[High(PanelTable)][1] := c;
1154 c := c + 1;
1156 SetLength(panels, Length(panels)+1);
1158 with panels[High(panels)] do
1159 begin
1160 X := gPanels[a].X;
1161 Y := gPanels[a].Y;
1162 Width := gPanels[a].Width;
1163 Height := gPanels[a].Height;
1164 PanelType := gPanels[a].PanelType;
1165 Alpha := gPanels[a].Alpha;
1167 TextureNum := 0;
1168 Flags := 0;
1170 if WordBool(gPanels[a].PanelType and
1171 (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) then
1172 Flags := PANEL_FLAG_WATERTEXTURES;
1174 // Может быть текстура:
1175 if not WordBool(gPanels[a].PanelType and
1176 (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT or PANEL_BLOCKMON)) then
1177 begin
1178 if gPanels[a].Blending then
1179 Flags := Flags or PANEL_FLAG_BLENDING;
1180 if gPanels[a].TextureID = TEXTURE_SPECIAL_NONE then
1181 Flags := Flags or PANEL_FLAG_HIDE;
1183 // Номер текстуры в списке текстур:
1184 if gPanels[a].TextureID <> TEXTURE_SPECIAL_NONE then
1185 for b := 0 to High(textures) do
1186 if utf2win(gPanels[a].TextureName) = textures[b].Resource then
1187 begin
1188 TextureNum := b;
1189 Break;
1190 end;
1191 end;
1192 end;
1193 end;
1195 MapWriter.AddPanels(panels);
1196 end;
1198 // Сохраняем предметы:
1199 if gItems <> nil then
1200 begin
1201 for a := 0 to High(gItems) do
1202 if gItems[a].ItemType <> 0 then
1203 begin
1204 SetLength(items, Length(items)+1);
1206 with items[High(items)] do
1207 begin
1208 X := gItems[a].X;
1209 Y := gItems[a].Y;
1210 ItemType := gItems[a].ItemType;
1211 if gItems[a].OnlyDM then
1212 Options := Options or ITEM_OPTION_ONLYDM;
1213 if gItems[a].Fall then
1214 Options := Options or ITEM_OPTION_FALL;
1215 end;
1216 end;
1218 MapWriter.AddItems(items);
1219 end;
1221 // Сохраняем монстров:
1222 if gMonsters <> nil then
1223 begin
1224 c := 0;
1226 for a := 0 to High(gMonsters) do
1227 if gMonsters[a].MonsterType <> 0 then
1228 begin
1229 SetLength(MonsterTable, Length(MonsterTable)+1);
1230 MonsterTable[High(MonsterTable)][0] := a;
1231 MonsterTable[High(MonsterTable)][1] := c;
1232 c := c + 1;
1234 SetLength(monsters, Length(monsters)+1);
1236 with monsters[High(monsters)] do
1237 begin
1238 X := gMonsters[a].X;
1239 Y := gMonsters[a].Y;
1240 MonsterType := gMonsters[a].MonsterType;
1241 Direction := Ord(gMonsters[a].Direction);
1242 end;
1243 end;
1245 MapWriter.AddMonsters(monsters);
1246 end;
1248 // Сохраняем области:
1249 if gAreas <> nil then
1250 begin
1251 for a := 0 to High(gAreas) do
1252 if gAreas[a].AreaType <> 0 then
1253 begin
1254 SetLength(areas, Length(areas)+1);
1256 with areas[High(areas)] do
1257 begin
1258 X := gAreas[a].X;
1259 Y := gAreas[a].Y;
1260 AreaType := gAreas[a].AreaType;
1261 Direction := Ord(gAreas[a].Direction);
1262 end;
1263 end;
1265 MapWriter.AddAreas(areas);
1266 end;
1268 // Сохраняем триггеры:
1269 if gTriggers <> nil then
1270 begin
1271 for a := 0 to High(gTriggers) do
1272 if gTriggers[a].TriggerType <> 0 then
1273 begin
1274 SetLength(triggers, Length(triggers)+1);
1276 with triggers[High(triggers)] do
1277 begin
1278 X := gTriggers[a].X;
1279 Y := gTriggers[a].Y;
1280 Width := gTriggers[a].Width;
1281 Height := gTriggers[a].Height;
1282 Enabled := Byte(gTriggers[a].Enabled);
1283 TexturePanel := -1;
1284 TriggerType := gTriggers[a].TriggerType;
1285 ActivateType := gTriggers[a].ActivateType;
1286 Keys := gTriggers[a].Key;
1287 DATA := gTriggers[a].Data.Default;
1289 if PanelTable <> nil then
1290 begin
1291 // Ищем номер панели, которой этот триггер меняет текстуру:
1292 if gTriggers[a].TexturePanel <> -1 then
1293 begin
1294 for c := 0 to High(PanelTable) do
1295 if PanelTable[c][0] = gTriggers[a].TexturePanel then
1296 TexturePanel := PanelTable[c][1];
1297 end;
1299 // Ищем номер панели, которую меняет этот триггер:
1300 if gTriggers[a].TriggerType in [
1301 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR,
1302 TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP,
1303 TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
1304 if TTriggerData(DATA).PanelID <> -1 then
1305 for c := 0 to High(PanelTable) do
1306 if PanelTable[c][0] = TTriggerData(DATA).PanelID then
1307 begin
1308 TTriggerData(DATA).PanelID := PanelTable[c][1];
1309 Break;
1310 end;
1312 // Ищем номер панели индикации, которой этот триггер меняет текстуру:
1313 if (gTriggers[a].TriggerType = TRIGGER_SHOT) and
1314 (TTriggerData(DATA).ShotPanelID <> -1) then
1315 begin
1316 for c := 0 to High(PanelTable) do
1317 if PanelTable[c][0] = TTriggerData(DATA).ShotPanelID then
1318 TTriggerData(DATA).ShotPanelID := PanelTable[c][1];
1319 end;
1320 end;
1322 if MonsterTable <> nil then
1323 begin
1324 // Ищем номер монстра - условие активации триггера:
1325 if gTriggers[a].TriggerType in [
1326 TRIGGER_PRESS, TRIGGER_ON,
1327 TRIGGER_OFF, TRIGGER_ONOFF] then
1328 if TTriggerData(DATA).MonsterID <> 0 then
1329 for c := 0 to High(MonsterTable) do
1330 if MonsterTable[c][0] = TTriggerData(DATA).MonsterID-1 then
1331 begin
1332 TTriggerData(DATA).MonsterID := MonsterTable[c][1]+1;
1333 Break;
1334 end;
1335 end;
1336 end;
1337 end;
1339 MapWriter.AddTriggers(triggers);
1340 end;
1342 // Сохраняем карту в память:
1343 Len := MapWriter.SaveMap(Data);
1345 MapWriter.Free();
1347 // Записываем в WAD, если надо:
1348 if Res <> '' then
1349 begin
1350 s := utf2win(ResName);
1351 WAD.RemoveResource('', s);
1352 WAD.AddResource(Data, Len, s, '');
1353 WAD.SaveTo(FileName);
1355 FreeMem(Data);
1356 WAD.Free();
1358 Result := nil;
1360 else
1361 Result := Data;
1362 end;
1364 procedure AddTexture(res: String; Error: Boolean);
1366 a: Integer;
1367 begin
1368 with MainForm.lbTextureList do
1369 begin
1370 for a := 0 to Count-1 do
1371 if Items[a] = res then
1372 Exit;
1374 if Error and (slInvalidTextures.IndexOf(res) = -1) then
1375 slInvalidTextures.Add(res);
1376 Items.Add(res);
1377 end;
1378 end;
1380 function map_CreateAnimTexture(TextureName, Resource: String): Boolean;
1382 Data: Pointer = nil;
1383 FrameLen: Integer = 0;
1384 Width: Word = 0;
1385 Height: Word = 0;
1386 begin
1387 Result := GetFrame(Resource, Data, FrameLen, Width, Height);
1388 if not Result then // Кадры
1389 e_WriteLog(Format('GetFrame() error, res=%s', [TextureName]), MSG_WARNING)
1390 else
1391 begin
1392 Result := g_CreateTextureMemorySize(Data, FrameLen, TextureName, 0, 0, Width, Height, 1);
1393 if not Result then // Сама текстура
1394 e_WriteLog(Format('g_CreateTextureMemorySize() error, res=%s', [TextureName]), MSG_WARNING);
1395 end;
1396 end;
1398 function LoadMap(Res: String): Boolean;
1400 WAD: TWADEditor_1;
1401 MapReader: TMapReader_1;
1402 Header: TMapHeaderRec_1;
1403 textures: TTexturesRec1Array;
1404 panels: TPanelsRec1Array;
1405 items: TItemsRec1Array;
1406 monsters: TMonsterRec1Array;
1407 areas: TAreasRec1Array;
1408 triggers: TTriggersRec1Array;
1409 panel: TPanel;
1410 item: TItem;
1411 monster: TMonster;
1412 area: TArea;
1413 trigger: TTrigger;
1414 a: Integer;
1415 m: Word;
1416 FileName, SectionName, ResName, _fn: String;
1417 TextureRes, ustr: String;
1418 pData: Pointer;
1419 Len: Integer;
1420 Success: Boolean;
1421 NoTextureID: DWORD;
1422 NW, NH: Word;
1423 begin
1424 Result := False;
1425 pData := nil;
1426 Len := 0;
1427 NoTextureID := 0;
1428 NW := 0;
1429 NH := 0;
1431 MainForm.pbLoad.Position := 0;
1432 MainForm.lLoad.Caption := MsgLoadWad;
1433 Application.ProcessMessages();
1435 // Открываем WAD:
1436 WAD := TWADEditor_1.Create();
1437 g_ProcessResourceStr(Res, FileName, SectionName, ResName);
1439 if not WAD.ReadFile(FileName) then
1440 begin
1441 WAD.Free();
1442 Exit;
1443 end;
1445 // Читаем ресурс карты:
1446 if not WAD.GetResource('', utf2win(ResName), pData, Len) then
1447 begin
1448 WAD.Free();
1449 Exit;
1450 end;
1452 WAD.Free();
1454 MapReader := TMapReader_1.Create();
1456 MainForm.lLoad.Caption := MsgLoadMap;
1457 Application.ProcessMessages();
1459 MapReader.LoadMap(pData);
1461 // Загружаем текстуры:
1462 textures := MapReader.GetTextures();
1464 if textures <> nil then
1465 begin
1466 MainForm.pbLoad.Position := 0;
1467 MainForm.pbLoad.Max := Length(textures);
1468 MainForm.lLoad.Caption := MsgLoadTextures;
1470 for a := 0 to High(textures) do
1471 begin
1472 MainForm.pbLoad.StepIt();
1473 Application.ProcessMessages();
1474 ustr := win2utf(textures[a].Resource);
1476 Success := True;
1477 if not IsSpecialTexture(ustr) then
1478 begin
1479 g_ProcessResourceStr(ustr, @_fn, nil, nil);
1481 if _fn = ''
1482 then TextureRes := FileName + ustr
1483 else TextureRes := WadsDir + DirectorySeparator + ustr;
1485 if not Boolean(textures[a].Anim) then
1486 begin // Обычная текстура
1487 if not g_CreateTextureWAD(ustr, TextureRes) then
1488 begin
1489 e_WriteLog(Format('g_CreateTextureWAD() error, res=%s', [ustr]), MSG_WARNING);
1490 Success := map_CreateAnimTexture(ustr, TextureRes);
1491 if Success then
1492 begin
1493 textures[a].Anim := Byte(ByteBool(True));
1494 e_WriteLog(Format(' wrong (outdated?) anim flag hint - texture #%d is actually animated: %s', [a, ustr]), MSG_WARNING);
1495 end;
1496 end;
1498 else
1499 begin // Анимированная текстура
1500 if not map_CreateAnimTexture(ustr, TextureRes) then
1501 begin
1502 Success := g_CreateTextureWAD(ustr, TextureRes);
1503 if Success then
1504 begin
1505 textures[a].Anim := Byte(ByteBool(False));
1506 e_WriteLog(Format(' wrong (outdated?) anim flag hint - texture #%d is actually static: %s', [a, ustr]), MSG_WARNING);
1507 end;
1508 end;
1509 end;
1510 end;
1512 AddTexture(ustr, not Success);
1513 end;
1514 end;
1516 // Загружаем панели:
1517 panels := MapReader.GetPanels();
1519 if panels <> nil then
1520 begin
1521 MainForm.pbLoad.Position := 0;
1522 MainForm.pbLoad.Max := Length(panels);
1523 MainForm.lLoad.Caption := MsgLoadPanels;
1525 for a := 0 to High(panels) do
1526 begin
1527 MainForm.pbLoad.StepIt();
1528 Application.ProcessMessages();
1530 panel.X := panels[a].X;
1531 panel.Y := panels[a].Y;
1532 panel.Height := panels[a].Height;
1533 panel.Width := panels[a].Width;
1534 panel.PanelType := panels[a].PanelType;
1535 panel.Alpha := panels[a].Alpha;
1537 panel.Blending := ByteBool(panels[a].Flags and PANEL_FLAG_BLENDING);
1539 panel.TextureWidth := 0;
1540 panel.TextureHeight := 0;
1541 panel.TextureName := '';
1542 panel.TextureID := TEXTURE_SPECIAL_NONE;
1544 m := PANEL_WALL or PANEL_BACK or PANEL_FORE or PANEL_LADDER or
1545 PANEL_OPENDOOR or PANEL_CLOSEDOOR;
1547 if ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES) then
1548 m := m or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
1550 // Если панель видима:
1551 if WordBool(panel.PanelType and m) and
1552 (not (ByteBool(panels[a].Flags and PANEL_FLAG_HIDE))) then
1553 begin
1554 ustr := win2utf(textures[panels[a].TextureNum].Resource);
1555 if not IsSpecialTexture(ustr) then
1556 begin // Текстура
1557 if g_GetTexture(ustr, panel.TextureID) then
1558 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight)
1559 else begin
1560 panel.TextureWidth := 1;
1561 panel.TextureHeight := 1;
1562 if g_GetTexture('NOTEXTURE', NoTextureID) then
1563 begin
1564 panel.TextureID := TEXTURE_SPECIAL_NOTEXTURE;
1565 g_GetTextureSizeByID(NoTextureID, NW, NH);
1566 panel.TextureWidth := NW;
1567 panel.TextureHeight := NH;
1568 end;
1569 end;
1571 else // Спец. текстура
1572 panel.TextureID := SpecialTextureID(ustr);
1574 panel.TextureName := ustr;
1575 end;
1577 // Жидкость без текстуры:
1578 if WordBool(panel.PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
1579 (not ByteBool(panels[a].Flags and PANEL_FLAG_WATERTEXTURES)) then
1580 begin
1581 case panel.PanelType of
1582 PANEL_WATER: panel.TextureName := TEXTURE_NAME_WATER;
1583 PANEL_ACID1: panel.TextureName := TEXTURE_NAME_ACID1;
1584 PANEL_ACID2: panel.TextureName := TEXTURE_NAME_ACID2;
1585 end;
1587 panel.TextureID := SpecialTextureID(panel.TextureName);
1588 AddTexture(panel.TextureName, False);
1589 end;
1591 AddPanel(panel);
1592 end;
1593 end;
1595 // Загружаем предметы:
1596 items := MapReader.GetItems();
1598 if items <> nil then
1599 begin
1600 MainForm.pbLoad.Position := 0;
1601 MainForm.pbLoad.Max := Length(items);
1602 MainForm.lLoad.Caption := MsgLoadItems;
1604 for a := 0 to High(items) do
1605 begin
1606 MainForm.pbLoad.StepIt();
1607 Application.ProcessMessages();
1609 item.X := items[a].X;
1610 item.Y := items[a].Y;
1611 item.ItemType := items[a].ItemType;
1612 item.OnlyDM := ByteBool(items[a].Options and ITEM_OPTION_ONLYDM);
1613 item.Fall := ByteBool(items[a].Options and ITEM_OPTION_FALL);
1615 AddItem(item);
1616 end;
1617 end;
1619 // Загружаем монстров:
1620 monsters := MapReader.GetMonsters();
1622 if monsters <> nil then
1623 begin
1624 MainForm.pbLoad.Position := 0;
1625 MainForm.pbLoad.Max := Length(monsters);
1626 MainForm.lLoad.Caption := MsgLoadMonsters;
1628 for a := 0 to High(monsters) do
1629 begin
1630 MainForm.pbLoad.StepIt();
1631 Application.ProcessMessages();
1633 monster.X := monsters[a].X;
1634 monster.Y := monsters[a].Y;
1635 monster.MonsterType := monsters[a].MonsterType;
1636 monster.Direction := TDirection(monsters[a].Direction);
1638 AddMonster(monster);
1639 end;
1640 end;
1642 // Загружаем области:
1643 areas := MapReader.GetAreas();
1645 if areas <> nil then
1646 begin
1647 MainForm.pbLoad.Position := 0;
1648 MainForm.pbLoad.Max := Length(areas);
1649 MainForm.lLoad.Caption := MsgLoadAreas;
1651 for a := 0 to High(areas) do
1652 begin
1653 MainForm.pbLoad.StepIt();
1654 Application.ProcessMessages();
1656 area.X := areas[a].X;
1657 area.Y := areas[a].Y;
1658 area.AreaType := areas[a].AreaType;
1659 area.Direction := TDirection(areas[a].Direction);
1661 AddArea(area);
1662 end;
1663 end;
1665 // Загружаем триггеры:
1666 triggers := MapReader.GetTriggers();
1668 if triggers <> nil then
1669 begin
1670 MainForm.pbLoad.Position := 0;
1671 MainForm.pbLoad.Max := Length(triggers);
1672 MainForm.lLoad.Caption := MsgLoadTriggers;
1674 for a := 0 to High(triggers) do
1675 begin
1676 MainForm.pbLoad.StepIt();
1677 Application.ProcessMessages();
1679 trigger.X := triggers[a].X;
1680 trigger.Y := triggers[a].Y;
1681 trigger.Width := triggers[a].Width;
1682 trigger.Height := triggers[a].Height;
1684 trigger.Enabled := ByteBool(triggers[a].Enabled);
1685 trigger.TexturePanel := triggers[a].TexturePanel;
1686 trigger.TriggerType := triggers[a].TriggerType;
1687 trigger.ActivateType := triggers[a].ActivateType;
1688 trigger.Key := triggers[a].Keys;
1689 trigger.Data.Default := triggers[a].DATA;
1691 AddTrigger(trigger);
1692 end;
1693 end;
1695 // Загружаем заголовок карты:
1696 Header := MapReader.GetMapHeader();
1698 gMapInfo.FileName := FileName;
1700 with gMapInfo do
1701 begin
1702 MapName := ResName;
1703 Name := win2utf(Header.MapName);
1704 Description := win2utf(Header.MapDescription);
1705 Author := win2utf(Header.MapAuthor);
1706 MusicName := win2utf(Header.MusicName);
1707 SkyName := win2utf(Header.SkyName);
1708 Height := Header.Height;
1709 Width := Header.Width;
1710 end;
1712 LoadSky(gMapInfo.SkyName);
1714 textures := nil;
1715 panels := nil;
1716 items := nil;
1717 areas := nil;
1718 triggers := nil;
1720 MapReader.Free();
1721 FreeMem(pData);
1723 Result := True;
1724 end;
1726 function LoadMapOld(_FileName: String): Boolean;
1727 const
1728 TexturePrefix = 'standart.wad:STDTEXTURES\';
1729 DefaultMusRes = 'standart.wad:STDMUS\MUS1';
1730 DefaultSkyRes = 'standart.wad:STDSKY\SKY0';
1733 map: TConfig;
1734 i, a: Integer;
1735 s, section: String;
1736 panel: TPanel;
1737 item: TItem;
1738 area: TArea;
1740 begin
1741 Result := False;
1743 if not FileExists(_FileName) then
1744 Exit;
1746 // Открытие карты:
1747 MainForm.pbLoad.Position := 0;
1748 MainForm.lLoad.Caption := MsgLoadMap;;
1749 Application.ProcessMessages();
1751 map := TConfig.CreateFile(_FileName);
1753 // Чтение текстур:
1754 i := map.ReadInt('MapOptions', 'TextureCount', 0);
1756 MainForm.pbLoad.Max := i;
1757 MainForm.pbLoad.Position := 0;
1758 MainForm.lLoad.Caption := MsgLoadTextures;
1760 for a := 1 to i do
1761 begin
1762 MainForm.pbLoad.StepIt();
1763 Application.ProcessMessages();
1765 s := TexturePrefix + UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
1766 if s = TexturePrefix then
1767 Continue;
1769 // Нет такой текстуры - ищем в WAD карты:
1770 if not g_CreateTextureWAD(s, WadsDir + DirectorySeparator + s) then
1771 begin
1772 s := ExtractFileName(_FileName);
1773 Delete(s, Length(s)-3, 4);
1774 s := UpperCase(s) + '.WAD:TEXTURES\'+ UpperCase(win2utf(map.ReadStr('Textures', 'TextureName'+IntToStr(a), '')));
1776 if not g_CreateTextureWAD(s, WadsDir + DirectorySeparator + s) then
1777 Continue;
1778 end;
1780 MainForm.lbTextureList.Items.Add(s);
1781 end;
1783 // Чтение панелей:
1784 i := map.ReadInt('MapOptions', 'PanelCount', 0);
1786 MainForm.pbLoad.Max := i;
1787 MainForm.pbLoad.Position := 0;
1788 MainForm.lLoad.Caption := MsgLoadPanels;
1790 for a := 1 to i do
1791 begin
1792 MainForm.pbLoad.StepIt();
1793 Application.ProcessMessages();
1795 section := 'Panel' + IntToStr(a);
1796 if not map.SectionExists(section) then
1797 Continue;
1799 panel := Default(TPanel);
1800 panel.X := map.ReadInt(section, 'X1', 0);
1801 panel.Y := map.ReadInt(section, 'Y1', 0);
1802 panel.Height := map.ReadInt(section, 'Height', 16);
1803 panel.Width := map.ReadInt(section, 'Width', 16);
1805 case map.ReadInt(section, 'PanelType', 0) of
1806 0: panel.PanelType := PANEL_WALL;
1807 1: panel.PanelType := PANEL_BACK;
1808 2: panel.PanelType := PANEL_FORE;
1809 3: panel.PanelType := PANEL_LADDER;
1810 4: panel.PanelType := PANEL_WATER;
1811 5: panel.PanelType := PANEL_ACID1;
1812 6: panel.PanelType := PANEL_ACID2;
1813 end;
1815 panel.Alpha := map.ReadInt(section, 'Alpha', 0);
1816 panel.Blending := false;
1818 // Текстура панели:
1819 if panel.PanelType in [PANEL_WALL, PANEL_BACK, PANEL_FORE, PANEL_LADDER] then
1820 begin
1821 s := TexturePrefix + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
1823 if g_GetTexture(s, panel.TextureID) then
1824 begin
1825 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1826 panel.TextureName := s;
1828 else // Нет такой текстуры - ищем в WAD карты:
1829 begin
1830 s := ExtractFileName(_FileName);
1831 Delete(s, Length(s)-3, 4);
1832 s := UpperCase(s) + '.WAD:TEXTURES\' + UpperCase(win2utf(map.ReadStr(section, 'TextureName', '')));
1834 if g_GetTexture(s, panel.TextureID) then
1835 begin
1836 g_GetTextureSizeByID(panel.TextureID, panel.TextureWidth, panel.TextureHeight);
1837 panel.TextureName := s;
1839 else
1840 Continue;
1841 end;
1843 else if panel.PanelType in [PANEL_WATER, PANEL_ACID1, PANEL_ACID2] then
1844 begin
1845 case panel.PanelType of
1846 PANEL_WATER:
1847 begin
1848 s := TEXTURE_NAME_WATER;
1849 panel.TextureID := TEXTURE_SPECIAL_WATER;
1850 end;
1851 PANEL_ACID1:
1852 begin
1853 s := TEXTURE_NAME_ACID2;
1854 panel.TextureID := TEXTURE_SPECIAL_ACID2;
1855 end;
1856 PANEL_ACID2:
1857 begin
1858 s := TEXTURE_NAME_ACID1;
1859 panel.TextureID := TEXTURE_SPECIAL_ACID1;
1860 end;
1861 end;
1863 with MainForm.lbTextureList.Items do
1864 if IndexOf(s) = -1 then
1865 Add(s);
1866 panel.TextureName := s;
1867 panel.TextureWidth := 1;
1868 panel.TextureHeight := 1;
1869 end;
1871 AddPanel(panel);
1872 end;
1874 // Чтение предметов:
1875 i := map.ReadInt('MapOptions', 'ItemCount', 0);
1877 MainForm.pbLoad.Max := i;
1878 MainForm.pbLoad.Position := 0;
1879 MainForm.lLoad.Caption := MsgLoadItems;
1881 for a := 1 to i do
1882 begin
1883 MainForm.pbLoad.StepIt();
1884 Application.ProcessMessages();
1886 section := 'Item' + IntToStr(a);
1887 if not map.SectionExists(section) then
1888 Continue;
1890 item := Default(TItem);
1891 item.X := map.ReadInt(section, 'X', 0);
1892 item.Y := map.ReadInt(section, 'Y', 0);
1893 item.ItemType := ITEMSCONVERT[map.ReadInt(section, 'Type', 0)];
1894 item.OnlyDM := False;
1895 item.Fall := item.ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE];
1897 // Размер предметов теперь другой:
1898 item.X := item.X + OldItemSize[item.ItemType][0] - ItemSize[item.ItemType][0];
1899 item.Y := item.Y + OldItemSize[item.ItemType][1] - ItemSize[item.ItemType][1];
1901 AddItem(item);
1902 end;
1904 // Чтение областей:
1905 i := map.ReadInt('MapOptions', 'AreaCount', 0);
1907 MainForm.pbLoad.Max := i;
1908 MainForm.pbLoad.Position := 0;
1909 MainForm.lLoad.Caption := MsgLoadAreas;
1911 for a := 1 to i do
1912 begin
1913 MainForm.pbLoad.StepIt();
1914 Application.ProcessMessages();
1916 section := 'Area' + IntToStr(a);
1917 if not map.SectionExists(section) then
1918 Continue;
1920 area := Default(TArea);
1921 area.X := map.ReadInt(section, 'X', 0);
1922 area.Y := map.ReadInt(section, 'Y', 0);
1923 area.AreaType := map.ReadInt(section, 'Type', 0);
1924 area.Direction := D_RIGHT;
1926 // Размер областей теперь другой:
1927 area.X := area.X + OldAreaSize[0] - AreaSize[area.AreaType].Width;
1928 area.Y := area.Y + OldAreaSize[1] - AreaSize[area.AreaType].Height;
1930 AddArea(area);
1931 end;
1933 // Чтение параметров карты:
1934 gMapInfo := Default(TMapInfo);
1935 with gMapInfo do
1936 begin
1937 Name := win2utf(map.ReadStr('MapOptions', 'MapName', ''));
1938 Description := win2utf(map.ReadStr('MapOptions', 'MapDescription', ''));
1939 Author := '';
1940 MusicName := DefaultMusRes;
1941 SkyName := DefaultSkyRes;
1942 FileName := _FileName;
1943 Height := map.ReadInt('MapOptions', 'Height', 1600);
1944 Width := map.ReadInt('MapOptions', 'Width', 1600);
1946 if Length(Name) > 32 then
1947 SetLength(Name, 32);
1948 if Length(Description) > 256 then
1949 SetLength(Description, 256);
1950 end;
1952 LoadSky(gMapInfo.SkyName);
1954 map.Free();
1956 Result := True;
1957 end;
1959 // TODO: Get rid of 'Sender' here, this is a temporary hack to avoid uninitialized variable access.
1960 procedure ClearMap(Sender: TMainForm);
1962 a: Integer;
1964 begin
1965 if gPanels <> nil then
1966 for a := 0 to High(gPanels) do
1967 if gPanels[a].TextureName <> '' then
1968 g_DeleteTexture(gPanels[a].TextureName);
1970 SetLength(gPanels, 0);
1971 gPanels := nil;
1972 SetLength(gItems, 0);
1973 gItems := nil;
1974 SetLength(gAreas, 0);
1975 gAreas := nil;
1976 SetLength(gMonsters, 0);
1977 gMonsters := nil;
1978 SetLength(gTriggers, 0);
1979 gTriggers := nil;
1981 gMapInfo := Default(TMapInfo);
1982 gMapInfo.Width := 1600;
1983 gMapInfo.Height := 1600;
1985 with Sender.lbTextureList do
1986 begin
1987 if Items.Count > 0 then
1988 for a := Items.Count-1 downto 0 do
1989 if not IsSpecialTexture(Items[a]) then
1990 g_DeleteTexture(Items[a]);
1992 Clear();
1993 end;
1995 MapOffset.X := 0;
1996 MapOffset.Y := 0;
1997 end;
1999 procedure DrawPanels(fPanelType: Word);
2001 procedure DrawTexture(a: Integer);
2003 NoTextureID: DWORD;
2004 NW, NH: Word;
2005 begin
2006 NoTextureID := 0;
2007 NW := 0;
2008 NH := 0;
2009 with gPanels[a] do
2010 begin
2011 case TextureID of
2012 TEXTURE_SPECIAL_NONE:
2013 if PreviewMode = 0 then
2014 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2015 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2016 64, 64, 64, 127);
2018 TEXTURE_SPECIAL_NOTEXTURE:
2019 if g_GetTexture('NOTEXTURE', NoTextureID) then
2020 begin
2021 g_GetTextureSizeByID(NoTextureID, NW, NH);
2022 e_DrawFill(NoTextureID, X+MapOffset.X, Y+MapOffset.Y,
2023 Width div NW, Height div NH, 0, False, False);
2024 end;
2026 TEXTURE_SPECIAL_WATER:
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 0, 0, 255, 0, B_FILTER)
2031 else
2032 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2033 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2034 0, 0, 255, 127);
2036 TEXTURE_SPECIAL_ACID1:
2037 if PreviewMode > 0 then
2038 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2039 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2040 0, 127, 0, 0, B_FILTER)
2041 else
2042 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2043 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2044 0, 255, 0, 127);
2046 TEXTURE_SPECIAL_ACID2:
2047 if PreviewMode > 0 then
2048 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2049 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2050 127, 0, 0, 0, B_FILTER)
2051 else
2052 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2053 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2054 255, 0, 0, 127);
2056 else
2057 e_DrawFill(TextureID, X+MapOffset.X, Y+MapOffset.Y,
2058 Width div TextureWidth, Height div TextureHeight,
2059 Alpha, True, Blending);
2060 end;
2061 end;
2062 end;
2065 a: Integer;
2066 begin
2067 if gPanels <> nil then
2068 for a := 0 to High(gPanels) do
2069 if (gPanels[a].PanelType <> 0) and
2070 WordBool(gPanels[a].PanelType and fPanelType) then
2071 with gPanels[a] do
2072 begin
2073 if (TextureID < TEXTURE_SPECIAL_NOTEXTURE) and (TextureWidth = 0) and (TextureWidth = 0) then
2074 TextureID := TEXTURE_SPECIAL_NOTEXTURE;
2075 case PanelType of
2076 PANEL_WALL, PANEL_BACK, PANEL_FORE,
2077 PANEL_LADDER, PANEL_OPENDOOR, PANEL_CLOSEDOOR,
2078 PANEL_WATER, PANEL_ACID1, PANEL_ACID2:
2079 DrawTexture(a);
2081 PANEL_LIFTUP:
2082 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2083 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2084 128, 64, 0, 0);
2085 PANEL_LIFTDOWN:
2086 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2087 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2088 90, 154, 138, 0);
2089 PANEL_LIFTLEFT:
2090 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2091 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2092 200, 80, 4, 0);
2093 PANEL_LIFTRIGHT:
2094 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2095 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2096 252, 140, 56, 0);
2097 PANEL_BLOCKMON:
2098 e_DrawFillQuad(X+MapOffset.X, Y+MapOffset.Y,
2099 X+MapOffset.X+Width-1, Y+MapOffset.Y+Height-1,
2100 192, 0, 192, 0);
2101 end;
2102 end;
2103 end;
2105 procedure DrawContours (fPanelType: Word);
2106 var i, xx, yy, ww, hh: Integer;
2107 begin
2108 if gPanels <> nil then
2109 for i := 0 to High(gPanels) do
2110 if (gPanels[i].PanelType <> 0) and WordBool(gPanels[i].PanelType and fPanelType) then
2111 begin
2112 xx := gPanels[i].X + MapOffset.X;
2113 yy := gPanels[i].Y + MapOffset.Y;
2114 ww := gPanels[i].X + MapOffset.X + gPanels[i].Width - 1;
2115 hh := gPanels[i].Y + MapOffset.Y + gPanels[i].Height - 1;
2116 case gPanels[i].PanelType of
2117 PANEL_NONE: ;
2118 PANEL_WALL: e_DrawQuad(xx, yy, ww, hh, 208, 208, 208, 0);
2119 PANEL_BACK: e_DrawQuad(xx, yy, ww, hh, 64, 64, 64, 0);
2120 PANEL_FORE: e_DrawQuad(xx, yy, ww, hh, 128, 128, 128, 0);
2121 PANEL_WATER: e_DrawQuad(xx, yy, ww, hh, 0, 0, 192, 0);
2122 PANEL_ACID1: e_DrawQuad(xx, yy, ww, hh, 0, 176, 0, 0);
2123 PANEL_ACID2: e_DrawQuad(xx, yy, ww, hh, 176, 0, 0, 0);
2124 PANEL_LADDER: e_DrawQuad(xx, yy, ww, hh, 128, 128, 128, 0);
2125 PANEL_LIFTUP: e_DrawQuad(xx, yy, ww, hh, 116, 72, 36, 0);
2126 PANEL_LIFTDOWN: e_DrawQuad(xx, yy, ww, hh, 116, 124, 96, 0);
2127 PANEL_OPENDOOR: e_DrawQuad(xx, yy, ww, hh, 100, 220, 92, 0);
2128 PANEL_CLOSEDOOR: e_DrawQuad(xx, yy, ww, hh, 212, 184, 64, 0);
2129 PANEL_BLOCKMON: e_DrawQuad(xx, yy, ww, hh, 192, 0, 192, 0);
2130 PANEL_LIFTLEFT: e_DrawQuad(xx, yy, ww, hh, 200, 80, 4, 0);
2131 PANEL_LIFTRIGHT: e_DrawQuad(xx, yy, ww, hh, 252, 140, 56, 0);
2132 else
2133 assert(false)
2134 end;
2135 end;
2136 end;
2138 procedure DrawMap();
2140 a, w, h: Integer;
2141 ID: DWORD;
2142 xx, yy, dx, dy: Integer;
2143 ww, hh: Word;
2144 sel: Boolean;
2145 r: TRectWH;
2146 mask: Word;
2147 begin
2148 ID := 0;
2149 // В режиме Превью рисуем небо:
2150 if PreviewMode > 0 then
2151 begin
2152 w := Max(MainForm.RenderPanel.Width, MainForm.RenderPanel.Height);
2153 if MainForm.RenderPanel.Height > MainForm.RenderPanel.Width*3/4 then
2154 w := Round(w*4/3);
2155 h := Round(w*3/4);
2157 if g_GetTexture(SKY_TEXTURE, ID) then
2158 e_DrawSize(ID, 0, 0, 0, False, False, w, h)
2159 else
2160 e_DrawFillQuad(0, 0, w-1, h-1, 0, 0, 0, 0, B_NONE);
2161 end;
2163 // Рисуем панели (если Превью или если включен слой):
2164 if MainForm.miLayerBackground.Checked or (PreviewMode = 1) then
2165 DrawPanels(PANEL_BACK);
2166 if PreviewMode = 0 then
2167 begin
2168 if MainForm.miLayerStreams.Checked then
2169 DrawPanels(PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT);
2170 if MainForm.miLayerZones.Checked then
2171 DrawPanels(PANEL_BLOCKMON);
2172 end;
2173 if MainForm.miLayerDoors.Checked or (PreviewMode = 1) then
2174 DrawPanels(PANEL_OPENDOOR or PANEL_CLOSEDOOR);
2175 if MainForm.miLayerWalls.Checked or (PreviewMode = 1) then
2176 DrawPanels(PANEL_WALL);
2177 if MainForm.miLayerLadders.Checked or (PreviewMode = 1) then
2178 DrawPanels(PANEL_LADDER);
2180 // Рисуем предметы:
2181 if (MainForm.miLayerItems.Checked or (PreviewMode = 1)) and
2182 (gItems <> nil) then
2183 for a := 0 to High(gItems) do
2184 if gItems[a].ItemType <> ITEM_NONE then
2185 with gItems[a] do
2186 begin
2187 ID := DWORD(-1);
2189 case ItemType of
2190 0: Continue;
2191 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2192 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2193 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2194 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2195 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2196 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2197 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2198 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2199 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2200 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2201 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2202 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2203 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2204 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2205 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2206 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2207 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2208 ITEM_WEAPON_SUPERCHAINGUN: g_GetTexture('ITEM_WEAPON_SUPERCHAINGUN', ID);
2209 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2210 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2211 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2212 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2213 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2214 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2215 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2216 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2217 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2218 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2219 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2220 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2221 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2222 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2223 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2224 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2225 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2226 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2227 end;
2229 if ID <> DWORD(-1) then
2230 e_Draw(ID, MapOffset.X+X, MapOffset.Y+Y, 0, True, False);
2231 end;
2233 // Рисуем монстров:
2234 if (MainForm.miLayerMonsters.Checked or (PreviewMode = 1)) and
2235 (gMonsters <> nil) then
2236 for a := 0 to High(gMonsters) do
2237 if gMonsters[a].MonsterType <> MONSTER_NONE then
2238 with MonsterSize[gMonsters[a].MonsterType] do
2239 begin
2240 ID := DWORD(-1);
2241 sel := ObjectSelected(OBJECT_MONSTER, a);
2243 case gMonsters[a].MonsterType of
2244 0: Continue;
2245 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2246 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2247 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2248 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2249 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2250 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2251 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2252 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2253 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2254 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2255 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2256 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2257 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2258 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2259 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2260 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2261 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2262 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2263 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2264 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2265 end;
2267 if ID <> DWORD(-1) then
2268 if gMonsters[a].Direction = D_LEFT then
2269 begin
2270 // Расстояние от края текстуры до края визуального положения объекта на текстуре:
2271 xx := (X - MonsterSizeDelta[gMonsters[a].MonsterType].X) + Width;
2272 // Расстояние от края хит бокса до края визуального положения объекта на текстуре:
2273 xx := MonsterSizeDelta[gMonsters[a].MonsterType].Width - xx - X;
2274 // Т.к. двигать текстуру нужно будет в противоположном направлении:
2275 xx := (gMonsters[a].X - X) - xx;
2277 yy := (gMonsters[a].Y - Y) +
2278 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2280 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2281 0, True, False, M_HORIZONTAL);
2283 else
2284 begin
2285 // Левый верхний угол текстуры + смещение анимации:
2286 xx := (gMonsters[a].X - X) +
2287 MonsterSizeDelta[gMonsters[a].MonsterType].X;
2288 yy := (gMonsters[a].Y - Y) +
2289 MonsterSizeDelta[gMonsters[a].MonsterType].Y;
2291 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2292 0, True, False);
2293 end;
2295 // Рамка:
2296 if PreviewMode = 0 then
2297 begin
2298 e_DrawQuad(MapOffset.X+gMonsters[a].X, MapOffset.Y+gMonsters[a].Y,
2299 MapOffset.X+gMonsters[a].X+Width-1, MapOffset.Y+gMonsters[a].Y+Height-1,
2300 255, 255, 255, IfThen(sel, 0, gAlphaMonsterRect));
2301 end;
2302 end;
2304 // Рисуем закрытые двери после монстров:
2305 if (PreviewMode = 1) or ((PreviewMode = 2) and MainForm.miLayerDoors.Checked) then
2306 DrawPanels(PANEL_CLOSEDOOR);
2308 // Рисуем области:
2309 if (MainForm.miLayerAreas.Checked or (PreviewMode = 1)) and
2310 (gAreas <> nil) then
2311 for a := 0 to High(gAreas) do
2312 if gAreas[a].AreaType <> AREA_NONE then
2313 with AreaSize[gAreas[a].AreaType] do
2314 begin
2315 ID := DWORD(-1);
2316 sel := ObjectSelected(OBJECT_AREA, a);
2318 case gAreas[a].AreaType of
2319 AREA_PLAYERPOINT1: g_GetTexture('AREA_PLAYERPOINT1', ID);
2320 AREA_PLAYERPOINT2: g_GetTexture('AREA_PLAYERPOINT2', ID);
2321 AREA_DMPOINT: g_GetTexture('AREA_DMPOINT', ID);
2322 AREA_REDFLAG: g_GetTexture('AREA_REDFLAG', ID);
2323 AREA_BLUEFLAG: g_GetTexture('AREA_BLUEFLAG', ID);
2324 AREA_DOMFLAG: g_GetTexture('AREA_DOMFLAG', ID);
2325 AREA_REDTEAMPOINT: g_GetTexture('AREA_REDPOINT', ID);
2326 AREA_BLUETEAMPOINT: g_GetTexture('AREA_BLUEPOINT', ID);
2327 end;
2329 if (PreviewMode = 0) or
2330 (gAreas[a].AreaType = AREA_REDFLAG) or
2331 (gAreas[a].AreaType = AREA_BLUEFLAG) or
2332 (gAreas[a].AreaType = AREA_DOMFLAG) then
2333 if ID <> DWORD(-1) then
2334 if gAreas[a].Direction = D_LEFT then
2335 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2336 0, True, False, M_HORIZONTAL)
2337 else
2338 e_Draw(ID, MapOffset.X+gAreas[a].X-X, MapOffset.Y+gAreas[a].Y-Y,
2339 0, True, False);
2341 // Рамка:
2342 if PreviewMode = 0 then
2343 begin
2344 e_DrawQuad(MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y,
2345 MapOffset.X+gAreas[a].X+Width-1, MapOffset.Y+gAreas[a].Y+Height-1,
2346 255, 255, 255, IfThen(sel, 0, gAlphaAreaRect));
2348 e_DrawPoint(2, MapOffset.X+gAreas[a].X, MapOffset.Y+gAreas[a].Y, 255, 0, 0);
2349 end;
2350 end;
2352 // Рисуем жидкости и передний план после областей:
2353 if MainForm.miLayerLiquids.Checked or (PreviewMode = 1) then
2354 DrawPanels(PANEL_WATER or PANEL_ACID1 or PANEL_ACID2);
2355 if MainForm.miLayerForeground.Checked or (PreviewMode = 1) then
2356 DrawPanels(PANEL_FORE);
2358 // Рисуем триггеры:
2359 if MainForm.miLayerTriggers.Checked and
2360 (PreviewMode = 0) and (gTriggers <> nil) then
2361 for a := 0 to High(gTriggers) do
2362 with gTriggers[a] do
2363 if TriggerType <> TRIGGER_NONE then
2364 begin
2365 // Если выбран - рисуем красным, иначе - белым:
2366 sel := ObjectSelected(OBJECT_TRIGGER, a);
2368 e_DrawFillQuad(MapOffset.X+X, MapOffset.Y+Y,
2369 MapOffset.X+X+Width-1, MapOffset.Y+Y+Height-1,
2370 0, 0, 0, 150);
2372 if TexturePanel <> -1 then
2373 begin
2374 with gPanels[TexturePanel] do
2375 begin
2376 xx := X;
2377 yy := Y;
2378 ww := Width;
2379 hh := Height;
2380 end;
2382 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2383 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2384 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2385 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2386 MapOffset.X+xx, MapOffset.Y+yy,
2387 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2388 end;
2390 case TriggerType of
2391 TRIGGER_EXIT, TRIGGER_SECRET: ;
2393 TRIGGER_TELEPORT:
2394 begin
2395 // Точка назначения Телепорта:
2396 if Data.d2d_teleport then
2397 e_DrawLine(2, MapOffset.X+Data.TargetPoint.X-16,
2398 MapOffset.Y+Data.TargetPoint.Y-1,
2399 MapOffset.X+Data.TargetPoint.X+16, MapOffset.Y+Data.TargetPoint.Y-1,
2400 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea))
2401 else
2402 e_DrawQuad(MapOffset.X+Data.TargetPoint.X,
2403 MapOffset.Y+Data.TargetPoint.Y,
2404 MapOffset.X+Data.TargetPoint.X+AreaSize[AREA_DMPOINT].Width-1,
2405 MapOffset.Y+Data.TargetPoint.Y+AreaSize[AREA_DMPOINT].Height-1,
2406 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2407 e_DrawPoint(2, MapOffset.X+Data.TargetPoint.X,
2408 MapOffset.Y+Data.TargetPoint.Y,
2409 255, 0, 0);
2410 // Линия к точке назначения Телепорта:
2411 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2412 MapOffset.Y+Y+(Height div 2),
2413 MapOffset.X+Data.TargetPoint.X,
2414 MapOffset.Y+Data.TargetPoint.Y,
2415 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2416 end;
2418 TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR,
2419 TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP,
2420 TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN,
2421 TRIGGER_LIFT:
2422 if Data.PanelID <> -1 then
2423 begin
2424 // Дверь/Ловушка/Лифт:
2425 e_DrawQuad(MapOffset.X+gPanels[Data.PanelID].X,
2426 MapOffset.Y+gPanels[Data.PanelID].Y,
2427 MapOffset.X+gPanels[Data.PanelID].X+gPanels[Data.PanelID].Width-1,
2428 MapOffset.Y+gPanels[Data.PanelID].Y+gPanels[Data.PanelID].Height-1,
2429 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2430 e_DrawPoint(2, MapOffset.X+gPanels[Data.PanelID].X,
2431 MapOffset.Y+gPanels[Data.PanelID].Y,
2432 255, 0, 0);
2433 // Линия к Двери/Ловушке/Лифту:
2434 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2435 MapOffset.Y+Y+(Height div 2),
2436 MapOffset.X+gPanels[Data.PanelID].X,
2437 MapOffset.Y+gPanels[Data.PanelID].Y,
2438 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2439 end;
2441 TRIGGER_PRESS, TRIGGER_ON,
2442 TRIGGER_OFF, TRIGGER_ONOFF:
2443 begin
2444 if (Data.tWidth > 0) and
2445 (Data.tHeight > 0) then
2446 begin
2447 // Область Расширителя:
2448 e_DrawQuad(MapOffset.X+Data.tX,
2449 MapOffset.Y+Data.tY,
2450 MapOffset.X+Data.tX+Data.tWidth-1,
2451 MapOffset.Y+Data.tY+Data.tHeight-1,
2452 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2453 e_DrawPoint(2, MapOffset.X+Data.tX,
2454 MapOffset.Y+Data.tY,
2455 255, 0, 0);
2456 // Линия к области Расширителя:
2457 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2458 MapOffset.Y+Y+(Height div 2),
2459 MapOffset.X+Data.tX,
2460 MapOffset.Y+Data.tY,
2461 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2462 end;
2464 if Data.MonsterID <> 0 then
2465 if (gMonsters <> nil) and
2466 (gMonsters[Data.MonsterID-1].MonsterType <> MONSTER_NONE) then
2467 begin
2468 // Рамка вокруг Монстра - условия активации:
2469 r := ObjectGetRect(OBJECT_MONSTER, Data.MonsterID-1);
2470 e_DrawQuad(MapOffset.X+r.X,
2471 MapOffset.Y+r.Y,
2472 MapOffset.X+r.X+r.Width-1,
2473 MapOffset.Y+r.Y+r.Height-1,
2474 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2475 // Линия к Монстру - условию активации:
2476 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2477 MapOffset.Y+Y+(Height div 2),
2478 MapOffset.X+r.X,
2479 MapOffset.Y+r.Y,
2480 0, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2482 end;
2483 end;
2485 TRIGGER_SPAWNMONSTER, TRIGGER_SPAWNITEM:
2486 begin
2487 if TriggerType = TRIGGER_SPAWNMONSTER then
2488 begin
2489 xx := Data.MonPos.X;
2490 yy := Data.MonPos.Y;
2492 else
2493 begin
2494 xx := Data.ItemPos.X;
2495 yy := Data.ItemPos.Y;
2496 end;
2497 // Точка появления Монстра/Предмета:
2498 e_DrawLine(2, MapOffset.X+xx-16,
2499 MapOffset.Y+yy-1,
2500 MapOffset.X+xx+16,
2501 MapOffset.Y+yy-1,
2502 0, 0, 255, IfThen(sel, 0, gAlphaTriggerArea));
2503 e_DrawPoint(2, MapOffset.X+xx,
2504 MapOffset.Y+yy,
2505 255, 0, 0);
2506 // Линия к точке появления Монстра/Предмета:
2507 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2508 MapOffset.Y+Y+(Height div 2),
2509 MapOffset.X+xx,
2510 MapOffset.Y+yy,
2511 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2512 // Предпросмотр создаваемого объекта:
2513 if sel then
2514 begin
2515 // Монстр:
2516 if TriggerType = TRIGGER_SPAWNMONSTER then
2517 begin
2518 if Data.MonType <> MONSTER_NONE then
2519 with MonsterSize[Data.MonType] do
2520 begin
2521 ID := DWORD(-1);
2522 case Data.MonType of
2523 MONSTER_DEMON: g_GetTexture('MONSTER_DEMON', ID);
2524 MONSTER_IMP: g_GetTexture('MONSTER_IMP', ID);
2525 MONSTER_ZOMBY: g_GetTexture('MONSTER_ZOMBY', ID);
2526 MONSTER_SERG: g_GetTexture('MONSTER_SERG', ID);
2527 MONSTER_CYBER: g_GetTexture('MONSTER_CYBER', ID);
2528 MONSTER_CGUN: g_GetTexture('MONSTER_CGUN', ID);
2529 MONSTER_BARON: g_GetTexture('MONSTER_BARON', ID);
2530 MONSTER_KNIGHT: g_GetTexture('MONSTER_KNIGHT', ID);
2531 MONSTER_CACO: g_GetTexture('MONSTER_CACO', ID);
2532 MONSTER_SOUL: g_GetTexture('MONSTER_SOUL', ID);
2533 MONSTER_PAIN: g_GetTexture('MONSTER_PAIN', ID);
2534 MONSTER_SPIDER: g_GetTexture('MONSTER_SPIDER', ID);
2535 MONSTER_BSP: g_GetTexture('MONSTER_BSP', ID);
2536 MONSTER_MANCUB: g_GetTexture('MONSTER_MANCUB', ID);
2537 MONSTER_SKEL: g_GetTexture('MONSTER_SKEL', ID);
2538 MONSTER_VILE: g_GetTexture('MONSTER_VILE', ID);
2539 MONSTER_FISH: g_GetTexture('MONSTER_FISH', ID);
2540 MONSTER_BARREL: g_GetTexture('MONSTER_BARREL', ID);
2541 MONSTER_ROBO: g_GetTexture('MONSTER_ROBO', ID);
2542 MONSTER_MAN: g_GetTexture('MONSTER_MAN', ID);
2543 end;
2544 if ID <> DWORD(-1) then
2545 begin
2546 if Data.MonDir = Byte(D_LEFT) then
2547 begin
2548 xx := X - MonsterSizeDelta[Data.MonType].X + Width;
2549 xx := MonsterSizeDelta[Data.MonType].Width - xx - X;
2550 xx := Data.TargetPoint.X - X - xx - (Width div 2);
2552 yy := Data.TargetPoint.Y - Y +
2553 MonsterSizeDelta[Data.MonType].Y-Height;
2555 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2556 128, True, False, M_HORIZONTAL);
2558 else
2559 begin
2560 xx := Data.TargetPoint.X - X +
2561 MonsterSizeDelta[Data.MonType].X-(Width div 2);
2562 yy := Data.TargetPoint.Y - Y +
2563 MonsterSizeDelta[Data.MonType].Y-Height;
2565 e_Draw(ID, MapOffset.X + xx, MapOffset.Y + yy,
2566 128, True, False);
2567 end;
2568 // Рамка:
2569 e_DrawQuad(MapOffset.X+Data.TargetPoint.X-(Width div 2), MapOffset.Y+Data.TargetPoint.Y-Height,
2570 MapOffset.X+Data.TargetPoint.X+(Width div 2)-1, MapOffset.Y+Data.TargetPoint.Y-1,
2571 255, 255, 0, 128);
2572 end;
2573 end;
2575 else
2576 // Предмет:
2577 begin
2578 if Data.ItemType <> ITEM_NONE then
2579 begin
2580 ID := DWORD(-1);
2581 case Data.ItemType of
2582 ITEM_MEDKIT_SMALL: g_GetTexture('ITEM_MEDKIT_SMALL', ID);
2583 ITEM_MEDKIT_LARGE: g_GetTexture('ITEM_MEDKIT_LARGE', ID);
2584 ITEM_MEDKIT_BLACK: g_GetTexture('ITEM_MEDKIT_BLACK', ID);
2585 ITEM_ARMOR_GREEN: g_GetTexture('ITEM_ARMORGREEN', ID);
2586 ITEM_ARMOR_BLUE: g_GetTexture('ITEM_ARMORBLUE', ID);
2587 ITEM_SPHERE_BLUE: g_GetTexture('ITEM_BLUESPHERE', ID);
2588 ITEM_SPHERE_WHITE: g_GetTexture('ITEM_WHITESPHERE', ID);
2589 ITEM_SUIT: g_GetTexture('ITEM_SUIT', ID);
2590 ITEM_OXYGEN: g_GetTexture('ITEM_OXYGEN', ID);
2591 ITEM_INVUL: g_GetTexture('ITEM_INVUL', ID);
2592 ITEM_WEAPON_SAW: g_GetTexture('ITEM_WEAPON_SAW', ID);
2593 ITEM_WEAPON_SHOTGUN1: g_GetTexture('ITEM_WEAPON_SHOTGUN1', ID);
2594 ITEM_WEAPON_SHOTGUN2: g_GetTexture('ITEM_WEAPON_SHOTGUN2', ID);
2595 ITEM_WEAPON_CHAINGUN: g_GetTexture('ITEM_WEAPON_CHAINGUN', ID);
2596 ITEM_WEAPON_ROCKETLAUNCHER: g_GetTexture('ITEM_WEAPON_ROCKETLAUNCHER', ID);
2597 ITEM_WEAPON_PLASMA: g_GetTexture('ITEM_WEAPON_PLASMA', ID);
2598 ITEM_WEAPON_BFG: g_GetTexture('ITEM_WEAPON_BFG', ID);
2599 ITEM_WEAPON_SUPERCHAINGUN: g_GetTexture('ITEM_WEAPON_SUPERCHAINGUN', ID);
2600 ITEM_AMMO_BULLETS: g_GetTexture('ITEM_AMMO_BULLETS', ID);
2601 ITEM_AMMO_BULLETS_BOX: g_GetTexture('ITEM_AMMO_BULLETS_BOX', ID);
2602 ITEM_AMMO_SHELLS: g_GetTexture('ITEM_AMMO_SHELLS', ID);
2603 ITEM_AMMO_SHELLS_BOX: g_GetTexture('ITEM_AMMO_SHELLS_BOX', ID);
2604 ITEM_AMMO_ROCKET: g_GetTexture('ITEM_AMMO_ROCKET', ID);
2605 ITEM_AMMO_ROCKET_BOX: g_GetTexture('ITEM_AMMO_ROCKET_BOX', ID);
2606 ITEM_AMMO_CELL: g_GetTexture('ITEM_AMMO_CELL', ID);
2607 ITEM_AMMO_CELL_BIG: g_GetTexture('ITEM_AMMO_CELL_BIG', ID);
2608 ITEM_AMMO_BACKPACK: g_GetTexture('ITEM_AMMO_BACKPACK', ID);
2609 ITEM_KEY_RED: g_GetTexture('ITEM_KEY_RED', ID);
2610 ITEM_KEY_GREEN: g_GetTexture('ITEM_KEY_GREEN', ID);
2611 ITEM_KEY_BLUE: g_GetTexture('ITEM_KEY_BLUE', ID);
2612 ITEM_BOTTLE: g_GetTexture('ITEM_BOTTLE', ID);
2613 ITEM_HELMET: g_GetTexture('ITEM_HELMET', ID);
2614 ITEM_JETPACK: g_GetTexture('ITEM_JETPACK', ID);
2615 ITEM_INVIS: g_GetTexture('ITEM_INVIS', ID);
2616 ITEM_WEAPON_FLAMETHROWER: g_GetTexture('ITEM_WEAPON_FLAMETHROWER', ID);
2617 ITEM_AMMO_FUELCAN: g_GetTexture('ITEM_AMMO_FUELCAN', ID);
2618 end;
2619 if ID <> DWORD(-1) then
2620 e_Draw(ID, MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2),
2621 MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2622 128, True, False);
2623 // Рамка:
2624 e_DrawQuad(MapOffset.X+Data.ItemPos.X-(ItemSize[Data.ItemType][0] div 2), MapOffset.Y+Data.ItemPos.Y-ItemSize[Data.ItemType][1],
2625 MapOffset.X+Data.ItemPos.X+(ItemSize[Data.ItemType][0] div 2)-1, MapOffset.Y+Data.ItemPos.Y-1,
2626 255, 255, 0, 128);
2627 end;
2628 end;
2629 end;
2630 end;
2632 TRIGGER_PUSH:
2633 begin
2634 // Линия направления и силы ускорения:
2635 xx := Round(Cos(-DegToRad(Data.PushAngle)) * Data.PushForce) + X+(Width div 2);
2636 yy := Round(Sin(-DegToRad(Data.PushAngle)) * Data.PushForce) + Y+(Height div 2);
2637 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2638 MapOffset.Y+Y+(Height div 2),
2639 MapOffset.X+xx,
2640 MapOffset.Y+yy,
2641 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2642 end;
2644 TRIGGER_SHOT:
2645 begin;
2646 xx := Data.ShotPos.X;
2647 yy := Data.ShotPos.Y;
2648 // Точка появления снаряда:
2649 e_DrawPoint(2, MapOffset.X+xx,
2650 MapOffset.Y+yy,
2651 255, 0, 0);
2652 // Линия к точке появления снаряда:
2653 e_DrawLine(1, MapOffset.X+X+(Width div 2),
2654 MapOffset.Y+Y+(Height div 2),
2655 MapOffset.X+xx,
2656 MapOffset.Y+yy,
2657 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2658 // Линия направления выстрела:
2659 dx := Round(Cos(-DegToRad(Data.ShotAngle)) * 24);
2660 dy := Round(Sin(-DegToRad(Data.ShotAngle)) * 24);
2661 e_DrawLine(1, MapOffset.X+xx,
2662 MapOffset.Y+yy,
2663 MapOffset.X+xx+dx,
2664 MapOffset.Y+yy+dy,
2665 255, 255, 255, IfThen(sel, 0, gAlphaTriggerLine));
2667 if (Data.ShotPanelID <> -1) and
2668 (Data.ShotPanelID <= High(gPanels)) then
2669 begin
2670 // Линия к панели индикации выстрела
2671 with gPanels[Data.ShotPanelID] do
2672 begin
2673 xx := X;
2674 yy := Y;
2675 ww := Width;
2676 hh := Height;
2677 end;
2679 e_DrawQuad(MapOffset.X+xx, MapOffset.Y+yy,
2680 MapOffset.X+xx+ww-1, MapOffset.Y+yy+hh-1,
2681 255, 255, 255, IfThen(sel, 0, gAlphaTriggerArea));
2682 e_DrawLine(1, MapOffset.X+X+(Width div 2), MapOffset.Y+Y+(Height div 2),
2683 MapOffset.X+xx, MapOffset.Y+yy,
2684 255, 255, 0, IfThen(sel, 0, gAlphaTriggerArea));
2685 end;
2686 end;
2687 end;
2688 end;
2690 // Draw panel contours
2691 mask := 0;
2692 if QWordBool(MainForm.miLayerBackground.Tag) then
2693 mask := mask or PANEL_BACK;
2694 if QWordBool(MainForm.miLayerDoors.Tag) then
2695 mask := mask or PANEL_OPENDOOR or PANEL_CLOSEDOOR;
2696 if QWordBool(MainForm.miLayerWalls.Tag) then
2697 mask := mask or PANEL_WALL;
2698 if QWordBool(MainForm.miLayerForeground.Tag) then
2699 mask := mask or PANEL_FORE;
2700 if QWordBool(MainForm.miLayerStreams.Tag) then
2701 mask := mask or PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT;
2702 if QWordBool(MainForm.miLayerZones.Tag) then
2703 mask := mask or PANEL_BLOCKMON;
2704 if QWordBool(MainForm.miLayerLadders.Tag) then
2705 mask := mask or PANEL_LADDER;
2706 if QWordBool(MainForm.miLayerLiquids.Tag) then
2707 mask := mask or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2;
2708 if mask <> 0 then
2709 DrawContours(mask);
2710 if QWordBool(MainForm.miLayerItems.Tag) and (gItems <> nil) then
2711 for a := 0 to High(gItems) do
2712 if gItems[a].ItemType <> ITEM_NONE then
2713 e_DrawQuad(
2714 MapOffset.X + gItems[a].X,
2715 MapOffset.Y + gItems[a].Y,
2716 MapOffset.X + gItems[a].X + ItemSize[gItems[a].ItemType, 0] - 1,
2717 MapOffset.Y + gItems[a].Y + ItemSize[gItems[a].ItemType, 1] - 1,
2718 0, 255, 255
2720 if QWordBool(MainForm.miLayerMonsters.Tag) and (gMonsters <> nil) then
2721 for a := 0 to High(gMonsters) do
2722 if gMonsters[a].MonsterType <> MONSTER_NONE then
2723 e_DrawQuad(
2724 MapOffset.X + gMonsters[a].X,
2725 MapOffset.Y + gMonsters[a].Y,
2726 MapOffset.X + gMonsters[a].X + MonsterSize[gMonsters[a].MonsterType].Width - 1,
2727 MapOffset.Y + gMonsters[a].Y + MonsterSize[gMonsters[a].MonsterType].Height - 1,
2728 200, 0, 0
2730 if QWordBool(MainForm.miLayerAreas.Tag) and (gAreas <> nil) then
2731 for a := 0 to High(gAreas) do
2732 if gAreas[a].AreaType <> AREA_NONE then
2733 e_DrawQuad(
2734 MapOffset.X + gAreas[a].X,
2735 MapOffset.Y + gAreas[a].Y,
2736 MapOffset.X + gAreas[a].X + AreaSize[gAreas[a].AreaType].Width - 1,
2737 MapOffset.Y + gAreas[a].Y + AreaSize[gAreas[a].AreaType].Height - 1,
2738 0, 255, 255
2740 if QWordBool(MainForm.miLayerTriggers.Tag) and (gTriggers <> nil) then
2741 for a := 0 to High(gTriggers) do
2742 if gTriggers[a].TriggerType <> TRIGGER_NONE then
2743 e_DrawQuad(
2744 MapOffset.X + gTriggers[a].X,
2745 MapOffset.Y + gTriggers[a].Y,
2746 MapOffset.X + gTriggers[a].X + gTriggers[a].Width - 1,
2747 MapOffset.Y + gTriggers[a].Y + gTriggers[a].Height - 1,
2748 255, 255, 0
2751 // Границы карты:
2752 if PreviewMode = 0 then
2753 begin
2754 e_DrawFillQuad(0,
2756 MainForm.RenderPanel.Width,
2757 -1 + MapOffset.Y,
2758 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Top
2759 e_DrawFillQuad(0,
2760 gMapInfo.Height + MapOffset.Y,
2761 MainForm.RenderPanel.Width,
2762 MainForm.RenderPanel.Height,
2763 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Bottom
2764 e_DrawFillQuad(0,
2765 MapOffset.Y,
2766 -1 + MapOffset.X,
2767 gMapInfo.Height + MapOffset.Y - 1,
2768 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Left
2769 e_DrawFillQuad(gMapInfo.Width + MapOffset.X,
2770 MapOffset.Y,
2771 MainForm.RenderPanel.Width,
2772 gMapInfo.Height + MapOffset.Y - 1,
2773 drEdge[0], drEdge[1], drEdge[2], drEdge[3], B_NONE); // Right
2774 end;
2775 end;
2777 procedure ShiftMapObjects(dx, dy: Integer);
2779 i: Integer;
2780 begin
2781 if gPanels <> nil then
2782 for i := 0 to High(gPanels) do
2783 if gPanels[i].PanelType <> 0 then
2784 begin
2785 Inc(gPanels[i].X, dx);
2786 Inc(gPanels[i].Y, dy);
2787 end;
2789 if gItems <> nil then
2790 for i := 0 to High(gItems) do
2791 if gItems[i].ItemType <> 0 then
2792 begin
2793 Inc(gItems[i].X, dx);
2794 Inc(gItems[i].Y, dy);
2795 end;
2797 if gAreas <> nil then
2798 for i := 0 to High(gAreas) do
2799 if gAreas[i].AreaType <> 0 then
2800 begin
2801 Inc(gAreas[i].X, dx);
2802 Inc(gAreas[i].Y, dy);
2803 end;
2805 if gMonsters <> nil then
2806 for i := 0 to High(gMonsters) do
2807 if gMonsters[i].MonsterType <> 0 then
2808 begin
2809 Inc(gMonsters[i].X, dx);
2810 Inc(gMonsters[i].Y, dy);
2811 end;
2813 if gTriggers <> nil then
2814 for i := 0 to High(gTriggers) do
2815 if gTriggers[i].TriggerType <> 0 then
2816 begin
2817 Inc(gTriggers[i].X, dx);
2818 Inc(gTriggers[i].Y, dy);
2820 case gTriggers[i].TriggerType of
2821 TRIGGER_TELEPORT:
2822 begin
2823 Inc(gTriggers[i].Data.TargetPoint.X, dx);
2824 Inc(gTriggers[i].Data.TargetPoint.Y, dy);
2825 end;
2827 TRIGGER_PRESS, TRIGGER_ON,
2828 TRIGGER_OFF, TRIGGER_ONOFF:
2829 begin
2830 Inc(gTriggers[i].Data.tX, dx);
2831 Inc(gTriggers[i].Data.tY, dy);
2832 end;
2834 TRIGGER_SPAWNMONSTER:
2835 begin
2836 Inc(gTriggers[i].Data.MonPos.X, dx);
2837 Inc(gTriggers[i].Data.MonPos.Y, dy);
2838 end;
2840 TRIGGER_SPAWNITEM:
2841 begin
2842 Inc(gTriggers[i].Data.ItemPos.X, dx);
2843 Inc(gTriggers[i].Data.ItemPos.Y, dy);
2844 end;
2846 TRIGGER_SHOT:
2847 begin
2848 Inc(gTriggers[i].Data.ShotPos.X, dx);
2849 Inc(gTriggers[i].Data.ShotPos.Y, dy);
2850 end;
2851 end;
2852 end;
2853 end;
2855 procedure LoadData();
2856 begin
2857 g_CreateTextureWAD('PREVIEW', EditorWad + ':TEXTURES\CHECKERS');
2858 g_CreateTextureWAD('NOTEXTURE', GameWad + ':TEXTURES\NOTEXTURE');
2860 g_CreateTextureWADSize('AREA_REDFLAG', GameWad + ':TEXTURES\FLAGRED', 0, 0, 64, 64);
2861 g_CreateTextureWADSize('AREA_BLUEFLAG', GameWad + ':TEXTURES\FLAGBLUE', 0, 0, 64, 64);
2862 g_CreateTextureWADSize('AREA_DOMFLAG', GameWad + ':TEXTURES\FLAGDOM', 0, 0, 64, 64);
2864 g_CreateTextureWADSize('MONSTER_DEMON', GameWad + ':MTEXTURES\DEMON_SLEEP', 0, 0, 64, 64);
2865 g_CreateTextureWADSize('MONSTER_IMP', GameWad + ':MTEXTURES\IMP_SLEEP', 0, 0, 64, 64);
2866 g_CreateTextureWADSize('MONSTER_ZOMBY', GameWad + ':MTEXTURES\ZOMBY_SLEEP', 0, 0, 64, 64);
2867 g_CreateTextureWADSize('MONSTER_SERG', GameWad + ':MTEXTURES\SERG_SLEEP', 0, 0, 64, 64);
2868 g_CreateTextureWADSize('MONSTER_CYBER', GameWad + ':MTEXTURES\CYBER_SLEEP', 0, 0, 128, 128);
2869 g_CreateTextureWADSize('MONSTER_CGUN', GameWad + ':MTEXTURES\CGUN_SLEEP', 0, 0, 64, 64);
2870 g_CreateTextureWADSize('MONSTER_BARON', GameWad + ':MTEXTURES\BARON_SLEEP', 0, 0, 128, 128);
2871 g_CreateTextureWADSize('MONSTER_KNIGHT', GameWad + ':MTEXTURES\KNIGHT_SLEEP', 0, 0, 128, 128);
2872 g_CreateTextureWADSize('MONSTER_CACO', GameWad + ':MTEXTURES\CACO_SLEEP', 0, 0, 128, 128);
2873 g_CreateTextureWADSize('MONSTER_SOUL', GameWad + ':MTEXTURES\SOUL_SLEEP', 0, 0, 64, 64);
2874 g_CreateTextureWADSize('MONSTER_PAIN', GameWad + ':MTEXTURES\PAIN_SLEEP', 0, 0, 128, 128);
2875 g_CreateTextureWADSize('MONSTER_SPIDER', GameWad + ':MTEXTURES\SPIDER_SLEEP', 0, 0, 256, 128);
2876 g_CreateTextureWADSize('MONSTER_BSP', GameWad + ':MTEXTURES\BSP_SLEEP', 0, 0, 128, 64);
2877 g_CreateTextureWADSize('MONSTER_MANCUB', GameWad + ':MTEXTURES\MANCUB_SLEEP', 0, 0, 128, 128);
2878 g_CreateTextureWADSize('MONSTER_SKEL', GameWad + ':MTEXTURES\SKEL_SLEEP', 0, 0, 128, 128);
2879 g_CreateTextureWADSize('MONSTER_VILE', GameWad + ':MTEXTURES\VILE_SLEEP', 0, 0, 128, 128);
2880 g_CreateTextureWADSize('MONSTER_FISH', GameWad + ':MTEXTURES\FISH_SLEEP', 0, 0, 32, 32);
2881 g_CreateTextureWADSize('MONSTER_BARREL', GameWad + ':MTEXTURES\BARREL_SLEEP', 0, 0, 64, 64);
2882 g_CreateTextureWADSize('MONSTER_ROBO', GameWad + ':MTEXTURES\ROBO_SLEEP', 0, 0, 128, 128);
2883 g_CreateTextureWADSize('MONSTER_MAN', GameWad + ':MTEXTURES\MAN_SLEEP', 0, 0, 64, 64);
2885 g_CreateTextureWADSize('ITEM_BLUESPHERE', GameWad + ':TEXTURES\SBLUE', 0, 0, 32, 32);
2886 g_CreateTextureWADSize('ITEM_WHITESPHERE', GameWad + ':TEXTURES\SWHITE', 0, 0, 32, 32);
2887 g_CreateTextureWADSize('ITEM_ARMORGREEN', GameWad + ':TEXTURES\ARMORGREEN', 0, 0, 32, 16);
2888 g_CreateTextureWADSize('ITEM_ARMORBLUE', GameWad + ':TEXTURES\ARMORBLUE', 0, 0, 32, 16);
2889 g_CreateTextureWADSize('ITEM_INVUL', GameWad + ':TEXTURES\INVUL', 0, 0, 32, 32);
2890 g_CreateTextureWADSize('ITEM_BOTTLE', GameWad + ':TEXTURES\BOTTLE', 0, 0, 16, 32);
2891 g_CreateTextureWADSize('ITEM_HELMET', GameWad + ':TEXTURES\HELMET', 0, 0, 16, 16);
2892 g_CreateTextureWADSize('ITEM_JETPACK', GameWad + ':TEXTURES\JETPACK', 0, 0, 32, 32);
2893 g_CreateTextureWADSize('ITEM_INVIS', GameWad + ':TEXTURES\INVIS', 0, 0, 32, 32);
2894 g_CreateTextureWADSize('ITEM_WEAPON_FLAMETHROWER', GameWad + ':TEXTURES\FLAMETHROWER', 0, 0, 64, 32);
2895 g_CreateTextureWADSize('ITEM_AMMO_FUELCAN', GameWad + ':TEXTURES\FUELCAN', 0, 0, 16, 32);
2897 g_CreateTextureWAD('ITEM_MEDKIT_SMALL', GameWad + ':TEXTURES\MED1');
2898 g_CreateTextureWAD('ITEM_MEDKIT_LARGE', GameWad + ':TEXTURES\MED2');
2899 g_CreateTextureWAD('ITEM_WEAPON_SAW', GameWad + ':TEXTURES\SAW');
2900 g_CreateTextureWAD('ITEM_WEAPON_PISTOL', GameWad + ':TEXTURES\PISTOL');
2901 g_CreateTextureWAD('ITEM_WEAPON_IRONFIST', GameWad + ':TEXTURES\IRONFIST');
2902 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN1', GameWad + ':TEXTURES\SHOTGUN1');
2903 g_CreateTextureWAD('ITEM_WEAPON_SHOTGUN2', GameWad + ':TEXTURES\SHOTGUN2');
2904 g_CreateTextureWAD('ITEM_WEAPON_CHAINGUN', GameWad + ':TEXTURES\MGUN');
2905 g_CreateTextureWAD('ITEM_WEAPON_ROCKETLAUNCHER', GameWad + ':TEXTURES\RLAUNCHER');
2906 g_CreateTextureWAD('ITEM_WEAPON_PLASMA', GameWad + ':TEXTURES\PGUN');
2907 g_CreateTextureWAD('ITEM_WEAPON_BFG', GameWad + ':TEXTURES\BFG');
2908 g_CreateTextureWAD('ITEM_WEAPON_SUPERCHAINGUN', GameWad + ':TEXTURES\SCHAINGUN');
2909 g_CreateTextureWAD('ITEM_AMMO_BULLETS', GameWad + ':TEXTURES\CLIP');
2910 g_CreateTextureWAD('ITEM_AMMO_BULLETS_BOX', GameWad + ':TEXTURES\AMMO');
2911 g_CreateTextureWAD('ITEM_AMMO_SHELLS', GameWad + ':TEXTURES\SHELL1');
2912 g_CreateTextureWAD('ITEM_AMMO_SHELLS_BOX', GameWad + ':TEXTURES\SHELL2');
2913 g_CreateTextureWAD('ITEM_AMMO_ROCKET', GameWad + ':TEXTURES\ROCKET');
2914 g_CreateTextureWAD('ITEM_AMMO_ROCKET_BOX', GameWad + ':TEXTURES\ROCKETS');
2915 g_CreateTextureWAD('ITEM_AMMO_CELL', GameWad + ':TEXTURES\CELL');
2916 g_CreateTextureWAD('ITEM_AMMO_CELL_BIG', GameWad + ':TEXTURES\CELL2');
2917 g_CreateTextureWAD('ITEM_AMMO_BACKPACK', GameWad + ':TEXTURES\BPACK');
2918 g_CreateTextureWAD('ITEM_KEY_RED', GameWad + ':TEXTURES\KEYR');
2919 g_CreateTextureWAD('ITEM_KEY_GREEN', GameWad + ':TEXTURES\KEYG');
2920 g_CreateTextureWAD('ITEM_KEY_BLUE', GameWad + ':TEXTURES\KEYB');
2921 g_CreateTextureWAD('ITEM_OXYGEN', GameWad + ':TEXTURES\OXYGEN');
2922 g_CreateTextureWAD('ITEM_SUIT', GameWad + ':TEXTURES\SUIT');
2923 g_CreateTextureWAD('ITEM_MEDKIT_BLACK', GameWad + ':TEXTURES\BMED');
2925 g_CreateTextureWAD('AREA_PLAYERPOINT1', EditorWad + ':TEXTURES\P1POINT');
2926 g_CreateTextureWAD('AREA_PLAYERPOINT2', EditorWad + ':TEXTURES\P2POINT');
2927 g_CreateTextureWAD('AREA_DMPOINT', EditorWad + ':TEXTURES\DMPOINT');
2928 g_CreateTextureWAD('AREA_REDPOINT', EditorWad + ':TEXTURES\REDPOINT');
2929 g_CreateTextureWAD('AREA_BLUEPOINT', EditorWad + ':TEXTURES\BLUEPOINT');
2930 end;
2932 procedure FreeData();
2933 begin
2934 g_DeleteTexture('NOTEXTURE');
2936 g_DeleteTexture('ITEM_BLUESPHERE');
2937 g_DeleteTexture('ITEM_WHITESPHERE');
2938 g_DeleteTexture('ITEM_ARMORGREEN');
2939 g_DeleteTexture('ITEM_ARMORBLUE');
2940 g_DeleteTexture('ITEM_INVUL');
2941 g_DeleteTexture('ITEM_BOTTLE');
2942 g_DeleteTexture('ITEM_HELMET');
2943 g_DeleteTexture('AREA_REDFLAG');
2944 g_DeleteTexture('AREA_BLUEFLAG');
2945 g_DeleteTexture('AREA_DOMFLAG');
2947 g_DeleteTexture('MONSTER_DEMON');
2948 g_DeleteTexture('MONSTER_IMP');
2949 g_DeleteTexture('MONSTER_ZOMBY');
2950 g_DeleteTexture('MONSTER_SERG');
2951 g_DeleteTexture('MONSTER_CGUN');
2952 g_DeleteTexture('MONSTER_BARREL');
2953 g_DeleteTexture('MONSTER_MAN');
2955 g_DeleteTexture('MONSTER_DEMON');
2956 g_DeleteTexture('MONSTER_IMP');
2957 g_DeleteTexture('MONSTER_ZOMBY');
2958 g_DeleteTexture('MONSTER_SERG');
2959 g_DeleteTexture('MONSTER_CYBER');
2960 g_DeleteTexture('MONSTER_CGUN');
2961 g_DeleteTexture('MONSTER_BARON');
2962 g_DeleteTexture('MONSTER_KNIGHT');
2963 g_DeleteTexture('MONSTER_CACO');
2964 g_DeleteTexture('MONSTER_SOUL');
2965 g_DeleteTexture('MONSTER_PAIN');
2966 g_DeleteTexture('MONSTER_SPIDER');
2967 g_DeleteTexture('MONSTER_BSP');
2968 g_DeleteTexture('MONSTER_MANCUB');
2969 g_DeleteTexture('MONSTER_SKEL');
2970 g_DeleteTexture('MONSTER_VILE');
2971 g_DeleteTexture('MONSTER_FISH');
2972 g_DeleteTexture('MONSTER_BARREL');
2973 g_DeleteTexture('MONSTER_ROBO');
2974 g_DeleteTexture('MONSTER_MAN');
2976 g_DeleteTexture('ITEM_MEDKIT_SMALL');
2977 g_DeleteTexture('ITEM_MEDKIT_LARGE');
2978 g_DeleteTexture('ITEM_WEAPON_SAW');
2979 g_DeleteTexture('ITEM_WEAPON_PISTOL');
2980 g_DeleteTexture('ITEM_WEAPON_IRONFIST');
2981 g_DeleteTexture('ITEM_WEAPON_SHOTGUN1');
2982 g_DeleteTexture('ITEM_WEAPON_SHOTGUN2');
2983 g_DeleteTexture('ITEM_WEAPON_CHAINGUN');
2984 g_DeleteTexture('ITEM_WEAPON_ROCKETLAUNCHER');
2985 g_DeleteTexture('ITEM_WEAPON_PLASMA');
2986 g_DeleteTexture('ITEM_WEAPON_BFG');
2987 g_DeleteTexture('ITEM_WEAPON_SUPERCHAINGUN');
2988 g_DeleteTexture('ITEM_AMMO_BULLETS');
2989 g_DeleteTexture('ITEM_AMMO_BULLETS_BOX');
2990 g_DeleteTexture('ITEM_AMMO_SHELLS');
2991 g_DeleteTexture('ITEM_AMMO_SHELLS_BOX');
2992 g_DeleteTexture('ITEM_AMMO_ROCKET');
2993 g_DeleteTexture('ITEM_AMMO_ROCKET_BOX');
2994 g_DeleteTexture('ITEM_AMMO_CELL');
2995 g_DeleteTexture('ITEM_AMMO_CELL_BIG');
2996 g_DeleteTexture('ITEM_AMMO_BACKPACK');
2997 g_DeleteTexture('ITEM_KEY_RED');
2998 g_DeleteTexture('ITEM_KEY_GREEN');
2999 g_DeleteTexture('ITEM_KEY_BLUE');
3000 g_DeleteTexture('ITEM_OXYGEN');
3001 g_DeleteTexture('ITEM_SUIT');
3002 g_DeleteTexture('ITEM_MEDKIT_BLACK');
3003 g_DeleteTexture('ITEM_JETPACK');
3004 g_DeleteTexture('ITEM_INVIS');
3005 g_DeleteTexture('ITEM_WEAPON_FLAMETHROWER');
3006 g_DeleteTexture('ITEM_AMMO_FUELCAN');
3008 g_DeleteTexture('AREA_PLAYERPOINT1');
3009 g_DeleteTexture('AREA_PLAYERPOINT2');
3010 g_DeleteTexture('AREA_DMPOINT');
3011 g_DeleteTexture('AREA_REDPOINT');
3012 g_DeleteTexture('AREA_BLUEPOINT');
3013 end;
3015 end.