43 #include "Core-Level-JR.h"
44 #include "laStagesJR.h"
46 double laLevel::_dZoom = 1;
48 laLevel::laLevel(
void)
63 strcpy(_strFileName,
"");
66 _nObjCnt = _nSegCnt = 0;
67 _bValid = _bCompleted = M_FALSE;
72 _bIntroPresent = M_FALSE;
73 strcpy(_strNextLevel,
"none");
74 strcpy(_strFileName,
"untitled");
77 laLevel::~laLevel(
void) {
79 MLOG(
"Level object destroyed");
84 void laLevel::discard()
87 ASSERT(_bValid,
"Not a valid level, cannot be discarded");
91 MLOG(
"Discarding objects...");
92 for(
int i=_nObjCnt-1; i>=0; i--)
101 MLOG(
"Discarding segment chain...");
111 _cbFirstSeg._pNext = NULL;
113 laPivot::colliderRange(NULL, 0);
117 MLOG(
"Discarding tileset...");
121 MLOG(
"Discarding terrain curviture data...");
122 delete [] _arCurviture_ZOffsets;
124 MLOG(
"Discarding noise texture...");
128 MLOG(
"Level object discarded");
134 void laLevel::reset()
140 for(
unsigned i=0; i<_nObjCnt; i++) {
141 _arObjects[i]->respawn();
151 p->_init_object_list(_arObjects, _nObjCnt);
152 }
while( p = p->next() );
160 void laLevel::create(
unsigned nSegCnt,
laTileset *pTS)
163 ASSERT(pTS,
"Nil tileset.");
174 for(
unsigned i=0; i<_nSegCnt - 1; i++)
178 p->setBackgroundElement(0);
186 p->setBackgroundElement(0);
196 void laLevel::load(
char* strFile, M_BOOL bReload)
199 ASSERT(!_bValid,
"Level is valid, must discard() it first.");
201 progressReset(
"Loading level '%s'...", strFile);
202 strcpy(_strFileName, strFile);
205 char strFilePath[128]=M_DIR_LEVEL, junk[128], strTilesetFile[128], strIntroFile[64];
210 strcat(strFilePath, strFile);
211 fp.fileOpen(strFilePath);
214 srand( ::GetTickCount() );
218 progressIncrease(0.05,
"Loading general section...");
220 try{ fp.readSectionSeparator(junk); }
221 catch(
laError& ){
throw laError(
"Section separator expected but not found (while parsing '%s')", strFile); }
224 ASSERT(!strcmp(junk,
"GENERAL"),
"Section [GENERAL] expected, [%s] found ('%s')", junk, strFile);
226 fp.readText(_strName);
227 fp.readText(strTilesetFile);
228 fp.readUnsigned(&len);
232 fp.readText(strIntroFile);
233 fp.readText(_strNextLevel);
235 _bIntroOver = M_FALSE;
236 if( strcmp(strIntroFile,
"none") )
240 fp.readObj( (stageIntro*)(laSystemIntegrator::getGame()->getStage(M_STAGE_INTRO)), M_FALSE);
242 _bIntroPresent = M_TRUE;
244 else _bIntroPresent = M_FALSE;
248 progressIncrease(0.65);
252 progressSubtask(_pTileSet, 0.6);
253 _pTileSet->load(strTilesetFile);
254 progressSubtask(NULL,0);
258 _load_segments(fp, len);
264 _pNoiseTex->load( _pTileSet->getBackgroundElement()->getText(
"terrain-noise-texture") );
268 progressIncrease(0.1,
"Distributing objects to segments...");
273 p->_init_object_list(_arObjects, _nObjCnt);
274 }
while( p=p->_pNext );
276 progressIncrease(0.1,
"Precomputing terrain curviture...");
277 _curviture_precompute();
279 progressIncrease(0.1,
"Level loaded.");
285 void laLevel::_load_segments(
laFileParser &fp,
unsigned len)
289 unsigned seg_index =0;
292 progressIncrease(0,
"Creating segment list of lenght %d...", len);
293 create(len, _pTileSet);
296 progressIncrease(0.2/len,
"Loading segment %d...", seg_index);
298 try{ fp.readSectionSeparator(junk); }
300 throw laError(
"Segment separator (%d) expected but not found", seg_index);
304 try{ fp.readObj(p, M_FALSE); }
305 catch(
laError& pe){
throw laError(
"%s\n\nLevel segment (%d) appears to be corrupted", pe.getText(), seg_index); }
308 p->bulidDomains(laPoint3(seg_index*
M_UNIT*M_SEGW,0,0));
312 unsigned nElement = _pTileSet->getSegmentBackground(rand()%_pTileSet->getSegmentBackgroundCount());
313 p->setBackgroundElement(nElement);
317 }
while( p=p->_pNext );
320 _cbFirstSeg.firstDomain()->optimize();
323 laPivot::colliderRange(_cbFirstSeg.firstNonemptyDomain(), _cbFirstSeg.countDomains(len));
331 char junk[128], strElementName[32], *strInstanceType;
332 unsigned nElementIndex;
337 progressIncrease(0,
"Loading dynamic objects...");
342 try{ fp.readSectionSeparator(junk); }
343 catch(
laError& ){
throw laError(
"Section separator expected but not found"); }
346 if(!strcmp(junk,
"END"))
break;
348 ASSERT(_nObjCnt <
M_MAXOBJCNT,
"Object count exceeds M_MAXOBJCNT");
349 ASSERT(!strcmp(junk,
"OBJECT"),
"[OBJECT] expected, [%s] found", junk);
353 try{ fp.readText(strElementName); }
354 catch(
laError& ){
throw laError(
"Corrupted object (%d) encountered", _nObjCnt); }
356 nElementIndex = _pTileSet->getElementIndex(strElementName);
358 ASSERT(_pTileSet->getElementCnt() > nElementIndex,
359 "Tileset element '%s' was requested by object (%d) but not found", strElementName, _nObjCnt);
363 pplr = _arObjects[_nObjCnt];
368 strInstanceType = _pTileSet->getElement(nElementIndex)->getInstanceType();
373 _arObjects[_nObjCnt]->setObject(nElementIndex, (
laElement*)_pTileSet->getElement(nElementIndex));
374 _arObjects[_nObjCnt]->setTS(_pTileSet);
375 _arObjects[_nObjCnt]->setLevel(
this);
377 try{ fp.readObj(_arObjects[_nObjCnt], M_FALSE); }
378 catch(
laError& pe){
throw laError(
"%s\n\nCorrupted object (%d) encountered", pe.getText(), _nObjCnt); }
380 MLOG(
"Object %d loaded...", _nObjCnt);
390 void laLevel::_save_profile(
char* strName)
393 sprintf(strfile,
"save\\%s.profile", strName);
395 FILE *f = fopen(strfile,
"w+");
396 fprintf(f,
"[profile]\n");
399 if(_bCompleted) fprintf(f,
"[text] load-level: '%s' \n", _strNextLevel);
400 else fprintf(f,
"[text] load-level: '%s' \n", _strFileName);
403 ((
laPlayer*)getPlayer())->saveProfile(f);
405 fprintf(f,
"\n[/profile]");
411 void laLevel::_curviture_precompute()
413 double *pmem =
new double [_nSegCnt*M_SEGW * 3];
415 _arCurviture_ZOffsets = pmem;
416 _arCurviture_Angles = pmem + 1 * _nSegCnt*M_SEGW;
417 _arCurviture_Scales = pmem + 2 * _nSegCnt*M_SEGW;
420 double arParCurrent[4], arParNext[4], arPar[4];
422 ps->_update_curviture_parameters();
423 ps->curvitureParams(arParCurrent);
426 for(
unsigned i=0; i<_nSegCnt; i++)
432 ps->_update_curviture_parameters();
433 ps->curvitureParams(arParNext);
437 for(
unsigned xs=0; xs<M_SEGW; xs++)
440 double w = 1.0 - (double)xs/M_SEGW;
441 for(
unsigned p=0; p<4; p++) arPar[p] = w * arParCurrent[p] + (1-w) * arParNext[p];
445 unsigned ix = i*(M_SEGW) + xs;
446 double dx = ix * 0.1;
448 _arCurviture_ZOffsets[ ix ] =
449 arPar[0] * sin( dx/2.0 ) * (
M_UNIT) +
450 arPar[1] * sin( dx ) * sin( dx*2 ) * (
M_UNIT*2) * (
M_UNIT*0.5) +
451 arPar[2] * sin( dx*8 ) * (
M_UNIT*0.6);
456 double dOffsetDelta = _arCurviture_ZOffsets[ix-1] - _arCurviture_ZOffsets[ix];
458 _arCurviture_Angles[ ix-1 ] = atan2( dOffsetDelta,
M_UNIT );
459 _arCurviture_Scales[ ix-1 ] = sqrt(
M_UNIT*
M_UNIT + dOffsetDelta*dOffsetDelta)/
M_UNIT;
463 memcpy(arParCurrent, arParNext,
sizeof(
double)*4);
467 _arCurviture_Angles[ (_nSegCnt)*M_SEGW -1 ] = _arCurviture_Angles[ (_nSegCnt)*M_SEGW -2 ];
468 _arCurviture_Scales[ (_nSegCnt)*M_SEGW -1 ] = _arCurviture_Scales[ (_nSegCnt)*M_SEGW -2 ];
laNamedClass * instantiate(std::string strClassName)
Instantiate class by name.
#define M_UNIT
Unit of 1 meter.
Base Class for Tileset Elements.
#define M_MAXOBJCNT
Count limitations.
Multi-state Level Object.
Level finsihing point collectable.
Object that can be activated by the player.
Adds capabilities and percepts specific to monster creatures.
#define REGISTER_CLASS(class_name)
Handy macro for registering named class prototype.
Base Class for Level Objects.
Collectable Level Object.