1 (* Copyright (C) DooM 2D:Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 {$INCLUDE a_modes.inc}
27 MAP_SIGNATURE
= 'MAP';
31 TEXTURE_NAME_WATER
= '_water_0';
32 TEXTURE_NAME_ACID1
= '_water_1';
33 TEXTURE_NAME_ACID2
= '_water_2';
37 TDFPoint
= packed record
42 constructor Create (ax
, ay
: LongInt);
44 function isZero (): Boolean; inline;
47 TDFSize
= packed record
52 constructor Create (aw
, ah
: LongInt);
54 function isZero (): Boolean; inline;
55 function isValid (): Boolean; inline;
58 Char16
= packed array[0..15] of Char;
59 Char32
= packed array[0..31] of Char;
60 Char64
= packed array[0..63] of Char;
61 Char100
= packed array[0..99] of Char;
62 Char256
= packed array[0..255] of Char;
63 Byte128
= packed array[0..127] of Byte;
67 // various helpers to access map structures
69 TDynRecordHelper
= class helper
for TDynRecord
71 function getFieldWithType (const aname
: AnsiString; atype
: TDynField
.TType
): TDynField
; inline;
73 function getPanelByIdx (idx
: Integer): TDynRecord
; inline;
75 function getTexturePanel (): Integer; inline;
76 function getTexturePanelRec (): TDynRecord
; inline;
78 function getPanelIndex (pan
: TDynRecord
): Integer;
80 function getPointField (const aname
: AnsiString): TDFPoint
; inline;
81 function getSizeField (const aname
: AnsiString): TDFSize
; inline;
84 function panelCount (): Integer; inline;
87 function mapName (): AnsiString; inline;
88 function mapAuthor (): AnsiString; inline;
89 function mapDesc (): AnsiString; inline;
90 function musicName (): AnsiString; inline;
91 function skyName (): AnsiString; inline;
94 function X (): Integer; inline;
95 function Y (): Integer; inline;
96 function Width (): Word; inline;
97 function Height (): Word; inline;
98 function TextureNum (): Word; inline;
99 function TextureRec (): TDynRecord
; inline;
100 function PanelType (): Word; inline;
101 function Alpha (): Byte; inline;
102 function Flags (): Byte; inline;
104 function moveSpeed (): TDFPoint
; inline;
105 function moveStart (): TDFPoint
; inline;
106 function moveEnd (): TDFPoint
; inline;
108 function moveOnce (): Boolean; inline;
110 function sizeSpeed (): TDFSize
; inline;
111 function sizeEnd (): TDFSize
; inline;
113 function endPosTrig (): Integer; inline;
114 function endSizeTrig (): Integer; inline;
117 function Resource (): AnsiString; inline;
118 function Anim (): Boolean; inline;
121 function ItemType (): Byte; inline;
122 function Options (): Byte; inline;
125 function MonsterType (): Byte; inline; // type, ubyte
126 function Direction (): Byte; inline; // direction, ubyte
129 function AreaType (): Byte; inline; // type, ubyte
130 //function Direction (): Byte; inline; // direction, ubyte
133 function trigRec (): TDynRecord
; inline;
134 function Enabled (): Boolean; inline; // enabled, bool
135 function TriggerType (): Byte; inline; // type, ubyte
136 function ActivateType (): Byte; inline; // activatetype, ubyte
137 function Keys (): Byte; inline; // keys, ubyte
138 //function DATA (): Byte128; inline; // triggerdata, trigdata[128]; // the only special nested structure
140 {$INCLUDE mapdef_help.inc}
141 function trigMonsterId (): Integer; inline;
142 function trigPanelId (): Integer; inline; // panel index in list
143 function trigPanelRec (): TDynRecord
; inline;
147 function getUserPanelId (): Integer; inline;
148 procedure setUserPanelId (v
: Integer); inline;
150 function getUserTrigRef (): Boolean; inline;
151 procedure setUserTrigRef (v
: Boolean); inline;
154 property panel
[idx
: Integer]: TDynRecord read getPanelByIdx
;
155 property panelIndex
[pan
: TDynRecord
]: Integer read getPanelIndex
;
157 property tgPanelId
: Integer read trigPanelId
;
158 property tgPanelRec
: TDynRecord read trigPanelRec
;
159 property TexturePanelId
: Integer read getTexturePanel
; // texturepanel, int
160 property TexturePanelRec
: TDynRecord read getTexturePanelRec
;
162 property userPanelId
: Integer read getUserPanelId write setUserPanelId
;
163 property userPanelTrigRef
: Boolean read getUserTrigRef write setUserTrigRef
;
169 SysUtils
, {e_log,} utils
, xparser
, xstreams
;
172 // ////////////////////////////////////////////////////////////////////////// //
173 constructor TDFPoint
.Create (ax
, ay
: LongInt); begin X
:= ax
; Y
:= ay
; end;
174 function TDFPoint
.isZero (): Boolean; inline; begin result
:= (X
= 0) and (Y
= 0); end;
177 constructor TDFSize
.Create (aw
, ah
: LongInt); begin w
:= aw
; h
:= ah
; end;
178 function TDFSize
.isZero (): Boolean; inline; begin result
:= (w
= 0) and (h
= 0); end;
179 function TDFSize
.isValid (): Boolean; inline; begin result
:= (w
> 0) and (h
> 0); end;
182 // ////////////////////////////////////////////////////////////////////////// //
183 function TDynRecordHelper
.getUserPanelId (): Integer; inline;
187 fld
:= field
['userPanelId'];
188 //if (fld = nil) or (fld.baseType <> TDynField.TType.TInt) then result := -1 else result := fld.ival;
189 if (fld
= nil) then result
:= -1 else result
:= Integer(fld
.value
);
193 procedure TDynRecordHelper
.setUserPanelId (v
: Integer); inline;
195 user
['userPanelId'] := v
;
199 function TDynRecordHelper
.getUserTrigRef (): Boolean; inline;
203 fld
:= field
['userPanelTrigRef'];
204 if (fld
= nil) then result
:= false else result
:= Boolean(fld
.value
);
205 //if (fld = nil) or (fld.baseType <> TDynField.TType.TBool) then result := false else result := (fld.ival <> 0);
209 procedure TDynRecordHelper
.setUserTrigRef (v
: Boolean); inline;
211 user
['userPanelTrigRef'] := v
;
215 // ////////////////////////////////////////////////////////////////////////// //
216 function TDynRecordHelper
.moveSpeed (): TDFPoint
; inline; begin result
:= getPointField('move_speed'); end;
217 function TDynRecordHelper
.moveStart (): TDFPoint
; inline; begin result
:= getPointField('move_start'); end;
218 function TDynRecordHelper
.moveEnd (): TDFPoint
; inline; begin result
:= getPointField('move_end'); end;
220 function TDynRecordHelper
.sizeSpeed (): TDFSize
; inline; begin result
:= getSizeField('size_speed'); end;
221 function TDynRecordHelper
.sizeEnd (): TDFSize
; inline; begin result
:= getSizeField('size_end'); end;
223 function TDynRecordHelper
.moveOnce (): Boolean; inline; begin result
:= (getFieldWithType('move_once', TDynField
.TType
.TBool
).ival
<> 0); end;
226 function TDynRecordHelper
.endPosTrig (): Integer; inline;
230 fld
:= getFieldWithType('end_pos_trigger', TDynField
.TType
.TInt
);
231 result
:= fld
.recrefIndex
;
234 function TDynRecordHelper
.endSizeTrig (): Integer; inline;
238 fld
:= getFieldWithType('end_size_trigger', TDynField
.TType
.TInt
);
239 result
:= fld
.recrefIndex
;
243 // ////////////////////////////////////////////////////////////////////////// //
244 function TDynRecordHelper
.getFieldWithType (const aname
: AnsiString; atype
: TDynField
.TType
): TDynField
; inline;
246 result
:= field
[aname
];
247 if (result
= nil) then raise Exception
.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname
, typeName
, id
]));
248 if (result
.baseType
<> atype
) then raise Exception
.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname
, typeName
, id
]));
252 function TDynRecordHelper
.getPointField (const aname
: AnsiString): TDFPoint
; inline;
257 if (fld
= nil) then raise Exception
.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname
, typeName
, id
]));
258 if (fld
.baseType
<> TPoint
) then raise Exception
.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname
, typeName
, id
]));
259 result
:= TDFPoint
.Create(fld
.ival
, fld
.ival2
);
263 function TDynRecordHelper
.getSizeField (const aname
: AnsiString): TDFSize
; inline;
268 if (fld
= nil) then raise Exception
.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname
, typeName
, id
]));
269 if (fld
.baseType
<> TSize
) and (fld
.baseType
<> TPoint
) then raise Exception
.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname
, typeName
, id
]));
270 result
:= TDFSize
.Create(fld
.ival
, fld
.ival2
);
274 function TDynRecordHelper
.getPanelByIdx (idx
: Integer): TDynRecord
; inline;
278 fld
:= headerRec
['panel'];
279 if (fld
<> nil) then result
:= fld
.itemAt
[idx
] else result
:= nil;
283 function TDynRecordHelper
.getPanelIndex (pan
: TDynRecord
): Integer;
291 fld
:= headerRec
['panel'];
294 for f
:= 0 to fld
.count
-1 do if (fld
.itemAt
[f
] = pan
) then begin result
:= f
; exit
; end;
300 function TDynRecordHelper
.panelCount (): Integer; inline;
304 fld
:= headerRec
['panel'];
305 if (fld
<> nil) then result
:= fld
.count
else result
:= 0;
309 function TDynRecordHelper
.TextureNum (): Word; inline;
314 fld
:= getFieldWithType('texture', TDynField
.TType
.TUShort
);
315 idx
:= fld
.recrefIndex
;
316 if (idx
< 0) then result
:= Word(TEXTURE_NONE
) else result
:= Word(idx
);
320 // ////////////////////////////////////////////////////////////////////////// //
322 function TDynRecordHelper
.trigRec (): TDynRecord
; inline;
326 fld
:= getFieldWithType('triggerdata', TDynField
.TType
.TTrigData
);
327 if (fld
<> nil) then result
:= fld
.recref
else result
:= nil;
330 function TDynRecordHelper
.trigMonsterId (): Integer; inline;
335 fld
:= field
['monsterid'];
336 if (fld
= nil) then exit
;
337 if (fld
.baseType
<> TDynField
.TType
.TInt
) then exit
;
338 if (fld
.recref
= nil) then exit
;
339 result
:= fld
.recrefIndex
;
342 function TDynRecordHelper
.trigPanelRec (): TDynRecord
; inline;
347 fld
:= field
['panelid'];
348 if (fld
= nil) then exit
;
349 if (fld
.baseType
<> TDynField
.TType
.TInt
) then exit
;
350 result
:= fld
.recref
;
351 if (result
<> nil) and (result
.typeName
<> 'panel') then result
:= nil;
354 // panel index in list
355 function TDynRecordHelper
.trigPanelId (): Integer; inline;
360 fld
:= field
['panelid'];
361 if (fld
= nil) then exit
;
362 if (fld
.baseType
<> TDynField
.TType
.TInt
) then exit
;
363 if (fld
.recref
= nil) then exit
;
364 if (fld
.recref
.typeName
<> 'panel') then exit
;
365 result
:= fld
.recrefIndex
;
368 function TDynRecordHelper
.getTexturePanelRec (): TDynRecord
;
373 fld
:= field
['texture_panel'];
374 if (fld
= nil) then exit
;
375 if (fld
.baseType
<> TDynField
.TType
.TInt
) then exit
;
376 result
:= fld
.recref
;
377 if (result
<> nil) and (result
.typeName
<> 'panel') then result
:= nil;
380 function TDynRecordHelper
.getTexturePanel (): Integer;
385 fld
:= field
['texture_panel'];
386 if (fld
= nil) then exit
;
387 if (fld
.baseType
<> TDynField
.TType
.TInt
) then exit
;
388 if (fld
.recref
= nil) then exit
;
389 if (fld
.recref
.typeName
<> 'panel') then exit
;
390 result
:= fld
.recrefIndex
;
394 // ////////////////////////////////////////////////////////////////////////// //
395 function TDynRecordHelper
.mapName (): AnsiString; inline; begin result
:= utf2win(getFieldWithType('name', TDynField
.TType
.TChar
).sval
); end;
396 function TDynRecordHelper
.mapAuthor (): AnsiString; inline; begin result
:= utf2win(getFieldWithType('author', TDynField
.TType
.TChar
).sval
); end;
397 function TDynRecordHelper
.mapDesc (): AnsiString; inline; begin result
:= utf2win(getFieldWithType('description', TDynField
.TType
.TChar
).sval
); end;
398 function TDynRecordHelper
.musicName (): AnsiString; inline; begin result
:= utf2win(getFieldWithType('music', TDynField
.TType
.TChar
).sval
); end;
399 function TDynRecordHelper
.skyName (): AnsiString; inline; begin result
:= utf2win(getFieldWithType('sky', TDynField
.TType
.TChar
).sval
); end;
400 function TDynRecordHelper
.X (): Integer; inline; begin result
:= getFieldWithType('position', TDynField
.TType
.TPoint
).ival
; end;
401 function TDynRecordHelper
.Y (): Integer; inline; begin result
:= getFieldWithType('position', TDynField
.TType
.TPoint
).ival2
; end;
402 function TDynRecordHelper
.Width (): Word; inline; begin result
:= Word(getFieldWithType('size', TDynField
.TType
.TSize
).ival
); end;
403 function TDynRecordHelper
.Height (): Word; inline; begin result
:= Word(getFieldWithType('size', TDynField
.TType
.TSize
).ival2
); end;
404 function TDynRecordHelper
.PanelType (): Word; inline; begin result
:= Word(getFieldWithType('type', TDynField
.TType
.TUShort
).ival
); end;
405 function TDynRecordHelper
.TextureRec (): TDynRecord
; inline; begin result
:= getFieldWithType('texture', TDynField
.TType
.TUShort
).recref
; end;
406 function TDynRecordHelper
.Alpha (): Byte; inline; begin result
:= Byte(getFieldWithType('alpha', TDynField
.TType
.TUByte
).ival
); end;
407 function TDynRecordHelper
.Flags (): Byte; inline; begin result
:= Byte(getFieldWithType('flags', TDynField
.TType
.TUByte
).ival
); end;
408 function TDynRecordHelper
.Resource (): AnsiString; inline; begin result
:= utf2win(getFieldWithType('path', TDynField
.TType
.TChar
).sval
); end;
409 function TDynRecordHelper
.Anim (): Boolean; inline; begin result
:= (getFieldWithType('animated', TDynField
.TType
.TBool
).ival
<> 0); end;
410 function TDynRecordHelper
.ItemType (): Byte; inline; begin result
:= Byte(getFieldWithType('type', TDynField
.TType
.TUByte
).ival
); end;
411 function TDynRecordHelper
.Options (): Byte; inline; begin result
:= Byte(getFieldWithType('options', TDynField
.TType
.TUByte
).ival
); end;
412 function TDynRecordHelper
.MonsterType (): Byte; inline; begin result
:= Byte(getFieldWithType('type', TDynField
.TType
.TUByte
).ival
); end;
413 function TDynRecordHelper
.Direction (): Byte; inline; begin result
:= Byte(getFieldWithType('direction', TDynField
.TType
.TUByte
).ival
); end;
414 function TDynRecordHelper
.AreaType (): Byte; inline; begin result
:= Byte(getFieldWithType('type', TDynField
.TType
.TUByte
).ival
); end;
415 function TDynRecordHelper
.Enabled (): Boolean; inline; begin result
:= (getFieldWithType('enabled', TDynField
.TType
.TBool
).ival
<> 0); end;
416 function TDynRecordHelper
.TriggerType (): Byte; inline; begin result
:= Byte(getFieldWithType('type', TDynField
.TType
.TUByte
).ival
); end;
417 function TDynRecordHelper
.ActivateType (): Byte; inline; begin result
:= Byte(getFieldWithType('activate_type', TDynField
.TType
.TUByte
).ival
); end;
418 function TDynRecordHelper
.Keys (): Byte; inline; begin result
:= Byte(getFieldWithType('keys', TDynField
.TType
.TUByte
).ival
); end;
420 {$INCLUDE mapdef_impl.inc}