summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 223356c)
raw | patch | inline | side by side (parent: 223356c)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Wed, 30 Aug 2017 01:27:34 +0000 (04:27 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Wed, 30 Aug 2017 01:28:16 +0000 (04:28 +0300) |
28 files changed:
index 83664b1c0050562fd35ae231ffcf7567d18273e9..b7ddd2c5f06a46d8834afe1dcce0cbb54964aa3a 100644 (file)
X, Y: Integer;
end;
- TPoint = MAPDEF.TPoint; // TODO: create an utiltypes.pas or something
- // for other types like rect as well
-
TPoint2f = record
X, Y: Double;
end;
R, G, B: Byte;
end;
- PPoint = ^TPoint;
+ PDFPoint = ^TDFPoint;
PPoint2f = ^TPoint2f;
PRect = ^TRect;
PRectWH = ^TRectWH;
procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
Blending: Boolean; Mirror: TMirrorType = M_NONE);
procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
- Blending: Boolean; Angle: Single; RC: PPoint; Mirror: TMirrorType = M_NONE);
+ Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = M_NONE);
procedure e_DrawSize(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE);
procedure e_DrawSizeMirror(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
end;
procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
- Blending: Boolean; Angle: Single; RC: PPoint; Mirror: TMirrorType = M_NONE);
+ Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = M_NONE);
begin
if e_NoGraphics then Exit;
diff --git a/src/game/Doom2DF.dpr b/src/game/Doom2DF.dpr
index bfd07a5b8f15c1a6668a003710606823d283b118..a66e792b6e38d9f44e537b7ac95d34254e571787 100644 (file)
--- a/src/game/Doom2DF.dpr
+++ b/src/game/Doom2DF.dpr
sfsPlainFS in '../sfs/sfsPlainFS.pas',
sfsZipFS in '../sfs/sfsZipFS.pas',
wadreader in '../shared/wadreader.pas',
- MAPSTRUCT in '../shared/MAPSTRUCT.pas',
- MAPREADER in '../shared/MAPREADER.pas',
MAPDEF in '../shared/MAPDEF.pas',
CONFIG in '../shared/CONFIG.pas',
g_basic in 'g_basic.pas',
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 93368940da0d943a1223f77191f923c7432b5bfd..1cf480864080a2c4115db2cae221b07de7e16299 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
uses
g_basic, g_player, e_graphics, Classes, g_res_downloader,
- SysUtils, g_sound, g_gui, MAPSTRUCT, wadreader, md5, xprofiler;
+ SysUtils, g_sound, g_gui, MAPDEF, wadreader, md5, xprofiler;
type
TGameSettings = record
THearPoint = record
Active: Boolean;
- Coords: TPoint;
+ Coords: TDFPoint;
end;
function g_Game_IsNet(): Boolean;
gPlayer1Settings: TPlayerSettings;
gPlayer2Settings: TPlayerSettings;
gGameOn: Boolean;
- gPlayerScreenSize: TPoint;
- gPlayer1ScreenCoord: TPoint;
- gPlayer2ScreenCoord: TPoint;
+ gPlayerScreenSize: TDFPoint;
+ gPlayer1ScreenCoord: TDFPoint;
+ gPlayer2ScreenCoord: TDFPoint;
gPlayer1: TPlayer = nil;
gPlayer2: TPlayer = nil;
gPlayerDrawn: TPlayer = nil;
g_textures, g_main, g_window, g_menu,
e_input, e_log, g_console, g_items, g_map, g_panel,
g_playermodel, g_gfx, g_options, g_weapons, Math,
- g_triggers, MAPDEF, g_monsters, e_sound, CONFIG,
+ g_triggers, g_monsters, e_sound, CONFIG,
BinEditor, g_language, g_net, SDL,
ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt,
utils, sfs, g_holmes;
var
a, b: Integer;
cmd: string;
- //pt: TPoint;
+ //pt: TDFPoint;
mon: TMonster;
begin
// Êîìàíäû îòëàäî÷íîãî ðåæèìà:
diff --git a/src/game/g_gui.pas b/src/game/g_gui.pas
index 5c60e10d77ec9a8ce97bea6abc446b984350034d..45b2364f8adba30e40aa89565fc3648bfd26e24a 100644 (file)
--- a/src/game/g_gui.pas
+++ b/src/game/g_gui.pas
interface
uses
- e_graphics, e_input, e_log, g_playermodel, g_basic, MAPSTRUCT, wadreader;
+ e_graphics, e_input, e_log, g_playermodel, g_basic, MAPDEF, wadreader;
const
MAINMENU_HEADER_COLOR: TRGB = (R:255; G:255; B:255);
TGUIMapPreview = class(TGUIControl)
private
FMapData: array of TPreviewPanel;
- FMapSize: TPoint;
+ FMapSize: TDFPoint;
FScale: Single;
public
constructor Create();
uses
GL, GLExt, g_textures, g_sound, SysUtils,
- g_game, Math, StrUtils, g_player, g_options, MAPREADER,
- g_map, MAPDEF, g_weapons;
+ g_game, Math, StrUtils, g_player, g_options,
+ g_map, g_weapons, xdynrec;
var
Box: Array [0..8] of DWORD;
procedure TGUIMapPreview.SetMap(Res: string);
var
WAD: TWADFile;
- MapReader: TMapReader_1;
+ //MapReader: TMapReader_1;
panels: TPanelsRec1Array;
header: TMapHeaderRec_1;
a: Integer;
Data: Pointer;
Len: Integer;
rX, rY: Single;
+ map: TDynRecord = nil;
begin
+ FMapSize.X := 0;
+ FMapSize.Y := 0;
+ FScale := 0.0;
+ FMapData := nil;
+
FileName := g_ExtractWadName(Res);
WAD := TWADFile.Create();
WAD.Free();
- MapReader := TMapReader_1.Create();
+ try
+ map := g_Map_ParseMap(Data, Len);
+ except
+ map.Free();
+ raise;
+ end;
+ {
+ MapReader := TMapReader_1.Create();
if not MapReader.LoadMap(Data) then
begin
FreeMem(Data);
FMapData := nil;
Exit;
end;
+ }
FreeMem(Data);
- panels := MapReader.GetPanels();
- header := MapReader.GetMapHeader();
+ panels := GetPanels(map);
+ header := GetMapHeader(map);
FMapSize.X := header.Width div 16;
FMapSize.Y := header.Height div 16;
panels := nil;
- MapReader.Free();
+ //MapReader.Free();
+ map.Free();
end;
procedure TGUIMapPreview.ClearMap();
diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas
index ae7c7b49e67e8c629b8fa7a2f28772048e3c5339..dfa8a00c5bb6eb86df978e88a432af2ad1bd7628 100644 (file)
--- a/src/game/g_holmes.pas
+++ b/src/game/g_holmes.pas
uses
SysUtils, Classes, GL, SDL2,
- MAPDEF, g_options, utils, hashtable, xparser;
+ MAPDEF, g_main, g_options, utils, hashtable, xparser;
var
// load bindings from file
try
- st := openDiskFileRO('holmes.rc');
+ st := openDiskFileRO(GameDir+'holmes.rc');
pr := TFileTextParser.Create(st);
conwriteln('parsing "holmes.rc"...');
while (pr.tokType <> pr.TTEOF) do
diff --git a/src/game/g_main.pas b/src/game/g_main.pas
index 7864bedebfd18c005a89a1e1c7003f51d39cb3d2..1b131f14e7bec2d12111b4487525f4a7232c5916 100644 (file)
--- a/src/game/g_main.pas
+++ b/src/game/g_main.pas
e_graphics, e_input, g_game, g_console, g_gui,
e_sound, g_options, g_sound, g_player,
g_weapons, SysUtils, g_triggers, MAPDEF, g_map,
- MAPSTRUCT, g_menu, g_language, g_net,
+ g_menu, g_language, g_net,
utils, conbuf, envvars;
var
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 4bb340d1026a97f86893f6843e0f0f3dfb93a61a..924dc000ada380a2b1b7a9010bffa327148b06fa 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
interface
uses
- e_graphics, g_basic, MAPSTRUCT, g_textures, Classes,
- g_phys, wadreader, BinEditor, g_panel, g_grid, md5, binheap, xprofiler;
+ e_graphics, g_basic, MAPDEF, g_textures, Classes,
+ g_phys, wadreader, BinEditor, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec;
type
TMapInfo = record
procedure g_Map_ProfilersEnd ();
+function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord;
+
+const
+ NNF_NO_NAME = 0;
+ NNF_NAME_BEFORE = 1;
+ NNF_NAME_EQUALS = 2;
+ NNF_NAME_AFTER = 3;
+
+function g_Texture_NumNameFindStart(name: String): Boolean;
+function g_Texture_NumNameFindNext(var newName: String): Byte;
+
const
RESPAWNPOINT_PLAYER1 = 1;
RESPAWNPOINT_PLAYER2 = 2;
gFlags: array [FLAG_RED..FLAG_BLUE] of TFlag;
//gDOMFlags: array of TFlag;
gMapInfo: TMapInfo;
- gBackSize: TPoint;
+ gBackSize: TDFPoint;
gDoorMap: array of array of DWORD;
gLiftMap: array of array of DWORD;
gWADHash: TMD5Digest;
uses
g_main, e_log, SysUtils, g_items, g_gfx, g_console,
GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG,
- g_options, MAPREADER, g_triggers, g_player, MAPDEF,
+ g_options, g_triggers, g_player,
Math, g_monsters, g_saveload, g_language, g_netmsg,
- utils, sfs, xparser, xdynrec, xstreams,
+ utils, sfs, xstreams,
ImagingTypes, Imaging, ImagingUtility,
ImagingGif, ImagingNetworkGraphics;
FLAG_SIGNATURE = $47414C46; // 'FLAG'
-{$IF DEFINED(D2D_NEW_MAP_READER)}
var
dfmapdef: TDynMapDef = nil;
if (st = nil) then
begin
WAD := TWADFile.Create();
- if not WAD.ReadFile(GameWAD) then raise Exception.Create('cannot load "game.wad"');
- st := WAD.openFileStream('mapdef.txt');
+ if not WAD.ReadFile(GameWAD) then
+ begin
+ //raise Exception.Create('cannot load "game.wad"');
+ st := nil;
+ end
+ else
+ begin
+ st := WAD.openFileStream('mapdef.txt');
+ end;
end;
- if (st = nil) then raise Exception.Create('cannot open "mapdef.txt"');
- pr := TFileTextParser.Create(st);
+ if (st = nil) then
+ begin
+ //raise Exception.Create('cannot open "mapdef.txt"');
+ e_LogWritefln('using default "mapdef.txt"...', [], MSG_WARNING);
+ pr := TStrTextParser.Create(defaultMapDef);
+ end
+ else
+ begin
+ pr := TFileTextParser.Create(st);
+ end;
try
dfmapdef := TDynMapDef.Create(pr);
st.Free();
WAD.Free();
end;
-{$ENDIF}
+
+
+function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord;
+var
+ wst: TSFSMemoryChunkStream = nil;
+ pr: TTextParser = nil;
+begin
+ result := nil;
+ if (dataLen < 4) then exit;
+ loadMapDefinition();
+ if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
+
+ wst := TSFSMemoryChunkStream.Create(data, dataLen);
+
+ if (PAnsiChar(data)[0] = 'M') and (PAnsiChar(data)[1] = 'A') and (PAnsiChar(data)[2] = 'P') and (PByte(data)[3] = 1) then
+ begin
+ // binary map
+ try
+ result := dfmapdef.parseBinMap(wst);
+ except on e: Exception do
+ begin
+ e_LogWritefln('ERROR: %s', [e.message]);
+ wst.Free();
+ result := nil;
+ exit;
+ end;
+ end;
+ wst.Free();
+ end
+ else
+ begin
+ // text map
+ pr := TFileTextParser.Create(wst);
+ try
+ result := dfmapdef.parseMap(pr);
+ except on e: Exception do
+ begin
+ if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
+ else e_LogWritefln('ERROR: %s', [e.message]);
+ pr.Free(); // will free `wst`
+ result := nil;
+ exit;
+ end;
+ end;
+ pr.Free(); // will free `wst`
+ end;
+end;
+
+
+var
+ NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
+ NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
+ NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
+
+
+function g_Texture_NumNameFindStart(name: String): Boolean;
+var
+ i: Integer;
+
+begin
+ Result := False;
+ NNF_PureName := '';
+ NNF_FirstNum := -1;
+ NNF_CurrentNum := -1;
+
+ for i := Length(name) downto 1 do
+ if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
+ begin
+ if i = Length(name) then
+ begin // Íåò öèôð â êîíöå ñòðîêè
+ Exit;
+ end
+ else
+ begin
+ NNF_PureName := Copy(name, 1, i);
+ Delete(name, 1, i);
+ Break;
+ end;
+ end;
+
+// Íå ïåðåâåñòè â ÷èñëî:
+ if not TryStrToInt(name, NNF_FirstNum) then
+ Exit;
+
+ NNF_CurrentNum := 0;
+
+ Result := True;
+end;
+
+
+function g_Texture_NumNameFindNext(var newName: String): Byte;
+begin
+ if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
+ begin
+ newName := '';
+ Result := NNF_NO_NAME;
+ Exit;
+ end;
+
+ newName := NNF_PureName + IntToStr(NNF_CurrentNum);
+
+ if NNF_CurrentNum < NNF_FirstNum then
+ Result := NNF_NAME_BEFORE
+ else
+ if NNF_CurrentNum > NNF_FirstNum then
+ Result := NNF_NAME_AFTER
+ else
+ Result := NNF_NAME_EQUALS;
+
+ Inc(NNF_CurrentNum);
+end;
function panelTypeToTag (panelType: Word): Integer;
Width := 1;
Height := 1;
Anim := False;
- TextureID := TEXTURE_NONE;
+ TextureID := LongWord(TEXTURE_NONE);
end;
end;
TextureName := RecName;
if TextureName = TEXTURE_NAME_WATER then
- TextureID := TEXTURE_SPECIAL_WATER
+ TextureID := LongWord(TEXTURE_SPECIAL_WATER)
else
if TextureName = TEXTURE_NAME_ACID1 then
- TextureID := TEXTURE_SPECIAL_ACID1
+ TextureID := LongWord(TEXTURE_SPECIAL_ACID1)
else
if TextureName = TEXTURE_NAME_ACID2 then
- TextureID := TEXTURE_SPECIAL_ACID2;
+ TextureID := LongWord(TEXTURE_SPECIAL_ACID2);
Anim := False;
end;
gExternalResources.Add(res);
end;
-procedure generateExternalResourcesList(mapReader: TMapReader_1);
+procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord);
var
textures: TTexturesRec1Array;
mapHeader: TMapHeaderRec_1;
gExternalResources := TStringList.Create;
gExternalResources.Clear;
- textures := mapReader.GetTextures();
+ textures := GetTextures(map);
for i := 0 to High(textures) do
begin
addResToExternalResList(resFile);
textures := nil;
- mapHeader := mapReader.GetMapHeader;
+ mapHeader := GetMapHeader(map);
addResToExternalResList(mapHeader.MusicName);
addResToExternalResList(mapHeader.SkyName);
DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
var
WAD: TWADFile;
- MapReader: TMapReader_1;
+ //MapReader: TMapReader_1;
+ mapReader: TDynRecord = nil;
Header: TMapHeaderRec_1;
_textures: TTexturesRec1Array;
_texnummap: array of Integer; // `_textures` -> `Textures`
Len: Integer;
ok, isAnim, trigRef: Boolean;
CurTex, ntn: Integer;
- {$IF DEFINED(D2D_NEW_MAP_READER)}
- pr: TTextParser = nil;
- st: TStream = nil;
- wst: TSFSMemoryChunkStream = nil;
- rec: TDynRecord;
- {$ENDIF}
begin
mapGrid.Free();
mapGrid := nil;
e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False);
- {$IF DEFINED(D2D_NEW_MAP_READER)}
- if (PChar(Data)[0] = 'M') and (PChar(Data)[1] = 'A') and (PChar(Data)[2] = 'P') and (PByte(Data)[3] = 1) then
- begin
- // nothing
- end
- else
- begin
- e_LogWritefln('Loading text map: %s', [mapResName]);
- loadMapDefinition();
- if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
- //e_LogWritefln('***'#10'%s'#10'***', [dfmapdef.headerType.definition]);
- wst := TSFSMemoryChunkStream.Create(Data, Len);
- try
- pr := TFileTextParser.Create(wst);
- e_LogWritefln('parsing text map: %s', [mapResName]);
- rec := dfmapdef.parseMap(pr);
- except on e: Exception do
- begin
- if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
- else e_LogWritefln('ERROR: %s', [e.message]);
- pr.Free();
- wst.Free();
- FreeMem(Data);
- exit;
- end;
+ {
+ if (PChar(Data)[0] = 'M') and (PChar(Data)[1] = 'A') and (PChar(Data)[2] = 'P') and (PByte(Data)[3] = 1) then
+ begin
+ // nothing
+ end
+ else
+ begin
+ e_LogWritefln('Loading text map: %s', [mapResName]);
+ loadMapDefinition();
+ if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
+ //e_LogWritefln('***'#10'%s'#10'***', [dfmapdef.headerType.definition]);
+ wst := TSFSMemoryChunkStream.Create(Data, Len);
+ try
+ pr := TFileTextParser.Create(wst);
+ e_LogWritefln('parsing text map: %s', [mapResName]);
+ rec := dfmapdef.parseMap(pr);
+ except on e: Exception do
+ begin
+ if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
+ else e_LogWritefln('ERROR: %s', [e.message]);
+ pr.Free();
+ wst.Free();
+ FreeMem(Data);
+ exit;
end;
- pr.Free();
- //wst.Free(); // pr will do it
- e_LogWritefln('writing text map to temporary bin storage...', []);
- st := TMemoryStream.Create();
- try
- rec.writeBinTo(st);
- Len := Integer(st.position);
- st.position := 0;
+ end;
+ pr.Free();
+ //wst.Free(); // pr will do it
+ e_LogWritefln('writing text map to temporary bin storage...', []);
+ st := TMemoryStream.Create();
+ try
+ rec.writeBinTo(st);
+ Len := Integer(st.position);
+ st.position := 0;
+ FreeMem(Data);
+ GetMem(Data, Len);
+ st.ReadBuffer(Data^, Len);
+ except on e: Exception do
+ begin
+ rec.Free();
+ st.Free();
+ e_LogWritefln('ERROR: %s', [e.message]);
FreeMem(Data);
- GetMem(Data, Len);
- st.ReadBuffer(Data^, Len);
- except on e: Exception do
- begin
- rec.Free();
- st.Free();
- e_LogWritefln('ERROR: %s', [e.message]);
- FreeMem(Data);
- exit;
- end;
+ exit;
end;
- st.Free();
end;
- {$ENDIF}
+ st.Free();
+ end;
+ }
+ try
+ mapReader := g_Map_ParseMap(Data, Len);
+ except
+ mapReader.Free();
+ g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]));
+ FreeMem(Data);
+ MapReader.Free();
+ Exit;
+ end;
+ {
MapReader := TMapReader_1.Create();
-
if not MapReader.LoadMap(Data) then
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]));
MapReader.Free();
Exit;
end;
+ }
FreeMem(Data);
generateExternalResourcesList(MapReader);
// Çàãðóçêà òåêñòóð:
g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False);
- _textures := MapReader.GetTextures();
+ _textures := GetTextures(mapReader);
_texnummap := nil;
// Çàãðóçêà îïèñàíèÿ êàðòû:
e_WriteLog(' Reading map info...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_MAP_HEADER], 0, False);
- Header := MapReader.GetMapHeader();
+ Header := GetMapHeader(mapReader);
with gMapInfo do
begin
gTriggerClientID := 0;
e_WriteLog(' Loading triggers...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS], 0, False);
- triggers := MapReader.GetTriggers();
+ triggers := GetTriggers(mapReader);
// Çàãðóçêà ïàíåëåé:
e_WriteLog(' Loading panels...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_PANELS], 0, False);
- panels := MapReader.GetPanels();
+ panels := GetPanels(mapReader);
// check texture numbers for panels
for a := 0 to High(panels) do
// Åñëè íå LoadState, òî ñîçäàåì òðèããåðû:
if (triggers <> nil) and not gLoadGameMode then
begin
- e_WriteLog(' Creating triggers...', MSG_NOTIFY);
+ e_LogWritefln(' Creating triggers (%d)...', [Length(triggers)]);
g_Game_SetLoadingText(_lc[I_LOAD_CREATE_TRIGGERS], 0, False);
// Óêàçûâàåì òèï ïàíåëè, åñëè åñòü:
for a := 0 to High(triggers) do
begin
- if triggers[a].TexturePanel <> -1 then
- b := panels[TriggersTable[a].TexturePanel].PanelType
+ if (triggers[a].TexturePanel <> -1) then
+ begin
+ if (TriggersTable[a].TexturePanel < 0) or (TriggersTable[a].TexturePanel > High(panels)) then
+ begin
+ e_WriteLog('error loading map: invalid panel index for trigger', MSG_FATALERROR);
+ result := false;
+ exit;
+ end;
+ b := panels[TriggersTable[a].TexturePanel].PanelType;
+ end
else
+ begin
b := 0;
- if (triggers[a].TriggerType = TRIGGER_SHOT) and
- (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then
+ end;
+ if (triggers[a].TriggerType = TRIGGER_SHOT) and (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then
+ begin
c := panels[TriggersTable[a].ShotPanel].PanelType
+ end
else
+ begin
c := 0;
+ end;
CreateTrigger(triggers[a], b, c);
end;
end;
// Çàãðóçêà ïðåäìåòîâ:
- e_WriteLog(' Loading triggers...', MSG_NOTIFY);
+ e_WriteLog(' Loading items...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_ITEMS], 0, False);
- items := MapReader.GetItems();
+ items := GetItems(mapReader);
// Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû:
if (items <> nil) and not gLoadGameMode then
// Çàãðóçêà îáëàñòåé:
e_WriteLog(' Loading areas...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_AREAS], 0, False);
- areas := MapReader.GetAreas();
+ areas := GetAreas(mapReader);
// Åñëè íå LoadState, òî ñîçäàåì îáëàñòè:
if areas <> nil then
// Çàãðóçêà ìîíñòðîâ:
e_WriteLog(' Loading monsters...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_MONSTERS], 0, False);
- monsters := MapReader.GetMonsters();
+ monsters := GetMonsters(mapReader);
gTotalMonsters := 0;
function g_Map_GetMapInfo(Res: String): TMapInfo;
var
WAD: TWADFile;
- MapReader: TMapReader_1;
+ MapReader: TDynRecord;
Header: TMapHeaderRec_1;
FileName: String;
Data: Pointer;
WAD.Free();
+ {
MapReader := TMapReader_1.Create();
-
if not MapReader.LoadMap(Data) then
begin
g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True);
Result.Name := Header.MapName;
Result.Description := Header.MapDescription;
end;
+ }
+ try
+ mapReader := g_Map_ParseMap(Data, Len);
+ except
+ mapReader := nil;
+ end;
FreeMem(Data);
+ //MapReader.Free();
+
+ if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0);
MapReader.Free();
+ if (Header.Width > 0) and (Header.Height > 0) then
+ begin
+ Result.Name := Header.MapName;
+ Result.Description := Header.MapDescription;
+ end
+ else
+ begin
+ g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True);
+ ZeroMemory(@Header, SizeOf(Header));
+ Result.Name := _lc[I_GAME_ERROR_MAP_SELECT];
+ Result.Description := _lc[I_GAME_ERROR_MAP_SELECT];
+ end;
+
Result.Map := Res;
Result.Author := Header.MapAuthor;
Result.Height := Header.Height;
if Textures[a].Anim then
g_Frames_DeleteByID(Textures[a].FramesID)
else
- if Textures[a].TextureID <> TEXTURE_NONE then
+ if Textures[a].TextureID <> LongWord(TEXTURE_NONE) then
e_DeleteTexture(Textures[a].TextureID);
Textures := nil;
end;
begin
- texid := TEXTURE_NONE;
+ texid := LongWord(TEXTURE_NONE);
result := texid;
if not checkPanels(gWater) then
if not checkPanels(gAcid1) then
if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquids');
if gdbg_map_use_accel_coldet then
begin
- texid := TEXTURE_NONE;
+ texid := LongWord(TEXTURE_NONE);
if (Width = 1) and (Height = 1) then
begin
mapGrid.forEachAtPoint(X, Y, checker, (GridTagWater or GridTagAcid1 or GridTagAcid2));
diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas
index 0905cdc6ddc78c02cc4ba1f520d23215c2331b30..5371f413c26e01849bafc272bbdd4c3e2d4aef6a 100644 (file)
--- a/src/game/g_menu.pas
+++ b/src/game/g_menu.pas
g_gui, g_textures, e_graphics, g_main, g_window, g_game, g_map,
g_basic, g_console, g_sound, g_gfx, g_player, g_options, g_weapons,
e_log, SysUtils, CONFIG, g_playermodel, DateUtils,
- MAPSTRUCT, wadreader, Math, g_saveload,
+ MAPDEF, wadreader, Math, g_saveload,
e_texture, GL, GLExt, g_language,
g_net, g_netmsg, g_netmaster, g_items, e_input;
index 2b70da642e49892257507eadf3da63de2a0d32db..5ec0099df31ef59bf398bb2c52b229cba0a5dc31 100644 (file)
--- a/src/game/g_monsters.pas
+++ b/src/game/g_monsters.pas
LeftAnim: Boolean;
wX, wY: Integer; // Îòêóäà âûëåòèò ïóëÿ
AnimSpeed: Array [ANIM_SLEEP..ANIM_PAIN] of Byte;
- AnimDeltaRight: Array [ANIM_SLEEP..ANIM_PAIN] of TPoint;
- AnimDeltaLeft: Array [ANIM_SLEEP..ANIM_PAIN] of TPoint;
+ AnimDeltaRight: Array [ANIM_SLEEP..ANIM_PAIN] of TDFPoint;
+ AnimDeltaLeft: Array [ANIM_SLEEP..ANIM_PAIN] of TDFPoint;
end = // SLEEP GO DIE MESS ATTACK ATTACK2 PAIN
((LeftAnim: False; wX: 54; wY: 32; AnimSpeed:(3, 2, 3, 2, 3, 0, 4); //DEMON
AnimDeltaRight: ((X: 1; Y: 4), (X: 1; Y: 4), (X: 0; Y: 4), (X: 0; Y: 4), (X: 2; Y: 6), (X: 2; Y: 6), (X: 2; Y: 5));
diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas
index 96bd7f1817f333246c470eea1933052bf2c2df83..c562934ec753748f26269fb776a629cd7d61ab08 100644 (file)
--- a/src/game/g_panel.pas
+++ b/src/game/g_panel.pas
interface
uses
- MAPSTRUCT, BinEditor, g_textures;
+ MAPDEF, BinEditor, g_textures;
type
TAddTextureArray = Array of
implementation
uses
- SysUtils, g_basic, g_map, MAPDEF, g_game, e_graphics,
+ SysUtils, g_basic, g_map, g_game, e_graphics,
g_console, g_language, e_log, GL;
const
case PanelRec.PanelType of
PANEL_WATER:
- FTextureIDs[0].Tex := TEXTURE_SPECIAL_WATER;
+ FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_WATER);
PANEL_ACID1:
- FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID1;
+ FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID1);
PANEL_ACID2:
- FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID2;
+ FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID2);
end;
FCurTexture := 0;
else
begin // Îáû÷íàÿ òåêñòóðà
case FTextureIDs[FCurTexture].Tex of
- TEXTURE_SPECIAL_WATER:
+ LongWord(TEXTURE_SPECIAL_WATER):
e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
0, 0, 255, 0, B_FILTER);
- TEXTURE_SPECIAL_ACID1:
+ LongWord(TEXTURE_SPECIAL_ACID1):
e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
0, 128, 0, 0, B_FILTER);
- TEXTURE_SPECIAL_ACID2:
+ LongWord(TEXTURE_SPECIAL_ACID2):
e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
128, 0, 0, 0, B_FILTER);
- TEXTURE_NONE:
+ LongWord(TEXTURE_NONE):
if g_Texture_Get('NOTEXTURE', NoTextureID) then
begin
e_GetTextureSize(NoTextureID, @NW, @NH);
if not FTextureIDs[FCurTexture].Anim then
begin
case FTextureIDs[FCurTexture].Tex of
- TEXTURE_SPECIAL_WATER: exit;
- TEXTURE_SPECIAL_ACID1: exit;
- TEXTURE_SPECIAL_ACID2: exit;
- TEXTURE_NONE: exit;
+ LongWord(TEXTURE_SPECIAL_WATER): exit;
+ LongWord(TEXTURE_SPECIAL_ACID1): exit;
+ LongWord(TEXTURE_SPECIAL_ACID2): exit;
+ LongWord(TEXTURE_NONE): exit;
end;
end;
if (X+Width < lightX-radius) then exit;
function TPanel.GetTextureID(): DWORD;
begin
- Result := TEXTURE_NONE;
+ Result := LongWord(TEXTURE_NONE);
if (FCurTexture >= 0) then
begin
diff --git a/src/game/g_phys.pas b/src/game/g_phys.pas
index 7780b3ba74806b71cc8d29d8fbfab261f1e5aae2..498bd7587489f9faf6e72ffca873c72e06de6702 100644 (file)
--- a/src/game/g_phys.pas
+++ b/src/game/g_phys.pas
Obj^.Rect.Width,
Obj^.Rect.Height*2 div 3);
case wtx of
- TEXTURE_SPECIAL_WATER:
+ LongWord(TEXTURE_SPECIAL_WATER):
g_Obj_Splash(Obj, 3);
- TEXTURE_SPECIAL_ACID1:
+ LongWord(TEXTURE_SPECIAL_ACID1):
g_Obj_Splash(Obj, 2);
- TEXTURE_SPECIAL_ACID2:
+ LongWord(TEXTURE_SPECIAL_ACID2):
g_Obj_Splash(Obj, 1);
- TEXTURE_NONE:
+ LongWord(TEXTURE_NONE):
;
else
g_Obj_Splash(Obj, 0);
diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index ebbd2043e5fc69d7784346b031c5b51d804f637c..488cee9edc6ce085a2c329f1f5d26f506bf4cb9e 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
uses
e_graphics, g_playermodel, g_basic, g_textures,
- g_weapons, g_phys, g_sound, g_saveload, MAPSTRUCT,
+ g_weapons, g_phys, g_sound, g_saveload, MAPDEF,
BinEditor, g_panel;
const
uses
e_log, g_map, g_items, g_console, SysUtils, g_gfx, Math,
- g_options, g_triggers, g_menu, MAPDEF, g_game, g_grid,
+ g_options, g_triggers, g_menu, g_game, g_grid,
wadreader, g_main, g_monsters, CONFIG, g_language,
g_net, g_netmsg, g_window, GL, g_holmes;
ANGLE_LEFTUP = 125;
ANGLE_LEFTDOWN = -145;
PLAYER_HEADRECT: TRectWH = (X:24; Y:12; Width:20; Height:12);
- WEAPONPOINT: Array [TDirection] of TPoint = ((X:16; Y:32), (X:47; Y:32));
+ WEAPONPOINT: Array [TDirection] of TDFPoint = ((X:16; Y:32), (X:47; Y:32));
BOT_MAXJUMP = 84;
BOT_LONGDIST = 300;
BOT_UNSAFEDIST = 128;
procedure g_Player_DrawCorpses();
var
i: Integer;
- a: TPoint;
+ a: TDFPoint;
begin
if gGibs <> nil then
for i := 0 to High(gGibs) do
procedure g_Player_DrawShells();
var
i: Integer;
- a: TPoint;
+ a: TDFPoint;
begin
if gShells <> nil then
for i := 0 to High(gShells) do
index 3c121dba7854435f9a2e5d6a5cc4419b82f72a40..72f5fb23e726f916f937f888e9991ebd7e69bbbf 100644 (file)
interface
uses
- g_textures, g_basic, g_weapons, e_graphics, wadreader;
+ MAPDEF, g_textures, g_basic, g_weapons, e_graphics, wadreader;
const
A_STAND = 0;
TGibsArray = Array of TGibSprite;
TWeaponPoints = Array [WP_FIRST + 1..WP_LAST] of
Array [A_STAND..A_LAST] of
- Array [D_LEFT..D_RIGHT] of Array of TPoint;
+ Array [D_LEFT..D_RIGHT] of Array of TDFPoint;
TPlayerModel = class (TObject)
private
FCurrentWeapon: Byte;
FDrawWeapon: Boolean;
FFlag: Byte;
- FFlagPoint: TPoint;
+ FFlagPoint: TDFPoint;
FFlagAngle: SmallInt;
FFlagAnim: TAnimation;
FFire: Boolean;
TPlayerModelInfo = record
Info: TModelInfo;
ModelSpeed: Array [A_STAND..A_PAIN] of Byte;
- FlagPoint: TPoint;
+ FlagPoint: TDFPoint;
FlagAngle: SmallInt;
WeaponPoints: TWeaponPoints;
Gibs: TGibsArray;
W_ACT_NORMAL = 0;
W_ACT_FIRE = 1;
- FLAG_BASEPOINT: TPoint = (X:16; Y:43);
- FLAG_DEFPOINT: TPoint = (X:32; Y:16);
+ FLAG_BASEPOINT: TDFPoint = (X:16; Y:43);
+ FLAG_DEFPOINT: TDFPoint = (X:32; Y:16);
FLAG_DEFANGLE = -20;
- WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TPoint =
+ WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TDFPoint =
((X:8; Y:4), (X:8; Y:8), (X:16; Y:16), (X:16; Y:24),
(X:16; Y:16), (X:24; Y:24), (X:16; Y:16), (X:24; Y:24),
(X:16; Y:16), (X:8; Y:8));
end;
end;
-function GetPoint(var str: String; var point: TPoint): Boolean;
+function GetPoint(var str: String; var point: TDFPoint): Boolean;
var
a, x, y: Integer;
s: String;
var
Mirror: TMirrorType;
pos, act: Byte;
- p: TPoint;
+ p: TDFPoint;
begin
// Ôëàãè:
if Direction = D_LEFT then
index e6a1ca293344ca1b603ff026a4fbc514c0ee7f54..5a130981eae9232f2e22269e20275397098f1829 100644 (file)
--- a/src/game/g_saveload.pas
+++ b/src/game/g_saveload.pas
uses
g_game, g_items, g_map, g_monsters, g_triggers,
g_basic, g_main, SysUtils, Math, wadreader,
- MAPSTRUCT, MAPDEF, g_weapons, g_player, g_console,
+ MAPDEF, g_weapons, g_player, g_console,
e_log, g_language;
const
index 660e999351988a4fb3dad1ccdecabe614d6dda3b..02098004a6432c4d64385e6d6f208c1380e2a569 100644 (file)
--- a/src/game/g_textures.pas
+++ b/src/game/g_textures.pas
interface
uses
- e_graphics, BinEditor, ImagingTypes, Imaging, ImagingUtility;
+ e_graphics, MAPDEF, BinEditor, ImagingTypes, Imaging, ImagingUtility;
Type
TLevelTexture = record
constructor Create(FramesID: DWORD; Loop: Boolean; Speed: Byte);
destructor Destroy(); override;
procedure Draw(X, Y: Integer; Mirror: TMirrorType);
- procedure DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TPoint;
+ procedure DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TDFPoint;
Angle: SmallInt);
procedure Reset();
procedure Update();
FEnabled := True;
end;
-procedure TAnimation.DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TPoint;
+procedure TAnimation.DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TDFPoint;
Angle: SmallInt);
begin
if not FEnabled then
index 3b1f911bf133db08b97b0c1f50da8e5a1732fed1..c327fdb55c2afcd0257ec015562191cdcc0aade1 100644 (file)
--- a/src/game/g_triggers.pas
+++ b/src/game/g_triggers.pas
interface
uses
- MAPSTRUCT, e_graphics, MAPDEF, g_basic, g_sound,
+ MAPDEF, e_graphics, g_basic, g_sound,
BinEditor;
type
diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas
index aa78ebd94e7ddae5fa7f224eada8b21f0cf3f79e..5d6a7848adf18b7b061505e667026823c8f13098 100644 (file)
--- a/src/game/g_weapons.pas
+++ b/src/game/g_weapons.pas
var
i: Integer;
a: SmallInt;
- p: TPoint;
+ p: TDFPoint;
begin
if Shots = nil then
Exit;
diff --git a/src/shared/MAPDEF.pas b/src/shared/MAPDEF.pas
index f6678e921683bb659ec77dd3a6805658f21fb0b2..12e05628ab16110b1582075be182cc15c0b5cb6f 100644 (file)
--- a/src/shared/MAPDEF.pas
+++ b/src/shared/MAPDEF.pas
interface
uses
- MAPSTRUCT;
+ xdynrec;
+
-// *** WARNING! ***
-// keep all constants in sync with "mapdesc.txt"!
-// or even better: regenerate this part directly from "mapdesc.txt".
const
- PANEL_NONE = 0;
- PANEL_WALL = 1;
- PANEL_BACK = 2;
- PANEL_FORE = 4;
- PANEL_WATER = 8;
- PANEL_ACID1 = 16;
- PANEL_ACID2 = 32;
- PANEL_STEP = 64;
- PANEL_LIFTUP = 128;
- PANEL_LIFTDOWN = 256;
- PANEL_OPENDOOR = 512;
- PANEL_CLOSEDOOR = 1024;
- PANEL_BLOCKMON = 2048;
- PANEL_LIFTLEFT = 4096;
- PANEL_LIFTRIGHT = 8192;
-
- PANEL_FLAG_BLENDING = 1;
- PANEL_FLAG_HIDE = 2;
- PANEL_FLAG_WATERTEXTURES = 4;
-
- EFFECT_NONE = 0;
- EFFECT_TELEPORT = 1;
- EFFECT_RESPAWN = 2;
- EFFECT_FIRE = 3;
-
- ITEM_NONE = 0;
- ITEM_MEDKIT_SMALL = 1;
- ITEM_MEDKIT_LARGE = 2;
- ITEM_MEDKIT_BLACK = 3;
- ITEM_ARMOR_GREEN = 4;
- ITEM_ARMOR_BLUE = 5;
- ITEM_SPHERE_BLUE = 6;
- ITEM_SPHERE_WHITE = 7;
- ITEM_SUIT = 8;
- ITEM_OXYGEN = 9;
- ITEM_INVUL = 10;
- ITEM_WEAPON_SAW = 11;
- ITEM_WEAPON_SHOTGUN1 = 12;
- ITEM_WEAPON_SHOTGUN2 = 13;
- ITEM_WEAPON_CHAINGUN = 14;
- ITEM_WEAPON_ROCKETLAUNCHER = 15;
- ITEM_WEAPON_PLASMA = 16;
- ITEM_WEAPON_BFG = 17;
- ITEM_WEAPON_SUPERPULEMET = 18;
- ITEM_AMMO_BULLETS = 19;
- ITEM_AMMO_BULLETS_BOX = 20;
- ITEM_AMMO_SHELLS = 21;
- ITEM_AMMO_SHELLS_BOX = 22;
- ITEM_AMMO_ROCKET = 23;
- ITEM_AMMO_ROCKET_BOX = 24;
- ITEM_AMMO_CELL = 25;
- ITEM_AMMO_CELL_BIG = 26;
- ITEM_AMMO_BACKPACK = 27;
- ITEM_KEY_RED = 28;
- ITEM_KEY_GREEN = 29;
- ITEM_KEY_BLUE = 30;
- ITEM_WEAPON_KASTET = 31;
- ITEM_WEAPON_PISTOL = 32;
- ITEM_BOTTLE = 33;
- ITEM_HELMET = 34;
- ITEM_JETPACK = 35;
- ITEM_INVIS = 36;
- ITEM_WEAPON_FLAMETHROWER = 37;
- ITEM_AMMO_FUELCAN = 38;
-
- ITEM_MAX = 38; // store the last item's id in here
- // use this in for loops
-
- ITEM_OPTION_ONLYDM = 1;
- ITEM_OPTION_FALL = 2;
-
- AREA_NONE = 0;
- AREA_PLAYERPOINT1 = 1;
- AREA_PLAYERPOINT2 = 2;
- AREA_DMPOINT = 3;
- AREA_REDFLAG = 4;
- AREA_BLUEFLAG = 5;
- AREA_DOMFLAG = 6;
- AREA_REDTEAMPOINT = 7;
- AREA_BLUETEAMPOINT = 8;
-
- MONSTER_NONE = 0;
- MONSTER_DEMON = 1;
- MONSTER_IMP = 2;
- MONSTER_ZOMBY = 3;
- MONSTER_SERG = 4;
- MONSTER_CYBER = 5;
- MONSTER_CGUN = 6;
- MONSTER_BARON = 7;
- MONSTER_KNIGHT = 8;
- MONSTER_CACO = 9;
- MONSTER_SOUL = 10;
- MONSTER_PAIN = 11;
- MONSTER_SPIDER = 12;
- MONSTER_BSP = 13;
- MONSTER_MANCUB = 14;
- MONSTER_SKEL = 15;
- MONSTER_VILE = 16;
- MONSTER_FISH = 17;
- MONSTER_BARREL = 18;
- MONSTER_ROBO = 19;
- MONSTER_MAN = 20;
-
- TRIGGER_NONE = 0;
- TRIGGER_EXIT = 1;
- TRIGGER_TELEPORT = 2;
- TRIGGER_OPENDOOR = 3;
- TRIGGER_CLOSEDOOR = 4;
- TRIGGER_DOOR = 5;
- TRIGGER_DOOR5 = 6;
- TRIGGER_CLOSETRAP = 7;
- TRIGGER_TRAP = 8;
- TRIGGER_PRESS = 9;
- TRIGGER_SECRET = 10;
- TRIGGER_LIFTUP = 11;
- TRIGGER_LIFTDOWN = 12;
- TRIGGER_LIFT = 13;
- TRIGGER_TEXTURE = 14;
- TRIGGER_ON = 15;
- TRIGGER_OFF = 16;
- TRIGGER_ONOFF = 17;
- TRIGGER_SOUND = 18;
- TRIGGER_SPAWNMONSTER = 19;
- TRIGGER_SPAWNITEM = 20;
- TRIGGER_MUSIC = 21;
- TRIGGER_PUSH = 22;
- TRIGGER_SCORE = 23;
- TRIGGER_MESSAGE = 24;
- TRIGGER_DAMAGE = 25;
- TRIGGER_HEALTH = 26;
- TRIGGER_SHOT = 27;
- TRIGGER_EFFECT = 28;
- TRIGGER_SCRIPT = 29;
- TRIGGER_MAX = 29;
-
- TRIGGER_SHOT_PISTOL = 0;
- TRIGGER_SHOT_BULLET = 1;
- TRIGGER_SHOT_SHOTGUN = 2;
- TRIGGER_SHOT_SSG = 3;
- TRIGGER_SHOT_IMP = 4;
- TRIGGER_SHOT_PLASMA = 5;
- TRIGGER_SHOT_SPIDER = 6;
- TRIGGER_SHOT_CACO = 7;
- TRIGGER_SHOT_BARON = 8;
- TRIGGER_SHOT_MANCUB = 9;
- TRIGGER_SHOT_REV = 10;
- TRIGGER_SHOT_ROCKET = 11;
- TRIGGER_SHOT_BFG = 12;
- TRIGGER_SHOT_EXPL = 13;
- TRIGGER_SHOT_BFGEXPL = 14;
- TRIGGER_SHOT_MAX = 14;
-
- TRIGGER_SHOT_TARGET_NONE = 0;
- TRIGGER_SHOT_TARGET_MON = 1;
- TRIGGER_SHOT_TARGET_PLR = 2;
- TRIGGER_SHOT_TARGET_RED = 3;
- TRIGGER_SHOT_TARGET_BLUE = 4;
- TRIGGER_SHOT_TARGET_MONPLR = 5;
- TRIGGER_SHOT_TARGET_PLRMON = 6;
-
- TRIGGER_SHOT_AIM_DEFAULT = 0;
- TRIGGER_SHOT_AIM_ALLMAP = 1;
- TRIGGER_SHOT_AIM_TRACE = 2;
- TRIGGER_SHOT_AIM_TRACEALL = 3;
-
- TRIGGER_EFFECT_PARTICLE = 0;
- TRIGGER_EFFECT_ANIMATION = 1;
-
- TRIGGER_EFFECT_SLIQUID = 0;
- TRIGGER_EFFECT_LLIQUID = 1;
- TRIGGER_EFFECT_DLIQUID = 2;
- TRIGGER_EFFECT_BLOOD = 3;
- TRIGGER_EFFECT_SPARK = 4;
- TRIGGER_EFFECT_BUBBLE = 5;
- TRIGGER_EFFECT_MAX = 5;
-
- TRIGGER_EFFECT_POS_CENTER = 0;
- TRIGGER_EFFECT_POS_AREA = 1;
-
- ACTIVATE_PLAYERCOLLIDE = 1;
- ACTIVATE_MONSTERCOLLIDE = 2;
- ACTIVATE_PLAYERPRESS = 4;
- ACTIVATE_MONSTERPRESS = 8;
- ACTIVATE_SHOT = 16;
- ACTIVATE_NOMONSTER = 32;
- ACTIVATE_CUSTOM = 255;
-
- KEY_RED = 1;
- KEY_GREEN = 2;
- KEY_BLUE = 4;
- KEY_REDTEAM = 8;
- KEY_BLUETEAM = 16;
+ MAP_SIGNATURE = 'MAP';
+
+const
TEXTURE_NAME_WATER = '_water_0';
TEXTURE_NAME_ACID1 = '_water_1';
TEXTURE_NAME_ACID2 = '_water_2';
- TEXTURE_SPECIAL_WATER = DWORD(-1);
- TEXTURE_SPECIAL_ACID1 = DWORD(-2);
- TEXTURE_SPECIAL_ACID2 = DWORD(-3);
- TEXTURE_NONE = DWORD(-4);
type
- TPoint = packed record
+ TDFPoint = packed record
X, Y: LongInt;
end;
- TTriggerData = record
- case Byte of
- 0: (Default: Byte128);
- TRIGGER_EXIT: (MapName: Char16);
- TRIGGER_TELEPORT: (TargetPoint: TPoint;
- d2d_teleport: Boolean;
- silent_teleport: Boolean;
- TlpDir: Byte);
- TRIGGER_OPENDOOR,
- TRIGGER_CLOSEDOOR,
- TRIGGER_DOOR,
- TRIGGER_DOOR5,
- TRIGGER_CLOSETRAP,
- TRIGGER_TRAP,
- TRIGGER_LIFTUP,
- TRIGGER_LIFTDOWN,
- TRIGGER_LIFT: (PanelID: Integer;
- NoSound: Boolean;
- d2d_doors: Boolean);
- TRIGGER_PRESS,
- TRIGGER_ON,
- TRIGGER_OFF,
- TRIGGER_ONOFF: (tX, tY: Integer;
- tWidth, tHeight: Word;
- Wait: Word;
- Count: Word;
- MonsterID: Integer;
- ExtRandom: Boolean);
- TRIGGER_SECRET: ();
- TRIGGER_TEXTURE: (ActivateOnce: Boolean;
- AnimOnce: Boolean);
- TRIGGER_SOUND: (SoundName: Char64;
- Volume: Byte;
- Pan: Byte;
- Local: Boolean;
- PlayCount: Byte;
- SoundSwitch: Boolean);
- TRIGGER_SPAWNMONSTER: (MonPos: TPoint;
- MonType: Byte;
- MonHealth: Integer;
- MonDir: Byte;
- MonActive: Boolean;
- MonCount: Integer;
- MonEffect: Byte;
- MonMax: Word;
- MonDelay: Word;
- MonBehav: Byte);
- TRIGGER_SPAWNITEM: (ItemPos: TPoint;
- ItemType: Byte;
- ItemFalls: Boolean;
- ItemOnlyDM: Boolean;
- ItemCount: Integer;
- ItemEffect: Byte;
- ItemMax: Word;
- ItemDelay: Word);
- TRIGGER_MUSIC: (MusicName: Char64;
- MusicAction: Byte);
- TRIGGER_PUSH: (PushAngle: Word;
- PushForce: Byte;
- ResetVel: Boolean);
- TRIGGER_SCORE: (ScoreAction: Byte;
- ScoreCount: Byte;
- ScoreTeam: Byte;
- ScoreCon,
- ScoreMsg: Boolean);
- TRIGGER_MESSAGE: (MessageKind: Byte;
- MessageSendTo: Byte;
- MessageText: Char100;
- MessageTime: Word);
- TRIGGER_DAMAGE: (DamageValue: Word;
- DamageInterval: Word);
- TRIGGER_HEALTH: (HealValue: Word;
- HealInterval: Word;
- HealMax: Boolean;
- HealSilent: Boolean);
- TRIGGER_SHOT: (ShotPos: TPoint;
- ShotType: Byte;
- ShotTarget: Byte;
- ShotSound: Boolean;
- ShotAim: Byte;
- ShotPanelID: Integer;
- ShotIntSight: Word;
- ShotAngle: Word;
- ShotWait: Word;
- ShotAccuracy: Word;
- ShotAmmo: Word;
- ShotIntReload: Word);
- TRIGGER_EFFECT: (FXCount: Byte;
- FXType: Byte;
- FXSubType: Byte;
- FXColorR: Byte;
- FXColorG: Byte;
- FXColorB: Byte;
- FXPos: Byte;
- FXWait: Word;
- FXVelX: ShortInt;
- FXVelY: ShortInt;
- FXSpreadL: Byte;
- FXSpreadR: Byte;
- FXSpreadU: Byte;
- FXSpreadD: Byte);
- TRIGGER_SCRIPT: (SCRProc: Char64;
- SCRArg: Integer);
- end;
+ Char16 = packed array[0..15] of Char;
+ Char32 = packed array[0..31] of Char;
+ Char64 = packed array[0..63] of Char;
+ Char100 = packed array[0..99] of Char;
+ Char256 = packed array[0..255] of Char;
+ Byte128 = packed array[0..127] of Byte;
+
+{$INCLUDE mapdef.inc}
+
+type
+ TTexturesRec1Array = array of TTextureRec_1;
+ TPanelsRec1Array = array of TPanelRec_1;
+ TItemsRec1Array = array of TItemRec_1;
+ TMonsterRec1Array = array of TMonsterRec_1;
+ TAreasRec1Array = array of TAreaRec_1;
+ TTriggersRec1Array = array of TTriggerRec_1;
+
+
+function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1;
+function GetTextures (rec: TDynRecord): TTexturesRec1Array;
+function GetPanels (rec: TDynRecord): TPanelsRec1Array;
+function GetItems (rec: TDynRecord): TItemsRec1Array;
+function GetAreas (rec: TDynRecord): TAreasRec1Array;
+function GetMonsters (rec: TDynRecord): TMonsterRec1Array;
+function GetTriggers (rec: TDynRecord): TTriggersRec1Array;
-{$INCLUDE mapstructsizes.inc}
implementation
-uses SysUtils;
+uses
+ e_log, xparser, xstreams;
+
+
+function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1;
+var
+ ws: TSFSMemoryChunkStream = nil;
+begin
+ FillChar(result, sizeof(result), 0);
+ if (rec = nil) then exit;
+ try
+ ws := TSFSMemoryChunkStream.Create(@result, sizeof(result));
+ rec.writeBinTo(ws, -1, true); // only fields
+ except // sorry
+ FillChar(result, sizeof(result), 0);
+ end;
+ ws.Free();
+end;
+
+
+function GetTextures (rec: TDynRecord): TTexturesRec1Array;
+var
+ ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
+ f: Integer;
+begin
+ result := nil;
+ fld := rec.field['texture'];
+ if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+ ws := TSFSMemoryChunkStream.Create(nil, 0);
+ try
+ SetLength(result, fld.list.count);
+ for f := 0 to fld.list.count-1 do
+ begin
+ FillChar(result[f], sizeof(result[f]), 0);
+ ws.setup(@result[f], sizeof(result[f]));
+ fld.list[f].writeBinTo(ws, -1, true); // only fields
+ end;
+ except
+ result := nil;
+ end;
+ ws.Free();
+end;
+
+
+function GetPanels (rec: TDynRecord): TPanelsRec1Array;
+var
+ ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
+ f: Integer;
+begin
+ result := nil;
+ fld := rec.field['panel'];
+ if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+ ws := TSFSMemoryChunkStream.Create(nil, 0);
+ try
+ SetLength(result, fld.list.count);
+ for f := 0 to fld.list.count-1 do
+ begin
+ FillChar(result[f], sizeof(result[f]), 0);
+ ws.setup(@result[f], sizeof(result[f]));
+ fld.list[f].writeBinTo(ws, -1, true); // only fields
+ end;
+ except
+ result := nil;
+ end;
+ ws.Free();
+end;
+
+
+function GetItems (rec: TDynRecord): TItemsRec1Array;
+var
+ ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
+ f: Integer;
+begin
+ result := nil;
+ fld := rec.field['item'];
+ if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+ ws := TSFSMemoryChunkStream.Create(nil, 0);
+ try
+ SetLength(result, fld.list.count);
+ for f := 0 to fld.list.count-1 do
+ begin
+ FillChar(result[f], sizeof(result[f]), 0);
+ ws.setup(@result[f], sizeof(result[f]));
+ fld.list[f].writeBinTo(ws, -1, true); // only fields
+ end;
+ except
+ result := nil;
+ end;
+ ws.Free();
+end;
+
+
+function GetAreas (rec: TDynRecord): TAreasRec1Array;
+var
+ ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
+ f: Integer;
+begin
+ result := nil;
+ fld := rec.field['area'];
+ if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+ ws := TSFSMemoryChunkStream.Create(nil, 0);
+ try
+ SetLength(result, fld.list.count);
+ for f := 0 to fld.list.count-1 do
+ begin
+ FillChar(result[f], sizeof(result[f]), 0);
+ ws.setup(@result[f], sizeof(result[f]));
+ fld.list[f].writeBinTo(ws, -1, true); // only fields
+ end;
+ except
+ result := nil;
+ end;
+ ws.Free();
+end;
+
+
+function GetMonsters (rec: TDynRecord): TMonsterRec1Array;
+var
+ ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
+ f: Integer;
+begin
+ result := nil;
+ fld := rec.field['monster'];
+ if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+ ws := TSFSMemoryChunkStream.Create(nil, 0);
+ try
+ SetLength(result, fld.list.count);
+ for f := 0 to fld.list.count-1 do
+ begin
+ FillChar(result[f], sizeof(result[f]), 0);
+ ws.setup(@result[f], sizeof(result[f]));
+ fld.list[f].writeBinTo(ws, -1, true); // only fields
+ end;
+ except
+ result := nil;
+ end;
+ ws.Free();
+end;
+
+
+function GetTriggers (rec: TDynRecord): TTriggersRec1Array;
+var
+ ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
+ f: Integer;
+ //wr: TTextWriter;
+ //fo: File;
+begin
+ result := nil;
+ fld := rec.field['trigger'];
+ if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+ ws := TSFSMemoryChunkStream.Create(nil, 0);
+ try
+ //wr := TFileTextWriter.Create('z00.txt');
+ SetLength(result, fld.list.count);
+ for f := 0 to fld.list.count-1 do
+ begin
+ FillChar(result[f], sizeof(result[f]), 0);
+ //e_LogWritefln(': trigger #%s; TexturePanel=%s', [f, result[f].TexturePanel]);
+ ws.setup(@result[f], sizeof(result[f]));
+ fld.list[f].writeBinTo(ws, -1, true); // only fields
+ {
+ e_LogWritefln(': trigger #%s; X=%s; Y=%s; Width=%s; Height=%s; Enabled=%s; TexturePanel=%s; TriggerType=%s; ActivateType=%s; Keys=%s', [f,
+ result[f].X,
+ result[f].Y,
+ result[f].Width,
+ result[f].Height,
+ result[f].Enabled,
+ result[f].TexturePanel,
+ result[f].TriggerType,
+ result[f].ActivateType,
+ result[f].Keys
+ ]);
+ //e_LogWritefln('***'#10'%s'#10'***', [);
+ fld.list[f].writeTo(wr);
+ if (f = 0) then
+ begin
+ AssignFile(fo, 'z00.bin');
+ Rewrite(fo, 1);
+ BlockWrite(fo, result[f], sizeof(result[f]));
+ CloseFile(fo);
+ end;
+ }
+ end;
+ //wr.Free();
+ except
+ result := nil;
+ end;
+ ws.Free();
+end;
-{$INCLUDE mapstructio.inc}
end.
diff --git a/src/shared/MAPREADER.pas b/src/shared/MAPREADER.pas
--- a/src/shared/MAPREADER.pas
+++ /dev/null
@@ -1,424 +0,0 @@
-(* Copyright (C) DooM 2D:Forever Developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE a_modes.inc}
-unit MAPREADER;
-
-{
------------------------------------
-MAPREADER.PAS ÂÅÐÑÈß ÎÒ 13.11.07
-
-Ïîääåðæêà êàðò âåðñèè 1
------------------------------------
-}
-
-interface
-
-uses
- MAPSTRUCT;
-
-type
- TDataBlock = packed record
- Block: TBlock;
- Data: Pointer;
- end;
-
- TDataBlocksArray = packed array of TDataBlock;
-
- TMapReader = class(TObject)
- private
- FError: Byte;
- FVersion: Byte;
- FDataBlocks: TDataBlocksArray;
- function GetBlocks(BlocksType: Byte): TDataBlocksArray;
- public
- constructor Create();
- destructor Destroy(); override;
- function LoadMap(Data: Pointer): Boolean;
- procedure FreeMap();
- function HandledVersion(): Byte; virtual;
-
- property GetError: Byte read FError;
- property GetVersion: Byte read FVersion;
- end;
-
- TMapReader_1 = class(TMapReader)
- private
- public
- function GetMapHeader(): TMapHeaderRec_1;
- function GetTextures(): TTexturesRec1Array;
- function GetPanels(): TPanelsRec1Array;
- function GetItems(): TItemsRec1Array;
- function GetAreas(): TAreasRec1Array;
- function GetMonsters(): TMonsterRec1Array;
- function GetTriggers(): TTriggersRec1Array;
- function HandledVersion(): Byte; override;
- end;
-
-const
- MAP_ERROR_NONE = $00;
- MAP_ERROR_SIGNATURE = $01;
- MAP_ERROR_VERSION = $02;
-
- NNF_NO_NAME = 0;
- NNF_NAME_BEFORE = 1;
- NNF_NAME_EQUALS = 2;
- NNF_NAME_AFTER = 3;
-
-function g_Texture_NumNameFindStart(name: String): Boolean;
-function g_Texture_NumNameFindNext(var newName: String): Byte;
-
-implementation
-
-uses
- SysUtils, BinEditor, MAPDEF;
-
-var
- NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
- NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
- NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
-
-function g_Texture_NumNameFindStart(name: String): Boolean;
-var
- i: Integer;
-
-begin
- Result := False;
- NNF_PureName := '';
- NNF_FirstNum := -1;
- NNF_CurrentNum := -1;
-
- for i := Length(name) downto 1 do
- if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
- begin
- if i = Length(name) then
- begin // Íåò öèôð â êîíöå ñòðîêè
- Exit;
- end
- else
- begin
- NNF_PureName := Copy(name, 1, i);
- Delete(name, 1, i);
- Break;
- end;
- end;
-
-// Íå ïåðåâåñòè â ÷èñëî:
- if not TryStrToInt(name, NNF_FirstNum) then
- Exit;
-
- NNF_CurrentNum := 0;
-
- Result := True;
-end;
-
-function g_Texture_NumNameFindNext(var newName: String): Byte;
-begin
- if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
- begin
- newName := '';
- Result := NNF_NO_NAME;
- Exit;
- end;
-
- newName := NNF_PureName + IntToStr(NNF_CurrentNum);
-
- if NNF_CurrentNum < NNF_FirstNum then
- Result := NNF_NAME_BEFORE
- else
- if NNF_CurrentNum > NNF_FirstNum then
- Result := NNF_NAME_AFTER
- else
- Result := NNF_NAME_EQUALS;
-
- Inc(NNF_CurrentNum);
-end;
-
-{ T M a p R e a d e r _ 1 : }
-
-function TMapReader_1.GetAreas(): TAreasRec1Array;
-var
- TempDataBlocks: TDataBlocksArray;
- a: Integer;
- b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_AREAS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TAreaRec_1;
-
- for a := 0 to High(TempDataBlocks) do
- for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
- begin
- SetLength(Result, Length(Result)+1);
- //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
- mb_Read_TAreaRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
- end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetItems(): TItemsRec1Array;
-var
- TempDataBlocks: TDataBlocksArray;
- a: Integer;
- b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_ITEMS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TItemRec_1;
-
- for a := 0 to High(TempDataBlocks) do
- for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
- begin
- SetLength(Result, Length(Result)+1);
- //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
- mb_Read_TItemRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
- end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetMapHeader(): TMapHeaderRec_1;
-var
- TempDataBlocks: TDataBlocksArray;
-begin
- ZeroMemory(@Result, SizeOf(TMapHeaderRec_1));
-
- TempDataBlocks := GetBlocks(BLOCK_HEADER);
-
- if TempDataBlocks = nil then Exit;
-
- //CopyMemory(@Result, TempDataBlocks[0].Data, SizeOf(TMapHeaderRec_1));
- mb_Read_TMapHeaderRec_1(Result, TempDataBlocks[0].Data^, SizeOf_TMapHeaderRec_1);
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetMonsters(): TMonsterRec1Array;
-var
- TempDataBlocks: TDataBlocksArray;
- a: Integer;
- b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_MONSTERS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TMonsterRec_1;
-
- for a := 0 to High(TempDataBlocks) do
- for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
- begin
- SetLength(Result, Length(Result)+1);
- //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
- mb_Read_TMonsterRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
- end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetPanels(): TPanelsRec1Array;
-var
- TempDataBlocks: TDataBlocksArray;
- a: Integer;
- b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_PANELS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TPanelRec_1;
-
- for a := 0 to High(TempDataBlocks) do
- for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
- begin
- SetLength(Result, Length(Result)+1);
- //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
- mb_Read_TPanelRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
- end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetTextures(): TTexturesRec1Array;
-var
- TempDataBlocks: TDataBlocksArray;
- a: Integer;
- b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_TEXTURES);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TTextureRec_1;
-
- for a := 0 to High(TempDataBlocks) do
- for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
- begin
- SetLength(Result, Length(Result)+1);
- //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
- mb_Read_TTextureRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
- end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetTriggers(): TTriggersRec1Array;
-var
- TempDataBlocks: TDataBlocksArray;
- a: Integer;
- b: NativeUInt;
- Size: LongWord;
- trdata: TTriggerData;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_TRIGGERS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TTriggerRec_1;
-
- for a := 0 to High(TempDataBlocks) do
- for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
- begin
- SetLength(Result, Length(Result)+1);
- //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
- mb_Read_TTriggerRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
- if (Result[High(Result)].TriggerType <> 0) then
- begin
- // preprocess trigger data
- ZeroMemory(@trdata, SizeOf(trdata));
- mb_Read_TriggerData(trdata, Result[High(Result)].TriggerType, Result[High(Result)].DATA, sizeof(trdata));
- Result[High(Result)].DATA := trdata.Default;
- end;
- end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.HandledVersion: Byte;
-begin
- Result := $01;
-end;
-
-{ T M a p R e a d e r : }
-
-constructor TMapReader.Create();
-begin
- FDataBlocks := nil;
- FError := MAP_ERROR_NONE;
- FVersion := $00;
-end;
-
-destructor TMapReader.Destroy();
-begin
- FreeMap();
-
- inherited;
-end;
-
-procedure TMapReader.FreeMap();
-var
- a: Integer;
-begin
- if FDataBlocks <> nil then
- for a := 0 to High(FDataBlocks) do
- if FDataBlocks[a].Data <> nil then FreeMem(FDataBlocks[a].Data);
-
- FDataBlocks := nil;
- FVersion := $00;
- FError := MAP_ERROR_NONE;
-end;
-
-function TMapReader.GetBlocks(BlocksType: Byte): TDataBlocksArray;
-var
- a: Integer;
-begin
- Result := nil;
-
- if FDataBlocks = nil then Exit;
-
- for a := 0 to High(FDataBlocks) do
- if FDataBlocks[a].Block.BlockType = BlocksType then
- begin
- SetLength(Result, Length(Result)+1);
- Result[High(Result)] := FDataBlocks[a];
- end;
-end;
-
-function TMapReader.HandledVersion(): Byte;
-begin
- Result := $00;
-end;
-
-function TMapReader.LoadMap(Data: Pointer): Boolean;
-var
- adr: NativeUInt;
- _id: Integer;
- Sign: array[0..2] of Char;
- Ver: Byte;
-begin
- Result := False;
-
- CopyMemory(@Sign[0], Data, 3);
- if Sign <> MAP_SIGNATURE then
- begin
- FError := MAP_ERROR_SIGNATURE;
- Exit;
- end;
- adr := 3;
-
- CopyMemory(@Ver, Pointer(NativeUInt(Data)+adr), 1);
- FVersion := Ver;
- if Ver > HandledVersion() then
- begin
- FError := MAP_ERROR_VERSION;
- Exit;
- end;
- adr := adr+1;
-
- repeat
- SetLength(FDataBlocks, Length(FDataBlocks)+1);
- _id := High(FDataBlocks);
-
- CopyMemory(@FDataBlocks[_id].Block, Pointer(NativeUInt(Data)+adr), SizeOf(TBlock));
- adr := adr+SizeOf(TBlock);
-
- FDataBlocks[_id].Data := GetMemory(FDataBlocks[_id].Block.BlockSize);
-
- CopyMemory(FDataBlocks[_id].Data, Pointer(NativeUInt(Data)+adr), FDataBlocks[_id].Block.BlockSize);
-
- adr := adr+FDataBlocks[_id].Block.BlockSize;
- until FDataBlocks[_id].Block.BlockType = BLOCK_NONE;
-
- Result := True;
-end;
-
-end.
diff --git a/src/shared/MAPSTRUCT.pas b/src/shared/MAPSTRUCT.pas
--- a/src/shared/MAPSTRUCT.pas
+++ /dev/null
@@ -1,144 +0,0 @@
-(* Copyright (C) DooM 2D:Forever Developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE a_modes.inc}
-{$M+}
-unit MAPSTRUCT;
-
-{
------------------------------------
-MAPSTRUCT.PAS ÂÅÐÑÈß ÎÒ 13.11.07
-
-Ïîääåðæêà êàðò âåðñèè 1
------------------------------------
-}
-
-{
- Êàðòà ïðåäñòàâëÿåò ñîáîþ WAD, â êîòîðîì ðåñóðñû â êîðíå - ñîáñòâåííî ñàìè êàðòû
- (MAP01, MAP02 è ò.ä.).
-
- Áëîêè çàêàí÷èâàþòñÿ íóëåâûì áëîêîì (BlockType=BLOCK_NONE)
-
- Ñòðóêòóðà êàðòû (MAP01, MAP02...):
- --------------------------------------
- SIGNATURE | Byte[3] | 'MAP'
- VERSION | Byte | $01
- BLOCK1 | TBlock |
- BLOCK1DATA | RAW |
- ... | ...... |
- BLOCKN | TBlock |
- BLOCKNDATA | RAW |
- --------------------------------------
-
- Ñòðóêòóðà áëîêà:
- --------------------------------------
- BLOCKTYPE | Byte | (BLOCK_TEXTURES, BLOCK_PANELS,...)
- RESERVED | LongWord | $00000000
- BLOCKSIZE | LongWord | Ñêîëüêî ýòîò áëîê â ðàçìåðå (áàéò ïîñëå record'à)
- --------------------------------------
-}
-
-interface
-
-const
- MAP_SIGNATURE = 'MAP';
- BLOCK_NONE = 0;
- BLOCK_TEXTURES = 1;
- BLOCK_PANELS = 2;
- BLOCK_ITEMS = 3;
- BLOCK_AREAS = 4;
- BLOCK_MONSTERS = 5;
- BLOCK_TRIGGERS = 6;
- BLOCK_HEADER = 7;
-
-type
- Char16 = packed array[0..15] of Char;
- Char32 = packed array[0..31] of Char;
- Char64 = packed array[0..63] of Char;
- Char100 = packed array[0..99] of Char;
- Char256 = packed array[0..255] of Char;
- Byte128 = packed array[0..127] of Byte;
-
- TMapHeaderRec_1 = packed record
- MapName: Char32;
- MapAuthor: Char32;
- MapDescription: Char256;
- MusicName: Char64;
- SkyName: Char64;
- Width: Word;
- Height: Word;
- end;
-
- TTextureRec_1 = packed record
- Resource: Char64;
- Anim: Byte;
- end;
-
- TPanelRec_1 = packed record
- X, Y: Integer;
- Width,
- Height: Word;
- TextureNum: Word;
- PanelType: Word;
- Alpha: Byte;
- Flags: Byte;
- end;
-
- TItemRec_1 = packed record
- X, Y: Integer;
- ItemType: Byte;
- Options: Byte;
- end;
-
- TMonsterRec_1 = packed record
- X, Y: Integer;
- MonsterType: Byte;
- Direction: Byte;
- end;
-
- TAreaRec_1 = packed record
- X, Y: Integer;
- AreaType: Byte;
- Direction: Byte;
- end;
-
- TTriggerRec_1 = packed record
- X, Y: Integer;
- Width,
- Height: Word;
- Enabled: Byte;
- TexturePanel: Integer;
- TriggerType: Byte;
- ActivateType: Byte;
- Keys: Byte;
- DATA: Byte128; //WARNING! should be exactly equal to sizeof(TTriggerData)
- end;
-
- TBlock = packed record
- BlockType: Byte;
- Reserved: LongWord;
- BlockSize: LongWord;
- end;
-
- TTexturesRec1Array = array of TTextureRec_1;
- TPanelsRec1Array = array of TPanelRec_1;
- TItemsRec1Array = array of TItemRec_1;
- TMonsterRec1Array = array of TMonsterRec_1;
- TAreasRec1Array = array of TAreaRec_1;
- TTriggersRec1Array = array of TTriggerRec_1;
-
-implementation
-
-end.
diff --git a/src/shared/mapdef.inc b/src/shared/mapdef.inc
--- /dev/null
+++ b/src/shared/mapdef.inc
@@ -0,0 +1,1148 @@
+// *** WARNING! ***
+// regenerate this part directly from "mapdef.txt" with 'zmapgen', NEVER manually change anything here!
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// enums and bitsets
+
+// TextureSpecial
+const
+ TEXTURE_SPECIAL_WATER = -1;
+ TEXTURE_SPECIAL_ACID1 = -2;
+ TEXTURE_SPECIAL_ACID2 = -3;
+ TEXTURE_NONE = -4;
+
+// DirType
+const
+ DIR_LEFT = 0;
+ DIR_RIGHT = 1;
+ DIR_SOMETHING2 = 2;
+
+// TriggerType
+const
+ TRIGGER_NONE = 0;
+ TRIGGER_EXIT = 1;
+ TRIGGER_TELEPORT = 2;
+ TRIGGER_OPENDOOR = 3;
+ TRIGGER_CLOSEDOOR = 4;
+ TRIGGER_DOOR = 5;
+ TRIGGER_DOOR5 = 6;
+ TRIGGER_CLOSETRAP = 7;
+ TRIGGER_TRAP = 8;
+ TRIGGER_PRESS = 9;
+ TRIGGER_SECRET = 10;
+ TRIGGER_LIFTUP = 11;
+ TRIGGER_LIFTDOWN = 12;
+ TRIGGER_LIFT = 13;
+ TRIGGER_TEXTURE = 14;
+ TRIGGER_ON = 15;
+ TRIGGER_OFF = 16;
+ TRIGGER_ONOFF = 17;
+ TRIGGER_SOUND = 18;
+ TRIGGER_SPAWNMONSTER = 19;
+ TRIGGER_SPAWNITEM = 20;
+ TRIGGER_MUSIC = 21;
+ TRIGGER_PUSH = 22;
+ TRIGGER_SCORE = 23;
+ TRIGGER_MESSAGE = 24;
+ TRIGGER_DAMAGE = 25;
+ TRIGGER_HEALTH = 26;
+ TRIGGER_SHOT = 27;
+ TRIGGER_EFFECT = 28;
+ TRIGGER_SCRIPT = 29;
+ TRIGGER_MAX = 29;
+
+// PanelType
+const
+ PANEL_NONE = 0;
+ PANEL_WALL = 1;
+ PANEL_BACK = 2;
+ PANEL_FORE = 4;
+ PANEL_WATER = 8;
+ PANEL_ACID1 = 16;
+ PANEL_ACID2 = 32;
+ PANEL_STEP = 64;
+ PANEL_LIFTUP = 128;
+ PANEL_LIFTDOWN = 256;
+ PANEL_OPENDOOR = 512;
+ PANEL_CLOSEDOOR = 1024;
+ PANEL_BLOCKMON = 2048;
+ PANEL_LIFTLEFT = 4096;
+ PANEL_LIFTRIGHT = 8192;
+
+// PanelFlag
+const
+ PANEL_FLAG_NONE = 0;
+ PANEL_FLAG_BLENDING = 1;
+ PANEL_FLAG_HIDE = 2;
+ PANEL_FLAG_WATERTEXTURES = 4;
+
+// EffectAction
+const
+ EFFECT_NONE = 0;
+ EFFECT_TELEPORT = 1;
+ EFFECT_RESPAWN = 2;
+ EFFECT_FIRE = 3;
+
+// Item
+const
+ ITEM_NONE = 0;
+ ITEM_MEDKIT_SMALL = 1;
+ ITEM_MEDKIT_LARGE = 2;
+ ITEM_MEDKIT_BLACK = 3;
+ ITEM_ARMOR_GREEN = 4;
+ ITEM_ARMOR_BLUE = 5;
+ ITEM_SPHERE_BLUE = 6;
+ ITEM_SPHERE_WHITE = 7;
+ ITEM_SUIT = 8;
+ ITEM_OXYGEN = 9;
+ ITEM_INVUL = 10;
+ ITEM_WEAPON_SAW = 11;
+ ITEM_WEAPON_SHOTGUN1 = 12;
+ ITEM_WEAPON_SHOTGUN2 = 13;
+ ITEM_WEAPON_CHAINGUN = 14;
+ ITEM_WEAPON_ROCKETLAUNCHER = 15;
+ ITEM_WEAPON_PLASMA = 16;
+ ITEM_WEAPON_BFG = 17;
+ ITEM_WEAPON_SUPERPULEMET = 18;
+ ITEM_AMMO_BULLETS = 19;
+ ITEM_AMMO_BULLETS_BOX = 20;
+ ITEM_AMMO_SHELLS = 21;
+ ITEM_AMMO_SHELLS_BOX = 22;
+ ITEM_AMMO_ROCKET = 23;
+ ITEM_AMMO_ROCKET_BOX = 24;
+ ITEM_AMMO_CELL = 25;
+ ITEM_AMMO_CELL_BIG = 26;
+ ITEM_AMMO_BACKPACK = 27;
+ ITEM_KEY_RED = 28;
+ ITEM_KEY_GREEN = 29;
+ ITEM_KEY_BLUE = 30;
+ ITEM_WEAPON_KASTET = 31;
+ ITEM_WEAPON_PISTOL = 32;
+ ITEM_BOTTLE = 33;
+ ITEM_HELMET = 34;
+ ITEM_JETPACK = 35;
+ ITEM_INVIS = 36;
+ ITEM_WEAPON_FLAMETHROWER = 37;
+ ITEM_AMMO_FUELCAN = 38;
+ ITEM_MAX = 38;
+
+// ItemOption
+const
+ ITEM_OPTION_NONE = 0;
+ ITEM_OPTION_ONLYDM = 1;
+ ITEM_OPTION_FALL = 2;
+
+// AreaType
+const
+ AREA_NONE = 0;
+ AREA_PLAYERPOINT1 = 1;
+ AREA_PLAYERPOINT2 = 2;
+ AREA_DMPOINT = 3;
+ AREA_REDFLAG = 4;
+ AREA_BLUEFLAG = 5;
+ AREA_DOMFLAG = 6;
+ AREA_REDTEAMPOINT = 7;
+ AREA_BLUETEAMPOINT = 8;
+
+// Monster
+const
+ MONSTER_NONE = 0;
+ MONSTER_DEMON = 1;
+ MONSTER_IMP = 2;
+ MONSTER_ZOMBY = 3;
+ MONSTER_SERG = 4;
+ MONSTER_CYBER = 5;
+ MONSTER_CGUN = 6;
+ MONSTER_BARON = 7;
+ MONSTER_KNIGHT = 8;
+ MONSTER_CACO = 9;
+ MONSTER_SOUL = 10;
+ MONSTER_PAIN = 11;
+ MONSTER_SPIDER = 12;
+ MONSTER_BSP = 13;
+ MONSTER_MANCUB = 14;
+ MONSTER_SKEL = 15;
+ MONSTER_VILE = 16;
+ MONSTER_FISH = 17;
+ MONSTER_BARREL = 18;
+ MONSTER_ROBO = 19;
+ MONSTER_MAN = 20;
+
+// TriggerShot
+const
+ TRIGGER_SHOT_PISTOL = 0;
+ TRIGGER_SHOT_BULLET = 1;
+ TRIGGER_SHOT_SHOTGUN = 2;
+ TRIGGER_SHOT_SSG = 3;
+ TRIGGER_SHOT_IMP = 4;
+ TRIGGER_SHOT_PLASMA = 5;
+ TRIGGER_SHOT_SPIDER = 6;
+ TRIGGER_SHOT_CACO = 7;
+ TRIGGER_SHOT_BARON = 8;
+ TRIGGER_SHOT_MANCUB = 9;
+ TRIGGER_SHOT_REV = 10;
+ TRIGGER_SHOT_ROCKET = 11;
+ TRIGGER_SHOT_BFG = 12;
+ TRIGGER_SHOT_EXPL = 13;
+ TRIGGER_SHOT_BFGEXPL = 14;
+ TRIGGER_SHOT_MAX = 14;
+
+// TriggerShotTarget
+const
+ TRIGGER_SHOT_TARGET_NONE = 0;
+ TRIGGER_SHOT_TARGET_MON = 1;
+ TRIGGER_SHOT_TARGET_PLR = 2;
+ TRIGGER_SHOT_TARGET_RED = 3;
+ TRIGGER_SHOT_TARGET_BLUE = 4;
+ TRIGGER_SHOT_TARGET_MONPLR = 5;
+ TRIGGER_SHOT_TARGET_PLRMON = 6;
+
+// TriggerShotAim
+const
+ TRIGGER_SHOT_AIM_DEFAULT = 0;
+ TRIGGER_SHOT_AIM_ALLMAP = 1;
+ TRIGGER_SHOT_AIM_TRACE = 2;
+ TRIGGER_SHOT_AIM_TRACEALL = 3;
+
+// TriggerEffect
+const
+ TRIGGER_EFFECT_PARTICLE = 0;
+ TRIGGER_EFFECT_ANIMATION = 1;
+
+// TriggerEffectType
+const
+ TRIGGER_EFFECT_SLIQUID = 0;
+ TRIGGER_EFFECT_LLIQUID = 1;
+ TRIGGER_EFFECT_DLIQUID = 2;
+ TRIGGER_EFFECT_BLOOD = 3;
+ TRIGGER_EFFECT_SPARK = 4;
+ TRIGGER_EFFECT_BUBBLE = 5;
+ TRIGGER_EFFECT_MAX = 5;
+
+// TriggerEffectPos
+const
+ TRIGGER_EFFECT_POS_CENTER = 0;
+ TRIGGER_EFFECT_POS_AREA = 1;
+
+// ActivateType
+const
+ ACTIVATE_NONE = 0;
+ ACTIVATE_PLAYERCOLLIDE = 1;
+ ACTIVATE_MONSTERCOLLIDE = 2;
+ ACTIVATE_PLAYERPRESS = 4;
+ ACTIVATE_MONSTERPRESS = 8;
+ ACTIVATE_SHOT = 16;
+ ACTIVATE_NOMONSTER = 32;
+ ACTIVATE_CUSTOM = 255;
+
+// Key
+const
+ KEY_NONE = 0;
+ KEY_RED = 1;
+ KEY_GREEN = 2;
+ KEY_BLUE = 4;
+ KEY_REDTEAM = 8;
+ KEY_BLUETEAM = 16;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// records
+type
+ TMapHeaderRec_1 = packed record
+ MapName: Char32;
+ MapAuthor: Char32;
+ MapDescription: Char256;
+ MusicName: Char64;
+ SkyName: Char64;
+ Width, Height: Word;
+ end;
+
+ TTextureRec_1 = packed record
+ Resource: Char64;
+ Anim: Boolean;
+ end;
+
+ TPanelRec_1 = packed record
+ X, Y: Integer;
+ Width, Height: Word;
+ TextureNum: Word;
+ PanelType: Word;
+ Alpha: Byte;
+ Flags: Byte;
+ end;
+
+ TItemRec_1 = packed record
+ X, Y: Integer;
+ ItemType: Byte;
+ Options: Byte;
+ end;
+
+ TMonsterRec_1 = packed record
+ X, Y: Integer;
+ MonsterType: Byte;
+ Direction: Byte;
+ end;
+
+ TAreaRec_1 = packed record
+ X, Y: Integer;
+ AreaType: Byte;
+ Direction: Byte;
+ end;
+
+ TTriggerRec_1 = packed record
+ X, Y: Integer;
+ Width, Height: Word;
+ Enabled: Boolean;
+ TexturePanel: LongInt;
+ TriggerType: Byte;
+ ActivateType: Byte;
+ Keys: Byte;
+ DATA: Byte128;
+ end;
+
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// triggerdata
+type
+ TTriggerData = record
+ case Byte of
+ 0: (Default: Byte128);
+ TRIGGER_EXIT: (
+ MapName: Char16;
+ );
+ TRIGGER_TELEPORT: (
+ TargetPoint: TDFPoint;
+ d2d_teleport: Boolean;
+ silent_teleport: Boolean;
+ TlpDir: Byte;
+ );
+ TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT: (
+ PanelID: LongInt;
+ NoSound: Boolean;
+ d2d_doors: Boolean;
+ );
+ TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF: (
+ tX, tY: Integer;
+ tWidth, tHeight: Word;
+ Wait: Word;
+ Count: Word;
+ MonsterID: LongInt;
+ ExtRandom: Boolean;
+ );
+ TRIGGER_SECRET: (
+ );
+ TRIGGER_TEXTURE: (
+ ActivateOnce: Boolean;
+ AnimOnce: Boolean;
+ );
+ TRIGGER_SOUND: (
+ SoundName: Char64;
+ Volume: Byte;
+ Pan: Byte;
+ Local: Boolean;
+ PlayCount: Byte;
+ SoundSwitch: Boolean;
+ );
+ TRIGGER_SPAWNMONSTER: (
+ MonPos: TDFPoint;
+ MonType: Byte;
+ MonHealth: LongInt;
+ MonDir: Byte;
+ MonActive: Boolean;
+ MonCount: LongInt;
+ MonEffect: Byte;
+ MonMax: Word;
+ MonDelay: Word;
+ MonBehav: Byte;
+ );
+ TRIGGER_SPAWNITEM: (
+ ItemPos: TDFPoint;
+ ItemType: Byte;
+ ItemFalls: Boolean;
+ ItemOnlyDM: Boolean;
+ ItemCount: LongInt;
+ ItemEffect: Byte;
+ ItemMax: Word;
+ ItemDelay: Word;
+ );
+ TRIGGER_MUSIC: (
+ MusicName: Char64;
+ MusicAction: Byte;
+ );
+ TRIGGER_PUSH: (
+ PushAngle: Word;
+ PushForce: Byte;
+ ResetVel: Boolean;
+ );
+ TRIGGER_SCORE: (
+ ScoreAction: Byte;
+ ScoreCount: Byte;
+ ScoreTeam: Byte;
+ ScoreCon: Boolean;
+ ScoreMsg: Boolean;
+ );
+ TRIGGER_MESSAGE: (
+ MessageKind: Byte;
+ MessageSendTo: Byte;
+ MessageText: Char100;
+ MessageTime: Word;
+ );
+ TRIGGER_DAMAGE: (
+ DamageValue: Word;
+ DamageInterval: Word;
+ );
+ TRIGGER_HEALTH: (
+ HealValue: Word;
+ HealInterval: Word;
+ HealMax: Boolean;
+ HealSilent: Boolean;
+ );
+ TRIGGER_SHOT: (
+ ShotPos: TDFPoint;
+ ShotType: Byte;
+ ShotTarget: Byte;
+ ShotSound: Boolean;
+ ShotAim: ShortInt;
+ ShotPanelID: LongInt;
+ ShotIntSight: Word;
+ ShotAngle: Word;
+ ShotWait: Word;
+ ShotAccuracy: Word;
+ ShotAmmo: Word;
+ ShotIntReload: Word;
+ );
+ TRIGGER_EFFECT: (
+ FXCount: Byte;
+ FXType: Byte;
+ FXSubType: Byte;
+ FXColorR: Byte;
+ FXColorG: Byte;
+ FXColorB: Byte;
+ FXPos: Byte;
+ FXWait: Word;
+ FXVelX: ShortInt;
+ FXVelY: ShortInt;
+ FXSpreadL: Byte;
+ FXSpreadR: Byte;
+ FXSpreadU: Byte;
+ FXSpreadD: Byte;
+ );
+ end;
+
+
+const defaultMapDef: AnsiString = ''+
+ #47#47#32#121#101#115#44#32#116#104#105#115#32#102#105#108#101#32#115#101+
+ #114#118#101#115#32#98#111#116#104#32#97#115#32#102#111#114#109#97#116#32+
+ #100#101#115#99#114#105#112#116#105#111#110#32#97#110#100#32#97#115#32#116+
+ #101#109#112#108#97#116#101#32#102#111#114#32#99#111#100#101#32#103#101#110+
+ #101#114#97#116#105#111#110#10#47#47#32#116#104#101#32#101#110#103#105#110+
+ #101#32#119#105#108#108#32#117#115#101#32#116#104#105#115#32#100#101#115#99+
+ #114#105#112#116#105#111#110#32#116#111#32#112#111#112#117#108#97#116#101#32+
+ #116#104#101#32#99#111#114#114#101#115#112#111#110#100#105#110#103#32#114+
+ #101#99#111#114#100#115#32#102#114#111#109#32#77#65#80#42#46#112#97#115#10+
+ #47#47#32#97#108#115#111#44#32#116#104#101#32#101#110#103#105#110#101#32#119+
+ #105#108#108#32#107#101#101#112#32#116#104#101#32#108#111#97#100#101#100#32+
+ #109#97#112#32#97#115#32#97#32#108#105#115#116#32#111#102#32#116#104#101#115+
+ #101#32#115#116#114#117#99#116#117#114#101#115#10#10#47#47#32#110#111#116+
+ #101#115#58#10#47#47#32#32#32#102#105#101#108#100#32#119#105#116#104#111#117+
+ #116#32#111#102#102#115#101#116#32#105#115#32#110#111#116#32#105#110#32#98+
+ #105#110#97#114#121#32#102#111#114#109#97#116#10#47#47#32#32#32#102#105#101+
+ #108#100#115#32#119#105#116#104#32#96#111#109#105#116#100#101#102#97#117#108+
+ #116#96#32#119#111#110#39#116#32#98#101#32#119#114#105#116#116#101#110#32+
+ #119#104#101#110#32#116#104#101#121#32#99#111#110#116#97#105#110#32#100#101+
+ #102#97#117#108#116#32#118#97#108#117#101#115#10#47#47#32#32#32#102#105#101+
+ #108#100#115#32#119#105#116#104#32#96#105#110#116#101#114#110#97#108#96#32+
+ #119#111#110#39#116#32#98#101#32#119#114#105#116#116#101#110#32#116#111#32+
+ #97#110#121#32#102#105#108#101#32#101#118#101#114#32#40#97#110#100#32#119+
+ #111#110#39#116#32#98#101#32#114#101#97#100#41#10#47#47#32#32#32#96#117#98+
+ #121#116#101#96#32#105#115#32#117#110#115#105#103#110#101#100#32#98#121#116+
+ #101#44#32#97#110#100#32#96#98#121#116#101#96#32#105#115#32#115#105#103#110+
+ #101#100#32#98#121#116#101#10#47#47#32#32#32#97#108#108#32#115#116#114#105+
+ #110#103#115#32#97#114#101#32#105#110#32#117#116#102#45#56#10#47#47#32#32#32+
+ #115#116#114#117#99#116#32#119#105#116#104#32#96#104#101#97#100#101#114#96+
+ #32#102#108#97#103#32#119#105#108#108#32#99#111#110#116#97#105#110#32#97#108+
+ #108#32#111#116#104#101#114#32#115#116#114#117#99#116#115#32#97#110#100#32+
+ #105#116#39#115#32#111#119#110#32#102#105#101#108#100#115#10#47#47#32#32#32+
+ #32#32#97#115#32#116#111#112#45#108#101#118#101#108#32#101#110#116#105#116+
+ #105#101#115#10#47#47#32#32#32#105#110#32#98#105#110#97#114#121#44#32#96#115+
+ #105#122#101#96#32#105#115#32#116#119#111#32#117#115#104#111#114#116#115#10+
+ #47#47#32#32#32#96#97#115#32#120#121#96#32#119#105#108#108#32#117#115#101#32+
+ #96#88#96#32#97#110#100#32#96#89#96#32#102#111#114#32#112#111#105#110#116+
+ #115#10#47#47#32#32#32#96#97#115#32#116#120#121#96#32#119#105#108#108#32#117+
+ #115#101#32#96#116#88#96#32#97#110#100#32#96#116#89#96#32#102#111#114#32#112+
+ #111#105#110#116#115#10#47#47#32#32#32#96#97#115#32#119#104#96#32#119#105+
+ #108#108#32#117#115#101#32#96#87#105#100#116#104#96#32#97#110#100#32#96#72+
+ #101#105#103#104#116#96#32#102#111#114#32#115#105#122#101#10#47#47#32#32#32+
+ #96#97#115#32#116#119#104#96#32#119#105#108#108#32#117#115#101#32#96#116#87+
+ #105#100#116#104#96#32#97#110#100#32#96#116#72#101#105#103#104#116#96#32#102+
+ #111#114#32#115#105#122#101#10#10#10#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#10#47#47#32#109#97#105+
+ #110#32#98#108#111#99#107#115#10#84#77#97#112#72#101#97#100#101#114#82#101+
+ #99#95#49#32#105#115#32#34#109#97#112#34#32#115#105#122#101#32#52#53#50#32+
+ #98#121#116#101#115#32#104#101#97#100#101#114#32#98#105#110#98#108#111#99+
+ #107#32#55#32#123#10#32#32#47#47#95#32#105#115#32#34#118#101#114#115#105#111+
+ #110#34#32#116#121#112#101#32#117#105#110#116#32#109#105#110#118#97#108#117+
+ #101#32#49#32#109#97#120#118#97#108#117#101#32#49#59#10#32#32#77#97#112#78+
+ #97#109#101#32#105#115#32#34#110#97#109#101#34#32#116#121#112#101#32#99#104+
+ #97#114#91#51#50#93#32#111#102#102#115#101#116#32#48#59#10#32#32#77#97#112+
+ #65#117#116#104#111#114#32#105#115#32#34#97#117#116#104#111#114#34#32#116+
+ #121#112#101#32#99#104#97#114#91#51#50#93#32#111#102#102#115#101#116#32#51+
+ #50#32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+ #117#108#116#59#10#32#32#77#97#112#68#101#115#99#114#105#112#116#105#111#110+
+ #32#105#115#32#34#100#101#115#99#114#105#112#116#105#111#110#34#32#116#121+
+ #112#101#32#99#104#97#114#91#50#53#54#93#32#111#102#102#115#101#116#32#54#52+
+ #32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+ #117#108#116#59#10#32#32#77#117#115#105#99#78#97#109#101#32#105#115#32#34+
+ #109#117#115#105#99#34#32#116#121#112#101#32#99#104#97#114#91#54#52#93#32+
+ #111#102#102#115#101#116#32#51#50#48#32#100#101#102#97#117#108#116#32#39#83+
+ #116#97#110#100#97#114#116#46#119#97#100#58#68#50#68#77#85#83#92#208#159#208+
+ #160#208#158#208#161#208#162#208#158#208#162#208#144#39#32#111#109#105#116+
+ #100#101#102#97#117#108#116#59#10#32#32#83#107#121#78#97#109#101#32#105#115+
+ #32#34#115#107#121#34#32#116#121#112#101#32#99#104#97#114#91#54#52#93#32#111+
+ #102#102#115#101#116#32#51#56#52#32#100#101#102#97#117#108#116#32#39#83#116+
+ #97#110#100#97#114#116#46#119#97#100#58#68#50#68#83#75#89#92#82#83#75#89#49+
+ #39#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47#47#87#105+
+ #100#116#104#32#105#115#32#34#119#105#100#116#104#34#32#116#121#112#101#32+
+ #117#115#104#111#114#116#32#111#102#102#115#101#116#32#52#52#56#59#10#32#32+
+ #47#47#72#101#105#103#104#116#32#105#115#32#34#104#101#105#103#104#116#34#32+
+ #116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#52+
+ #53#48#59#10#32#32#83#105#122#101#32#105#115#32#34#115#105#122#101#34#32#116+
+ #121#112#101#32#115#105#122#101#32#111#102#102#115#101#116#32#52#52#56#32#97+
+ #115#32#119#104#59#10#32#32#47#47#32#110#111#116#32#105#110#32#98#105#110#97+
+ #114#121#10#32#32#84#105#116#108#101#32#105#115#32#34#116#105#116#108#101#34+
+ #32#116#121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116+
+ #32#34#34#32#32#111#109#105#116#100#101#102#97#117#108#116#59#10#125#10#10+
+ #84#84#101#120#116#117#114#101#82#101#99#95#49#32#105#115#32#34#116#101#120+
+ #116#117#114#101#34#32#115#105#122#101#32#54#53#32#98#121#116#101#115#32#98+
+ #105#110#98#108#111#99#107#32#49#32#123#10#32#32#82#101#115#111#117#114#99+
+ #101#32#105#115#32#34#112#97#116#104#34#32#116#121#112#101#32#99#104#97#114+
+ #91#54#52#93#32#111#102#102#115#101#116#32#48#59#10#32#32#65#110#105#109#32+
+ #105#115#32#34#97#110#105#109#97#116#101#100#34#32#116#121#112#101#32#98#111+
+ #111#108#32#111#102#102#115#101#116#32#54#52#32#100#101#102#97#117#108#116+
+ #32#102#97#108#115#101#32#111#109#105#116#100#101#102#97#117#108#116#59#10+
+ #32#32#47#47#32#105#110#116#101#114#110#97#108#115#10#32#32#84#101#120#73+
+ #100#120#32#105#115#32#34#116#101#120#105#100#120#34#32#116#121#112#101#32+
+ #117#105#110#116#32#105#110#116#101#114#110#97#108#59#10#125#10#10#84#80#97+
+ #110#101#108#82#101#99#95#49#32#105#115#32#34#112#97#110#101#108#34#32#115+
+ #105#122#101#32#49#56#32#98#121#116#101#115#32#98#105#110#98#108#111#99#107+
+ #32#50#32#123#10#32#32#47#47#88#32#105#115#32#34#120#34#32#116#121#112#101+
+ #32#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47#89#32#105+
+ #115#32#34#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115#101+
+ #116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105#116#105+
+ #111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115#101+
+ #116#32#48#32#97#115#32#120#121#59#10#32#32#47#47#87#105#100#116#104#32#105+
+ #115#32#34#119#105#100#116#104#34#32#116#121#112#101#32#117#115#104#111#114+
+ #116#32#111#102#102#115#101#116#32#56#59#10#32#32#47#47#72#101#105#103#104+
+ #116#32#105#115#32#34#104#101#105#103#104#116#34#32#116#121#112#101#32#117+
+ #115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#59#10#32#32#83#105+
+ #122#101#32#105#115#32#34#115#105#122#101#34#32#116#121#112#101#32#115#105+
+ #122#101#32#111#102#102#115#101#116#32#56#32#97#115#32#119#104#32#97#115#32+
+ #119#104#59#10#32#32#84#101#120#116#117#114#101#78#117#109#32#105#115#32#34+
+ #116#101#120#116#117#114#101#34#32#116#121#112#101#32#117#115#104#111#114+
+ #116#32#111#102#102#115#101#116#32#49#50#32#116#101#120#116#117#114#101#59+
+ #10#32#32#80#97#110#101#108#84#121#112#101#32#105#115#32#34#116#121#112#101+
+ #34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116+
+ #32#49#52#32#98#105#116#115#101#116#32#117#110#105#113#117#101#32#80#97#110+
+ #101#108#84#121#112#101#59#10#32#32#65#108#112#104#97#32#105#115#32#34#97+
+ #108#112#104#97#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#49#54#32#100#101#102#97#117#108#116#32#48#32#111#109#105#116+
+ #100#101#102#97#117#108#116#59#10#32#32#70#108#97#103#115#32#105#115#32#34+
+ #102#108#97#103#115#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+
+ #102#115#101#116#32#49#55#32#98#105#116#115#101#116#32#80#97#110#101#108#70+
+ #108#97#103#32#100#101#102#97#117#108#116#32#80#65#78#69#76#95#70#76#65#71+
+ #95#78#79#78#69#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47+
+ #47#32#110#111#116#32#105#110#32#98#105#110#97#114#121#10#32#32#47#47#73#100+
+ #32#105#115#32#34#105#100#34#32#116#121#112#101#32#115#116#114#105#110#103+
+ #32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+ #117#108#116#59#10#32#32#47#47#32#105#110#116#101#114#110#97#108#115#10#32+
+ #32#80#97#110#73#100#120#32#105#115#32#34#112#97#110#105#100#120#34#32#116+
+ #121#112#101#32#117#105#110#116#32#105#110#116#101#114#110#97#108#59#10#125+
+ #10#10#84#73#116#101#109#82#101#99#95#49#32#105#115#32#34#105#116#101#109#34+
+ #32#115#105#122#101#32#49#48#32#98#121#116#101#115#32#98#105#110#98#108#111+
+ #99#107#32#51#32#123#10#32#32#47#47#88#32#105#115#32#34#120#34#32#116#121+
+ #112#101#32#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47+
+ #89#32#105#115#32#34#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102+
+ #115#101#116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105+
+ #116#105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102+
+ #115#101#116#32#48#32#97#115#32#120#121#59#10#32#32#73#116#101#109#84#121+
+ #112#101#32#105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117#98+
+ #121#116#101#32#111#102#102#115#101#116#32#56#32#101#110#117#109#32#73#116+
+ #101#109#59#10#32#32#79#112#116#105#111#110#115#32#105#115#32#34#111#112#116+
+ #105#111#110#115#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#57#32#98#105#116#115#101#116#32#73#116#101#109#79#112#116+
+ #105#111#110#32#100#101#102#97#117#108#116#32#73#84#69#77#95#79#80#84#73#79+
+ #78#95#78#79#78#69#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32+
+ #47#47#32#110#111#116#32#105#110#32#98#105#110#97#114#121#10#32#32#47#47#73+
+ #100#32#105#115#32#34#105#100#34#32#116#121#112#101#32#115#116#114#105#110+
+ #103#32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102+
+ #97#117#108#116#59#10#32#32#47#47#32#105#110#116#101#114#110#97#108#115#10+
+ #32#32#73#116#101#109#73#100#120#32#105#115#32#34#105#116#101#109#105#100+
+ #120#34#32#116#121#112#101#32#117#105#110#116#32#105#110#116#101#114#110#97+
+ #108#59#10#125#10#10#84#77#111#110#115#116#101#114#82#101#99#95#49#32#105+
+ #115#32#34#109#111#110#115#116#101#114#34#32#115#105#122#101#32#49#48#32#98+
+ #121#116#101#115#32#98#105#110#98#108#111#99#107#32#53#32#123#10#32#32#47#47+
+ #88#32#105#115#32#34#120#34#32#116#121#112#101#32#105#110#116#32#111#102#102+
+ #115#101#116#32#48#59#10#32#32#47#47#89#32#105#115#32#34#121#34#32#116#121+
+ #112#101#32#105#110#116#32#111#102#102#115#101#116#32#52#59#10#32#32#80#111+
+ #115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112#101+
+ #32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#32#97#115#32#120+
+ #121#59#10#32#32#77#111#110#115#116#101#114#84#121#112#101#32#105#115#32#34+
+ #116#121#112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#56#32#101#110#117#109#32#77#111#110#115#116#101#114#59#10#32+
+ #32#68#105#114#101#99#116#105#111#110#32#105#115#32#34#100#105#114#101#99+
+ #116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#57#32#101#110#117#109#32#68#105#114#84#121#112#101#32#100+
+ #101#102#97#117#108#116#32#68#73#82#95#76#69#70#84#32#111#109#105#116#100+
+ #101#102#97#117#108#116#59#10#32#32#47#47#32#110#111#116#32#105#110#32#98+
+ #105#110#97#114#121#10#32#32#47#47#73#100#32#105#115#32#34#105#100#34#32#116+
+ #121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116#32#34+
+ #34#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47#47#32#105+
+ #110#116#101#114#110#97#108#115#10#32#32#77#111#110#115#73#100#120#32#105+
+ #115#32#34#109#111#110#115#105#100#120#34#32#116#121#112#101#32#117#105#110+
+ #116#32#105#110#116#101#114#110#97#108#59#10#125#10#10#84#65#114#101#97#82+
+ #101#99#95#49#32#105#115#32#34#97#114#101#97#34#32#115#105#122#101#32#49#48+
+ #32#98#121#116#101#115#32#98#105#110#98#108#111#99#107#32#52#32#123#10#32#32+
+ #47#47#88#32#105#115#32#34#120#34#32#116#121#112#101#32#105#110#116#32#111+
+ #102#102#115#101#116#32#48#59#10#32#32#47#47#89#32#105#115#32#34#121#34#32+
+ #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#52#59#10#32#32+
+ #80#111#115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121+
+ #112#101#32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#32#97#115+
+ #32#120#121#59#10#32#32#65#114#101#97#84#121#112#101#32#105#115#32#34#116+
+ #121#112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+ #101#116#32#56#32#101#110#117#109#32#65#114#101#97#84#121#112#101#59#10#32+
+ #32#68#105#114#101#99#116#105#111#110#32#105#115#32#34#100#105#114#101#99+
+ #116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#57#32#101#110#117#109#32#68#105#114#84#121#112#101#32#100+
+ #101#102#97#117#108#116#32#68#73#82#95#76#69#70#84#32#111#109#105#116#100+
+ #101#102#97#117#108#116#59#10#32#32#47#47#32#110#111#116#32#105#110#32#98+
+ #105#110#97#114#121#10#32#32#47#47#73#100#32#105#115#32#34#105#100#34#32#116+
+ #121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116#32#34+
+ #34#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47#47#32#105+
+ #110#116#101#114#110#97#108#115#10#32#32#65#114#101#97#73#100#120#32#105#115+
+ #32#34#97#114#101#97#105#100#120#34#32#116#121#112#101#32#117#105#110#116#32+
+ #105#110#116#101#114#110#97#108#59#10#125#10#10#84#84#114#105#103#103#101+
+ #114#82#101#99#95#49#32#105#115#32#34#116#114#105#103#103#101#114#34#32#115+
+ #105#122#101#32#49#52#56#32#98#121#116#101#115#32#98#105#110#98#108#111#99+
+ #107#32#54#32#123#10#32#32#47#47#88#32#105#115#32#34#120#34#32#116#121#112+
+ #101#32#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47#89#32+
+ #105#115#32#34#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115+
+ #101#116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105#116+
+ #105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115+
+ #101#116#32#48#32#97#115#32#120#121#59#10#32#32#47#47#87#105#100#116#104#32+
+ #105#115#32#34#119#105#100#116#104#34#32#116#121#112#101#32#117#115#104#111+
+ #114#116#32#111#102#102#115#101#116#32#56#59#10#32#32#47#47#72#101#105#103+
+ #104#116#32#105#115#32#34#104#101#105#103#104#116#34#32#116#121#112#101#32+
+ #117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#59#10#32#32#83+
+ #105#122#101#32#105#115#32#34#115#105#122#101#34#32#116#121#112#101#32#115+
+ #105#122#101#32#111#102#102#115#101#116#32#56#32#97#115#32#119#104#59#10#32+
+ #32#69#110#97#98#108#101#100#32#105#115#32#34#101#110#97#98#108#101#100#34+
+ #32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#50#32+
+ #100#101#102#97#117#108#116#32#116#114#117#101#32#111#109#105#116#100#101+
+ #102#97#117#108#116#59#10#32#32#84#101#120#116#117#114#101#80#97#110#101#108+
+ #32#105#115#32#34#116#101#120#116#117#114#101#112#97#110#101#108#34#32#116+
+ #121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#51#32#112#97+
+ #110#101#108#32#100#101#102#97#117#108#116#32#110#117#108#108#32#111#109#105+
+ #116#100#101#102#97#117#108#116#59#10#32#32#84#114#105#103#103#101#114#84+
+ #121#112#101#32#105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117+
+ #98#121#116#101#32#111#102#102#115#101#116#32#49#55#32#101#110#117#109#32#84+
+ #114#105#103#103#101#114#84#121#112#101#59#10#32#32#65#99#116#105#118#97#116+
+ #101#84#121#112#101#32#105#115#32#34#97#99#116#105#118#97#116#101#116#121+
+ #112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+
+ #116#32#49#56#32#98#105#116#115#101#116#32#65#99#116#105#118#97#116#101#84+
+ #121#112#101#59#10#32#32#75#101#121#115#32#105#115#32#34#107#101#121#115#34+
+ #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49+
+ #57#32#98#105#116#115#101#116#32#75#101#121#32#100#101#102#97#117#108#116#32+
+ #75#69#89#95#78#79#78#69#32#111#109#105#116#100#101#102#97#117#108#116#59#10+
+ #32#32#47#47#87#65#82#78#73#78#71#58#32#34#116#114#105#103#100#97#116#97#34+
+ #32#77#85#83#84#32#98#101#32#100#101#102#105#110#101#100#32#98#101#102#111+
+ #114#101#32#34#116#121#112#101#34#44#32#97#110#100#32#34#116#121#112#101#34+
+ #32#77#85#83#84#32#98#101#32#110#97#109#101#100#32#34#116#121#112#101#34#32+
+ #40#102#111#114#32#110#111#119#44#32#99#97#110#32#98#101#32#99#104#97#110+
+ #103#101#100#32#108#97#116#101#114#41#10#32#32#68#65#84#65#32#105#115#32#34+
+ #116#114#105#103#103#101#114#100#97#116#97#34#32#116#121#112#101#32#116#114+
+ #105#103#100#97#116#97#91#49#50#56#93#32#111#102#102#115#101#116#32#50#48#59+
+ #32#47#47#32#116#104#101#32#111#110#108#121#32#115#112#101#99#105#97#108#32+
+ #110#101#115#116#101#100#32#115#116#114#117#99#116#117#114#101#10#32#32#47+
+ #47#32#110#111#116#32#105#110#32#98#105#110#97#114#121#10#32#32#47#47#73#100+
+ #32#105#115#32#34#105#100#34#32#116#121#112#101#32#115#116#114#105#110#103+
+ #32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+ #117#108#116#59#10#32#32#47#47#32#105#110#116#101#114#110#97#108#115#10#32+
+ #32#84#114#105#103#73#100#120#32#105#115#32#34#116#114#105#103#105#100#120+
+ #34#32#116#121#112#101#32#117#105#110#116#32#105#110#116#101#114#110#97#108+
+ #59#10#125#10#10#10#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#10#47#42#10#101#110#117#109#32#123#10#32+
+ #32#84#69#88#84#85#82#69#95#78#65#77#69#95#87#65#84#69#82#32#61#32#39#95#119+
+ #97#116#101#114#95#48#39#44#10#32#32#84#69#88#84#85#82#69#95#78#65#77#69#95+
+ #65#67#73#68#49#32#61#32#39#95#119#97#116#101#114#95#49#39#44#10#32#32#84#69+
+ #88#84#85#82#69#95#78#65#77#69#95#65#67#73#68#50#32#61#32#39#95#119#97#116+
+ #101#114#95#50#39#44#10#125#10#42#47#10#10#101#110#117#109#32#84#101#120#116+
+ #117#114#101#83#112#101#99#105#97#108#32#123#10#32#32#84#69#88#84#85#82#69+
+ #95#83#80#69#67#73#65#76#95#87#65#84#69#82#32#61#32#45#49#44#10#32#32#84#69+
+ #88#84#85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#49#32#61#32#45#50#44+
+ #10#32#32#84#69#88#84#85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#50#32+
+ #61#32#45#51#44#10#32#32#84#69#88#84#85#82#69#95#78#79#78#69#32#61#32#45#52+
+ #44#10#125#10#10#47#47#32#100#105#114#101#99#116#105#111#110#115#10#101#110+
+ #117#109#32#68#105#114#84#121#112#101#32#123#10#32#32#68#73#82#95#76#69#70+
+ #84#44#32#47#47#32#48#10#32#32#68#73#82#95#82#73#71#72#84#44#32#47#47#32#49+
+ #10#32#32#68#73#82#95#83#79#77#69#84#72#73#78#71#50#44#32#47#47#32#50#10#125+
+ #10#10#47#47#32#116#114#105#103#103#101#114#115#10#101#110#117#109#32#84#114+
+ #105#103#103#101#114#84#121#112#101#32#123#10#32#32#84#82#73#71#71#69#82#95+
+ #78#79#78#69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#88#73#84+
+ #44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84+
+ #44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#79#80#69#78#68#79#79#82+
+ #44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#67#76#79#83#69#68#79#79+
+ #82#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#47+
+ #47#32#53#10#32#32#84#82#73#71#71#69#82#95#68#79#79#82#53#44#32#47#47#32#54+
+ #10#32#32#84#82#73#71#71#69#82#95#67#76#79#83#69#84#82#65#80#44#32#47#47#32+
+ #55#10#32#32#84#82#73#71#71#69#82#95#84#82#65#80#44#32#47#47#32#56#10#32#32+
+ #84#82#73#71#71#69#82#95#80#82#69#83#83#44#32#47#47#32#57#10#32#32#84#82#73+
+ #71#71#69#82#95#83#69#67#82#69#84#44#32#47#47#32#49#48#10#32#32#84#82#73#71+
+ #71#69#82#95#76#73#70#84#85#80#44#32#47#47#32#49#49#10#32#32#84#82#73#71#71+
+ #69#82#95#76#73#70#84#68#79#87#78#44#32#47#47#32#49#50#10#32#32#84#82#73#71+
+ #71#69#82#95#76#73#70#84#44#32#47#47#32#49#51#10#32#32#84#82#73#71#71#69#82+
+ #95#84#69#88#84#85#82#69#44#32#47#47#32#49#52#10#32#32#84#82#73#71#71#69#82+
+ #95#79#78#44#32#47#47#32#49#53#10#32#32#84#82#73#71#71#69#82#95#79#70#70#44+
+ #32#47#47#32#49#54#10#32#32#84#82#73#71#71#69#82#95#79#78#79#70#70#44#32#47+
+ #47#32#49#55#10#32#32#84#82#73#71#71#69#82#95#83#79#85#78#68#44#32#47#47#32+
+ #49#56#10#32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#77#79#78#83#84#69#82+
+ #44#32#47#47#32#49#57#10#32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#73#84+
+ #69#77#44#32#47#47#32#50#48#10#32#32#84#82#73#71#71#69#82#95#77#85#83#73#67+
+ #44#32#47#47#32#50#49#10#32#32#84#82#73#71#71#69#82#95#80#85#83#72#44#32#47+
+ #47#32#50#50#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#44#32#47#47#32+
+ #50#51#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#44#32#47#47#32+
+ #50#52#10#32#32#84#82#73#71#71#69#82#95#68#65#77#65#71#69#44#32#47#47#32#50+
+ #53#10#32#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#44#32#47#47#32#50#54+
+ #10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#44#32#47#47#32#50#55#10#32#32+
+ #84#82#73#71#71#69#82#95#69#70#70#69#67#84#44#32#47#47#32#50#56#10#32#32#84+
+ #82#73#71#71#69#82#95#83#67#82#73#80#84#44#32#47#47#32#50#57#10#32#32#47#47+
+ #10#32#32#84#82#73#71#71#69#82#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10+
+ #47#47#32#34#97#115#32#88#88#88#34#32#109#101#97#110#115#32#34#103#101#110+
+ #101#114#97#116#101#32#116#104#105#115#32#105#100#101#110#116#105#102#105+
+ #101#114#32#102#111#114#32#112#97#115#99#97#108#32#115#111#117#114#99#101+
+ #115#10#98#105#116#115#101#116#32#80#97#110#101#108#84#121#112#101#32#123#10+
+ #32#32#80#65#78#69#76#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32+
+ #80#65#78#69#76#95#87#65#76#76#44#32#47#47#32#49#10#32#32#80#65#78#69#76#95+
+ #66#65#67#75#44#32#47#47#32#50#10#32#32#80#65#78#69#76#95#70#79#82#69#44#32+
+ #47#47#32#52#10#32#32#80#65#78#69#76#95#87#65#84#69#82#44#32#47#47#32#56#10+
+ #32#32#80#65#78#69#76#95#65#67#73#68#49#44#32#47#47#32#49#54#10#32#32#80#65+
+ #78#69#76#95#65#67#73#68#50#44#32#47#47#32#51#50#10#32#32#80#65#78#69#76#95+
+ #83#84#69#80#44#32#47#47#32#54#52#10#32#32#80#65#78#69#76#95#76#73#70#84#85+
+ #80#44#32#47#47#32#49#50#56#10#32#32#80#65#78#69#76#95#76#73#70#84#68#79#87+
+ #78#44#32#47#47#32#50#53#54#10#32#32#80#65#78#69#76#95#79#80#69#78#68#79#79+
+ #82#44#32#47#47#32#53#49#50#10#32#32#80#65#78#69#76#95#67#76#79#83#69#68#79+
+ #79#82#44#32#47#47#32#49#48#50#52#10#32#32#80#65#78#69#76#95#66#76#79#67#75+
+ #77#79#78#44#32#47#47#32#50#48#52#56#10#32#32#80#65#78#69#76#95#76#73#70#84+
+ #76#69#70#84#44#32#47#47#32#52#48#57#54#10#32#32#80#65#78#69#76#95#76#73#70+
+ #84#82#73#71#72#84#44#32#47#47#32#56#49#57#50#10#125#10#10#98#105#116#115+
+ #101#116#32#80#97#110#101#108#70#108#97#103#32#123#10#32#32#80#65#78#69#76+
+ #95#70#76#65#71#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#80#65+
+ #78#69#76#95#70#76#65#71#95#66#76#69#78#68#73#78#71#44#32#47#47#32#49#10#32+
+ #32#80#65#78#69#76#95#70#76#65#71#95#72#73#68#69#44#32#47#47#32#50#10#32#32+
+ #80#65#78#69#76#95#70#76#65#71#95#87#65#84#69#82#84#69#88#84#85#82#69#83#44+
+ #32#47#47#32#52#10#125#10#10#101#110#117#109#32#69#102#102#101#99#116#65#99+
+ #116#105#111#110#32#123#10#32#32#69#70#70#69#67#84#95#78#79#78#69#44#32#47+
+ #47#32#48#10#32#32#69#70#70#69#67#84#95#84#69#76#69#80#79#82#84#44#32#47#47+
+ #32#49#10#32#32#69#70#70#69#67#84#95#82#69#83#80#65#87#78#44#32#47#47#32#50+
+ #10#32#32#69#70#70#69#67#84#95#70#73#82#69#44#32#47#47#32#51#10#125#10#10+
+ #101#110#117#109#32#73#116#101#109#32#123#10#32#32#73#84#69#77#95#78#79#78+
+ #69#44#32#47#47#32#48#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#83#77#65+
+ #76#76#44#32#47#47#32#49#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#76#65+
+ #82#71#69#44#32#47#47#32#50#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#66+
+ #76#65#67#75#44#32#47#47#32#51#10#32#32#73#84#69#77#95#65#82#77#79#82#95#71+
+ #82#69#69#78#44#32#47#47#32#52#10#32#32#73#84#69#77#95#65#82#77#79#82#95#66+
+ #76#85#69#44#32#47#47#32#53#10#32#32#73#84#69#77#95#83#80#72#69#82#69#95#66+
+ #76#85#69#44#32#47#47#32#54#10#32#32#73#84#69#77#95#83#80#72#69#82#69#95#87+
+ #72#73#84#69#44#32#47#47#32#55#10#32#32#73#84#69#77#95#83#85#73#84#44#32#47+
+ #47#32#56#10#32#32#73#84#69#77#95#79#88#89#71#69#78#44#32#47#47#32#57#10#32+
+ #32#73#84#69#77#95#73#78#86#85#76#44#32#47#47#32#49#48#10#32#32#73#84#69#77+
+ #95#87#69#65#80#79#78#95#83#65#87#44#32#47#47#32#49#49#10#32#32#73#84#69#77+
+ #95#87#69#65#80#79#78#95#83#72#79#84#71#85#78#49#44#32#47#47#32#49#50#10#32+
+ #32#73#84#69#77#95#87#69#65#80#79#78#95#83#72#79#84#71#85#78#50#44#32#47#47+
+ #32#49#51#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#67#72#65#73#78#71#85+
+ #78#44#32#47#47#32#49#52#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#82#79+
+ #67#75#69#84#76#65#85#78#67#72#69#82#44#32#47#47#32#49#53#10#32#32#73#84#69+
+ #77#95#87#69#65#80#79#78#95#80#76#65#83#77#65#44#32#47#47#32#49#54#10#32#32+
+ #73#84#69#77#95#87#69#65#80#79#78#95#66#70#71#44#32#47#47#32#49#55#10#32#32+
+ #73#84#69#77#95#87#69#65#80#79#78#95#83#85#80#69#82#80#85#76#69#77#69#84#44+
+ #32#47#47#32#49#56#10#32#32#73#84#69#77#95#65#77#77#79#95#66#85#76#76#69#84+
+ #83#44#32#47#47#32#49#57#10#32#32#73#84#69#77#95#65#77#77#79#95#66#85#76#76+
+ #69#84#83#95#66#79#88#44#32#47#47#32#50#48#10#32#32#73#84#69#77#95#65#77#77+
+ #79#95#83#72#69#76#76#83#44#32#47#47#32#50#49#10#32#32#73#84#69#77#95#65#77+
+ #77#79#95#83#72#69#76#76#83#95#66#79#88#44#32#47#47#32#50#50#10#32#32#73#84+
+ #69#77#95#65#77#77#79#95#82#79#67#75#69#84#44#32#47#47#32#50#51#10#32#32#73+
+ #84#69#77#95#65#77#77#79#95#82#79#67#75#69#84#95#66#79#88#44#32#47#47#32#50+
+ #52#10#32#32#73#84#69#77#95#65#77#77#79#95#67#69#76#76#44#32#47#47#32#50#53+
+ #10#32#32#73#84#69#77#95#65#77#77#79#95#67#69#76#76#95#66#73#71#44#32#47#47+
+ #32#50#54#10#32#32#73#84#69#77#95#65#77#77#79#95#66#65#67#75#80#65#67#75#44+
+ #32#47#47#32#50#55#10#32#32#73#84#69#77#95#75#69#89#95#82#69#68#44#32#47#47+
+ #32#50#56#10#32#32#73#84#69#77#95#75#69#89#95#71#82#69#69#78#44#32#47#47#32+
+ #50#57#10#32#32#73#84#69#77#95#75#69#89#95#66#76#85#69#44#32#47#47#32#51#48+
+ #10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#75#65#83#84#69#84#44#32#47#47+
+ #32#51#49#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#80#73#83#84#79#76#44+
+ #32#47#47#32#51#50#10#32#32#73#84#69#77#95#66#79#84#84#76#69#44#32#47#47#32+
+ #51#51#10#32#32#73#84#69#77#95#72#69#76#77#69#84#44#32#47#47#32#51#52#10#32+
+ #32#73#84#69#77#95#74#69#84#80#65#67#75#44#32#47#47#32#51#53#10#32#32#73#84+
+ #69#77#95#73#78#86#73#83#44#32#47#47#32#51#54#10#32#32#73#84#69#77#95#87#69+
+ #65#80#79#78#95#70#76#65#77#69#84#72#82#79#87#69#82#44#32#47#47#32#51#55#10+
+ #32#32#73#84#69#77#95#65#77#77#79#95#70#85#69#76#67#65#78#44#32#47#47#32#51+
+ #56#10#32#32#47#47#10#32#32#73#84#69#77#95#77#65#88#32#61#32#77#65#88#44#32+
+ #47#47#32#115#116#111#114#101#32#116#104#101#32#108#97#115#116#32#105#116+
+ #101#109#39#115#32#105#100#32#105#110#32#104#101#114#101#32#117#115#101#32+
+ #116#104#105#115#32#105#110#32#102#111#114#32#108#111#111#112#115#10#125#10+
+ #10#98#105#116#115#101#116#32#73#116#101#109#79#112#116#105#111#110#32#123+
+ #10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#78#79#78#69#32#61#32#48#44#32+
+ #47#47#32#48#10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#79#78#76#89#68#77+
+ #44#32#47#47#32#49#10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#70#65#76#76+
+ #44#32#47#47#32#50#10#125#10#10#101#110#117#109#32#65#114#101#97#84#121#112+
+ #101#32#123#10#32#32#65#82#69#65#95#78#79#78#69#44#32#47#47#32#48#10#32#32+
+ #65#82#69#65#95#80#76#65#89#69#82#80#79#73#78#84#49#44#32#47#47#32#49#10#32+
+ #32#65#82#69#65#95#80#76#65#89#69#82#80#79#73#78#84#50#44#32#47#47#32#50#10+
+ #32#32#65#82#69#65#95#68#77#80#79#73#78#84#44#32#47#47#32#51#10#32#32#65#82+
+ #69#65#95#82#69#68#70#76#65#71#44#32#47#47#32#52#10#32#32#65#82#69#65#95#66+
+ #76#85#69#70#76#65#71#44#32#47#47#32#53#10#32#32#65#82#69#65#95#68#79#77#70+
+ #76#65#71#44#32#47#47#32#54#10#32#32#65#82#69#65#95#82#69#68#84#69#65#77#80+
+ #79#73#78#84#44#32#47#47#32#55#10#32#32#65#82#69#65#95#66#76#85#69#84#69#65+
+ #77#80#79#73#78#84#44#32#47#47#32#56#10#125#10#10#101#110#117#109#32#77#111+
+ #110#115#116#101#114#32#123#10#32#32#77#79#78#83#84#69#82#95#78#79#78#69#44+
+ #32#47#47#32#48#10#32#32#77#79#78#83#84#69#82#95#68#69#77#79#78#44#32#47#47+
+ #32#49#10#32#32#77#79#78#83#84#69#82#95#73#77#80#44#32#47#47#32#50#10#32#32+
+ #77#79#78#83#84#69#82#95#90#79#77#66#89#44#32#47#47#32#51#10#32#32#77#79#78+
+ #83#84#69#82#95#83#69#82#71#44#32#47#47#32#52#10#32#32#77#79#78#83#84#69#82+
+ #95#67#89#66#69#82#44#32#47#47#32#53#10#32#32#77#79#78#83#84#69#82#95#67#71+
+ #85#78#44#32#47#47#32#54#10#32#32#77#79#78#83#84#69#82#95#66#65#82#79#78#44+
+ #32#47#47#32#55#10#32#32#77#79#78#83#84#69#82#95#75#78#73#71#72#84#44#32#47+
+ #47#32#56#10#32#32#77#79#78#83#84#69#82#95#67#65#67#79#44#32#47#47#32#57#10+
+ #32#32#77#79#78#83#84#69#82#95#83#79#85#76#44#32#47#47#32#49#48#10#32#32#77+
+ #79#78#83#84#69#82#95#80#65#73#78#44#32#47#47#32#49#49#10#32#32#77#79#78#83+
+ #84#69#82#95#83#80#73#68#69#82#44#32#47#47#32#49#50#10#32#32#77#79#78#83#84+
+ #69#82#95#66#83#80#44#32#47#47#32#49#51#10#32#32#77#79#78#83#84#69#82#95#77+
+ #65#78#67#85#66#44#32#47#47#32#49#52#10#32#32#77#79#78#83#84#69#82#95#83#75+
+ #69#76#44#32#47#47#32#49#53#10#32#32#77#79#78#83#84#69#82#95#86#73#76#69#44+
+ #32#47#47#32#49#54#10#32#32#77#79#78#83#84#69#82#95#70#73#83#72#44#32#47#47+
+ #32#49#55#10#32#32#77#79#78#83#84#69#82#95#66#65#82#82#69#76#44#32#47#47#32+
+ #49#56#10#32#32#77#79#78#83#84#69#82#95#82#79#66#79#44#32#47#47#32#49#57#10+
+ #32#32#77#79#78#83#84#69#82#95#77#65#78#44#32#47#47#32#50#48#10#125#10#10+
+ #101#110#117#109#32#84#114#105#103#103#101#114#83#104#111#116#32#123#10#32+
+ #32#84#82#73#71#71#69#82#95#83#72#79#84#95#80#73#83#84#79#76#44#32#47#47#32+
+ #48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#85#76#76#69#84#44#32+
+ #47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#83#72#79#84#71+
+ #85#78#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#83+
+ #83#71#44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#73+
+ #77#80#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#80+
+ #76#65#83#77#65#44#32#47#47#32#53#10#32#32#84#82#73#71#71#69#82#95#83#72#79+
+ #84#95#83#80#73#68#69#82#44#32#47#47#32#54#10#32#32#84#82#73#71#71#69#82#95+
+ #83#72#79#84#95#67#65#67#79#44#32#47#47#32#55#10#32#32#84#82#73#71#71#69#82+
+ #95#83#72#79#84#95#66#65#82#79#78#44#32#47#47#32#56#10#32#32#84#82#73#71#71+
+ #69#82#95#83#72#79#84#95#77#65#78#67#85#66#44#32#47#47#32#57#10#32#32#84#82+
+ #73#71#71#69#82#95#83#72#79#84#95#82#69#86#44#32#47#47#32#49#48#10#32#32#84+
+ #82#73#71#71#69#82#95#83#72#79#84#95#82#79#67#75#69#84#44#32#47#47#32#49#49+
+ #10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#70#71#44#32#47#47#32#49+
+ #50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#69#88#80#76#44#32#47#47+
+ #32#49#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#70#71#69#88#80+
+ #76#44#32#47#47#32#49#52#10#32#32#47#47#10#32#32#84#82#73#71#71#69#82#95#83+
+ #72#79#84#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10#101#110#117#109#32+
+ #84#114#105#103#103#101#114#83#104#111#116#84#97#114#103#101#116#32#123#10+
+ #32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#78#79#78+
+ #69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65+
+ #82#71#69#84#95#77#79#78#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95+
+ #83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#44#32#47#47#32#50#10#32#32#84+
+ #82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#82#69#68#44#32#47+
+ #47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84+
+ #95#66#76#85#69#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#83#72#79+
+ #84#95#84#65#82#71#69#84#95#77#79#78#80#76#82#44#32#47#47#32#53#10#32#32#84+
+ #82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#77#79#78+
+ #44#32#47#47#32#54#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101+
+ #114#83#104#111#116#65#105#109#32#123#10#32#32#84#82#73#71#71#69#82#95#83#72+
+ #79#84#95#65#73#77#95#68#69#70#65#85#76#84#44#32#47#47#32#48#10#32#32#84#82+
+ #73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#65#76#76#77#65#80#44#32#47#47+
+ #32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#84#82#65+
+ #67#69#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65+
+ #73#77#95#84#82#65#67#69#65#76#76#44#32#47#47#32#51#10#125#10#10#101#110#117+
+ #109#32#84#114#105#103#103#101#114#69#102#102#101#99#116#32#123#10#32#32#84+
+ #82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#65#82#84#73#67#76#69#44#32#47+
+ #47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#65#78#73#77+
+ #65#84#73#79#78#44#32#47#47#32#49#10#125#10#10#101#110#117#109#32#84#114#105+
+ #103#103#101#114#69#102#102#101#99#116#84#121#112#101#32#123#10#32#32#84#82+
+ #73#71#71#69#82#95#69#70#70#69#67#84#95#83#76#73#81#85#73#68#44#32#47#47#32+
+ #48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#76#76#73#81#85#73+
+ #68#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95+
+ #68#76#73#81#85#73#68#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#69+
+ #70#70#69#67#84#95#66#76#79#79#68#44#32#47#47#32#51#10#32#32#84#82#73#71#71+
+ #69#82#95#69#70#70#69#67#84#95#83#80#65#82#75#44#32#47#47#32#52#10#32#32#84+
+ #82#73#71#71#69#82#95#69#70#70#69#67#84#95#66#85#66#66#76#69#44#32#47#47#32+
+ #53#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#77#65#88#32#61#32+
+ #77#65#88#44#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101#114#69+
+ #102#102#101#99#116#80#111#115#32#123#10#32#32#84#82#73#71#71#69#82#95#69#70+
+ #70#69#67#84#95#80#79#83#95#67#69#78#84#69#82#44#32#47#47#32#48#10#32#32#84+
+ #82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#79#83#95#65#82#69#65#44#32#47+
+ #47#32#49#10#125#10#10#98#105#116#115#101#116#32#65#99#116#105#118#97#116+
+ #101#84#121#112#101#32#123#10#32#32#65#67#84#73#86#65#84#69#95#78#79#78#69+
+ #32#61#32#48#44#32#47#47#32#48#10#32#32#65#67#84#73#86#65#84#69#95#80#76#65+
+ #89#69#82#67#79#76#76#73#68#69#44#32#47#47#32#49#10#32#32#65#67#84#73#86#65+
+ #84#69#95#77#79#78#83#84#69#82#67#79#76#76#73#68#69#44#32#47#47#32#50#10#32+
+ #32#65#67#84#73#86#65#84#69#95#80#76#65#89#69#82#80#82#69#83#83#44#32#47#47+
+ #32#52#10#32#32#65#67#84#73#86#65#84#69#95#77#79#78#83#84#69#82#80#82#69#83+
+ #83#44#32#47#47#32#56#10#32#32#65#67#84#73#86#65#84#69#95#83#72#79#84#44#32+
+ #47#47#32#49#54#10#32#32#65#67#84#73#86#65#84#69#95#78#79#77#79#78#83#84#69+
+ #82#44#32#47#47#32#51#50#10#32#32#65#67#84#73#86#65#84#69#95#67#85#83#84#79+
+ #77#32#61#32#50#53#53#44#32#47#47#32#110#111#116#101#32#116#104#97#116#32#34+
+ #100#105#114#101#99#116#32#97#115#115#105#103#110#34#32#102#105#101#108#100+
+ #32#100#111#101#115#110#39#116#32#97#102#102#101#99#116#32#98#105#116#32#99+
+ #111#117#110#116#101#114#10#125#10#10#98#105#116#115#101#116#32#75#101#121+
+ #32#123#10#32#32#75#69#89#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32+
+ #32#75#69#89#95#82#69#68#44#32#47#47#32#49#10#32#32#75#69#89#95#71#82#69#69+
+ #78#44#32#47#47#32#50#10#32#32#75#69#89#95#66#76#85#69#44#32#47#47#32#52#10+
+ #32#32#75#69#89#95#82#69#68#84#69#65#77#44#32#47#47#32#56#10#32#32#75#69#89+
+ #95#66#76#85#69#84#69#65#77#44#32#47#47#32#49#54#10#125#10#10#10#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+ #47#10#47#47#32#118#97#114#105#111#117#115#32#116#114#105#103#103#101#114+
+ #115#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73+
+ #71#71#69#82#95#69#88#73#84#32#123#10#32#32#77#97#112#78#97#109#101#32#105+
+ #115#32#34#109#97#112#34#32#116#121#112#101#32#99#104#97#114#91#49#54#93#32+
+ #111#102#102#115#101#116#32#48#59#10#125#10#10#84#114#105#103#103#101#114#68+
+ #97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84+
+ #32#123#10#32#32#84#97#114#103#101#116#80#111#105#110#116#32#105#115#32#34+
+ #116#97#114#103#101#116#34#32#116#121#112#101#32#112#111#105#110#116#32#111+
+ #102#102#115#101#116#32#48#59#10#32#32#100#50#100#95#116#101#108#101#112#111+
+ #114#116#32#105#115#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111#108+
+ #32#111#102#102#115#101#116#32#56#32#100#101#102#97#117#108#116#32#102#97+
+ #108#115#101#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#115+
+ #105#108#101#110#116#95#116#101#108#101#112#111#114#116#32#105#115#32#34#115+
+ #105#108#101#110#116#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102+
+ #115#101#116#32#57#32#100#101#102#97#117#108#116#32#102#97#108#115#101#32+
+ #111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#84#108#112#68#105+
+ #114#32#105#115#32#34#100#105#114#101#99#116#105#111#110#34#32#116#121#112+
+ #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#48#32#101#110+
+ #117#109#32#68#105#114#84#121#112#101#32#100#101#102#97#117#108#116#32#68#73+
+ #82#95#76#69#70#84#32#111#109#105#116#100#101#102#97#117#108#116#59#10#125+
+ #10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#40#84#82#73+
+ #71#71#69#82#95#79#80#69#78#68#79#79#82#44#32#84#82#73#71#71#69#82#95#67#76+
+ #79#83#69#68#79#79#82#44#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#84#82+
+ #73#71#71#69#82#95#68#79#79#82#53#44#32#84#82#73#71#71#69#82#95#67#76#79#83+
+ #69#84#82#65#80#44#32#84#82#73#71#71#69#82#95#84#82#65#80#44#32#84#82#73#71+
+ #71#69#82#95#76#73#70#84#85#80#44#32#84#82#73#71#71#69#82#95#76#73#70#84#68+
+ #79#87#78#44#32#84#82#73#71#71#69#82#95#76#73#70#84#41#32#123#10#32#32#80#97+
+ #110#101#108#73#68#32#105#115#32#34#112#97#110#101#108#105#100#34#32#116#121+
+ #112#101#32#105#110#116#32#111#102#102#115#101#116#32#48#32#112#97#110#101+
+ #108#59#10#32#32#78#111#83#111#117#110#100#32#105#115#32#34#115#105#108#101+
+ #110#116#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116+
+ #32#52#32#100#101#102#97#117#108#116#32#102#97#108#115#101#32#111#109#105+
+ #116#100#101#102#97#117#108#116#59#10#32#32#100#50#100#95#100#111#111#114+
+ #115#32#105#115#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111#108#32+
+ #111#102#102#115#101#116#32#53#32#100#101#102#97#117#108#116#32#102#97#108+
+ #115#101#32#111#109#105#116#100#101#102#97#117#108#116#59#10#125#10#10#84+
+ #114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#40#84#82#73#71#71#69+
+ #82#95#80#82#69#83#83#44#32#84#82#73#71#71#69#82#95#79#78#44#32#84#82#73#71+
+ #71#69#82#95#79#70#70#44#32#84#82#73#71#71#69#82#95#79#78#79#70#70#41#32#123+
+ #10#32#32#47#47#116#88#32#105#115#32#34#116#120#34#32#116#121#112#101#32#105+
+ #110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47#116#89#32#105+
+ #115#32#34#116#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115+
+ #101#116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105#116+
+ #105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115+
+ #101#116#32#48#32#97#115#32#116#120#121#59#10#32#32#47#47#116#87#105#100#116+
+ #104#32#105#115#32#34#119#105#100#116#104#34#32#116#121#112#101#32#117#115+
+ #104#111#114#116#32#111#102#102#115#101#116#32#56#59#10#32#32#47#47#116#72+
+ #101#105#103#104#116#32#105#115#32#34#104#101#105#103#104#116#34#32#116#121+
+ #112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#59+
+ #10#32#32#83#105#122#101#32#105#115#32#34#115#105#122#101#34#32#116#121#112+
+ #101#32#115#105#122#101#32#111#102#102#115#101#116#32#56#32#97#115#32#116+
+ #119#104#59#10#32#32#87#97#105#116#32#105#115#32#34#119#97#105#116#34#32#116+
+ #121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#50+
+ #59#10#32#32#67#111#117#110#116#32#105#115#32#34#99#111#117#110#116#34#32+
+ #116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49+
+ #52#59#10#32#32#77#111#110#115#116#101#114#73#68#32#105#115#32#34#109#111+
+ #110#115#116#101#114#105#100#34#32#116#121#112#101#32#105#110#116#32#111#102+
+ #102#115#101#116#32#49#54#32#109#111#110#115#116#101#114#59#10#32#32#69#120+
+ #116#82#97#110#100#111#109#32#105#115#32#34#101#120#116#114#97#110#100#111+
+ #109#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32+
+ #50#48#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111+
+ #114#32#84#82#73#71#71#69#82#95#83#69#67#82#69#84#32#123#10#125#10#10#84#114+
+ #105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95+
+ #84#69#88#84#85#82#69#32#123#10#32#32#65#99#116#105#118#97#116#101#79#110#99+
+ #101#32#105#115#32#34#97#99#116#105#118#97#116#101#111#110#99#101#34#32#116+
+ #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#48#59#10#32#32+
+ #65#110#105#109#79#110#99#101#32#105#115#32#34#97#110#105#109#97#116#101#111+
+ #110#99#101#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101+
+ #116#32#49#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+
+ #111#114#32#84#82#73#71#71#69#82#95#83#79#85#78#68#32#123#10#32#32#83#111+
+ #117#110#100#78#97#109#101#32#105#115#32#34#115#111#117#110#100#110#97#109+
+ #101#34#32#116#121#112#101#32#99#104#97#114#91#54#52#93#32#111#102#102#115+
+ #101#116#32#48#59#10#32#32#86#111#108#117#109#101#32#105#115#32#34#118#111+
+ #108#117#109#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#54#52#59#10#32#32#80#97#110#32#105#115#32#34#112#97#110#34+
+ #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#54+
+ #53#59#10#32#32#76#111#99#97#108#32#105#115#32#34#108#111#99#97#108#34#32+
+ #116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#54#54#59#10+
+ #32#32#80#108#97#121#67#111#117#110#116#32#105#115#32#34#112#108#97#121#99+
+ #111#117#110#116#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+ #115#101#116#32#54#55#59#10#32#32#83#111#117#110#100#83#119#105#116#99#104+
+ #32#105#115#32#34#115#111#117#110#100#115#119#105#116#99#104#34#32#116#121+
+ #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#54#56#59#10#125#10+
+ #10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71+
+ #69#82#95#83#80#65#87#78#77#79#78#83#84#69#82#32#123#10#32#32#77#111#110#80+
+ #111#115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112+
+ #101#32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#77+
+ #111#110#84#121#112#101#32#105#115#32#34#116#121#112#101#34#32#116#121#112+
+ #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#56#59#10#32#32#77+
+ #111#110#72#101#97#108#116#104#32#105#115#32#34#104#101#97#108#116#104#34#32+
+ #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#59#10#32+
+ #32#77#111#110#68#105#114#32#105#115#32#34#100#105#114#101#99#116#105#111+
+ #110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+ #32#49#54#32#101#110#117#109#32#68#105#114#84#121#112#101#59#10#32#32#77#111+
+ #110#65#99#116#105#118#101#32#105#115#32#34#97#99#116#105#118#101#34#32#116+
+ #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#55#59#10#32+
+ #32#77#111#110#67#111#117#110#116#32#105#115#32#34#99#111#117#110#116#34#32+
+ #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#50#48#59#10#32+
+ #32#77#111#110#69#102#102#101#99#116#32#105#115#32#34#101#102#102#101#99#116+
+ #34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32+
+ #50#52#59#10#32#32#77#111#110#77#97#120#32#105#115#32#34#109#97#120#34#32+
+ #116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50+
+ #54#59#10#32#32#77#111#110#68#101#108#97#121#32#105#115#32#34#100#101#108#97+
+ #121#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+
+ #116#32#50#56#59#10#32#32#77#111#110#66#101#104#97#118#32#105#115#32#34#98+
+ #101#104#97#118#105#111#117#114#34#32#116#121#112#101#32#117#98#121#116#101+
+ #32#111#102#102#115#101#116#32#51#48#59#10#125#10#10#84#114#105#103#103#101+
+ #114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#80#65#87#78+
+ #73#84#69#77#32#123#10#32#32#73#116#101#109#80#111#115#32#105#115#32#34#112+
+ #111#115#105#116#105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32+
+ #111#102#102#115#101#116#32#48#59#10#32#32#73#116#101#109#84#121#112#101#32+
+ #105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117#98#121#116#101+
+ #32#111#102#102#115#101#116#32#56#59#10#32#32#73#116#101#109#70#97#108#108+
+ #115#32#105#115#32#34#103#114#97#118#105#116#121#34#32#116#121#112#101#32#98+
+ #111#111#108#32#111#102#102#115#101#116#32#57#59#10#32#32#73#116#101#109#79+
+ #110#108#121#68#77#32#105#115#32#34#100#109#111#110#108#121#34#32#116#121+
+ #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#48#59#10#32#32+
+ #73#116#101#109#67#111#117#110#116#32#105#115#32#34#99#111#117#110#116#34#32+
+ #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#59#10#32+
+ #32#73#116#101#109#69#102#102#101#99#116#32#105#115#32#34#101#102#102#101#99+
+ #116#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+ #32#49#54#59#10#32#32#73#116#101#109#77#97#120#32#105#115#32#34#109#97#120+
+ #34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116+
+ #32#49#56#59#10#32#32#73#116#101#109#68#101#108#97#121#32#105#115#32#34#100+
+ #101#108#97#121#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102+
+ #102#115#101#116#32#50#48#59#10#125#10#10#84#114#105#103#103#101#114#68#97+
+ #116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#77#85#83#73#67#32#123#10+
+ #32#32#77#117#115#105#99#78#97#109#101#32#105#115#32#34#110#97#109#101#34#32+
+ #116#121#112#101#32#99#104#97#114#91#54#52#93#32#111#102#102#115#101#116#32+
+ #48#59#10#32#32#77#117#115#105#99#65#99#116#105#111#110#32#105#115#32#34#97+
+ #99#116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+
+ #102#115#101#116#32#54#52#59#10#125#10#10#84#114#105#103#103#101#114#68#97+
+ #116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#80#85#83#72#32#123#10#32+
+ #32#80#117#115#104#65#110#103#108#101#32#105#115#32#34#97#110#103#108#101#34+
+ #32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32+
+ #48#59#10#32#32#80#117#115#104#70#111#114#99#101#32#105#115#32#34#102#111+
+ #114#99#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+ #101#116#32#50#59#10#32#32#82#101#115#101#116#86#101#108#32#105#115#32#34+
+ #114#101#115#101#116#118#101#108#111#99#105#116#121#34#32#116#121#112#101#32+
+ #98#111#111#108#32#111#102#102#115#101#116#32#51#59#10#125#10#10#84#114#105+
+ #103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83+
+ #67#79#82#69#32#123#10#32#32#83#99#111#114#101#65#99#116#105#111#110#32#105+
+ #115#32#34#97#99#116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101+
+ #32#111#102#102#115#101#116#32#48#59#10#32#32#83#99#111#114#101#67#111#117+
+ #110#116#32#105#115#32#34#99#111#117#110#116#34#32#116#121#112#101#32#117#98+
+ #121#116#101#32#111#102#102#115#101#116#32#49#59#10#32#32#83#99#111#114#101+
+ #84#101#97#109#32#105#115#32#34#116#101#97#109#34#32#116#121#112#101#32#117+
+ #98#121#116#101#32#111#102#102#115#101#116#32#50#59#10#32#32#83#99#111#114+
+ #101#67#111#110#32#105#115#32#34#99#111#110#115#111#108#101#34#32#116#121+
+ #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#51#59#10#32#32#83+
+ #99#111#114#101#77#115#103#32#105#115#32#34#109#101#115#115#97#103#101#34#32+
+ #116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#52#59#10+
+ #125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82+
+ #73#71#71#69#82#95#77#69#83#83#65#71#69#32#123#10#32#32#77#101#115#115#97+
+ #103#101#75#105#110#100#32#105#115#32#34#107#105#110#100#34#32#116#121#112+
+ #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#48#59#10#32#32#77+
+ #101#115#115#97#103#101#83#101#110#100#84#111#32#105#115#32#34#115#101#110+
+ #100#116#111#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+ #101#116#32#49#59#10#32#32#77#101#115#115#97#103#101#84#101#120#116#32#105+
+ #115#32#34#116#101#120#116#34#32#116#121#112#101#32#99#104#97#114#91#49#48+
+ #48#93#32#111#102#102#115#101#116#32#50#59#10#32#32#77#101#115#115#97#103+
+ #101#84#105#109#101#32#105#115#32#34#116#105#109#101#34#32#116#121#112#101+
+ #32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#50#59#10#125+
+ #10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71+
+ #71#69#82#95#68#65#77#65#71#69#32#123#10#32#32#68#97#109#97#103#101#86#97+
+ #108#117#101#32#105#115#32#34#97#109#111#117#110#116#34#32#116#121#112#101+
+ #32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#48#59#10#32#32#68+
+ #97#109#97#103#101#73#110#116#101#114#118#97#108#32#105#115#32#34#105#110+
+ #116#101#114#118#97#108#34#32#116#121#112#101#32#117#115#104#111#114#116#32+
+ #111#102#102#115#101#116#32#50#59#10#125#10#10#84#114#105#103#103#101#114#68+
+ #97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#32+
+ #123#10#32#32#72#101#97#108#86#97#108#117#101#32#105#115#32#34#97#109#111+
+ #117#110#116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102+
+ #115#101#116#32#48#59#10#32#32#72#101#97#108#73#110#116#101#114#118#97#108+
+ #32#105#115#32#34#105#110#116#101#114#118#97#108#34#32#116#121#112#101#32+
+ #117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#59#10#32#32#72#101+
+ #97#108#77#97#120#32#105#115#32#34#109#97#120#34#32#116#121#112#101#32#98+
+ #111#111#108#32#111#102#102#115#101#116#32#52#59#10#32#32#72#101#97#108#83+
+ #105#108#101#110#116#32#105#115#32#34#115#105#108#101#110#116#34#32#116#121+
+ #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#53#59#10#125#10#10+
+ #84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69+
+ #82#95#83#72#79#84#32#123#10#32#32#83#104#111#116#80#111#115#32#105#115#32+
+ #34#112#111#115#105#116#105#111#110#34#32#116#121#112#101#32#112#111#105#110+
+ #116#32#111#102#102#115#101#116#32#48#59#10#32#32#83#104#111#116#84#121#112+
+ #101#32#105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117#98#121+
+ #116#101#32#111#102#102#115#101#116#32#56#32#101#110#117#109#32#84#114#105+
+ #103#103#101#114#83#104#111#116#59#10#32#32#83#104#111#116#84#97#114#103#101+
+ #116#32#105#115#32#34#116#97#114#103#101#116#34#32#116#121#112#101#32#117#98+
+ #121#116#101#32#111#102#102#115#101#116#32#57#32#101#110#117#109#32#84#114+
+ #105#103#103#101#114#83#104#111#116#84#97#114#103#101#116#59#10#32#32#83#104+
+ #111#116#83#111#117#110#100#32#105#115#32#34#115#105#108#101#110#116#34#32+
+ #116#121#112#101#32#110#101#103#98#111#111#108#32#111#102#102#115#101#116#32+
+ #49#48#59#32#47#47#32#110#101#103#98#111#111#108#33#10#32#32#83#104#111#116+
+ #65#105#109#32#105#115#32#34#97#105#109#34#32#116#121#112#101#32#98#121#116+
+ #101#32#111#102#102#115#101#116#32#49#49#59#10#32#32#83#104#111#116#80#97+
+ #110#101#108#73#68#32#105#115#32#34#112#97#110#101#108#105#100#34#32#116#121+
+ #112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#59#10#32#32#83+
+ #104#111#116#73#110#116#83#105#103#104#116#32#105#115#32#34#115#105#103#104+
+ #116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+
+ #116#32#49#54#59#10#32#32#83#104#111#116#65#110#103#108#101#32#105#115#32#34+
+ #97#110#103#108#101#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111+
+ #102#102#115#101#116#32#49#56#59#10#32#32#83#104#111#116#87#97#105#116#32+
+ #105#115#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115#104#111#114+
+ #116#32#111#102#102#115#101#116#32#50#48#59#10#32#32#83#104#111#116#65#99#99+
+ #117#114#97#99#121#32#105#115#32#34#97#99#99#117#114#97#99#121#34#32#116#121+
+ #112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#50#59+
+ #10#32#32#83#104#111#116#65#109#109#111#32#105#115#32#34#97#109#109#111#34+
+ #32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32+
+ #50#52#59#10#32#32#83#104#111#116#73#110#116#82#101#108#111#97#100#32#105+
+ #115#32#34#114#101#108#111#97#100#34#32#116#121#112#101#32#117#115#104#111+
+ #114#116#32#111#102#102#115#101#116#32#50#54#59#10#125#10#10#84#114#105#103+
+ #103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#69#70#70+
+ #69#67#84#32#123#10#32#32#70#88#67#111#117#110#116#32#105#115#32#34#99#111+
+ #117#110#116#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+ #101#116#32#48#59#10#32#32#70#88#84#121#112#101#32#105#115#32#34#116#121#112+
+ #101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+ #32#49#59#10#32#32#70#88#83#117#98#84#121#112#101#32#105#115#32#34#115#117+
+ #98#116#121#112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+
+ #102#115#101#116#32#50#59#10#32#32#70#88#67#111#108#111#114#82#32#105#115#32+
+ #34#99#111#108#111#114#114#34#32#116#121#112#101#32#117#98#121#116#101#32+
+ #111#102#102#115#101#116#32#51#59#10#32#32#70#88#67#111#108#111#114#71#32+
+ #105#115#32#34#99#111#108#111#114#103#34#32#116#121#112#101#32#117#98#121+
+ #116#101#32#111#102#102#115#101#116#32#52#59#10#32#32#70#88#67#111#108#111+
+ #114#66#32#105#115#32#34#99#111#108#111#114#98#34#32#116#121#112#101#32#117+
+ #98#121#116#101#32#111#102#102#115#101#116#32#53#59#10#32#32#70#88#80#111+
+ #115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112#101+
+ #32#117#98#121#116#101#32#111#102#102#115#101#116#32#54#59#10#32#32#70#88#87+
+ #97#105#116#32#105#115#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115+
+ #104#111#114#116#32#111#102#102#115#101#116#32#56#59#10#32#32#70#88#86#101+
+ #108#88#32#105#115#32#34#118#101#108#120#34#32#116#121#112#101#32#98#121#116+
+ #101#32#111#102#102#115#101#116#32#49#48#59#10#32#32#70#88#86#101#108#89#32+
+ #105#115#32#34#118#101#108#121#34#32#116#121#112#101#32#98#121#116#101#32+
+ #111#102#102#115#101#116#32#49#49#59#10#32#32#70#88#83#112#114#101#97#100#76+
+ #32#105#115#32#34#115#112#114#101#97#100#108#34#32#116#121#112#101#32#117#98+
+ #121#116#101#32#111#102#102#115#101#116#32#49#50#59#10#32#32#70#88#83#112+
+ #114#101#97#100#82#32#105#115#32#34#115#112#114#101#97#100#114#34#32#116#121+
+ #112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#51#59#10#32+
+ #32#70#88#83#112#114#101#97#100#85#32#105#115#32#34#115#112#114#101#97#100+
+ #117#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+ #32#49#52#59#10#32#32#70#88#83#112#114#101#97#100#68#32#105#115#32#34#115+
+ #112#114#101#97#100#100#34#32#116#121#112#101#32#117#98#121#116#101#32#111+
+ #102#102#115#101#116#32#49#53#59#10#125#10
+;
\ No newline at end of file
diff --git a/src/shared/mapdef.txt b/src/shared/mapdef.txt
index d93b48d58bf87449d3b2b8356176eb8f26dee0a3..db3a64fe7de8c6d1b20d16f2c3a58ab9ee103385 100644 (file)
--- a/src/shared/mapdef.txt
+++ b/src/shared/mapdef.txt
ShotType is "type" type ubyte offset 8 enum TriggerShot;
ShotTarget is "target" type ubyte offset 9 enum TriggerShotTarget;
ShotSound is "silent" type negbool offset 10; // negbool!
- ShotAllMap is "allmap" type bool offset 11;
+ ShotAim is "aim" type byte offset 11;
ShotPanelID is "panelid" type int offset 12;
ShotIntSight is "sight" type ushort offset 16;
ShotAngle is "angle" type ushort offset 18;
diff --git a/src/shared/mapstructio.inc b/src/shared/mapstructio.inc
+++ /dev/null
@@ -1,685 +0,0 @@
-procedure getBytesAt (var dest; const buf; ofs, len: Integer);
-begin
- Move((PChar(@buf)+ofs)^, dest, len);
-end;
-
-procedure getWordAt (var dest; const buf; ofs: Integer);
-type PWord = ^Word; PByte = ^Byte;
-var
- p: PByte;
- d: PWord;
-begin
- p := PByte(@buf); Inc(p, ofs);
- d := PWord(@dest);
- d^ := p^;
- Inc(p);
- d^ := (d^) or ((p^) shl 8);
-end;
-
-procedure getIntAt (var dest; const buf; ofs: Integer);
-type PInt = ^LongWord; PByte = ^Byte;
-var
- p: PByte;
- d: PInt;
-begin
- p := PByte(@buf); Inc(p, ofs);
- d := PInt(@dest);
- d^ := p^;
- Inc(p);
- d^ := (d^) or ((p^) shl 8);
- Inc(p);
- d^ := (d^) or ((p^) shl 16);
- Inc(p);
- d^ := (d^) or ((p^) shl 24);
-end;
-
-procedure putBytesAt (var buf; ofs: Integer; const src; len: Integer);
-begin
- Move(src, (PChar(@buf)+ofs)^, len);
-end;
-
-procedure putWordAt (var buf; ofs: Integer; const src);
-type PWord = ^Word; PByte = ^Byte;
-var
- p: PByte;
- d: PWord;
-begin
- p := PByte(PChar(@buf)+ofs);
- d := PWord(@src);
- p^ := (d^) and $ff;
- Inc(p);
- p^ := ((d^) shr 8) and $ff;
-end;
-
-procedure putIntAt (var buf; ofs: Integer; const src);
-type PInt = ^LongWord; PByte = ^Byte;
-var
- p: PByte;
- d: PInt;
-begin
- p := PByte(PChar(@buf)+ofs);
- d := PInt(@src);
- p^ := (d^) and $ff;
- Inc(p);
- p^ := ((d^) shr 8) and $ff;
- Inc(p);
- p^ := ((d^) shr 16) and $ff;
- Inc(p);
- p^ := ((d^) shr 24) and $ff;
-end;
-
-procedure mb_Read_TriggerData (var tr: TTriggerData; ttype: Integer; const buf; bufsize: Integer);
- procedure xreadExit ();
- begin
- getBytesAt(tr.MapName, buf, 0, 16);
- end;
-
- procedure xreadTeleport ();
- begin
- getIntAt(tr.TargetPoint.x, buf, 0);
- getIntAt(tr.TargetPoint.y, buf, 4);
- getBytesAt(tr.d2d_teleport, buf, 8, 1);
- getBytesAt(tr.silent_teleport, buf, 9, 1);
- getBytesAt(tr.TlpDir, buf, 10, 1);
- end;
-
- procedure xreadOpendoor ();
- begin
- getIntAt(tr.PanelID, buf, 0);
- getBytesAt(tr.NoSound, buf, 4, 1);
- getBytesAt(tr.d2d_doors, buf, 5, 1);
- end;
-
- procedure xreadPress ();
- begin
- getIntAt(tr.tX, buf, 0);
- getIntAt(tr.tY, buf, 4);
- getWordAt(tr.tWidth, buf, 8);
- getWordAt(tr.tHeight, buf, 10);
- getWordAt(tr.Wait, buf, 12);
- getWordAt(tr.Count, buf, 14);
- getIntAt(tr.MonsterID, buf, 16);
- getBytesAt(tr.ExtRandom, buf, 20, 1);
- end;
-
- procedure xreadSecret ();
- begin
- end;
-
- procedure xreadTexture ();
- begin
- getBytesAt(tr.ActivateOnce, buf, 0, 1);
- getBytesAt(tr.AnimOnce, buf, 1, 1);
- end;
-
- procedure xreadSound ();
- begin
- getBytesAt(tr.SoundName, buf, 0, 64);
- getBytesAt(tr.Volume, buf, 64, 1);
- getBytesAt(tr.Pan, buf, 65, 1);
- getBytesAt(tr.Local, buf, 66, 1);
- getBytesAt(tr.PlayCount, buf, 67, 1);
- getBytesAt(tr.SoundSwitch, buf, 68, 1);
- end;
-
- procedure xreadSpawnmonster ();
- begin
- getIntAt(tr.MonPos.x, buf, 0);
- getIntAt(tr.MonPos.y, buf, 4);
- getBytesAt(tr.MonType, buf, 8, 1);
- getIntAt(tr.MonHealth, buf, 12);
- getBytesAt(tr.MonDir, buf, 16, 1);
- getBytesAt(tr.MonActive, buf, 17, 1);
- getIntAt(tr.MonCount, buf, 20);
- getBytesAt(tr.MonEffect, buf, 24, 1);
- getWordAt(tr.MonMax, buf, 26);
- getWordAt(tr.MonDelay, buf, 28);
- getBytesAt(tr.MonBehav, buf, 30, 1);
- end;
-
- procedure xreadSpawnitem ();
- begin
- getIntAt(tr.ItemPos.x, buf, 0);
- getIntAt(tr.ItemPos.y, buf, 4);
- getBytesAt(tr.ItemType, buf, 8, 1);
- getBytesAt(tr.ItemFalls, buf, 9, 1);
- getBytesAt(tr.ItemOnlyDM, buf, 10, 1);
- getIntAt(tr.ItemCount, buf, 12);
- getBytesAt(tr.ItemEffect, buf, 16, 1);
- getWordAt(tr.ItemMax, buf, 18);
- getWordAt(tr.ItemDelay, buf, 20);
- end;
-
- procedure xreadMusic ();
- begin
- getBytesAt(tr.MusicName, buf, 0, 64);
- getBytesAt(tr.MusicAction, buf, 64, 1);
- end;
-
- procedure xreadPush ();
- begin
- getWordAt(tr.PushAngle, buf, 0);
- getBytesAt(tr.PushForce, buf, 2, 1);
- getBytesAt(tr.ResetVel, buf, 3, 1);
- end;
-
- procedure xreadScore ();
- begin
- getBytesAt(tr.ScoreAction, buf, 0, 1);
- getBytesAt(tr.ScoreCount, buf, 1, 1);
- getBytesAt(tr.ScoreTeam, buf, 2, 1);
- getBytesAt(tr.ScoreCon, buf, 3, 1);
- getBytesAt(tr.ScoreMsg, buf, 4, 1);
- end;
-
- procedure xreadMessage ();
- begin
- getBytesAt(tr.MessageKind, buf, 0, 1);
- getBytesAt(tr.MessageSendTo, buf, 1, 1);
- getBytesAt(tr.MessageText, buf, 2, 100);
- getWordAt(tr.MessageTime, buf, 102);
- end;
-
- procedure xreadDamage ();
- begin
- getWordAt(tr.DamageValue, buf, 0);
- getWordAt(tr.DamageInterval, buf, 2);
- end;
-
- procedure xreadHealth ();
- begin
- getWordAt(tr.HealValue, buf, 0);
- getWordAt(tr.HealInterval, buf, 2);
- getBytesAt(tr.HealMax, buf, 4, 1);
- getBytesAt(tr.HealSilent, buf, 5, 1);
- end;
-
- procedure xreadShot ();
- begin
- getIntAt(tr.ShotPos.x, buf, 0);
- getIntAt(tr.ShotPos.y, buf, 4);
- getBytesAt(tr.ShotType, buf, 8, 1);
- getBytesAt(tr.ShotTarget, buf, 9, 1);
- getBytesAt(tr.ShotSound, buf, 10, 1);
- getBytesAt(tr.ShotAim, buf, 11, 1);
- getIntAt(tr.ShotPanelID, buf, 12);
- getWordAt(tr.ShotIntSight, buf, 16);
- getWordAt(tr.ShotAngle, buf, 18);
- getWordAt(tr.ShotWait, buf, 20);
- getWordAt(tr.ShotAccuracy, buf, 22);
- getWordAt(tr.ShotAmmo, buf, 24);
- getWordAt(tr.ShotIntReload, buf, 26);
- end;
-
- procedure xreadEffect ();
- begin
- getBytesAt(tr.FXCount, buf, 0, 1);
- getBytesAt(tr.FXType, buf, 1, 1);
- getBytesAt(tr.FXSubType, buf, 2, 1);
- getBytesAt(tr.FXColorR, buf, 3, 1);
- getBytesAt(tr.FXColorG, buf, 4, 1);
- getBytesAt(tr.FXColorB, buf, 5, 1);
- getBytesAt(tr.FXPos, buf, 6, 1);
- getWordAt(tr.FXWait, buf, 8);
- getBytesAt(tr.FXVelX, buf, 10, 1);
- getBytesAt(tr.FXVelY, buf, 11, 1);
- getBytesAt(tr.FXSpreadL, buf, 12, 1);
- getBytesAt(tr.FXSpreadR, buf, 13, 1);
- getBytesAt(tr.FXSpreadU, buf, 14, 1);
- getBytesAt(tr.FXSpreadD, buf, 15, 1);
- end;
-
- procedure xreadScript ();
- begin
- getBytesAt(tr.SCRProc, buf, 0, 64);
- getIntAt(tr.SCRArg, buf, 64);
- end;
-
-begin
- if (bufsize < 104) then raise Exception.Create('invalid buffer size in mb_Read_TriggerData');
- if (ttype = TRIGGER_EXIT) then begin xreadExit(); exit; end;
- if (ttype = TRIGGER_TELEPORT) then begin xreadTeleport(); exit; end;
- if (ttype = TRIGGER_OPENDOOR) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_CLOSEDOOR) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_DOOR) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_DOOR5) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_CLOSETRAP) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_TRAP) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_LIFTUP) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_LIFTDOWN) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_LIFT) then begin xreadOpendoor(); exit; end;
- if (ttype = TRIGGER_PRESS) then begin xreadPress(); exit; end;
- if (ttype = TRIGGER_ON) then begin xreadPress(); exit; end;
- if (ttype = TRIGGER_OFF) then begin xreadPress(); exit; end;
- if (ttype = TRIGGER_ONOFF) then begin xreadPress(); exit; end;
- if (ttype = TRIGGER_SECRET) then begin xreadSecret(); exit; end;
- if (ttype = TRIGGER_TEXTURE) then begin xreadTexture(); exit; end;
- if (ttype = TRIGGER_SOUND) then begin xreadSound(); exit; end;
- if (ttype = TRIGGER_SPAWNMONSTER) then begin xreadSpawnmonster(); exit; end;
- if (ttype = TRIGGER_SPAWNITEM) then begin xreadSpawnitem(); exit; end;
- if (ttype = TRIGGER_MUSIC) then begin xreadMusic(); exit; end;
- if (ttype = TRIGGER_PUSH) then begin xreadPush(); exit; end;
- if (ttype = TRIGGER_SCORE) then begin xreadScore(); exit; end;
- if (ttype = TRIGGER_MESSAGE) then begin xreadMessage(); exit; end;
- if (ttype = TRIGGER_DAMAGE) then begin xreadDamage(); exit; end;
- if (ttype = TRIGGER_HEALTH) then begin xreadHealth(); exit; end;
- if (ttype = TRIGGER_SHOT) then begin xreadShot(); exit; end;
- if (ttype = TRIGGER_EFFECT) then begin xreadEffect(); exit; end;
- if (ttype = TRIGGER_SCRIPT) then begin xreadScript(); exit; end;
- raise Exception.Create('invalid trigger type in mb_Read_TriggerData');
-end;
-
-
-procedure mb_Read_TMapHeaderRec_1 (var tr: TMapHeaderRec_1; const buf; bufsize: Integer);
- procedure xreadTmapheaderrec_1 ();
- begin
- getBytesAt(tr.MapName, buf, 0, 32);
- getBytesAt(tr.MapAuthor, buf, 32, 32);
- getBytesAt(tr.MapDescription, buf, 64, 256);
- getBytesAt(tr.MusicName, buf, 320, 64);
- getBytesAt(tr.SkyName, buf, 384, 64);
- getWordAt(tr.Width, buf, 448);
- getWordAt(tr.Height, buf, 450);
- end;
-
-begin
- if (bufsize < 452) then raise Exception.Create('invalid buffer size in readTMapHeaderRec_1');
- xreadTmapheaderrec_1();
-end;
-
-procedure mb_Read_TTextureRec_1 (var tr: TTextureRec_1; const buf; bufsize: Integer);
- procedure xreadTtexturerec_1 ();
- begin
- getBytesAt(tr.Resource, buf, 0, 64);
- getBytesAt(tr.Anim, buf, 64, 1);
- end;
-
-begin
- if (bufsize < 65) then raise Exception.Create('invalid buffer size in readTTextureRec_1');
- xreadTtexturerec_1();
-end;
-
-procedure mb_Read_TPanelRec_1 (var tr: TPanelRec_1; const buf; bufsize: Integer);
- procedure xreadTpanelrec_1 ();
- begin
- getIntAt(tr.X, buf, 0);
- getIntAt(tr.Y, buf, 4);
- getWordAt(tr.Width, buf, 8);
- getWordAt(tr.Height, buf, 10);
- getWordAt(tr.TextureNum, buf, 12);
- getWordAt(tr.PanelType, buf, 14);
- getBytesAt(tr.Alpha, buf, 16, 1);
- getBytesAt(tr.Flags, buf, 17, 1);
- end;
-
-begin
- if (bufsize < 18) then raise Exception.Create('invalid buffer size in readTPanelRec_1');
- xreadTpanelrec_1();
-end;
-
-procedure mb_Read_TItemRec_1 (var tr: TItemRec_1; const buf; bufsize: Integer);
- procedure xreadTitemrec_1 ();
- begin
- getIntAt(tr.X, buf, 0);
- getIntAt(tr.Y, buf, 4);
- getBytesAt(tr.ItemType, buf, 8, 1);
- getBytesAt(tr.Options, buf, 9, 1);
- end;
-
-begin
- if (bufsize < 10) then raise Exception.Create('invalid buffer size in readTItemRec_1');
- xreadTitemrec_1();
-end;
-
-procedure mb_Read_TMonsterRec_1 (var tr: TMonsterRec_1; const buf; bufsize: Integer);
- procedure xreadTmonsterrec_1 ();
- begin
- getIntAt(tr.X, buf, 0);
- getIntAt(tr.Y, buf, 4);
- getBytesAt(tr.MonsterType, buf, 8, 1);
- getBytesAt(tr.Direction, buf, 9, 1);
- end;
-
-begin
- if (bufsize < 10) then raise Exception.Create('invalid buffer size in readTMonsterRec_1');
- xreadTmonsterrec_1();
-end;
-
-procedure mb_Read_TAreaRec_1 (var tr: TAreaRec_1; const buf; bufsize: Integer);
- procedure xreadTarearec_1 ();
- begin
- getIntAt(tr.X, buf, 0);
- getIntAt(tr.Y, buf, 4);
- getBytesAt(tr.AreaType, buf, 8, 1);
- getBytesAt(tr.Direction, buf, 9, 1);
- end;
-
-begin
- if (bufsize < 10) then raise Exception.Create('invalid buffer size in readTAreaRec_1');
- xreadTarearec_1();
-end;
-
-procedure mb_Read_TTriggerRec_1 (var tr: TTriggerRec_1; const buf; bufsize: Integer);
- procedure xreadTtriggerrec_1 ();
- begin
- getIntAt(tr.X, buf, 0);
- getIntAt(tr.Y, buf, 4);
- getWordAt(tr.Width, buf, 8);
- getWordAt(tr.Height, buf, 10);
- getBytesAt(tr.Enabled, buf, 12, 1);
- getIntAt(tr.TexturePanel, buf, 13);
- getBytesAt(tr.TriggerType, buf, 17, 1);
- getBytesAt(tr.ActivateType, buf, 18, 1);
- getBytesAt(tr.Keys, buf, 19, 1);
- getBytesAt(tr.DATA, buf, 20, 128);
- end;
-
-begin
- if (bufsize < 148) then raise Exception.Create('invalid buffer size in readTTriggerRec_1');
- xreadTtriggerrec_1();
-end;
-
-procedure mb_Write_TriggerData (var buf; bufsize: Integer; ttype: Integer; var tr: TTriggerData);
- procedure xwriteExit ();
- begin
- putBytesAt(buf, 0, tr.MapName, 16);
- end;
-
- procedure xwriteTeleport ();
- begin
- putIntAt(buf, 0, tr.TargetPoint.x);
- putIntAt(buf, 4, tr.TargetPoint.y);
- putBytesAt(buf, 8, tr.d2d_teleport, 1);
- putBytesAt(buf, 9, tr.silent_teleport, 1);
- putBytesAt(buf, 10, tr.TlpDir, 1);
- end;
-
- procedure xwriteOpendoor ();
- begin
- putIntAt(buf, 0, tr.PanelID);
- putBytesAt(buf, 4, tr.NoSound, 1);
- putBytesAt(buf, 5, tr.d2d_doors, 1);
- end;
-
- procedure xwritePress ();
- begin
- putIntAt(buf, 0, tr.tX);
- putIntAt(buf, 4, tr.tY);
- putWordAt(buf, 8, tr.tWidth);
- putWordAt(buf, 10, tr.tHeight);
- putWordAt(buf, 12, tr.Wait);
- putWordAt(buf, 14, tr.Count);
- putIntAt(buf, 16, tr.MonsterID);
- putBytesAt(buf, 20, tr.ExtRandom, 1);
- end;
-
- procedure xwriteSecret ();
- begin
- end;
-
- procedure xwriteTexture ();
- begin
- putBytesAt(buf, 0, tr.ActivateOnce, 1);
- putBytesAt(buf, 1, tr.AnimOnce, 1);
- end;
-
- procedure xwriteSound ();
- begin
- putBytesAt(buf, 0, tr.SoundName, 64);
- putBytesAt(buf, 64, tr.Volume, 1);
- putBytesAt(buf, 65, tr.Pan, 1);
- putBytesAt(buf, 66, tr.Local, 1);
- putBytesAt(buf, 67, tr.PlayCount, 1);
- putBytesAt(buf, 68, tr.SoundSwitch, 1);
- end;
-
- procedure xwriteSpawnmonster ();
- begin
- putIntAt(buf, 0, tr.MonPos.x);
- putIntAt(buf, 4, tr.MonPos.y);
- putBytesAt(buf, 8, tr.MonType, 1);
- putIntAt(buf, 12, tr.MonHealth);
- putBytesAt(buf, 16, tr.MonDir, 1);
- putBytesAt(buf, 17, tr.MonActive, 1);
- putIntAt(buf, 20, tr.MonCount);
- putBytesAt(buf, 24, tr.MonEffect, 1);
- putWordAt(buf, 26, tr.MonMax);
- putWordAt(buf, 28, tr.MonDelay);
- putBytesAt(buf, 30, tr.MonBehav, 1);
- end;
-
- procedure xwriteSpawnitem ();
- begin
- putIntAt(buf, 0, tr.ItemPos.x);
- putIntAt(buf, 4, tr.ItemPos.y);
- putBytesAt(buf, 8, tr.ItemType, 1);
- putBytesAt(buf, 9, tr.ItemFalls, 1);
- putBytesAt(buf, 10, tr.ItemOnlyDM, 1);
- putIntAt(buf, 12, tr.ItemCount);
- putBytesAt(buf, 16, tr.ItemEffect, 1);
- putWordAt(buf, 18, tr.ItemMax);
- putWordAt(buf, 20, tr.ItemDelay);
- end;
-
- procedure xwriteMusic ();
- begin
- putBytesAt(buf, 0, tr.MusicName, 64);
- putBytesAt(buf, 64, tr.MusicAction, 1);
- end;
-
- procedure xwritePush ();
- begin
- putWordAt(buf, 0, tr.PushAngle);
- putBytesAt(buf, 2, tr.PushForce, 1);
- putBytesAt(buf, 3, tr.ResetVel, 1);
- end;
-
- procedure xwriteScore ();
- begin
- putBytesAt(buf, 0, tr.ScoreAction, 1);
- putBytesAt(buf, 1, tr.ScoreCount, 1);
- putBytesAt(buf, 2, tr.ScoreTeam, 1);
- putBytesAt(buf, 3, tr.ScoreCon, 1);
- putBytesAt(buf, 4, tr.ScoreMsg, 1);
- end;
-
- procedure xwriteMessage ();
- begin
- putBytesAt(buf, 0, tr.MessageKind, 1);
- putBytesAt(buf, 1, tr.MessageSendTo, 1);
- putBytesAt(buf, 2, tr.MessageText, 100);
- putWordAt(buf, 102, tr.MessageTime);
- end;
-
- procedure xwriteDamage ();
- begin
- putWordAt(buf, 0, tr.DamageValue);
- putWordAt(buf, 2, tr.DamageInterval);
- end;
-
- procedure xwriteHealth ();
- begin
- putWordAt(buf, 0, tr.HealValue);
- putWordAt(buf, 2, tr.HealInterval);
- putBytesAt(buf, 4, tr.HealMax, 1);
- putBytesAt(buf, 5, tr.HealSilent, 1);
- end;
-
- procedure xwriteShot ();
- begin
- putIntAt(buf, 0, tr.ShotPos.x);
- putIntAt(buf, 4, tr.ShotPos.y);
- putBytesAt(buf, 8, tr.ShotType, 1);
- putBytesAt(buf, 9, tr.ShotTarget, 1);
- putBytesAt(buf, 10, tr.ShotSound, 1);
- putBytesAt(buf, 11, tr.ShotAim, 1);
- putIntAt(buf, 12, tr.ShotPanelID);
- putWordAt(buf, 16, tr.ShotIntSight);
- putWordAt(buf, 18, tr.ShotAngle);
- putWordAt(buf, 20, tr.ShotWait);
- putWordAt(buf, 22, tr.ShotAccuracy);
- putWordAt(buf, 24, tr.ShotAmmo);
- putWordAt(buf, 26, tr.ShotIntReload);
- end;
-
- procedure xwriteEffect ();
- begin
- putBytesAt(buf, 0, tr.FXCount, 1);
- putBytesAt(buf, 1, tr.FXType, 1);
- putBytesAt(buf, 2, tr.FXSubType, 1);
- putBytesAt(buf, 3, tr.FXColorR, 1);
- putBytesAt(buf, 4, tr.FXColorG, 1);
- putBytesAt(buf, 5, tr.FXColorB, 1);
- putBytesAt(buf, 6, tr.FXPos, 1);
- putWordAt(buf, 8, tr.FXWait);
- putBytesAt(buf, 10, tr.FXVelX, 1);
- putBytesAt(buf, 11, tr.FXVelY, 1);
- putBytesAt(buf, 12, tr.FXSpreadL, 1);
- putBytesAt(buf, 13, tr.FXSpreadR, 1);
- putBytesAt(buf, 14, tr.FXSpreadU, 1);
- putBytesAt(buf, 15, tr.FXSpreadD, 1);
- end;
-
-begin
- if (bufsize < 104) then raise Exception.Create('invalid buffer size in mb_Write_TriggerData');
- if (ttype = TRIGGER_EXIT) then begin xwriteExit(); exit; end;
- if (ttype = TRIGGER_TELEPORT) then begin xwriteTeleport(); exit; end;
- if (ttype = TRIGGER_OPENDOOR) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_CLOSEDOOR) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_DOOR) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_DOOR5) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_CLOSETRAP) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_TRAP) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_LIFTUP) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_LIFTDOWN) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_LIFT) then begin xwriteOpendoor(); exit; end;
- if (ttype = TRIGGER_PRESS) then begin xwritePress(); exit; end;
- if (ttype = TRIGGER_ON) then begin xwritePress(); exit; end;
- if (ttype = TRIGGER_OFF) then begin xwritePress(); exit; end;
- if (ttype = TRIGGER_ONOFF) then begin xwritePress(); exit; end;
- if (ttype = TRIGGER_SECRET) then begin xwriteSecret(); exit; end;
- if (ttype = TRIGGER_TEXTURE) then begin xwriteTexture(); exit; end;
- if (ttype = TRIGGER_SOUND) then begin xwriteSound(); exit; end;
- if (ttype = TRIGGER_SPAWNMONSTER) then begin xwriteSpawnmonster(); exit; end;
- if (ttype = TRIGGER_SPAWNITEM) then begin xwriteSpawnitem(); exit; end;
- if (ttype = TRIGGER_MUSIC) then begin xwriteMusic(); exit; end;
- if (ttype = TRIGGER_PUSH) then begin xwritePush(); exit; end;
- if (ttype = TRIGGER_SCORE) then begin xwriteScore(); exit; end;
- if (ttype = TRIGGER_MESSAGE) then begin xwriteMessage(); exit; end;
- if (ttype = TRIGGER_DAMAGE) then begin xwriteDamage(); exit; end;
- if (ttype = TRIGGER_HEALTH) then begin xwriteHealth(); exit; end;
- if (ttype = TRIGGER_SHOT) then begin xwriteShot(); exit; end;
- if (ttype = TRIGGER_EFFECT) then begin xwriteEffect(); exit; end;
- raise Exception.Create('invalid trigger type in mb_Write_TriggerData');
-end;
-
-
-procedure mb_Write_TMapHeaderRec_1 (var buf; bufsize: Integer; var tr: TMapHeaderRec_1);
- procedure xwriteTmapheaderrec_1 ();
- begin
- putBytesAt(buf, 0, tr.MapName, 32);
- putBytesAt(buf, 32, tr.MapAuthor, 32);
- putBytesAt(buf, 64, tr.MapDescription, 256);
- putBytesAt(buf, 320, tr.MusicName, 64);
- putBytesAt(buf, 384, tr.SkyName, 64);
- putWordAt(buf, 448, tr.Width);
- putWordAt(buf, 450, tr.Height);
- end;
-
-begin
- if (bufsize < 452) then raise Exception.Create('invalid buffer size in writeTMapHeaderRec_1');
- xwriteTmapheaderrec_1();
-end;
-
-procedure mb_Write_TTextureRec_1 (var buf; bufsize: Integer; var tr: TTextureRec_1);
- procedure xwriteTtexturerec_1 ();
- begin
- putBytesAt(buf, 0, tr.Resource, 64);
- putBytesAt(buf, 64, tr.Anim, 1);
- end;
-
-begin
- if (bufsize < 65) then raise Exception.Create('invalid buffer size in writeTTextureRec_1');
- xwriteTtexturerec_1();
-end;
-
-procedure mb_Write_TPanelRec_1 (var buf; bufsize: Integer; var tr: TPanelRec_1);
- procedure xwriteTpanelrec_1 ();
- begin
- putIntAt(buf, 0, tr.X);
- putIntAt(buf, 4, tr.Y);
- putWordAt(buf, 8, tr.Width);
- putWordAt(buf, 10, tr.Height);
- putWordAt(buf, 12, tr.TextureNum);
- putWordAt(buf, 14, tr.PanelType);
- putBytesAt(buf, 16, tr.Alpha, 1);
- putBytesAt(buf, 17, tr.Flags, 1);
- end;
-
-begin
- if (bufsize < 18) then raise Exception.Create('invalid buffer size in writeTPanelRec_1');
- xwriteTpanelrec_1();
-end;
-
-procedure mb_Write_TItemRec_1 (var buf; bufsize: Integer; var tr: TItemRec_1);
- procedure xwriteTitemrec_1 ();
- begin
- putIntAt(buf, 0, tr.X);
- putIntAt(buf, 4, tr.Y);
- putBytesAt(buf, 8, tr.ItemType, 1);
- putBytesAt(buf, 9, tr.Options, 1);
- end;
-
-begin
- if (bufsize < 10) then raise Exception.Create('invalid buffer size in writeTItemRec_1');
- xwriteTitemrec_1();
-end;
-
-procedure mb_Write_TMonsterRec_1 (var buf; bufsize: Integer; var tr: TMonsterRec_1);
- procedure xwriteTmonsterrec_1 ();
- begin
- putIntAt(buf, 0, tr.X);
- putIntAt(buf, 4, tr.Y);
- putBytesAt(buf, 8, tr.MonsterType, 1);
- putBytesAt(buf, 9, tr.Direction, 1);
- end;
-
-begin
- if (bufsize < 10) then raise Exception.Create('invalid buffer size in writeTMonsterRec_1');
- xwriteTmonsterrec_1();
-end;
-
-procedure mb_Write_TAreaRec_1 (var buf; bufsize: Integer; var tr: TAreaRec_1);
- procedure xwriteTarearec_1 ();
- begin
- putIntAt(buf, 0, tr.X);
- putIntAt(buf, 4, tr.Y);
- putBytesAt(buf, 8, tr.AreaType, 1);
- putBytesAt(buf, 9, tr.Direction, 1);
- end;
-
-begin
- if (bufsize < 10) then raise Exception.Create('invalid buffer size in writeTAreaRec_1');
- xwriteTarearec_1();
-end;
-
-procedure mb_Write_TTriggerRec_1 (var buf; bufsize: Integer; var tr: TTriggerRec_1);
- procedure xwriteTtriggerrec_1 ();
- begin
- putIntAt(buf, 0, tr.X);
- putIntAt(buf, 4, tr.Y);
- putWordAt(buf, 8, tr.Width);
- putWordAt(buf, 10, tr.Height);
- putBytesAt(buf, 12, tr.Enabled, 1);
- putIntAt(buf, 13, tr.TexturePanel);
- putBytesAt(buf, 17, tr.TriggerType, 1);
- putBytesAt(buf, 18, tr.ActivateType, 1);
- putBytesAt(buf, 19, tr.Keys, 1);
- putBytesAt(buf, 20, tr.DATA, 128);
- end;
-
-begin
- if (bufsize < 148) then raise Exception.Create('invalid buffer size in writeTTriggerRec_1');
- xwriteTtriggerrec_1();
-end;
-
diff --git a/src/shared/mapstructsizes.inc b/src/shared/mapstructsizes.inc
+++ /dev/null
@@ -1,25 +0,0 @@
-const
- SizeOf_TMapHeaderRec_1 = 452;
- SizeOf_TTextureRec_1 = 65;
- SizeOf_TPanelRec_1 = 18;
- SizeOf_TItemRec_1 = 10;
- SizeOf_TMonsterRec_1 = 10;
- SizeOf_TAreaRec_1 = 10;
- SizeOf_TTriggerRec_1 = 148;
-
-procedure mb_Read_TriggerData (var tr: TTriggerData; ttype: Integer; const buf; bufsize: Integer);
-procedure mb_Write_TriggerData (var buf; bufsize: Integer; ttype: Integer; var tr: TTriggerData);
-procedure mb_Read_TMapHeaderRec_1 (var tr: TMapHeaderRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TMapHeaderRec_1 (var buf; bufsize: Integer; var tr: TMapHeaderRec_1);
-procedure mb_Read_TTextureRec_1 (var tr: TTextureRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TTextureRec_1 (var buf; bufsize: Integer; var tr: TTextureRec_1);
-procedure mb_Read_TPanelRec_1 (var tr: TPanelRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TPanelRec_1 (var buf; bufsize: Integer; var tr: TPanelRec_1);
-procedure mb_Read_TItemRec_1 (var tr: TItemRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TItemRec_1 (var buf; bufsize: Integer; var tr: TItemRec_1);
-procedure mb_Read_TMonsterRec_1 (var tr: TMonsterRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TMonsterRec_1 (var buf; bufsize: Integer; var tr: TMonsterRec_1);
-procedure mb_Read_TAreaRec_1 (var tr: TAreaRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TAreaRec_1 (var buf; bufsize: Integer; var tr: TAreaRec_1);
-procedure mb_Read_TTriggerRec_1 (var tr: TTriggerRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TTriggerRec_1 (var buf; bufsize: Integer; var tr: TTriggerRec_1);
index 3830af240f6f924519c5704f81f1dc9683ab0dc5..8207f602fcac68605e3d9d58194b117ddb4cc65c 100644 (file)
--- a/src/shared/wadreader.pas
+++ b/src/shared/wadreader.pas
implementation
uses
- SysUtils, e_log, utils, MAPSTRUCT;
+ SysUtils, e_log, utils, MAPDEF;
function findDiskWad (fname: AnsiString): AnsiString;
diff --git a/src/shared/xdynrec.pas b/src/shared/xdynrec.pas
index 3a31a9663c9c96ef3e0bd3d3ba2d5c8603dc679f..f129dd035af96a9b8c12f84feec6bf58a35349b8 100644 (file)
--- a/src/shared/xdynrec.pas
+++ b/src/shared/xdynrec.pas
// TTrigData: array of mMaxDim bytes, but internally a record (mRecRef)
// arrays of chars are pascal shortstrings (with counter in the first byte)
- TDynFieldArray = array of TDynField;
- TDynRecordArray = array of TDynRecord;
-
private
type
TEBS = (TNone, TRec, TEnum, TBitSet);
class function getTypeName (t: TType): AnsiString;
function definition (): AnsiString;
+ function pasdef (): AnsiString;
function clone (newOwner: TDynRecord=nil): TDynField;
property ebs: TEBS read mEBS;
property ebstype: TObject read mEBSType;
property ebstypename: AnsiString read mEBSTypeName; // enum/bitset name
+ property list: TDynRecList read mRVal; // for list
property x: Integer read mIVal;
property w: Integer read mIVal;
destructor Destroy (); override;
function definition (): AnsiString;
+ function pasdef (): AnsiString;
function clone (): TDynRecord;
procedure parseBinValue (st: TStream; forceData: Boolean=false);
procedure writeTo (wr: TTextWriter; putHeader: Boolean=true);
- procedure writeBinTo (st: TStream; trigbufsz: Integer=-1);
+ procedure writeBinTo (st: TStream; trigbufsz: Integer=-1; onlyFields: Boolean=false);
// find field with `TriggerType` type
function trigTypeField (): TDynField;
+ // number of records of the given instance
+ function instanceCount (const typename: AnsiString): Integer;
+
public
property id: AnsiString read mId; // for map parser
property pasname: AnsiString read mPasName;
property field[const aname: AnsiString]: TDynField read getFieldByName;
property isTrigData: Boolean read getIsTrigData;
property isForTrig[const aname: AnsiString]: Boolean read getIsForTrig;
+ property headerType: TDynRecord read mHeaderRec;
+ property isHeader: Boolean read mHeader;
end;
-
TDynEBS = class
private
mOwner: TDynMapDef;
destructor Destroy (); override;
function definition (): AnsiString;
+ function pasdef (): AnsiString;
// return empty string if not found
function nameByValue (v: Integer): AnsiString;
function findTrigFor (const aname: AnsiString): TDynRecord;
function findEBSType (const aname: AnsiString): TDynEBS;
+ function pasdef (): AnsiString;
+
// creates new header record
function parseMap (pr: TTextParser): TDynRecord;
SysUtils;
+// ////////////////////////////////////////////////////////////////////////// //
+function StrEqu (const a, b: AnsiString): Boolean; inline; begin result := (a = b); end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
constructor TDynField.Create (const aname: AnsiString; atype: TType);
begin
end;
+function TDynField.pasdef (): AnsiString;
+begin
+ result := mPasName+': ';
+ case mType of
+ TType.TBool: result += 'Boolean;';
+ TType.TChar: if (mMaxDim > 0) then result += formatstrf('Char%d;', [mMaxDim]) else result += 'Char;';
+ TType.TByte: result += 'ShortInt;';
+ TType.TUByte: result += 'Byte;';
+ TType.TShort: result += 'SmallInt;';
+ TType.TUShort: result += 'Word;';
+ TType.TInt: result += 'LongInt;';
+ TType.TUInt: result += 'LongWord;';
+ TType.TString: result += 'AnsiString;';
+ TType.TPoint:
+ if mAsT then result := 'tX, tY: Integer;'
+ else if mSepPosSize then result := 'X, Y: Integer;'
+ else result += 'TDFPoint;';
+ TType.TSize:
+ if mAsT then result := 'tWidth, tHeight: Word;'
+ else if mSepPosSize then result := 'Width, Height: Word;'
+ else result += 'TSize;';
+ TType.TList: assert(false);
+ TType.TTrigData: result += formatstrf('Byte%d;', [mMaxDim]);
+ else raise Exception.Create('ketmar forgot to handle some field type');
+ end;
+end;
+
+
procedure TDynField.parseDef (pr: TTextParser);
var
fldname: AnsiString;
exit;
end;
// record reference
- if (mRecRef = nil) then
- begin
- // no ref, write -1
- case mType of
- TType.TByte, TType.TUByte: writeInt(st, Byte(-1));
- TType.TShort, TType.TUShort: writeInt(st, SmallInt(-1));
- TType.TInt, TType.TUInt: writeInt(st, Integer(-1));
- else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
- end;
- exit;
- end;
case mType of
TType.TByte: maxv := 127;
TType.TUByte: maxv := 254;
else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
end;
// find record number
- f := mOwner.findRecordNumByType(mEBSTypeName, mRecRef);
- if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
- if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
+ if (mRecRef <> nil) then
+ begin
+ f := mOwner.findRecordNumByType(mEBSTypeName, mRecRef);
+ if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
+ if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
+ end
+ else
+ begin
+ f := -1;
+ end;
case mType of
TType.TByte, TType.TUByte: writeInt(st, Byte(f));
TType.TShort, TType.TUShort: writeInt(st, SmallInt(f));
- TType.TInt, TType.TUInt: writeInt(st, Integer(f));
+ TType.TInt, TType.TUInt: writeInt(st, LongWord(f));
else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
end;
exit;
result := 0;
while (result < mFields.count) do
begin
- if (CompareText(aname, mFields[result].mName) = 0) then exit;
+ if StrEqu(aname, mFields[result].mName) then exit;
Inc(result);
end;
result := -1;
f: Integer;
begin
result := true;
- for f := 0 to High(mTrigTypes) do if (CompareText(mTrigTypes[f], aname) = 0) then exit;
+ for f := 0 to High(mTrigTypes) do if StrEqu(mTrigTypes[f], aname) then exit;
result := false;
end;
begin
for rec in fld.mRVal do
begin
- if (CompareText(rec.mId, aid) = 0) then begin result := rec; exit; end;
+ if StrEqu(rec.mId, aid) then begin result := rec; exit; end;
end;
end;
// alas
if not (fld.mEBSType is TDynEBS) then continue;
es := (fld.mEBSType as TDynEBS);
assert(es <> nil);
- if (CompareText(es.mName, 'TriggerType') = 0) then begin result := fld; exit; end;
+ if StrEqu(es.mName, 'TriggerType') then begin result := fld; exit; end;
end;
result := nil;
end;
+// number of records of the given instance
+function TDynRecord.instanceCount (const typename: AnsiString): Integer;
+var
+ fld: TDynField;
+begin
+ result := 0;
+ fld := field[typename];
+ if (fld <> nil) and (fld.mType = fld.TType.TList) then result := fld.mRVal.count;
+end;
+
+
procedure TDynRecord.parseDef (pr: TTextParser);
var
fld: TDynField;
end;
+function TDynRecord.pasdef (): AnsiString;
+var
+ fld: TDynField;
+begin
+ if isTrigData then
+ begin
+ assert(false);
+ result := '';
+ end
+ else
+ begin
+ // record
+ result := ' '+mPasName+' = packed record'#10;
+ end;
+ for fld in mFields do
+ begin
+ if fld.mInternal then continue;
+ if (fld.mBinOfs < 0) then continue;
+ result += ' '+fld.pasdef+#10;
+ end;
+ result += ' end;'#10;
+end;
+
+
function TDynRecord.definition (): AnsiString;
var
f: Integer;
if (btype = 0) then break; // no more blocks
readLongWord(st); // reserved
bsize := readLongInt(st);
- writeln('btype=', btype, '; bsize=', bsize);
+ //writeln('btype=', btype, '; bsize=', bsize);
if (bsize < 0) or (bsize > $1fffffff) then raise Exception.Create(Format('block of type %d has invalid size %d', [btype, bsize]));
if loaded[btype] then raise Exception.Create(Format('block of type %d already loaded', [btype]));
loaded[btype] := true;
rect := nil;
for rec in mOwner.recTypes do if (rec.mBinBlock = btype) then begin rect := rec; break; end;
if (rect = nil) then raise Exception.Create(Format('block of type %d has no corresponding record', [btype]));
- writeln('found type ''', rec.mName, ''' for block type ', btype);
+ //writeln('found type ''', rec.mName, ''' for block type ', btype);
if (rec.mSize = 0) or ((bsize mod rec.mSize) <> 0) then raise Exception.Create(Format('block of type %d has invalid number of records', [btype]));
// header?
if (rect.mHeader) then
end;
// read fields
- if (CompareText(mName, 'TriggerData') = 0) then mSize := Integer(st.size-st.position);
+ if StrEqu(mName, 'TriggerData') then mSize := Integer(st.size-st.position);
if (mSize < 1) then raise Exception.Create(Format('cannot read record of type ''%s'' with unknown size', [mName]));
GetMem(buf, mSize);
st.ReadBuffer(buf^, mSize);
end;
-procedure TDynRecord.writeBinTo (st: TStream; trigbufsz: Integer=-1);
+procedure TDynRecord.writeBinTo (st: TStream; trigbufsz: Integer=-1; onlyFields: Boolean=false);
var
fld: TDynField;
rec, rv: TDynRecord;
end;
// write block with normal fields
- if mHeader then
+ if mHeader and not onlyFields then
begin
//writeln('writing header...');
// signature and version
FreeMem(buf); buf := nil;
// write other blocks, if any
- if mHeader then
+ if mHeader and not onlyFields then
begin
// calculate blkmax
blkmax := 0;
begin
for rv in fld.mRVal do
begin
- if (Length(rv.mId) > 0) and (CompareText(rv.mId, rec.mId) = 0) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
+ if (Length(rv.mId) > 0) and StrEqu(rv.mId, rec.mId) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
end;
end;
end;
result := 0;
while (result < Length(mIds)) do
begin
- if (CompareText(aname, mIds[result]) = 0) then exit;
+ if StrEqu(aname, mIds[result]) then exit;
Inc(result);
end;
result := -1;
end;
+function TDynEBS.pasdef (): AnsiString;
+var
+ f: Integer;
+begin
+ result := '// '+mName+#10'const'#10;
+ // fields
+ for f := 0 to High(mIds) do
+ begin
+ result += formatstrf(' %s = %d;'#10, [mIds[f], mVals[f]]);
+ end;
+end;
+
+
function TDynEBS.nameByValue (v: Integer): AnsiString;
var
f: Integer;
idname := pr.expectId();
for f := 0 to High(mIds) do
begin
- if (CompareText(mIds[f], idname) = 0) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
+ if StrEqu(mIds[f], idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
end;
- if (CompareText(mMaxName, idname) = 0) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
+ if StrEqu(mMaxName, idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
skipAdd := false;
hasV := false;
v := cv;
begin
for rec in recTypes do
begin
- if (CompareText(rec.name, aname) = 0) then begin result := rec; exit; end;
+ if StrEqu(rec.name, aname) then begin result := rec; exit; end;
end;
result := nil;
end;
begin
for ebs in ebsTypes do
begin
- if (CompareText(ebs.name, aname) = 0) then begin result := ebs; exit; end;
+ if StrEqu(ebs.name, aname) then begin result := ebs; exit; end;
end;
result := nil;
end;
rec := TDynRecord.Create(pr);
//writeln(dr.definition); writeln;
if (findRecType(rec.name) <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
- if (hdr <> nil) and (CompareText(rec.name, hdr.name) = 0) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
+ if (hdr <> nil) and StrEqu(rec.name, hdr.name) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
rec.mOwner := self;
if rec.mHeader then
begin
end;
+function TDynMapDef.pasdef (): AnsiString;
+var
+ ebs: TDynEBS;
+ rec: TDynRecord;
+ fld: TDynField;
+ needComma: Boolean;
+ tn: AnsiString;
+begin
+ result := '';
+ result += '// ////////////////////////////////////////////////////////////////////////// //'#10;
+ result += '// enums and bitsets'#10;
+ for ebs in ebsTypes do result += #10+ebs.pasdef();
+ result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
+ result += '// records'#10'type'#10;
+ for rec in recTypes do
+ begin
+ if (rec.mSize < 1) then continue;
+ result += rec.pasdef();
+ result += #10;
+ end;
+ result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
+ result += '// triggerdata'#10'type'#10;
+ result += ' TTriggerData = record'#10;
+ result += ' case Byte of'#10;
+ result += ' 0: (Default: Byte128);'#10;
+ for rec in trigTypes do
+ begin
+ result += ' ';
+ needComma := false;
+ for tn in rec.mTrigTypes do
+ begin
+ if needComma then result += ', ' else needComma := true;
+ result += tn;
+ end;
+ result += ': ('#10;
+ for fld in rec.mFields do
+ begin
+ if fld.mInternal then continue;
+ if (fld.mBinOfs < 0) then continue;
+ result += ' '+fld.pasdef+#10;
+ end;
+ result += ' );'#10;
+ end;
+ result += ' end;'#10;
+end;
+
+
end.
diff --git a/src/shared/xparser.pas b/src/shared/xparser.pas
index d0f0d3af202bef33b10715f495e13db098ce7dd3..7263b7db60037eef69dba6c49ffa9b6cac5a3108 100644 (file)
--- a/src/shared/xparser.pas
+++ b/src/shared/xparser.pas
SysUtils, utils;
+// ////////////////////////////////////////////////////////////////////////// //
+function StrEqu (const a, b: AnsiString): Boolean; inline; begin result := (a = b); end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
var
wc2shitmap: array[0..65535] of AnsiChar;
wc2shitmapInited: Boolean = false;
procedure TTextParser.expectId (const aid: AnsiString);
begin
- if (mTokType <> TTId) or (CompareText(mTokStr, aid) <> 0) then raise Exception.Create('identifier '''+aid+''' expected');
+ if (mTokType <> TTId) or (not StrEqu(mTokStr, aid)) then raise Exception.Create('identifier '''+aid+''' expected');
skipToken();
end;
function TTextParser.eatId (const aid: AnsiString): Boolean;
begin
result := false;
- if (mTokType <> TTId) or (CompareText(mTokStr, aid) <> 0) then exit;
+ if (mTokType <> TTId) or (not StrEqu(mTokStr, aid)) then exit;
result := true;
skipToken();
end;
diff --git a/src/shared/zmapgen.dpr b/src/shared/zmapgen.dpr
--- /dev/null
+++ b/src/shared/zmapgen.dpr
@@ -0,0 +1,53 @@
+{$INCLUDE a_modes.inc}
+{$M+}
+
+uses
+ SysUtils, Classes,
+ xparser in 'xparser.pas',
+ xdynrec in 'xdynrec.pas',
+ utils in 'utils.pas';
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+var
+ pr: TTextParser;
+ dfmapdef: TDynMapDef;
+ fo: TextFile;
+ st: TStream;
+ ch: AnsiChar;
+ wdt: Integer;
+ s: AnsiString;
+begin
+ writeln('parsing "mapdef.txt"...');
+ pr := TFileTextParser.Create('mapdef.txt');
+ try
+ dfmapdef := TDynMapDef.Create(pr);
+ except on e: Exception do
+ begin
+ writeln('ERROR at (', pr.line, ',', pr.col, '): ', e.message);
+ Halt(1);
+ end;
+ end;
+
+ writeln('writing "mapdef.inc"...');
+ AssignFile(fo, 'mapdef.inc');
+ Rewrite(fo);
+ write(fo, '// *** WARNING! ***'#10);
+ write(fo, '// regenerate this part directly from "mapdef.txt" with ''zmapgen'', NEVER manually change anything here!'#10#10#10);
+ write(fo, dfmapdef.pasdef);
+
+ st := openDiskFileRO('mapdef.txt');
+ write(fo, #10#10'const defaultMapDef: AnsiString = ''''+'#10' ');
+ wdt := 2;
+ while true do
+ begin
+ if (st.Read(ch, 1) <> 1) then break;
+ s := formatstrf('#%d', [Byte(ch)]);
+ if (wdt+Length(s) > 78) then begin wdt := 2; write(fo, '+'#10' '); end;
+ write(fo, s);
+ Inc(wdt, Length(s));
+ end;
+ write(fo, #10';');
+
+ CloseFile(fo);
+end.