3 {$INCLUDE ../shared/a_modes.inc}
6 -----------------------------------
7 MAPREADER.PAS ÂÅÐÑÈß ÎÒ 13.11.07
9 Ïîääåðæêà êàðò âåðñèè 1
10 -----------------------------------
19 TDataBlock
= packed record
24 TDataBlocksArray
= packed array of TDataBlock
;
26 TMapReader
= class(TObject
)
30 FDataBlocks
: TDataBlocksArray
;
31 function GetBlocks(BlocksType
: Byte): TDataBlocksArray
;
34 destructor Destroy(); override;
35 function LoadMap(Data
: Pointer): Boolean;
37 function HandledVersion(): Byte; virtual;
39 property GetError
: Byte read FError
;
40 property GetVersion
: Byte read FVersion
;
43 TMapReader_1
= class(TMapReader
)
46 function GetMapHeader(): TMapHeaderRec_1
;
47 function GetTextures(): TTexturesRec1Array
;
48 function GetPanels(): TPanelsRec1Array
;
49 function GetItems(): TItemsRec1Array
;
50 function GetAreas(): TAreasRec1Array
;
51 function GetMonsters(): TMonsterRec1Array
;
52 function GetTriggers(): TTriggersRec1Array
;
53 function HandledVersion(): Byte; override;
58 MAP_ERROR_SIGNATURE
= $01;
59 MAP_ERROR_VERSION
= $02;
66 function g_Texture_NumNameFindStart(name
: String): Boolean;
67 function g_Texture_NumNameFindNext(var newName
: String): Byte;
72 SysUtils
, BinEditor
, MAPDEF
;
75 NNF_PureName
: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
76 NNF_FirstNum
: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
77 NNF_CurrentNum
: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
79 function g_Texture_NumNameFindStart(name
: String): Boolean;
89 for i
:= Length(name
) downto 1 do
90 if (name
[i
] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
92 if i
= Length(name
) then
93 begin // Íåò öèôð â êîíöå ñòðîêè
98 NNF_PureName
:= Copy(name
, 1, i
);
104 // Íå ïåðåâåñòè â ÷èñëî:
105 if not TryStrToInt(name
, NNF_FirstNum
) then
113 function g_Texture_NumNameFindNext(var newName
: String): Byte;
115 if (NNF_PureName
= '') or (NNF_CurrentNum
< 0) then
118 Result
:= NNF_NO_NAME
;
122 newName
:= NNF_PureName
+ IntToStr(NNF_CurrentNum
);
124 if NNF_CurrentNum
< NNF_FirstNum
then
125 Result
:= NNF_NAME_BEFORE
127 if NNF_CurrentNum
> NNF_FirstNum
then
128 Result
:= NNF_NAME_AFTER
130 Result
:= NNF_NAME_EQUALS
;
135 { T M a p R e a d e r _ 1 : }
137 function TMapReader_1
.GetAreas(): TAreasRec1Array
;
139 TempDataBlocks
: TDataBlocksArray
;
145 TempDataBlocks
:= GetBlocks(BLOCK_AREAS
);
147 if TempDataBlocks
= nil then Exit
;
149 size
:= SizeOf(TAreaRec_1
);
151 for a
:= 0 to High(TempDataBlocks
) do
152 for b
:= 0 to (TempDataBlocks
[a
].Block
.BlockSize
div size
)-1 do
154 SetLength(Result
, Length(Result
)+1);
155 CopyMemory(@Result
[High(Result
)], Pointer(PtrUInt(TempDataBlocks
[a
].Data
)+b
*size
), size
);
158 {$IFDEF FPC_BIG_ENDIAN}
159 for a
:= 0 to High(Result
) do
161 Result
[a
].X
:= LEtoN(Result
[a
].X
);
162 Result
[a
].Y
:= LEtoN(Result
[a
].Y
);
166 TempDataBlocks
:= nil;
169 function TMapReader_1
.GetItems(): TItemsRec1Array
;
171 TempDataBlocks
: TDataBlocksArray
;
177 TempDataBlocks
:= GetBlocks(BLOCK_ITEMS
);
179 if TempDataBlocks
= nil then Exit
;
181 size
:= SizeOf(TItemRec_1
);
183 for a
:= 0 to High(TempDataBlocks
) do
184 for b
:= 0 to (TempDataBlocks
[a
].Block
.BlockSize
div size
)-1 do
186 SetLength(Result
, Length(Result
)+1);
187 CopyMemory(@Result
[High(Result
)], Pointer(PtrUInt(TempDataBlocks
[a
].Data
)+b
*size
), size
);
190 {$IFDEF FPC_BIG_ENDIAN}
191 for a
:= 0 to High(Result
) do
193 Result
[a
].X
:= LEtoN(Result
[a
].X
);
194 Result
[a
].Y
:= LEtoN(Result
[a
].Y
);
198 TempDataBlocks
:= nil;
201 function TMapReader_1
.GetMapHeader(): TMapHeaderRec_1
;
203 TempDataBlocks
: TDataBlocksArray
;
205 ZeroMemory(@Result
, SizeOf(TMapHeaderRec_1
));
207 TempDataBlocks
:= GetBlocks(BLOCK_HEADER
);
209 if TempDataBlocks
= nil then Exit
;
211 CopyMemory(@Result
, TempDataBlocks
[0].Data
, SizeOf(TMapHeaderRec_1
));
213 {$IFDEF FPC_BIG_ENDIAN}
214 Result
.Width
:= LEtoN(Result
.Width
);
215 Result
.Height
:= LEtoN(Result
.Height
);
218 TempDataBlocks
:= nil;
221 function TMapReader_1
.GetMonsters(): TMonsterRec1Array
;
223 TempDataBlocks
: TDataBlocksArray
;
229 TempDataBlocks
:= GetBlocks(BLOCK_MONSTERS
);
231 if TempDataBlocks
= nil then Exit
;
233 size
:= SizeOf(TMonsterRec_1
);
235 for a
:= 0 to High(TempDataBlocks
) do
236 for b
:= 0 to (TempDataBlocks
[a
].Block
.BlockSize
div size
)-1 do
238 SetLength(Result
, Length(Result
)+1);
239 CopyMemory(@Result
[High(Result
)], Pointer(PtrUInt(TempDataBlocks
[a
].Data
)+b
*size
), size
);
242 {$IFDEF FPC_BIG_ENDIAN}
243 for a
:= 0 to High(Result
) do
245 Result
[a
].X
:= LEtoN(Result
[a
].X
);
246 Result
[a
].Y
:= LEtoN(Result
[a
].Y
);
250 TempDataBlocks
:= nil;
253 function TMapReader_1
.GetPanels(): TPanelsRec1Array
;
255 TempDataBlocks
: TDataBlocksArray
;
261 TempDataBlocks
:= GetBlocks(BLOCK_PANELS
);
263 if TempDataBlocks
= nil then Exit
;
265 size
:= SizeOf(TPanelRec_1
);
267 for a
:= 0 to High(TempDataBlocks
) do
268 for b
:= 0 to (TempDataBlocks
[a
].Block
.BlockSize
div size
)-1 do
270 SetLength(Result
, Length(Result
)+1);
271 CopyMemory(@Result
[High(Result
)], Pointer(PtrUInt(TempDataBlocks
[a
].Data
)+b
*size
), size
);
274 {$IFDEF FPC_BIG_ENDIAN}
275 for a
:= 0 to High(Result
) do
277 Result
[a
].X
:= LEtoN(Result
[a
].X
);
278 Result
[a
].Y
:= LEtoN(Result
[a
].Y
);
279 Result
[a
].Width
:= LEtoN(Result
[a
].Width
);
280 Result
[a
].Height
:= LEtoN(Result
[a
].Height
);
281 Result
[a
].TextureNum
:= LEtoN(Result
[a
].TextureNum
);
282 Result
[a
].PanelType
:= LEtoN(Result
[a
].PanelType
);
286 TempDataBlocks
:= nil;
289 function TMapReader_1
.GetTextures(): TTexturesRec1Array
;
291 TempDataBlocks
: TDataBlocksArray
;
297 TempDataBlocks
:= GetBlocks(BLOCK_TEXTURES
);
299 if TempDataBlocks
= nil then Exit
;
301 size
:= SizeOf(TTextureRec_1
);
303 for a
:= 0 to High(TempDataBlocks
) do
304 for b
:= 0 to (TempDataBlocks
[a
].Block
.BlockSize
div size
)-1 do
306 SetLength(Result
, Length(Result
)+1);
307 CopyMemory(@Result
[High(Result
)], Pointer(PtrUInt(TempDataBlocks
[a
].Data
)+b
*size
), size
);
310 TempDataBlocks
:= nil;
313 function TMapReader_1
.GetTriggers(): TTriggersRec1Array
;
315 PTriggerData
= ^TTriggerData
;
317 TempDataBlocks
: TDataBlocksArray
;
324 TempDataBlocks
:= GetBlocks(BLOCK_TRIGGERS
);
326 if TempDataBlocks
= nil then Exit
;
328 size
:= SizeOf(TTriggerRec_1
);
330 for a
:= 0 to High(TempDataBlocks
) do
331 for b
:= 0 to (TempDataBlocks
[a
].Block
.BlockSize
div size
)-1 do
333 SetLength(Result
, Length(Result
)+1);
334 CopyMemory(@Result
[High(Result
)], Pointer(PtrUInt(TempDataBlocks
[a
].Data
)+b
*size
), size
);
337 {$IFDEF FPC_BIG_ENDIAN}
338 for a
:= 0 to High(Result
) do
340 Result
[a
].X
:= LEtoN(Result
[a
].X
);
341 Result
[a
].Y
:= LEtoN(Result
[a
].Y
);
342 Result
[a
].Width
:= LEtoN(Result
[a
].Width
);
343 Result
[a
].Height
:= LEtoN(Result
[a
].Height
);
344 Result
[a
].TexturePanel
:= LEtoN(Result
[a
].TexturePanel
);
345 data
:= PTriggerData(@Result
[a
].DATA
);
346 case Result
[a
].TriggerType
of
350 data
.TargetPoint
.X
:= LEtoN(data
.TargetPoint
.X
);
351 data
.TargetPoint
.Y
:= LEtoN(data
.TargetPoint
.Y
);
353 TRIGGER_OPENDOOR
, TRIGGER_CLOSEDOOR
, TRIGGER_DOOR
, TRIGGER_DOOR5
,
354 TRIGGER_CLOSETRAP
, TRIGGER_TRAP
, TRIGGER_LIFTUP
, TRIGGER_LIFTDOWN
,
356 data
.PanelID
:= LEtoN(data
.PanelID
);
357 TRIGGER_PRESS
, TRIGGER_ON
, TRIGGER_OFF
, TRIGGER_ONOFF
:
359 data
.tX
:= LEtoN(data
.tX
);
360 data
.tY
:= LEtoN(data
.tY
);
361 data
.tWidth
:= LEtoN(data
.tWidth
);
362 data
.tHeight
:= LEtoN(data
.tHeight
);
363 data
.Wait
:= LEtoN(data
.Wait
);
364 data
.Count
:= LEtoN(data
.Count
);
365 data
.MonsterID
:= LEtoN(data
.MonsterID
);
370 TRIGGER_SPAWNMONSTER
:
372 data
.MonPos
.X
:= LEtoN(data
.MonPos
.X
);
373 data
.MonPos
.Y
:= LEtoN(data
.MonPos
.Y
);
374 data
.MonHealth
:= LEtoN(data
.MonHealth
);
375 data
.MonCount
:= LEtoN(data
.MonCount
);
376 data
.MonMax
:= LEtoN(data
.MonMax
);
377 data
.MonDelay
:= LEtoN(data
.MonDelay
);
381 data
.ItemPos
.X
:= LEtoN(data
.ItemPos
.X
);
382 data
.ItemPos
.Y
:= LEtoN(data
.ItemPos
.Y
);
383 data
.ItemCount
:= LEtoN(data
.ItemCount
);
384 data
.ItemMax
:= LEtoN(data
.ItemMax
);
385 data
.ItemDelay
:= LEtoN(data
.ItemDelay
);
389 data
.PushAngle
:= LEtoN(data
.PushAngle
);
392 data
.MessageTime
:= LEtoN(data
.MessageTime
);
395 data
.DamageValue
:= LEtoN(data
.DamageValue
);
396 data
.DamageInterval
:= LEtoN(data
.DamageInterval
);
400 data
.HealValue
:= LEtoN(data
.HealValue
);
401 data
.HealInterval
:= LEtoN(data
.HealInterval
);
405 data
.ShotPos
.X
:= LEtoN(data
.ShotPos
.X
);
406 data
.ShotPos
.Y
:= LEtoN(data
.ShotPos
.Y
);
407 data
.ShotPanelID
:= LEtoN(data
.ShotPanelID
);
408 data
.ShotIntSight
:= LEtoN(data
.ShotIntSight
);
409 data
.ShotAngle
:= LEtoN(data
.ShotAngle
);
410 data
.ShotWait
:= LEtoN(data
.ShotWait
);
411 data
.ShotAccuracy
:= LEtoN(data
.ShotAccuracy
);
412 data
.ShotAmmo
:= LEtoN(data
.ShotAmmo
);
413 data
.ShotIntReload
:= LEtoN(data
.ShotIntReload
);
417 data
.FXWait
:= LEtoN(data
.FXWait
);
418 data
.FXVelX
:= LEtoN(data
.FXVelX
);
419 data
.FXVelY
:= LEtoN(data
.FXVelY
);
425 TempDataBlocks
:= nil;
428 function TMapReader_1
.HandledVersion
: Byte;
433 { T M a p R e a d e r : }
435 constructor TMapReader
.Create();
438 FError
:= MAP_ERROR_NONE
;
442 destructor TMapReader
.Destroy();
449 procedure TMapReader
.FreeMap();
453 if FDataBlocks
<> nil then
454 for a
:= 0 to High(FDataBlocks
) do
455 if FDataBlocks
[a
].Data
<> nil then FreeMem(FDataBlocks
[a
].Data
);
459 FError
:= MAP_ERROR_NONE
;
462 function TMapReader
.GetBlocks(BlocksType
: Byte): TDataBlocksArray
;
468 if FDataBlocks
= nil then Exit
;
470 for a
:= 0 to High(FDataBlocks
) do
471 if FDataBlocks
[a
].Block
.BlockType
= BlocksType
then
473 SetLength(Result
, Length(Result
)+1);
474 Result
[High(Result
)] := FDataBlocks
[a
];
478 function TMapReader
.HandledVersion(): Byte;
483 function TMapReader
.LoadMap(Data
: Pointer): Boolean;
487 Sign
: array[0..2] of Char;
492 CopyMemory(@Sign
[0], Data
, 3);
493 if Sign
<> MAP_SIGNATURE
then
495 FError
:= MAP_ERROR_SIGNATURE
;
500 CopyMemory(@Ver
, Pointer(PtrUInt(Data
)+adr
), 1);
502 if Ver
> HandledVersion() then
504 FError
:= MAP_ERROR_VERSION
;
510 SetLength(FDataBlocks
, Length(FDataBlocks
)+1);
511 _id
:= High(FDataBlocks
);
513 CopyMemory(@FDataBlocks
[_id
].Block
, Pointer(PtrUInt(Data
)+adr
), SizeOf(TBlock
));
514 {$IFDEF FPC_BIG_ENDIAN}
515 FDataBlocks
[_id
].Block
.Reserved
:= LEtoN(FDataBlocks
[_id
].Block
.Reserved
);
516 FDataBlocks
[_id
].Block
.BlockSize
:= LEtoN(FDataBlocks
[_id
].Block
.BlockSize
);
518 adr
:= adr
+SizeOf(TBlock
);
520 FDataBlocks
[_id
].Data
:= GetMemory(FDataBlocks
[_id
].Block
.BlockSize
);
522 CopyMemory(FDataBlocks
[_id
].Data
, Pointer(PtrUInt(Data
)+adr
), FDataBlocks
[_id
].Block
.BlockSize
);
524 adr
:= adr
+FDataBlocks
[_id
].Block
.BlockSize
;
525 until FDataBlocks
[_id
].Block
.BlockType
= BLOCK_NONE
;