root/trunk/MobFormat.cpp

Revision 12, 66.2 kB (checked in by sagrer, 9 months ago)
  • Добавлен пункт меню для закрытия текущего открытого моба.
  • Исправлена ошибка, проявлявшаяся в некоторых случаях если начать крутить ориентатор при не выделенном в дереве реальном объекте.
  • При любом закрытии активного моба, в т.ч. при выходе из программы если файл был изменен - появляется вопрос о том что делать с измененным файлом.
  • Добавлен svn-clean.cmd для удаления неверсифицированных файлов в рабочей копии.
Line 
1 ///////////////////////////////////////////////////////////
2 //                      MobSurgeon                       //
3 //          Ðåäàêòîð mob-îâ äëÿ Ïðîêëÿòûõ Çåìåëü         //
4 //           Copyright (C) 2005-2007 Gipat Group         //
5 //              Ðàñïðîñòðàíÿåòñÿ íà óñëîâèÿõ             //
6 //    Gipat Group's opened EI-editor-utility license     //
7 //                      âåðñèè 1.0                       //
8 //                                                       //
9 //                  www.gipatgroup.org                   //
10 ///////////////////////////////////////////////////////////
11
12 //Ê ðàáîòå íàä äàííûì ôàéëîì ïðèëîæèëè ðóêè, íîãè.... êîðî÷å àôôòàðû:
13 // 1) Sagrer (sagrer@yandex.ru)
14
15 ////////////////////////////////////////////////////////////////////////
16
17 //---------------------------------------------------------------------------
18
19
20 #pragma hdrstop
21
22 #include "MobFormat.h"
23 #include <Dialogs.hpp>
24 #include "MainForm.h"
25
26 //---------------------------------------------------------------------------
27
28 #pragma package(smart_init)
29
30 TMobLoaderThread *MobLoaderThr;
31 TMobSaverThread *MobSaverThr;
32
33 TMob::TMob()
34 {
35   //Êîíñòðóêòîð.
36   UsingThread = false;
37   Loading = false;
38   Saving = false;
39   SaveAttempts = 10;  //Ïî óìîë÷àíèþ ïîñëå ñáîÿ ïûòàòüñÿ ñäåëàòü ñàâ åùå 10 ðàç.
40   TailSize = 0;
41
42   UnloadMob();  //Èíôà î ìîáå - èíèöèàëèçîâàòü.
43 }
44
45 TMob::~TMob()
46 {
47   //Äåñòðóêòîð.
48   //Óáèðàåò ìóñîð
49   UnloadMob();
50
51 }
52
53 void TMob::UnloadMob()
54 //Òèïà ÷èñòèò êëàññ îò èíôû íà ñëó÷àé åñëè ìîá äî ýòîãî çàãðóæàëñÿ óæå.
55 {
56   FullLogStr = "";
57   LastLogMessage = "";
58   NewMessageSent = false;
59   UnknownBlocks.Length = 0;
60
61   if (TailSize > 0)
62   {
63     //Î÷èñòèòü ïàìÿòü, çàíÿòóþ ïîä õâîñò.
64     delete Tail;
65     TailSize = 0;
66   };
67   MobLoaded = false;     //Âñå, òèïà äàæå åñëè ìîá áûë çàãðóæåí - òåïåðü íè÷å íå çàãðóæåíî.
68   CurrBlockSgn = false;
69
70   //Èíôà î áëîêàõ...
71   ScriptBlockExists = false;   //Áëîê ñêðèïòà...
72   ClearObjectsBlockInfo();     //Áëîê îáúåêòîâ...
73
74 };
75
76 void TMob::ClearObjectsBlockInfo()
77 //×èñòèò êëàññ îò èíôû îòíîñÿùåéñÿ ê áëîêó îáúåêòîâ...
78 {
79   UnknObjs.Length = 0;
80   UnitObjs.Length = 0;
81   ObjectObjs.Length = 0;
82   LeverObjs.Length = 0;
83   TrapObjs.Length = 0;
84   FlameObjs.Length = 0;
85   Particle1Objs.Length = 0;
86   Particle2Objs.Length = 0;
87   Particle3Objs.Length = 0;
88
89   ObjectsBlockExists = false;
90 };
91
92 bool TMob::LoadMob(String& FileName)
93 //Ãðóçèò ìîá â îáúåêò.
94 {
95   bool Result = false;
96
97   //Ïåðåèíèöèàëèçàöèÿ ïåðåìåííûõ è î÷èñòêà ìóñîðà...
98   UnloadMob();
99
100   Loading = true;  //Òèïà ÷òîá çíàòü ÷òî ùà çàãðóæàåìñÿ...
101   if (UsingThread == false)
102   {
103     //Åñëè íèòêà íå èñïîëüçóåòñÿ
104     Result = ReallyLoadMob(FileName);
105   }
106   else
107   {
108     //Åñëè èñïîëüçóåòñÿ íèòêà.
109     //Ñîçäàòü íèòêó...
110     MobLoaderThr = new TMobLoaderThread(true);
111     //Ïåðåäàòü íóæíóþ íèòêå èíôó...
112     MobLoaderThr->FileName = FileName;
113     MobLoaderThr->PMobObj = this; //Ññûëêà íà îáúåêò êëàññà TMob - ÷òîá ó íèòêè
114                                   //áûë ê íåìó äîñòóï.
115     //Î÷èñòèòü ðåäàêòîð ëîãà.
116     //LogEd->Lines->Clear();
117     //È çàôîêóñèòü - ÷òîá ëîã ïðîêðó÷èâàëñÿ ïî ìåðå âûâîäà.
118     //Ôîêóñèòü - òîëüêî åñëè àêòèâåí òàá ñ ëîãîì...
119     if (MainF->MainF_PK->ActivePage->Name == "LogSh")
120     {
121       LogEd->SetFocus();
122     }; 
123
124     //Íà÷àòü âûïîëíåíèå íèòêè...
125     MobLoaderThr->Resume();
126
127     //Äîæäàòüñÿ çàâåðøåíèÿ ðàáîòû íèòêè...
128     do
129     {
130       Application->ProcessMessages();
131
132       //Ïðîâåðèòü, íåò ëè íîâîé èíôû...
133       if (NewMessageSent == true)
134       {
135         //Ïðèøëà íîâàÿ ìåññàãà â ëîã. Âûâåñòè åå.
136         LogEd->Lines->Add(LastLogMessage);
137         NewMessageSent = false;
138         //È ðàçìîðîçèòü íèòêó, êîòîðàÿ çàìîðîçèëà ñàìà ñåáÿ....
139         MobLoaderThr->Resume();
140        
141       };
142     } while (MobLoaderThr->Finished != true);
143
144     //Çàïîìíèòü ðåçóëüòàò...
145     Result = MobLoaderThr->result;
146
147     UsingThread = false;
148   };
149
150   Loading = false;  //Âñå, áîëüøå íå çàãðóæàåìñÿ...
151
152   return Result;  //È âåðíóòü ðåçóëüòàò...
153
154 };
155
156 bool TMob::SaveMob(String& FileName)
157 //Ñåéâèò ìîá èç îáúåêòà.
158 {
159   bool Result = false;
160
161   //Ïåðåèíèöèàëèçàöèÿ ïåðåìåííûõ è î÷èñòêà ìóñîðà...
162   FullLogStr = "";
163   LastLogMessage = "";
164   NewMessageSent = false;
165
166   Saving = true;   //Òèïà íà÷èíàåì ñåéâèòüñÿ...
167   if (UsingThread == false)
168   {
169     //Åñëè íèòêà íå èñïîëüçóåòñÿ
170     Result = ReallySaveMob(FileName);
171   }
172   else
173   {
174     //Åñëè èñïîëüçóåòñÿ íèòêà.
175     //Ñîçäàòü íèòêó...
176     MobSaverThr = new TMobSaverThread(true);
177     //Ïåðåäàòü íóæíóþ íèòêå èíôó...
178     MobSaverThr->FileName = FileName;
179     MobSaverThr->PMobObj = this; //Ññûëêà íà îáúåêò êëàññà TMob - ÷òîá ó íèòêè
180                                   //áûë ê íåìó äîñòóï.
181     //Î÷èñòèòü ðåäàêòîð ëîãà.
182     //È çàôîêóñèòü - ÷òîá ëîã ïðîêðó÷èâàëñÿ ïî ìåðå âûâîäà.
183     if (MainF->MainF_PK->ActivePage->Name == "LogSh")
184     {
185       LogEd->SetFocus();
186     }; 
187
188     //Íà÷àòü âûïîëíåíèå íèòêè...
189     MobSaverThr->Resume();
190
191     //Äîæäàòüñÿ çàâåðøåíèÿ ðàáîòû íèòêè...
192     do
193     {
194       Application->ProcessMessages();
195
196       //Ïðîâåðèòü, íåò ëè íîâîé èíôû...
197       if (NewMessageSent == true)
198       {
199         //Ïðèøëà íîâàÿ ìåññàãà â ëîã. Âûâåñòè åå.
200         LogEd->Lines->Add(LastLogMessage);
201         NewMessageSent = false;
202         //È ðàçìîðîçèòü íèòêó, êîòîðàÿ çàìîðîçèëà ñàìà ñåáÿ....
203         MobSaverThr->Resume();
204        
205       };
206     } while (MobSaverThr->Finished != true);
207
208     //Çàïîìíèòü ðåçóëüòàò...
209     Result = MobSaverThr->result;
210    
211     UsingThread = false;
212   };
213   Saving = false;  //Âñå, çàñåéâèëèñü...
214
215   return Result;
216 };
217
218 void TMob::StringToLog(String& message)
219 //Äîáàâëÿåò ìåññàãó â ëîã.
220 {
221   //Äîáàâèü ìåññàã â îáùèé ëîã
222   FullLogStr = FullLogStr+message+char(13)+char(10);
223
224   //Åñëè èñïîëüçóåòñÿ íèòêà - äîáàâèòü è ïîñëåäíþþ ìåññàãó:
225   if (UsingThread == true)
226   {
227     if (Loading == true)
228     {
229       //Åñëè èäåò çàãðóçêà...
230       //Âûçâàòü ôóíêöèþ îáúåêòà òðåäà, ÷òîá îíà ñèíõðîíèçîâàëà
231       MobLoaderThr->SynchrLogMess(message);
232     };
233
234     if (Saving == true)
235     {
236       //Åñëè èäåò ñåéâèíã...
237       //Âûçâàòü ôóíêöèþ îáúåêòà òðåäà, ÷òîá îíà ñèíõðîíèçîâàëà
238       MobSaverThr->SynchrLogMess(message);
239     };
240   };
241  
242 };
243
244 bool TMob::ReallyLoadMob(String& FileName)
245 //Ðåàëüíî çàãðóæàåò ìîá. Ìîæåò ðàáîòàòü èç íèòêè.
246 {
247   //Ëîêàëüíûå ïåðåìåííûå...
248   DWORD ChetireBaita, BlockSignature;
249   bool Result = false;
250   bool AllOk = true;
251   DWORD MainBlock_Size, CurrBlockSize = 0;
252   __int64 Cursor = 0;
253   __int64 FileSize, VosemBaitov = 0;
254   int BlockNumber = 1;
255   byte *TempBuff;
256
257   //Â ëîãå - íàðèñîâàü îòäåëèòåëü - äëÿ êðàñîòû :)
258   StringToLog("");
259   StringToLog("-----------------------------");
260   //Èòàê.  íà÷àëå íàäî çàãðóçèòü ôàéë.
261   TFileStream *File1;
262   if (FileExists(FileName) == true)
263   {
264     //Òîëüêî åñëè ôàéëî ñóùåñòâóåò.
265     StringToLog(FileName);
266     StringToLog("Ôàéëî ñóùåñòâóåò... îòêðûâàþ...");
267     //Ñîçäàòü ïîòîê...
268     TFileStream *File1;
269     try
270     {
271       File1 = new TFileStream(FileName,fmOpenRead);
272     }
273     catch (...)
274     {
275       StringToLog("Íå ìîãó ïîëó÷èòü äîñòóï ê ôàéëó!");
276       AllOk = false;
277       goto StopLoadMob_noloaded_Label;
278     };
279
280     //Ïîäãîòîâèòü ïàìÿòü ïîä ôàéë.
281     FileSize = File1->Size;
282     byte *File1Loaded;
283     File1Loaded = new byte[FileSize];
284
285     //Ãðóçàíóòü ôàéë â ïàìÿòü
286     File1->Read(File1Loaded,FileSize);
287     //Óáèòü ïîòîê... îí áîëüøå íå íóæåí.
288     delete File1;
289
290     //À âîò òåïåðü, ñîáñòâåííî - ìîæíî è çàãðóçèòü èíôó â ïåðåìåííûå êëàññà.
291
292     //Äëÿ íà÷àëà - ïðîâåðèòü, ìîá ëè ýòî âîîáùå.
293     Cursor = 0;
294     memcpy(&ChetireBaita,&File1Loaded[Cursor],4);
295     Cursor = Cursor+4;
296     if (ChetireBaita == MobSignature)
297     {
298       //Åñëè ýòî íîðìàëüíûé ìîá
299       StringToLog("Ýòî íîðìàëüíûé ìîá");
300
301       //Íó è ñîáñíî òåïåðü - ìîæíî òèïà íà÷èíàòü òèïà ãðóçèòü òèïà ìîá :).
302
303       //Ïîëó÷èòü ðàçìåð ïåðâîãî áëîêà ìîáà.
304       memcpy(&ChetireBaita,&File1Loaded[Cursor],4);
305       Cursor = Cursor+4;
306       MainBlock_Size = ChetireBaita;
307       StringToLog("Îñíîâíîé áëîê ìîáà âåñèò "+IntToStr(MainBlock_Size)+" áàéò.");
308
309       if (MainBlock_Size < FileSize)
310       {
311         //Åñëè ïîñëå îñíîâíîãî áëîêà åñòü åùå ÷åãî-òî
312         StringToLog("Ýòî ìåíüøå ðàçìåðà ôàéëà ("+IntToStr(FileSize)+" áàéò) - ÎÁÍÀÐÓÆÅÍ ÕÂÎÑÒ! :)");
313         TailSize = FileSize-MainBlock_Size;  //È ñðàçó-æå ïîäñ÷èòàòü è çàïîìíèòü ðàçìåð õâîñòà :).
314       };
315
316       if (MainBlock_Size > FileSize)
317       {
318         //Åñëè ðàçìåð áëîêà áîëüøå ðàçìåðà ôàéëà - òî ýòî áðåä êàêîé-òî...
319         //Çàãðóçêà òèïà îòìåíÿåòñÿ...
320         StringToLog("Îñíîâíîé áëîê ìîáà âåñèò "+IntToStr(MainBlock_Size)+" áàéò. - ýòî áîëüøå ðàçìåðà ôàéëà! ("+IntToStr(FileSize)+" áàéò).");
321         AllOk = false;
322         goto StopLoadMobLabel;
323       };
324
325       //Åñëè ðàçìåð áëîêà íå áîëüøå ðàçìåðà ôàéëà òî ïðîäîëæàòü...
326
327       //×òåíèå ãëàâíîãî áëîêà...
328
329       //Ïðîâåðèòü ïåðâûé áëîê
330       memcpy(&VosemBaitov,&File1Loaded[Cursor],8);
331       Cursor = Cursor+8;
332       if ((VosemBaitov != MainBlock_QuestMob) && (VosemBaitov != MainBlock_ZonalMob))
333       {
334         //Êàêîé-òî íåñòàíäàðòíûé âòîðîé áëîîê.
335         // äàííûé ìîìåíò - ýòî ïðèâåäåò ê íå÷èòàáåëüíîñòè ìîáà.
336         StringToLog("Ïåðâûé áëîê ãëàâíîãî áëîêà íåñòàíäàðòåí. Çàãðóçêà îòìåíåíà.");
337         AllOk = false;
338         goto StopLoadMobLabel;
339       }
340       else if (VosemBaitov == MainBlock_QuestMob)
341       {
342         //Êâåñòîâûé ìîá.
343         MobType = "QuestMob";
344         StringToLog("Ìîá ïîìå÷åí êàê êâåñòîâûé.");
345       }
346       else if (VosemBaitov == MainBlock_ZonalMob)
347       {
348         //Çîíàëüíûé ìîá.
349         MobType = "ZonalMob";
350         StringToLog("Ìîá ïîìå÷åí êàê çîíàëüíûé.");
351       };
352
353       //Ïåðâûé áëîê ñòàíäàðòåí, ìîæíî ïðîäîëæàòü...
354       BlocksInMob = 1;
355
356       //Òåïåðü ñîáñíî - íàäî èäòè òèïà ïî áëîêàì :). Ïîêà âñå áëîêè íå áóäóò çàãðóæåíû,
357       //ëèáî ïîêà ÷òî-òî òàì íå îáëîìèòñÿ.
358       do
359       {
360         //Ïîëó÷èòü òèï áëîêà.
361         memcpy(&ChetireBaita,&File1Loaded[Cursor],4);
362         Cursor = Cursor+4;
363         BlockSignature = ChetireBaita;  //×òîá îñâîáîäèòü áóôôåð
364         BlocksInMob = BlocksInMob+1;    //Ïîñ÷èòàòü íàéäåííûé áëîê.
365
366         //Òåïåðü â çàâèñèìîñòè îò òèïà áëîêà...
367         if (BlockSignature == TextBlockSgn)
368         {
369           //Òèïà áëîê ñêðèïòà.
370           BlockNumber = BlockNumber+1;  //Òèïà óâåëè÷èòü íîìåð áëîêà :).
371           ScriptBlockExists = true;  //Îòìåòèòü ÷òî áëîê ñóùåñòâóåò :).
372
373           //Ïîëó÷èòü ðàçìåð áëîêà
374           memcpy(&ChetireBaita,&File1Loaded[Cursor],4);
375           Cursor = Cursor+4;
376           CurrBlockSize = ChetireBaita;  //Âîò òóò ñîáñíî ðàçìåð.
377
378           //Ïðî÷èòàòü áëîê òèïà öåëèêîì :)
379           TempBuff = new byte[CurrBlockSize];
380           Cursor = Cursor-8;  //Îòêàòèòü êóðñîð íàçàä ÷òîá ñ÷èòàòü öåëüíûé áëîê...
381           memcpy(&TempBuff[0],&File1Loaded[Cursor],CurrBlockSize);
382           Cursor = Cursor+CurrBlockSize;
383
384           //Ñêîðìèòü òî ÷òî ïðî÷èòàíî ôóíêöèè-ðàñêîâûðèâàëêå áëîêà.
385           ReadScriptBlock(TempBuff,CurrBlockSize);
386
387           //Î÷èñòèòü áóôôåð
388           delete TempBuff;
389
390           //È ñîîáùèòü â ëîã î ñ÷èòàííîì áëîêå...
391           StringToLog("Çàãðóæåí ñêðèïò äëèíîé "+IntToStr(ScriptText.Length())+" áàéò. Áëîê ¹ "+IntToStr(BlockNumber)+". Äëèíà âñåãî áëîêà "+IntToStr(CurrBlockSize)+" áàéò.");
392         }
393
394         else if (BlockSignature == ObjectsBlockSgn)
395         {
396           //Òèïà áëîê îáúåêòîâ.
397           BlockNumber = BlockNumber+1;  //Òèïà óâåëè÷èòü íîìåð áëîêà :).
398           //Îòìåòêó î òîì ÷òî áëîê ñóùåñòâóåò ïîñòàâèò ôóíêöèÿ, ñ÷èòûâàþùàÿ áëîê :).
399
400           //Ïîëó÷èòü ðàçìåð áëîêà
401           memcpy(&ChetireBaita,&File1Loaded[Cursor],4);
402           Cursor = Cursor+4;
403           CurrBlockSize = ChetireBaita;  //Âîò òóò ñîáñíî ðàçìåð.
404
405           //Ïðî÷èòàòü áëîê òèïà öåëèêîì :)
406           TempBuff = new byte[CurrBlockSize];
407           Cursor = Cursor-8;  //Îòêàòèòü êóðñîð íàçàä ÷òîá ñ÷èòàòü öåëüíûé áëîê...
408           memcpy(&TempBuff[0],&File1Loaded[Cursor],CurrBlockSize);
409           Cursor = Cursor+CurrBlockSize;
410
411           //Ñêîðìèòü òî ÷òî ïðî÷èòàíî ôóíêöèè-ðàñêîâûðèâàëêå áëîêà.
412           AllOk = ReadObjectsBlock(TempBuff,CurrBlockSize);
413           if (AllOk == false)
414           {
415             //Åñëè áûë òèïà ñáîé ïðè ÷òåíèè áëîêà - òî àààáëîì.
416             goto StopLoadMobLabel;
417           };
418
419           //Î÷èñòèòü áóôôåð
420           delete TempBuff;
421
422           //È ñîîáùèòü â ëîã î ñ÷èòàííîì áëîêå...
423           StringToLog("Çàãðóæåí áëîê îáúåêòîâ äëèíîé "+IntToStr(CurrBlockSize)+" áàéò. Áëîê ¹ "+IntToStr(BlockNumber)+".");
424           StringToLog("Â áëîêå íàéäåíî "+IntToStr(UnitObjs.Length)+" þíèòîâ.");
425           StringToLog("Â áëîêå íàéäåíî "+IntToStr(ObjectObjs.Length)+" îáúåêòîâ.");
426           StringToLog(" áëîêå íàéäåíî "+IntToStr(LeverObjs.Length)+" ðû÷àãîâ.");
427           StringToLog("Â áëîêå íàéäåíî "+IntToStr(TrapObjs.Length)+" ëîâóøåê.");
428           StringToLog("Â áëîêå íàéäåíî "+IntToStr(FlameObjs.Length)+" ôëåéìîâ.");
429           StringToLog("Â áëîêå íàéäåíî "+IntToStr(Particle1Objs.Length)+" ïàðòèêëîâ 1-ãî òèïà.");
430           StringToLog("Â áëîêå íàéäåíî "+IntToStr(Particle2Objs.Length)+" ïàðòèêëîâ 2-ãî òèïà.");
431           StringToLog("Â áëîêå íàéäåíî "+IntToStr(Particle3Objs.Length)+" ïàðòèêëîâ 3-ãî òèïà.");
432           StringToLog("Â áëîêå íàéäåíî "+IntToStr(UnknObjs.Length)+" îáúåêòîâ íåèçâåñòíîãî òèïà.");
433         }
434
435         else
436         {
437           BlockNumber = BlockNumber+1;  //Òèïà óâåëè÷èòü íîìåð áëîêà :).
438           //Åñëè òèï áëîêà íåèçâåñòåí.
439           //Òî áëîê ïðîñòî ÷èòàåòñÿ êàê íåèçâåñòíûé.
440
441           UnknownBlocks.Length = UnknownBlocks.Length+1; //Äîáàâèòü íîâûé ýëåìåíò.
442           //Ïîëó÷èòü ðàçìåð áëîêà
443           memcpy(&ChetireBaita,&File1Loaded[Cursor],4);
444           Cursor = Cursor+4;
445
446           //È çàïîìíèòü èíôó áëîêà...
447           UnknownBlocks[UnknownBlocks.High].BlockSize = ChetireBaita;
448           UnknownBlocks[UnknownBlocks.High].BlockNumber = BlockNumber;
449           UnknownBlocks[UnknownBlocks.High].BlockContent = new byte[ChetireBaita];
450           Cursor = Cursor-8; //×òîá ÷èòàòü áëîê ñ ñàìîãî íà÷àëà.
451           memcpy(&UnknownBlocks[UnknownBlocks.High].BlockContent[0],&File1Loaded[Cursor],ChetireBaita);
452           Cursor = Cursor+ChetireBaita;
453
454           //Íó è â ëîã ñîîáùèòü ïðî ýòî äåëî :).
455           StringToLog("Ñ÷èòàí áëîê íåèçâåñòíîãî òèïà. Âñòðåòèëñÿ ïîä íîìåðîì "+IntToStr(BlockNumber)+".");
456         }; //Ïîñëåäíèé else 
457
458       } while (Cursor != MainBlock_Size);
459
460       //À òåïåðü - åñëè ó ìîáà áûë "õâîñò" - òî íàäî ýòîò õâîñò òîæå çàïîìíèòü :).
461       if (TailSize > 0)
462       {
463         Tail = new byte[TailSize];
464         memcpy(&Tail[0],&File1Loaded[Cursor],TailSize);
465         Cursor = Cursor+TailSize;
466         StringToLog("Ïðî÷èòàí õâîñò äëèíîé "+IntToStr(TailSize)+" áàéò.");
467       };
468
469       //Ïðîâåðêà ïîëîæåíèÿ êóðñîðà...
470       if (Cursor == FileSize)
471       {
472         //Åñëè êóðñîð ñòîèò â êîíöå ôàéëà - çíà÷èò òèïà âñå îê :).
473         StringToLog("Êóðñîð ñòîèò â êîíöå ôàéëà - çíà÷èò âñÿ èíôà çàãðóæåíà â îáúåêò êëàññà.");
474         Result = true;
475         MobLoaded = true;  //Ïîìåòèòü, ÷òî ìîá çàãðóæåí â îáúåêò.
476       };
477
478     }
479     else
480     {
481       //Ýòî íå ìîá íèõðåíà!
482       StringToLog("Ýòî íå ìîá íèõðåíà!");
483       AllOk = false;
484     };
485
486     StopLoadMobLabel:  //Ñþäà áóäåò ñêà÷åê åñëè âîçíèêíåò îøèáêà â ïðîöåññå çàãðóçêè
487     ;
488     //Ïî÷èñòèòü ìóñîð
489     //Óáèòü óêàçÿâó íà ïàìÿòü, êóäà ãðóçèëñÿ ôàéë
490     delete File1Loaded;
491     StopLoadMob_noloaded_Label:   //À ñþäà - åñëè íå óäàñòñÿ îòêðûòü ôàéë.
492     ;
493   };
494
495   //Òèïà ïðîöåññ çàâåðøåí. Âåðíóòü ðåçóëüòàò, à òàêæå ñîîáùèòü â ëîã
496   //îá ócïåõå\íåóñïåõå îïåðàöèè.
497   if (Result == true)
498   {
499     StringToLog("Ìîá çàãðóæåí óñïåøíî!");
500   }
501   else
502   {
503     StringToLog("Çàãðóçèòü ìîá íå óäàëîñü!");
504   };
505
506   //Ïî ïðè÷èíå âñòðå÷è ñ íåïîíÿòíûìè ãëþêàíÿðàìè
507
508   return Result;
509 };
510
511 bool TMob::ReallySaveMob(String& FileName)
512 //Ðåàëüíî ñåéâèò ìîá. Ìîæåò ðàáîòàòü èç íèòêè.
513 {
514   //Ëîêàëüíûå ïåðåìåííûå...
515   DWORD ChetireBaita, BlockSignature;
516   bool Result, BlockWrote, SgnFinded = false;
517   bool AllOk = true, FileSaved = true;
518   DWORD MainBlock_Size, CurrBlockSize, SizeAdress = 0;
519   __int64 Cursor = 0;
520   __int64 FileSize, VosemBaitov = 0;
521   int BlockNumber = 1;
522   int i;   //Ñ÷åò÷èê :).
523   DynamicArray <byte> SaveBuffer;   //Â ýòîò ìàññèâ ñîáñíî è áóäåò çàïèñûâàòüñÿ èíôà ïåðåä ñåéâîì....
524   byte *TempBuff;   //Âðåìåííûé áàéòîâûé ìàññèâ...
525   DynamicArray <byte> TempBuff2;  //Äèíàìè÷åñêèé âðåìåííûé áàéòîâûé ìàññèâ...
526
527   //Ñîáñíî ñàìà ôóíêöèÿ...
528
529   //Ïðî÷èñòèòü ñëóæåáíûå ïåðåìåííûå...
530   CurrBlockSgn = 0;
531   AllKnownBlocksSaved = false;
532
533   //Â ëîãå - íàðèñîâàü îòäåëèòåëü - äëÿ êðàñîòû :)
534   StringToLog("");
535   StringToLog("-----------------------------");
536   //StringToLog("Çàïóùåíà ñåéâèëêà...");
537
538   if (MobLoaded == true)
539   {
540     //Åñëè ìîá õîòü ðàç áûë çàãðóæåí è âîîîáùå åñòü ÷åãî ñîõðàíÿòü...
541     //Çàïèñàòü ñèãíàòóðó ìîáà...
542     SaveBuffer.Length = Cursor+4;
543     memcpy(&SaveBuffer[Cursor],&MobSignature,4);
544     Cursor = Cursor+4;
545     StringToLog("Ñèãíàòóðà çàïèñàíà...");
546
547     //Äëèíó ãëàâíîãî áëîêà âðåìåííî çàáèòü íóëÿìè...
548     SaveBuffer.Length = Cursor+4;
549     ChetireBaita = 0;
550     memcpy(&SaveBuffer[Cursor],&ChetireBaita,4);
551     Cursor = Cursor+4;
552
553     //Â çàâèñèìîñòè îò òèïà ìîáà - ïîëîæèòü ñîîòâ. áëîê-ìåòêó...
554     if (MobType == "QuestMob")
555     {
556       SaveBuffer.Length = Cursor+8;
557       memcpy(&SaveBuffer[Cursor],&MainBlock_QuestMob,8);
558       Cursor = Cursor+8;
559       StringToLog("Ìîá ïîìå÷åí êàê êâåñòîâûé...");
560     }
561     else if (MobType == "ZonalMob")
562     {
563       SaveBuffer.Length = Cursor+8;
564       memcpy(&SaveBuffer[Cursor],&MainBlock_ZonalMob,8);
565       Cursor = Cursor+8;
566       StringToLog("Ìîá ïîìå÷åí êàê çîíàëüíûé...");
567     };
568
569     //À òåïåðü - çàêèäàòü òóäû âîâíóòðü ðàçíûå áëîêè.
570     //Çàïèñûâàòü áëîêè ëèáî ïî ïîðÿäêó, ïðîâåðÿÿ íåèçâåñòíûå áëîêè,
571     //ëèáî, åñëè áëîê ñ íóæíûì íîìåðîì ñðåäè íåèçâåñòíûõ íå íàéäåí -
572     //ïî ñòàíäàðòíîìó ïîðÿäêó :).
573
574     do
575     {
576       //Óâåëè÷èòü íîìåð áëîêà.
577       BlockNumber = BlockNumber+1;
578
579       BlockWrote = false;   //Èíäèêàòîð....
580
581       //Ïðîâåðèòü, åñòü ëè ñðåäè íåèçâåñòíûõ áëîê ñ òàêèì íîìåðîì...
582       for(i = 0;i<=UnknownBlocks.High;i++)
583       {
584         //Òèïà ïðîáåæàòüñÿ ïî ñïèñêó áëîêîâ :).
585         if (UnknownBlocks[i].BlockNumber == BlockNumber)
586         {
587           //Íàøëè áëîê, êîòîðûé õî÷åò çàïèñàòüñÿ ïîä ýòèì íîìåðîì :).
588
589           //Íó çíà÷èò - ïèøåì! :).
590           SaveBuffer.Length = Cursor+UnknownBlocks[i].BlockSize;
591           memcpy(&SaveBuffer[Cursor],&UnknownBlocks[i].BlockContent[0],UnknownBlocks[i].BlockSize);
592           Cursor = Cursor+UnknownBlocks[i].BlockSize;
593           StringToLog("Ïîä íîìåðîì "+IntToStr(BlockNumber)+" çàïèñàí áëîê íåèçâåñòíîãî òèïà.");
594
595           BlockWrote = true;  //Èíäèêàòîð ÷òî áëîê óæå çàïèñàí.
596
597           i = UnknownBlocks.High;  //×òîá áîëüøå ïî ñïèñêó íå øàðèòü...
598         };
599       };
600
601       //Òåîðåòè÷åñêè - åñëè áëîê åùå íå áûë çàïèñàí - çàïèñàòü áëîê èçâåñòíîãî
602       //òèïà, èäóùèé "ïî ïîðÿäêó".
603
604       if (AllKnownBlocksSaved == false)
605       {
606         //Òîêà åñëè âñå áëîêè åùå íå çàïèñàíû...
607         if (BlockWrote == false)
608         {
609           //Ñîáñíî - ïèñàòü òîò áëîê èçâåñòíîãî òèïà, ÷úÿ ïðèøëà î÷åðåäü.
610
611           //Îïðåäåëèòü - êàêîé èç áëîêîâ ñåéâèòü...
612           SgnFinded = false;
613           do
614           {
615             //Ïîëó÷èòü î÷åðåäíóþ ñèãíàòóðó...
616             CurrBlockSgn = GetNextBlockSgn(CurrBlockSgn);
617
618             //Ïðîâåðèòü, ñóùåñòâóåò ëè â ìîáå íóæíûé áëîê.
619             if (CurrBlockSgn == 0)
620             {
621               //Îáíàðóæåí ñèãíàë çàâåðøåíèÿ ïîèñêà...
622               SgnFinded = true;
623             }
624             else if (CurrBlockSgn == TextBlockSgn)
625             {
626               //Áëîê ñêðèïòà.
627               if (ScriptBlockExists == true)
628               {
629                 SgnFinded = true;
630               };
631             }
632             else if (CurrBlockSgn == ObjectsBlockSgn)
633             {
634               //Áëîê îáúåêòîâ.
635               if (ObjectsBlockExists == true)
636               {
637                 SgnFinded = true;
638               };
639             };
640           }
641           while (SgnFinded != true);
642
643           //À òåïåðü - â çàâèñèìîñòè îò òîãî, êàêîé áëîê "ðåøåíî" ñîõðàíèòü...
644           if (CurrBlockSgn == 0)
645           {
646             //Îáíàðóæåí ñèãíàë çàâåðøåíèÿ ïîèñêà...
647             //íó òèïà âñå, áîëüøå áëîêè èçâåñòíîãî òèïà ñåéâèòüñÿ íå áóäóò...
648             AllKnownBlocksSaved = true;
649           }
650           else if (CurrBlockSgn == TextBlockSgn)
651           {
652             //Áëîê ñêðèïòà.
653
654             //Ïîäãîòîâèòü áóôôåð...
655             TempBuff2.Length = 0;
656
657             //Íó è - ñ÷èòàòü â íåãî èíôó :).
658             GenScriptBlock(TempBuff2);
659
660             //À òåïåðü - çàïèñàòü áëîê â áóäóþùèé ôàéë :).
661             SaveBuffer.Length = Cursor+TempBuff2.Length;
662             memcpy(&SaveBuffer[Cursor],&TempBuff2[0],TempBuff2.Length);
663             Cursor = Cursor+TempBuff2.Length;
664
665             StringToLog("Ïîä íîìåðîì "+IntToStr(BlockNumber)+" çàïèñàí áëîê ñêðèïòà äëèíîé "+IntToStr(TempBuff2.Length)+" áàéò.");
666             BlockWrote = true;  //Èíäèêàòîð ÷òî áëîê óæå çàïèñàí.
667
668             //Íó è ïðî÷èñòèòü áóôôåð...
669             TempBuff2.Length = 0;
670
671           }
672           else if (CurrBlockSgn == ObjectsBlockSgn)
673           {
674             //Áëîê îáúåêòîâ.
675
676             //Ïîäãîòîâèòü áóôôåð...
677             TempBuff2.Length = 0;
678
679             //Íó è - ñ÷èòàòü â íåãî èíôó :).
680             GenObjectsBlock(TempBuff2);
681
682             //À òåïåðü - çàïèñàòü áëîê â áóäóþùèé ôàéë :).
683             SaveBuffer.Length = Cursor+TempBuff2.Length;
684             memcpy(&SaveBuffer[Cursor],&TempBuff2[0],TempBuff2.Length);
685             Cursor = Cursor+TempBuff2.Length;
686
687             StringToLog("Ïîä íîìåðîì "+IntToStr(BlockNumber)+" çàïèñàí áëîê îáúåêòîâ äëèíîé "+IntToStr(TempBuff2.Length)+" áàéò.");
688             BlockWrote = true;  //Èíäèêàòîð ÷òî áëîê óæå çàïèñàí.
689
690             //Íó è ïðî÷èñòèòü áóôôåð...
691             TempBuff2.Length = 0;
692            
693           };
694
695         };  //if (BlockWrote == false)
696       };  //if (AllKnownBlocksSaved == false)
697
698     }
699     while (BlockNumber != BlocksInMob);
700
701     //Ïîñêîëüêó óæå çàïèñàí ãëàâíûé áëîê ìîáà - òî ñòîèò ïîäñ÷èòàòü åãî äëèíó
702     //(â ïðèíöèïå îíà èçâåñòíà - ýòî êóðñîð :) ), è çàïèñàòü åž êóäà ñëåäóåò...
703     ChetireBaita = Cursor;
704     memcpy(&SaveBuffer[4],&ChetireBaita,4);
705     StringToLog("Çàïèñàíà äëèíà ãëàâíîãî áëîêà...");
706
707     //Òàê. Òåïåðü íàäî ïîðàáîòàòü íàä õâîñòîì. Åñëè õâîñòà íåòó íèôèãà
708     // - òî êîíå÷íî ìîæíî çàáèòü, à âîò åñëè õâîñò åñòü - ïðèäåòñÿ åãî
709     //ïðèêðåïëÿòü ê... ýýý... çàäíåé ÷àñòè òåëà ìîáà :).
710
711     if (TailSize > 0)
712     {
713       SaveBuffer.Length = Cursor+TailSize;
714       memcpy(&SaveBuffer[Cursor],&Tail[0],TailSize);
715       Cursor = Cursor+TailSize;
716       StringToLog(" êîíåö ìîáà ïðèñàáà÷åí õâîñò, äëèíîé "+IntToStr(TailSize)+" áàéò.");
717     };
718
719     //Òåïåðü - ñîîáùèòü þçâåðþ ðàçìåð ïîëó÷åííîãî ôàéëà...
720     StringToLog("Â ðåçóëüòàòå âñåé ýòîé ôèãíè ó íàñ âûëåïèëñÿ ôàéëèê ðàçìåðîì "+IntToStr(Cursor)+" áàéò.");
721
722     //À òåïåðü - òèïà ñàìûé îòâåòñòâåííûé ìîìåíò - íàäî âñþ ýòó ôèãíþ çàñåéâèòü
723     //â ðåàëüíûé ôàéë :).
724
725     for (i = 0; i <= SaveAttempts; i++)
726     {
727       try
728       {
729
730         if (FileExists(FileName) == true)
731         {
732           //Åñëè ôàéë åñòü - óáèòü áåç ëèøíèõ ðàçãîâîðîâ.
733           //Ðàçãîâîðû ãîâîðèòü â ñëó÷àå ÷åãî áóäåò èíòåðôåéñ ïðîãè
734           //åùå äî íà÷àëà ñîõðàíåíèÿ... À ìû òóò ðàáîòàåì ïðîñòî -
735           //åñëè êàêàÿ-òî ïàäëà ìåøàåò ñäåëàòü ñåéâ - çàìî÷èòü åå íàôèê :).
736
737           if (DeleteFile(FileName) == true)
738           {
739             StringToLog("Ôàéë "+FileName+" óäàëåí, ò.ê. íà åãî ìåñòî áóäåò ñîõðàíÿòüñÿ ôàéë.");
740           };
741         };
742
743         //Òåîðåòè÷åñêè - åñëè è áûë ôàéë ñ òàêèì èìåíåì - åãî óæå äîëæíî íå áûòü :).
744
745         //Ñîçäàåì ôàéë è ïîòîê...
746         TFileStream *File1;
747         File1 = new TFileStream(FileName,fmCreate);
748
749         //Ïèøåì èíôó â ôàéë...
750         File1->Write(&SaveBuffer[0],Cursor);
751
752         //Çàêðûâàåì ôàéë...
753         delete File1;
754
755         if (FileExists(FileName) == true)
756         {
757           //Ñîîáùàåì þçâåðþ î òîì ÷òî ôàéë çàïèñàí.
758           StringToLog("Ìîá ñîõðàíåí íà äèñê â ôàéë "+FileName+" .");
759           Result = true; //Óñïåøíûé ñåéâ :).
760           i = SaveAttempts;
761         }
762         else
763         {
764           //Ïî íåïîíÿòíîé ïðè÷èíå íåòó âðîäå áû ñîõðàíåííîãî ôàéëà. Îøèáêó åìó :)
765           //òî÷íåå - îòïðàâèòü íà ïîâòîðíûå ñåéâû.
766           StringToLog("×Å ÇÀ ÕÅÐÍß!!!!! ÎØÈÁÎÊ ÍÈÕÅÐÀ ÍÅ ÁÛËÎ À ÔÀÉËÀ ÌËß ÍÅÒÓ!!!!!!!!!! ÑÎÎÁÙÈÒÅ ÐÀÇÐÀÁÎÒ×ÈÊÓ!!!!!!");
767           StringToLog("Ïûòàþñü ñîõðàíèòü åùå ðàç....");
768           //à äëÿ åòîãî è äåëàòü íèôèãà íå íàäî - îíî ñàìî :).
769         };
770       }
771       catch(...)
772       {
773         //Ïðîèçîøëà êàêàÿ-òî îøèáêà.
774
775         //Ñîîáùàåì þçâåðþ î òîì ÷òî ôàéë íå çàïèñàí.
776         StringToLog("Ïî íåïîíÿòíîé ïðè÷èíå íå óäàëîñü ñîõðàíèòü íà äèñê ôàéë "+FileName+" .");
777
778         //È ñêàçàòü ÷òî ùà áóäåò ïîïûòêà ñäåëàòü åùå 1 ñåéâ...
779         if (i < SaveAttempts)
780         {
781           StringToLog("Ïûòàþñü ñîõðàíèòü åùå ðàç....");
782         };
783       };
784     };
785
786     if ( (FileExists(FileName) == false) && (Result == false) )
787     {
788       //Êîðî÷å ïîñëå 10 ïîïûòîê íèõåðà íå ñîõðàíèëîñü.
789       StringToLog("ÅÒÀ ÏÈÏÅÖ ÒÐÙ ÊÀÌÀÍÄÈÐ!!! ÍÈÕÅÐÀ ÍÅ ÑÀÂÈÒÑß!!! È ÔÀÉË ÓÃÐÎÁÈËÑß!!! ÍÎ ÎÍ ÅÙÅ Â ÏÀÌßÒÈ - ÏÎÏÐÎÁÓÉÒÅ ÇÀÑÀÂÈÒÜ ÍÀ ÄÐÓÃÎÅ ÈÌß!!!");
790     };
791   }
792   else
793   {
794     //Åñëè ñîõðàíÿòü íå÷åãî... ïîñëàòü íàõ :).
795     StringToLog(" îáúåêò êëàññà åùå íå áûëî íè÷åãî çàãðóæåíî!!! Ñîõðàíÿòü íå÷åãî!!!");
796   };
797
798   if (Result == true)
799   {
800     //Åñëè ñîõðàíåíèå óñïåøíî...
801     StringToLog("Ìîá óñïåøíî ñîõðàíåí :).");
802   }
803   else
804   {
805     //Åñëè ñîõðàíåíèå íåóñïåøíî...
806     StringToLog("Ìîá íèõðåíà íå ñîõðàíåí :(.");
807   };
808
809   return Result;
810 };
811
812 String TMob::DeCodeScript(byte *ScriptTextBytes,DWORD Size,DWORD Key)
813 //Ôóíêöèÿ äîëæíà òèïà äåêîäèðîâàòü ñêðèïò. È âîçâðàùàòü åãî óæå â âèäå ñòðîêè.
814 {
815   //Ëîêàëüíûå ïåðåìåííûå...
816   String Result = "";
817   DWORD TmpKey = 0;
818
819   //Ñîáñíî ðàáîòà íàä ñêðèïòîì...
820   // íà÷àëå - òèïà ïåðåêîïèðîâàòü ñòðîêó :)
821   Result.SetLength(Size);
822   memcpy(&Result[1],&ScriptTextBytes[0],Size);
823
824   //Òåïåðü - ðàñêîäèðîâàòü ñêðèïò.
825   for (DWORD i=1; i<=Size; i++)
826   {
827     TmpKey = (((((Key*13) << 4 ) + Key) << 8 ) - Key);
828     Key = Key + TmpKey*4 + 2531011;
829     TmpKey = Key;
830     TmpKey = TmpKey >> 16;
831     Result[i] = Result[i] ^ TmpKey;
832   };
833
834   return Result;
835 };
836
837 byte* TMob::EnCodeScript(String ScriptTextStr,DWORD Size,DWORD Key)
838 //Ôóíêöèÿ äîëæíà òèïà çàêîäèðîâàòü ñêðèïò. È âîçâðàùàòü åãî óæå â âèäå ïîñëåäîâàòåëüíîñòè áàéòîâ.
839 {
840   //Ëîêàëüíûå ïåðåìåííûå...
841   byte *Result = new byte[Size];
842   DWORD TmpKey = 0;
843
844   //Ñîáñíî ðàáîòà íàä ñêðèïòîì...
845   // íà÷àëå - òèïà ïåðåêîïèðîâàòü ñòðîêó :)
846   memcpy(&Result[0],&ScriptTextStr[1],Size);
847
848   //Òåïåðü - ðàñêîäèðîâàòü ñêðèïò.
849   for (DWORD i=0; i<Size; i++)
850   {
851     TmpKey = (((((Key*13) << 4 ) + Key) << 8 ) - Key);
852     Key = Key + TmpKey*4 + 2531011;
853     TmpKey = Key;
854     TmpKey = TmpKey >> 16;
855     Result[i] = Result[i] ^ TmpKey;
856   };
857
858   return Result;
859 };
860
861 DWORD TMob::GetNextBlockSgn(DWORD CurrSgn)
862 //Âîçâðàùàåò ñèãíàòóðó áëîêà êîòîðûé äîëæåí ñåéâèòüñÿ ñëåäóþùèì.
863 {
864   //Ïåðåìåííûå
865   DWORD Result = 0;
866
867   //Âûâîä ñèãíàòóðû...
868   if (CurrSgn == 0)
869   {
870     //Âûäàòü ñèãíàòóðó ñàìîãî ïåðâîãî áëîêà - ñêðèïòà.
871     Result = TextBlockSgn;
872   }
873   else if (CurrSgn == TextBlockSgn)
874   {
875     //Âûäàòü ïîñëåäíþþ ñèãíàòóðó - íîëü - íå áûâàåò íè ó 1 áëîêà.
876     Result = ObjectsBlockSgn;
877   }
878   else if (CurrSgn == ObjectsBlockSgn)
879   {
880     //Âûäàòü ïîñëåäíþþ ñèãíàòóðó - íîëü - íå áûâàåò íè ó 1 áëîêà.
881     Result = 0;
882   };
883
884   return Result;
885 };
886
887 ///////////////////////////////////
888 //  ×èòàëêè áëîêîâ
889 ///////////////////////////////////
890
891 bool TMob::ReadScriptBlock(byte *Buff, DWORD& Size)
892 //Áëîê ñêðèïòà.
893 {
894   //Ëîêàëüíûå ïåðåìåííûå...
895   DWORD ChetireBaita;
896   bool Result = false;
897   __int64 Cursor = 0;
898   byte *TempBuff;
899   DWORD ScriptTextSize = Size - 12; //âûñ÷èòàòü ðàçìåð òåêñòà ñêðèïòà :)
900
901   ScriptText = "";  // ëþáîì ñëó÷àå - ïðî÷èñòèòü ñêðèïò.
902
903   Cursor = Cursor+8;
904
905   //Ïîëó÷èòü êëþ÷
906   memcpy(&ChetireBaita,&Buff[Cursor],4);
907   Cursor = Cursor+4;
908   ScriptKey = ChetireBaita;
909
910   if (ScriptTextSize > 0)
911   {
912     //Ñ÷èòàòü ñàì ñêðèïò - òîëüêî åñëè îí áîëüøå íóëÿ :).
913     TempBuff = new byte[ScriptTextSize];
914     memcpy(&TempBuff[0],&Buff[Cursor],ScriptTextSize);
915     Cursor = Cursor+ScriptTextSize;
916
917     //Äåêîäèðîâàòü ñêðèïò è çàïèñàòü åãî â ñòðîêó...
918     ScriptText = DeCodeScript(TempBuff,ScriptTextSize,ScriptKey);
919     delete TempBuff;
920   };
921
922   Result = true;
923   return Result;
924 };
925
926 bool TMob::ReadObjectsBlock(byte *Buff, DWORD& Size)
927 //Áëîê îáúåêòîâ.
928 {
929   //Ëîêàëüíûå ïåðåìåííûå...
930   DWORD ChetireBaita, CurrBlockSignature, ObjBlockSize, TempDW1,
931   MinBlockSgn, MinBlockSize, TempDW2, i;
932   bool Result = true;
933   __int64 Cursor = 0, StartBlockPos = 0, UnknObjsNum = 0, UnitObjsNum = 0,
934   ObjectObjsNum = 0, UnknObjsCurr = -1, UnitObjsCurr = -1, ObjectObjsCurr = -1,
935   LeverObjsNum = 0, LeverObjsCurr = -1, TrapObjsNum = 0, TrapObjsCurr = -1,
936   FlameObjsNum = 0, FlameObjsCurr = -1, Particle1ObjsNum = 0, Particle1ObjsCurr = -1,
937   Particle2ObjsNum = 0, Particle2ObjsCurr = -1, Particle3ObjsNum = 0, Particle3ObjsCurr = -1;
938   byte *TempBuff;
939   byte TempByte;
940
941   //Èòàê, ñèíãàòóðà áëîêà óæå ñ÷èòàíà, äëèíà áëîêà èçâåñòíà. Íàäî íà÷èíàòü
942   //ñêàíèðîâàòü áëîê, âñå îáíàðóæåííûå áëîêè - çàïèñàòü â ïåðåìåííûå êëàññà.
943   //Ïîðÿäîê çàïèñè áëîêîâ îáúåêòîâ - çíà÷åíèÿ íå èìååò â ïðèíöèïå.
944
945   //Èòàê. Îáû÷íûé öèêë. Ðàáîòàòü áóäåò äî òåõ ïîð, ïîêà êóðñîð íå îêàæåòñÿ
946   //â êîíöå áëîêà.
947
948   Cursor = Cursor+8;  //Òèïà ïðîñêî÷èòü çàãîëîâîê è äëèíó áëîêà.
949
950   //Ïî÷èñòèòü èíôó î ñóùåñòâîâàíèè ýòîãî áëîêà.... ïàìÿòü òàì îñâîáîäèòü çàîäíî...
951   ClearObjectsBlockInfo();
952
953   if (Size > 8)
954   {
955     //Òîëüêî åñëè åñòü îáúåêòû â áëîêå.
956
957     //Ïîäñ÷èòàòü êîëè÷åñòâî ðàçíîîáðàçíûõ áëîêîâ...
958     do
959     {
960       //Ïîëó÷èòü ñèãíàòóðó áëîêà îáúåêòà...
961       memcpy(&CurrBlockSignature,&Buff[Cursor],4);
962       StartBlockPos = Cursor;  //Çàïîìíèòü ïîçèöèþ â íà÷àëå áëîêà...
963       Cursor = Cursor+4;
964       //Ñ÷èòàòü äëèíó áëîêà...
965       memcpy(&ObjBlockSize,&Buff[Cursor],4);
966       Cursor = Cursor+4;
967       //Ïðûãíóòü ê ñëåäóþùåé ñèãíàòóðå :).
968       Cursor = Cursor+ObjBlockSize-8;
969
970       //Â çàâèñèìîñòè îò ñèãíàòóðû...
971       if (CurrBlockSignature == OB_Sgn_Unit)
972       {
973         //Åñëè ýòî þíèò...
974         UnitObjsNum = UnitObjsNum+1;
975       }
976       else if (CurrBlockSignature == OB_Sgn_Object)
977       {
978         //Åñëè ýòî ïðîñòî îáúåêò...
979         ObjectObjsNum = ObjectObjsNum+1;
980       }
981       else if (CurrBlockSignature == OB_Sgn_Lever)
982       {
983         //Åñëè ýòî ðû÷àã...
984         LeverObjsNum = LeverObjsNum+1;
985       }
986       else if (CurrBlockSignature == OB_Sgn_Trap)
987       {
988         //Åñëè ýòî ëîâóøêà...
989         TrapObjsNum = TrapObjsNum+1;
990       }
991       else if (CurrBlockSignature == OB_Sgn_Flame)
992       {
993         //Åñëè ýòî ôëåéì...
994         FlameObjsNum = FlameObjsNum+1;
995       }
996       else if (CurrBlockSignature == OB_Sgn_Particle1)
997       {
998         //Åñëè ýòî ïàðòèêë 1-ãî òèïà...
999         Particle1ObjsNum = Particle1ObjsNum+1;
1000       }
1001       else if (CurrBlockSignature == OB_Sgn_Particle2)
1002       {
1003         //Åñëè ýòî ïàðòèêë 2-ãî òèïà...
1004         Particle2ObjsNum = Particle2ObjsNum+1;
1005       }
1006       else if (CurrBlockSignature == OB_Sgn_Particle3)
1007       {
1008         //Åñëè ýòî ïàðòèêë 3-ãî òèïà...
1009         Particle3ObjsNum = Particle3ObjsNum+1;
1010       }
1011       else
1012       {
1013         //Åñëè òèï áëîêà íåèçâåñòåí.
1014         UnknObjsNum = UnknObjsNum+1;
1015       };
1016     }
1017     while (Cursor != Size);
1018
1019     Cursor = 8;  //Âåðíóòü êóðñîð ãäå áûë - íà âîñüìåðêó :).
1020     //À áûë îí òàì äî ïîäñ÷åòà êîëè÷åñòâà áëîêîâ.
1021
1022     //Âûäåëèòü ïàìÿòü ïîä áëîêè...
1023     UnitObjs.Length = UnitObjsNum;
1024     ObjectObjs.Length = ObjectObjsNum;
1025     LeverObjs.Length = LeverObjsNum;
1026     TrapObjs.Length = TrapObjsNum;
1027     FlameObjs.Length = FlameObjsNum;
1028     Particle1Objs.Length = Particle1ObjsNum;
1029     Particle2Objs.Length = Particle2ObjsNum;
1030     Particle3Objs.Length = Particle3ObjsNum;
1031     UnknObjs.Length = UnknObjsNum;
1032
1033     //À òåïåðü ïðî÷èòàòü ýòè áëîêè :).
1034     do
1035     {
1036       //Ïîëó÷èòü ñèãíàòóðó áëîêà îáúåêòà...
1037       memcpy(&CurrBlockSignature,&Buff[Cursor],4);
1038       StartBlockPos = Cursor;  //Çàïîìíèòü ïîçèöèþ â íà÷àëå áëîêà...
1039       Cursor = Cursor+4;
1040
1041       //Â çàâèñèìîñòè îò ñèãíàòóðû...
1042       if (CurrBlockSignature == OB_Sgn_Unit)
1043       {
1044         //Åñëè ýòî þíèò...
1045         //Ñäâèíóòü êóðñîð ìàññèâà...
1046         UnitObjsCurr = UnitObjsCurr+1;
1047
1048         //Ñ÷èòàòü äëèíó áëîêà...
1049         memcpy(&ObjBlockSize,&Buff[Cursor],4);
1050         Cursor = Cursor+4;
1051
1052         //Ñ÷èòàòü ñàì áëîê.
1053         TempBuff = new byte[ObjBlockSize];
1054         Cursor = Cursor-8;  //Îòêàòèòü êóðñîð íàçàä.
1055         memcpy(&TempBuff[0],&Buff[Cursor],ObjBlockSize);
1056         Cursor = Cursor+ObjBlockSize;
1057
1058         //È ðàñøèôðèòü åãî â ñòðóêòóðó :)
1059         Result = UnitObjs[UnitObjsCurr].ReadBlock(TempBuff,ObjBlockSize,true,this);
1060         //Åñëè áûë àààáëîì...
1061         if (Result == false)
1062         {
1063           goto StopLoadObjBlock;
1064         }
1065         else
1066         {
1067           //Îòëàäî÷íàÿ âåòêà. Ïðîâåðêà - âñå ëè ïðî÷èòàíî èç áëîêà.
1068           TempDW1 = UnitObjs[UnitObjsCurr].GetBlockSize();
1069           if (TempDW1 != ObjBlockSize)
1070           {
1071             //Ñîîáñ÷èòü åòó õðåíü â ëîã.
1072             StringToLog(" áëîêå þíèòà "+IntToStr(UnitObjs[UnitObjsCurr].ObjectID)+" ÷òî-òî \"ëèøíåå\" - ñ÷èòàíî "+IntToStr(TempDW1)+" à ðåàëüíî òàì "+IntToStr(ObjBlockSize)+" áàéò.");
1073           };
1074         };
1075       }
1076
1077       else if (CurrBlockSignature == OB_Sgn_Object)
1078       {
1079         //Åñëè ýòî ïðîñòî îáúåêò...
1080         //Ñäâèíóòü êóðñîð ìàññèâà...
1081         ObjectObjsCurr = ObjectObjsCurr+1;
1082
1083         //Ñ÷èòàòü äëèíó áëîêà...
1084         memcpy(&ObjBlockSize,&Buff[Cursor],4);
1085         Cursor = Cursor+4;
1086
1087         //Ñ÷èòàòü ñàì áëîê.
1088         TempBuff = new byte[ObjBlockSize];
1089         Cursor = Cursor-8;  //Îòêàòèòü êóðñîð íàçàä.
1090         memcpy(&TempBuff[0],&Buff[Cursor],ObjBlockSize);
1091         Cursor = Cursor+ObjBlockSize;
1092
1093         //È ðàñøèôðèòü åãî â ñòðóêòóðó :)
1094         Result = ObjectObjs[ObjectObjsCurr].ReadBlock(TempBuff,ObjBlockSize,true,this);
1095         //Åñëè áûë àààáëîì...
1096         if (Result == false)
1097         {
1098           goto StopLoadObjBlock;
1099         }