Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

buildinglayer.cpp

00001 /***************************************************************************
00002                         buildinglayer.cpp  -  description
00003                             -------------------
00004     begin                : sam sep 20 2003
00005     copyright            : (C) 2003-2006 by Duong-Khang NGUYEN
00006     email                : neoneurone @ users sourceforge net
00007     
00008     $Id: buildinglayer.cpp 77 2006-11-01 18:27:53Z neoneurone $
00009  ***************************************************************************/
00010 
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Public License as published by  *
00015  *   the Free Software Foundation; either version 2 of the License, or     *
00016  *   any later version.                                                    *
00017  *                                                                         *
00018  ***************************************************************************/
00019 
00020 #include "buildinglayer.h"
00021 #include "city.h"
00022 #include "rcistructure.h"
00023 #include "wegstructure.h"
00024 #include "pathstructure.h"
00025 #include "treestructure.h"
00026 #include "guicontainer.h"
00027 #include "guibutton.h"
00028 
00029 #include "globalvar.h"
00030 extern GlobalVar gVars;
00031 
00032 
00033    /*=====================================================================*/
00034 BuildingLayer::BuildingLayer
00035 (
00036     const City & rcCity
00037 )
00038 {
00039     OPENCITY_DEBUG( "ctor" );
00040 // initialization of width and height
00041     rcCity.GetWL( _uiLayerWidth, _uiLayerLength );
00042 
00043 // initialization of the table of pointer of Structure
00044     uint citySurface = _uiLayerLength * _uiLayerWidth;
00045     _tabpStructure = new Structure*[citySurface];
00046     for ( uint counter = 0; counter < citySurface; counter++ ) {
00047         _tabpStructure[ counter ] = NULL;
00048     }
00049 
00050 }
00051 
00052 
00053    /*=====================================================================*/
00054 BuildingLayer::~BuildingLayer()
00055 {
00056     OPENCITY_DEBUG("dtor");
00057 
00058     uint citySurface = _uiLayerLength * _uiLayerWidth;
00059     for ( uint counter = 0; counter < citySurface; counter++ ) {
00060     // delete NULL pointer is allowed ?
00061     // delete seems to have no effects on NULL
00062         if (_tabpStructure[counter] != NULL) {
00063             delete _tabpStructure[counter];
00064             _tabpStructure[counter] = NULL;
00065         }
00066     }
00067 
00068     delete [] _tabpStructure;
00069 }
00070 
00071 
00072    /*=====================================================================*/
00073 void
00074 BuildingLayer::SaveTo( std::fstream& rfs )
00075 {
00076     OPENCITY_DEBUG( __PRETTY_FUNCTION__ << "saving" );
00077     Structure* p = NULL;
00078     uint w = 0, l = 0, linear = 0;
00079 
00080     rfs << _uiLayerWidth << std::ends;
00081     rfs << _uiLayerLength << std::ends;
00082 
00083     for ( l = 0; l < _uiLayerLength; l++ )
00084     for ( w = 0; w < _uiLayerWidth; w++ ) {
00085 // debug
00086 //      rfs << w << " " << l << std::endl;
00087 
00088         p = _tabpStructure[linear++];
00089 
00090     // We save only extra information for main structures
00091         if ((p != NULL) && (p->GetMain() != NULL)) {
00092             p = NULL;
00093         }
00094         rfs << p << std::ends;
00095 
00096         if (p != NULL) {
00097             rfs << p->GetType() << std::ends;
00098             p->SaveTo( rfs );
00099         }
00100     } // for
00101 }
00102 
00103 
00104    /*=====================================================================*/
00105 void
00106 BuildingLayer::LoadFrom( std::fstream& rfs )
00107 {
00108     OPENCITY_DEBUG( __PRETTY_FUNCTION__ << "loading" );
00109     Structure* p = NULL;
00110     void* t = NULL;
00111     uint w = 0, l = 0, anUint = 0, linear = 0;
00112     OPENCITY_STRUCTURE_TYPE type = OC_TYPE_UNUSED;      
00113 
00114 // Remove the old structures
00115     uint citySurface = _uiLayerLength * _uiLayerWidth;
00116     for ( linear = 0; linear < citySurface; linear++ ) {
00117         delete _tabpStructure[linear];
00118     }
00119     delete [] _tabpStructure;
00120 
00121 // Reset the counter
00122     Structure::SetNumber( 0 );
00123 
00124 // Read the saved size
00125     rfs >> _uiLayerWidth; rfs.ignore();
00126     rfs >> _uiLayerLength; rfs.ignore();
00127 
00128 // initialization of the table of pointer of Structure
00129     citySurface = _uiLayerLength * _uiLayerWidth;
00130     _tabpStructure = new Structure*[citySurface];
00131     for ( linear = 0; linear < citySurface; linear++ ) {
00132         _tabpStructure[linear] = NULL;
00133     }
00134 
00135 // debug
00136 //  uint wt = 0, lt = 0;
00137 
00138 // Load the structures
00139     for ( l = 0; l < _uiLayerLength; l++ )
00140     for ( w = 0; w < _uiLayerWidth; w++ ) {
00141 // debug
00142 //      rfs >> wt; rfs.ignore();
00143 //      rfs >> lt; rfs.ignore();
00144 
00145         rfs >> t; rfs.ignore();
00146 //      OPENCITY_DEBUG( "Current w/l: " << w << " / " << l << " | Reading w/l/t: " << wt << " / " << lt << " / " << t );
00147 
00148         if (t != NULL) {
00149             rfs >> anUint; rfs.ignore(); type = (OPENCITY_STRUCTURE_TYPE)anUint;
00150             switch (type) {
00151                 case OC_TYPE_RESIDENCE:
00152                 case OC_TYPE_COMMERCE:
00153                 case OC_TYPE_INDUSTRY:
00154                     p = new RCIStructure();
00155                     break;
00156 
00157                 case OC_TYPE_WATER:
00158                 case OC_TYPE_ELECTRICITY:
00159                 case OC_TYPE_GAS:
00160                 case OC_TYPE_GOVERNMENT:        // hack
00161                     p = new WEGStructure();
00162                     break;
00163 
00164                 case OC_TYPE_PATH:
00165                     p = new PathStructure();
00166                     break;
00167 
00168                 case OC_TYPE_TREE:
00169                     p = new TreeStructure();
00170                     break;
00171 
00172                 default:
00173                     OPENCITY_DEBUG( "Unknown structure's type: " << type );
00174                     assert( 0 );
00175             }
00176 
00177             p->LoadFrom( rfs );
00178             _LoadStructure( w, l, p );
00179         } // if (p != NULL)
00180     } // for
00181 }
00182 
00183 
00184    /*=====================================================================*/
00185 void
00186 BuildingLayer::uiKeyboard( const SDL_KeyboardEvent & rcsSDLKeyboardEvent )
00187 {}
00188 
00189 void
00190 BuildingLayer::uiMouseMotion( const SDL_MouseMotionEvent &
00191                 rcsSDLMouseMotionEvent )
00192 {}
00193 
00194 void
00195 BuildingLayer::uiMouseButton( const SDL_MouseButtonEvent & 
00196                 rcsSDLMouseButtonEvent )
00197 {}
00198 
00199 void
00200 BuildingLayer::uiExpose( const SDL_ExposeEvent & rcsSDLExposeEvent )
00201 {}
00202 
00203 void
00204 BuildingLayer::uiResize( const SDL_ResizeEvent & rcsSDLResizeEvent )
00205 {}
00206 
00207 
00208    /*=====================================================================*/
00209 const bool
00210 BuildingLayer::IsConstructive(
00211     uint W1, uint L1,
00212     uint W2, uint L2,
00213     const OPENCITY_STRUCTURE_CODE & enumStructCode ) const
00214 {
00215     uint linearIndex;
00216     uint w;
00217 
00218 // Out of map ?
00219     if ((L2 >= _uiLayerLength) || (W2 >= _uiLayerWidth))
00220         return false;
00221 
00222 // cheking for the availability of a free room
00223     while (L1 <= L2) {
00224         linearIndex = (L1*_uiLayerWidth) + W1;
00225         w = W1;
00226         while (w <= W2) {
00227             switch (enumStructCode) {
00228             case OC_STRUCTURE_RES:
00229             case OC_STRUCTURE_IND:
00230             case OC_STRUCTURE_COM:
00231             case OC_STRUCTURE_PARK:
00232             case OC_STRUCTURE_FLORA:
00233             case OC_STRUCTURE_EPLANT_COAL:
00234             case OC_STRUCTURE_FIREDEPT:
00235             case OC_STRUCTURE_POLICEDEPT:
00236             case OC_STRUCTURE_HOSPITALDEPT:
00237             case OC_STRUCTURE_EDUCATIONDEPT:
00238             case OC_STRUCTURE_TEST:
00239             // IF there's a structure on the square
00240             // OR the square is not plane
00241             // then the square is not constructive
00242                 if ((this->GetLinearStructure(linearIndex) != NULL)
00243                   ||(gVars.gpMapMgr->IsSquarePlane(w, L1) != true ))
00244                     return false;
00245                 break;
00246 
00247             case OC_STRUCTURE_ROAD:
00248             case OC_STRUCTURE_ELINE:
00249             // The case of "road structure"
00250             // OR "eline" is
00251             // processed in a seperate method
00252                 if (_IsPathConstructive(w, L1, enumStructCode) != true)
00253                     return false;
00254                 break;
00255 
00256             default:
00257                 OPENCITY_DEBUG( "Unknown structure" );
00258                 assert(0);
00259                 break;
00260 
00261             }  // switch
00262             w++;
00263             linearIndex++;
00264         }  // while w
00265         L1++;
00266     }
00267 
00268     return true;
00269 }
00270 
00271 
00272    /*=====================================================================*/
00273 const OPENCITY_ERR_CODE
00274 BuildingLayer::BuildPreview(
00275     const uint & W,
00276     const uint & L,
00277     const OPENCITY_STRUCTURE_CODE & enumStructCode,
00278     OPENCITY_GRAPHIC_CODE & enumGraphicCode ) const
00279 {
00280 //  OPENCITY_DEBUG( "I'm previewing a building" );
00281     static uint W1, L1, W2, L2;
00282     static uint sw, sl, sh;         // Structure's width, length and height
00283 
00284 
00285 // FIXME: Work for WEG structure only !
00286 // Get the graphic code of the structure
00287     enumGraphicCode = gVars.gpPropertyMgr->GetGC( enumStructCode );
00288     if ( enumGraphicCode == OC_EMPTY ) {
00289         OPENCITY_DEBUG( "WARNING: not implemented" );
00290         assert(0);
00291     }
00292 
00293 // Get the corresponding WLH and calculate the range
00294 // An coal electric plant is 4x4 size by default
00295     gVars.gpPropertyMgr->GetWLH( enumGraphicCode, sw, 4, sl, 4, sh, 1 );
00296     W1 = W;
00297     L1 = L;
00298     W2 = W + sw - 1;
00299     L2 = L + sl - 1;
00300 
00301 // Isn't there enough space ?
00302 // OR is there already something on the surface ?
00303     if (IsConstructive(W1, L1, W2, L2, enumStructCode) == false) {
00304         return OC_ERR_SOMETHING;
00305     }
00306 
00307     return OC_ERR_FREE;
00308 }
00309 
00310 
00311    /*=====================================================================*/
00312 const OPENCITY_ERR_CODE
00313 BuildingLayer::BuildStructure(
00314     const uint & W1,
00315     const uint & L1,
00316     const uint & W2,
00317     const uint & L2,
00318     const OPENCITY_STRUCTURE_CODE & enumStructCode,
00319     uint& rCost )
00320 {
00321     OPENCITY_DEBUG( "I'm building some structures" );
00322 
00323 // For more obvious coding
00324     OPENCITY_ERR_CODE errCode;
00325 
00326     switch (enumStructCode) {
00327         case OC_STRUCTURE_RES:
00328         case OC_STRUCTURE_COM:
00329         case OC_STRUCTURE_IND:
00330         case OC_STRUCTURE_PARK:
00331         case OC_STRUCTURE_TEST:
00332             errCode = _BuildRCIStructure( W1, L1, W2, L2, enumStructCode, rCost );
00333             break;
00334 
00335         case OC_STRUCTURE_EDUCATIONDEPT:
00336         case OC_STRUCTURE_FIREDEPT:
00337         case OC_STRUCTURE_POLICEDEPT:
00338         case OC_STRUCTURE_HOSPITALDEPT:
00339         case OC_STRUCTURE_EPLANT_COAL:
00340             errCode = _BuildWEGStructure( W1, L1, enumStructCode, rCost );
00341             break;
00342 
00343         case OC_STRUCTURE_ROAD:
00344         case OC_STRUCTURE_ELINE:
00345             errCode = _BuildPathStructure( W1, L1, W2, L2, enumStructCode, rCost );
00346             break;
00347 
00348         case OC_STRUCTURE_FLORA:
00349             errCode = _BuildFloraStructure( W1, L1, W2, L2, enumStructCode, rCost );
00350             break;
00351 
00352         default:
00353             OPENCITY_DEBUG( "WARNING: Unknown structure to build" );
00354             errCode = OC_ERR_SOMETHING;
00355             assert(0);
00356             break;
00357     } // switch
00358 
00359     return errCode;
00360 }
00361 
00362 
00363    /*=====================================================================*/
00364 const OPENCITY_ERR_CODE
00365 BuildingLayer::ResizeStructure(
00366     const uint & w,
00367     const uint & l,
00368     const OPENCITY_GRAPHIC_CODE & oldGC )
00369 {
00370     uint linearIndex = (l*_uiLayerWidth) + w;
00371     Structure* pStruct = NULL, * pTemp = NULL, * pMain = NULL;
00372     uint ow = 0, ol = 0, oh = 0;                    // Old structure dimensions
00373     uint nw = 0, nl = 0, nh = 0;                    // New structure dimensions
00374     uint xw = 0, xl = 0, xh = 0;                    // Destroyed structure dimensions
00375     uint dw, dl;                                    // Used in the "for loop"
00376     uint uiCost;                                    // Temp cost, necessary to call internal methods
00377 
00378     OPENCITY_STRUCTURE_CODE structCode;
00379     OPENCITY_STRUCTURE_CODE destroyedSC;            // The destroyed structure's code. It's used for rebuild
00380 
00381 
00382 // Get the pointer to the structure that we need to modify
00383     pStruct = _tabpStructure[ linearIndex ];
00384     assert( pStruct != NULL );
00385 
00386 // IF the graphic code has not changed THEN it's okay
00387     if ( oldGC == pStruct->GetGraphicCode() )
00388         return OC_ERR_FREE;
00389     structCode = pStruct->GetCode();
00390 
00391 // Get the old WLH
00392     gVars.gpPropertyMgr->GetWLH(
00393         oldGC,
00394         ow, 0,
00395         ol, 0,
00396         oh, 0 );
00397     assert((ow != 0) && (ol != 0));     // not used yet: && (oh != 0) 
00398 
00399 // Get the new WLH
00400     gVars.gpPropertyMgr->GetWLH(
00401         pStruct->GetGraphicCode(),
00402         nw, 0,
00403         nl, 0,
00404         nh, 0 );
00405     assert((nw != 0) && (nl != 0));     // not used yet: && (nh != 0) 
00406 
00407 // Remove all existing marks on the old surface used by the structure
00408     for (dl = l; dl < l + ol; dl++) {
00409         linearIndex = (dl*_uiLayerWidth) + w;
00410         for (dw = w; dw < w + ow; dw++) {
00411             pTemp = _tabpStructure[ linearIndex++ ];
00412         // NOTE: the following "if" is unnecessary, since pTemp is never NULL
00413             assert( pTemp != NULL );
00414             if (pTemp != NULL)
00415                 pTemp->Unset( OC_STRUCTURE_MARK );
00416         }
00417     }
00418 
00419 // Build the eventual missing parts of the new structure
00420     for (dl = l; dl < l + nl; dl++) {
00421         linearIndex = (dl*_uiLayerWidth) + w;
00422         for (dw = w; dw < w + nw; dw++) {
00423             pTemp = _tabpStructure[ linearIndex ];
00424 
00425         // IF there is nothing here, THEN build a new part
00426             if (pTemp == NULL) {
00427                 pTemp = new RCIStructure( OC_STRUCTURE_PART, pStruct );
00428                 _tabpStructure[ linearIndex ] = pTemp;
00429             }
00430         // ELSE IF there is something 
00431         // AND it's not the current structure
00432         // AND it's not the current structure's part neither THEN remove it
00433             else if (pTemp != pStruct and pTemp->GetMain() != pStruct) {
00434             // Remember the structure which is going to be destroyed
00435                 if (pTemp->GetCode() == OC_STRUCTURE_PART)
00436                     pMain = pTemp->GetMain();
00437                 else
00438                     pMain = pTemp;
00439 
00440                 destroyedSC = pMain->GetCode();
00441                 gVars.gpPropertyMgr->GetWLH( pMain->GetGraphicCode(), xw, 0, xl, 0, xh, 0 );
00442 
00443                 _DestroyStructure( dw, dl, uiCost );
00444                 pTemp = new RCIStructure( OC_STRUCTURE_PART, pStruct );
00445                 _tabpStructure[ linearIndex ] = pTemp;
00446 
00447                 // Rebuild the neighbourhood
00448                 if (xw > 1 or xl > 1) {
00449                     BuildStructure( dw, dl, dw + xw-1, dl + xl-1, destroyedSC, uiCost );
00450                 }
00451             }
00452             pTemp->Set( OC_STRUCTURE_MARK );
00453             linearIndex++;
00454         }
00455     }
00456 
00457 // Remove the unmarked structures on the old surface 
00458 // then build the first level structures on it
00459     for (dl = l; dl < l + ol; dl++) {
00460         linearIndex = (dl*_uiLayerWidth) + w;
00461         for (dw = w; dw < w + ow; dw++) {
00462             pTemp = _tabpStructure[ linearIndex ];
00463 // debug
00464             assert( pTemp != NULL );
00465             if (pTemp->IsSet(OC_STRUCTURE_MARK) == false) {
00466                 _DestroyStructure( dw, dl, uiCost );
00467                 _tabpStructure[ linearIndex ] = new RCIStructure( structCode );
00468             }
00469             linearIndex++;
00470         } // for dw
00471     } // for dl
00472 
00473     return OC_ERR_FREE;
00474 }
00475 
00476 
00477    /*=====================================================================*/
00478 const OPENCITY_ERR_CODE
00479 BuildingLayer::DestroyStructure(
00480     uint W1, uint L1,
00481     uint W2, uint L2,
00482     uint& rCost )
00483 {
00484     uint w, l;
00485     uint costPerSquare;
00486 
00487     OPENCITY_SWAP( W1, W2, uint );
00488     OPENCITY_SWAP( L1, L2, uint );
00489     rCost = 0;
00490 
00491     for (w = W1; w <= W2; w++)
00492         for (l = L1; l <= L2; l++) {
00493         if (_DestroyStructure( w, l, costPerSquare ) == OC_ERR_FREE)
00494             rCost += costPerSquare;
00495     }
00496 
00497     return OC_ERR_FREE;
00498 }
00499 
00500 
00501    /*=====================================================================*/
00502 Structure *
00503 BuildingLayer::GetLinearStructure( const uint cuiLinearIndex ) const
00504 {
00505     return _tabpStructure[ cuiLinearIndex ];
00506 }
00507 
00508 
00509    /*=====================================================================*/
00510 Structure*
00511 BuildingLayer::GetStructure(
00512     const uint & w,
00513     const uint & h ) const
00514 {
00515     return _tabpStructure[ h*_uiLayerWidth + w ];
00516 }
00517 
00518 
00519    /*=====================================================================*/
00520 Structure*
00521 BuildingLayer::GetRandomStructure(
00522     uint & w,
00523     uint & h,
00524     const OPENCITY_STRUCTURE_CODE & enumStructCode ) const
00525 {
00526     if (enumStructCode == OC_STRUCTURE_UNDEFINED)
00527         return NULL;
00528 
00529 // nothing can be static because we can be called by more than 1 thread
00530     uint linear;
00531     uint counter;
00532     Structure* pstruct;
00533 
00534 // we try 100 times before giving up
00535 // OC_CHANCE_COUNTER_MAX = 100
00536     counter = 0;
00537     do {
00538         linear = rand() % (_uiLayerWidth*_uiLayerLength);
00539         pstruct = GetLinearStructure(linear);
00540         if (pstruct != NULL)
00541             if ((pstruct->GetCode() == enumStructCode)
00542              || (enumStructCode == OC_STRUCTURE_ANY)) {
00543                 h = linear / _uiLayerWidth;
00544                 w = linear % _uiLayerWidth;
00545                 return pstruct;
00546             }
00547 
00548         counter++;
00549     } while (counter < OC_CHANCE_COUNTER_MAX);
00550 
00551 //debug cout << "coco: " << linear << endl;
00552     return NULL;
00553 }
00554 
00555 
00556    /*=====================================================================*/
00557 const uint
00558 BuildingLayer::GetNumberStructure() const
00559 {
00560     cout << "WARNING: not implemented" << endl;
00561     assert(0);
00562 
00563     return 0;
00564 }
00565 
00566 
00567    /*=====================================================================*/
00568 void
00569 BuildingLayer::StructureSet(
00570     const OC_BYTE & status )
00571 {
00572     uint citySurface = _uiLayerLength * _uiLayerWidth;
00573     for ( uint counter = 0; counter < citySurface; counter++ ) {
00574         if (_tabpStructure[ counter ] != NULL)
00575             _tabpStructure[ counter ]->Set( status );
00576     }
00577 }
00578 
00579 
00580    /*=====================================================================*/
00581 void
00582 BuildingLayer::StructureUnset(
00583     const OC_BYTE & status )
00584 {
00585     uint citySurface = _uiLayerLength * _uiLayerWidth;
00586     for ( uint counter = 0; counter < citySurface; counter++ ) {
00587         if (_tabpStructure[ counter ] != NULL)
00588             _tabpStructure[ counter ]->Unset( status );
00589     }
00590 }
00591 
00592 
00593    /*=====================================================================*/
00594 const bool
00595 BuildingLayer::ContainStructure(
00596     const uint & W1,
00597     const uint & L1,
00598     const uint & W2,
00599     const uint & L2,
00600     const OPENCITY_STRUCTURE_CODE & enumStructCode ) const
00601 {
00602     uint w, h, linear;
00603     Structure* pstruct;
00604 
00605     switch (enumStructCode) {
00606         case OC_STRUCTURE_UNDEFINED:
00607             return false;
00608 
00609 //TODO: better checking for each type
00610         case OC_STRUCTURE_ANY:
00611         case OC_STRUCTURE_PART:
00612         case OC_STRUCTURE_RES:
00613         case OC_STRUCTURE_COM:
00614         case OC_STRUCTURE_IND:
00615         case OC_STRUCTURE_PARK:
00616         case OC_STRUCTURE_ROAD:
00617         case OC_STRUCTURE_ELINE:
00618         case OC_STRUCTURE_EPLANT_COAL:
00619         case OC_STRUCTURE_FIREDEPT:
00620         case OC_STRUCTURE_POLICEDEPT:
00621         case OC_STRUCTURE_EDUCATIONDEPT:
00622         case OC_STRUCTURE_TEST:
00623             for (h = L1; h <= L2; h++) {
00624                 linear = h*_uiLayerWidth + W1;
00625                 for (w = W1; w <= W2; w++, linear++) {
00626                     pstruct = GetLinearStructure( linear );
00627                     if (pstruct != NULL) {
00628                         if ((pstruct->GetCode() == enumStructCode)
00629                           ||(enumStructCode == OC_STRUCTURE_ANY))
00630                             return true;
00631                     }
00632                 }  // while w
00633             }  // while h
00634             break;
00635 
00636         case OC_STRUCTURE_ELECTRIC:
00637             for (h = L1; h <= L2; h++) {
00638                 linear = h*_uiLayerWidth + W1;
00639                 for (w = W1; w <= W2; w++, linear++) {
00640                     pstruct = GetLinearStructure( linear );
00641                     if (pstruct != NULL) {
00642                     // return true if this structure is
00643                     // connected to the electric system
00644                         if (pstruct->IsSet( OC_STRUCTURE_E ) == true)
00645                             return true;
00646                     }
00647                 }  // while w
00648             }  // while h
00649             break;
00650 
00651         default:
00652             cerr << "WARNING: unknown structure code" << endl;
00653             assert(0);
00654             break;          // keep the compiler happy
00655     }  // switch
00656 
00657     return false;
00658 }
00659 
00660 
00661    /*=====================================================================*/
00662 const bool
00663 BuildingLayer::ContainStructureOnly(
00664     const uint & W1,
00665     const uint & L1,
00666     const uint & W2,
00667     const uint & L2,
00668     const OPENCITY_STRUCTURE_CODE & enumStructCode ) const
00669 {
00670 // Safe
00671     assert( W1 >= 0 );
00672     assert( L1 >= 0 );
00673     assert( W2 < _uiLayerWidth );
00674     assert( L2 < _uiLayerLength );
00675 
00676 
00677     uint w = 0, l = 0, linear = 0;
00678     Structure* pstruct = NULL;
00679 
00680     switch (enumStructCode) {
00681         case OC_STRUCTURE_UNDEFINED:
00682             return false;
00683 
00684         case OC_STRUCTURE_ANY:
00685             return true;
00686 
00687         case OC_STRUCTURE_PART:
00688         case OC_STRUCTURE_RES:
00689         case OC_STRUCTURE_COM:
00690         case OC_STRUCTURE_IND:
00691         case OC_STRUCTURE_PARK:
00692         case OC_STRUCTURE_ROAD:
00693         case OC_STRUCTURE_ELINE:
00694         case OC_STRUCTURE_EPLANT_COAL:
00695         case OC_STRUCTURE_FIREDEPT:
00696         case OC_STRUCTURE_POLICEDEPT:
00697         case OC_STRUCTURE_EDUCATIONDEPT:
00698         case OC_STRUCTURE_TEST:
00699             for (l = L1; l <= L2; l++) {
00700                 linear = l*_uiLayerWidth + W1;
00701                 for (w = W1; w <= W2; w++, linear++) {
00702                     pstruct = GetLinearStructure( linear );
00703                     if (pstruct != NULL) {
00704                         if (pstruct->GetCode() != enumStructCode)
00705                             return false;
00706                     }
00707                 }  // while w
00708             }  // while l
00709             break;
00710 
00711         case OC_STRUCTURE_ELECTRIC:
00712         // Return true if all the contained structures are electrified
00713             for (l = L1; l <= L2; l++) {
00714                 linear = l*_uiLayerWidth + W1;
00715                 for (w = W1; w <= W2; w++, linear++) {
00716                     pstruct = GetLinearStructure( linear );
00717                     if (pstruct != NULL) {
00718                     // Return true if this structure is
00719                     // connected to the electric system
00720                         if (pstruct->IsSet( OC_STRUCTURE_E ) == false)
00721                             return false;
00722                     }
00723                 }  // while w
00724             }  // while h
00725             break;
00726 
00727         default:
00728             cerr << "WARNING: unknown structure code" << endl;
00729             assert(0);
00730             break;          // keep the compiler happy
00731     }  // switch
00732 
00733     return true;
00734 }
00735 
00736 
00737    /*=====================================================================*/
00738 GUIContainer*
00739 BuildingLayer::QueryStructure(
00740     const uint & w,
00741     const uint & l ) const
00742 {
00743     GUIContainer* pcontainer = new GUIContainer( 100, 100, 140, 140 );
00744     Structure* pstruct = _tabpStructure[ l*_uiLayerWidth + w ];
00745     Color red = { 255, 0, 0, 255 };
00746     Color green = { 0, 255, 0, 255 };
00747 
00748 // everything is RED :D
00749     Layer::pbtnQW->SetBackground( red );
00750     Layer::pbtnQE->SetBackground( red );
00751     Layer::pbtnQG->SetBackground( red );
00752     Layer::pbtnQR->SetBackground( red );
00753     Layer::pbtnQC->SetBackground( red );
00754     Layer::pbtnQI->SetBackground( red );
00755 
00756 // look for the RCI structures around
00757 // and WEG properties
00758     if ( pstruct != NULL ) {
00759     // we check only the E bit, WG are NOT implemented yet
00760         if ( pstruct->IsSet( OC_STRUCTURE_E ) )
00761             Layer::pbtnQE->SetBackground( green );
00762 
00763     // check for RCI
00764         if ( pstruct->IsSet( OC_STRUCTURE_R ) )
00765             Layer::pbtnQR->SetBackground( green );
00766         if ( pstruct->IsSet( OC_STRUCTURE_C ) )
00767             Layer::pbtnQC->SetBackground( green );
00768         if ( pstruct->IsSet( OC_STRUCTURE_I ) )
00769             Layer::pbtnQI->SetBackground( green );
00770     }
00771 
00772 // add all the controls
00773     pcontainer->Add( Layer::pbtnQW );
00774     pcontainer->Add( Layer::pbtnQE );
00775     pcontainer->Add( Layer::pbtnQG );
00776     pcontainer->Add( Layer::pbtnQR );
00777     pcontainer->Add( Layer::pbtnQC );
00778     pcontainer->Add( Layer::pbtnQI );
00779 
00780     return pcontainer;
00781 }
00782 
00783 
00784 
00785 
00786    /*=====================================================================*/
00787    /*                        PRIVATE     METHODS                          */
00788    /*=====================================================================*/
00789 const bool
00790 BuildingLayer::_IsPathConstructive(
00791     const uint& w,
00792     const uint& h,
00793     const OPENCITY_STRUCTURE_CODE& enumStructCode ) const
00794 {
00795     OC_BYTE tabH[4];
00796     OC_BYTE minH = 127;
00797     OC_BYTE maxH = -127;
00798     OC_BYTE deltaH = 0;
00799     uint uiIndex = 0;
00800     OC_BYTE minHNb = 0;
00801     Structure* pStruct = NULL;
00802 
00803 // Return immediatly if there's already 
00804 // something different than enumStructCode built on it
00805     pStruct = this->GetStructure(w,h);
00806     if ((pStruct != NULL) && (pStruct->GetCode() != enumStructCode))
00807         return false;
00808 
00809 // Calculate the min and the max heights
00810     gVars.gpMapMgr->GetSquareHeight( w, h, tabH );
00811     for (uiIndex = 0; uiIndex < 4; uiIndex++) {
00812         if (tabH[uiIndex] < minH)
00813             minH = tabH[uiIndex];
00814         if (tabH[uiIndex] > maxH)
00815             maxH = tabH[uiIndex];
00816     }
00817 
00818 // Calculate the absolute difference
00819     deltaH = maxH - minH;
00820     if (deltaH > 1)
00821     // we can not build road if the difference is too big
00822         return false;
00823 
00824 // Else, calculate the number of minH points
00825 // minHNb is already initialized
00826     for (uiIndex = 0; uiIndex < 4; uiIndex++) {
00827         if (tabH[uiIndex] == minH)
00828             minHNb++;
00829     }
00830 
00831 // The number of minH points should be the multiple of 2
00832     if ((minHNb % 2) != 0)
00833         return false;
00834 
00835 // Here, the square is "road constructive"
00836     return true;
00837 }
00838 
00839 
00840    /*=====================================================================*/
00841 const OPENCITY_ERR_CODE
00842 BuildingLayer::_BuildPathStructure(
00843     uint W1, uint L1,
00844     uint W2, uint L2,
00845     const OPENCITY_STRUCTURE_CODE & enumStructCode,
00846     uint& rCost )
00847 {
00848     OPENCITY_DEBUG( "I'm building some path structures" );
00849 
00850     uint w = 0, l = 0;
00851     uint cost = 0;
00852 
00853     OPENCITY_SWAP( W1, W2, uint );
00854     OPENCITY_SWAP( L1, L2, uint );
00855 
00856     rCost = 0;
00857 
00858 // is the area road constructive ?
00859 // which is the largest side ?
00860     if (W2 - W1 >= L2 - L1) {
00861     // we test the largest side first
00862         for (w = W1; w < W2; w++)
00863             if (_IsPathConstructive( w, L1, enumStructCode ) == false)
00864                 return OC_ERR_SOMETHING;
00865     // we test the rest
00866         for (l = L1; l <= L2; l++)
00867             if (_IsPathConstructive( W2, l, enumStructCode ) == false)
00868                 return OC_ERR_SOMETHING;
00869     }
00870     else {
00871     // we test the largest side first
00872         for (l = L1; l < L2; l++)
00873             if (_IsPathConstructive( W1, l, enumStructCode ) == false)
00874                 return OC_ERR_SOMETHING;
00875     // we test the rest
00876         for (w = W1; w <= W2; w++)
00877             if (_IsPathConstructive( w, L2, enumStructCode ) == false)
00878                 return OC_ERR_SOMETHING;
00879     }
00880 
00881 
00882 // it's OK, let's GO !
00883     uint linearIndex = 0;
00884 
00885     if (W2 - W1 >= L2 - L1) {
00886     // we build the largest side first
00887         linearIndex = (L1*_uiLayerWidth) + W1;
00888         for (w = W1; w < W2; w++, linearIndex++) {
00889             _BuildPathStructure( w, L1, linearIndex, enumStructCode, cost );
00890             rCost += cost;
00891         }
00892 
00893     // then we build the rest
00894 // this is already calculated by the previous "for"
00895 //      linearIndex = (L1*_uiLayerWidth) + W2;
00896         for (l = L1; l <= L2; l++, linearIndex += _uiLayerWidth) {
00897             _BuildPathStructure( W2, l, linearIndex, enumStructCode, cost );
00898             rCost += cost;
00899         }
00900     }
00901     else {
00902     // we build the largest side first
00903         linearIndex = (L1*_uiLayerWidth) + W1;
00904         for (l = L1; l < L2; l++, linearIndex += _uiLayerWidth) {
00905             _BuildPathStructure( W1, l, linearIndex, enumStructCode, cost );
00906             rCost += cost;
00907         }
00908 
00909     // then we build the rest
00910 // this is already calculated by the previous "for"
00911 //      linearIndex = (L2*_uiLayerWidth) + W1;
00912         for (w = W1; w <= W2; w++, linearIndex++) {
00913             _BuildPathStructure( w, L2, linearIndex, enumStructCode, cost );
00914             rCost += cost;
00915         }
00916     }
00917 
00918     return OC_ERR_FREE;
00919 }
00920 
00921 
00922    /*=====================================================================*/
00923 void
00924 BuildingLayer::_BuildPathStructure(
00925     const uint & w,
00926     const uint & l,
00927     const uint & linearIndex,
00928     const OPENCITY_STRUCTURE_CODE & enumStructCode,
00929     uint& rCost )
00930 {
00931     Structure* pstructNeighbour             = NULL;
00932     PathStructure* ppathstructNeighbour     = NULL;
00933     PathStructure* pNewStructure            = NULL;
00934     uint nW = 0, nL = 0;
00935 
00936 
00937 // IF there's already something, THEN we return
00938     if (_tabpStructure[linearIndex] != NULL) {
00939         rCost = 0;
00940         return;
00941     }
00942 
00943 // Build the new road
00944     pNewStructure = new PathStructure(enumStructCode);
00945     rCost = gVars.gpPropertyMgr->Get( OC_BUILD_COST, enumStructCode );
00946     _tabpStructure[ linearIndex ] = pNewStructure;
00947 
00948 // Get the neighbour in the North
00949     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nL, OC_DIR_N ) == true) {
00950         pstructNeighbour = BuildingLayer::GetStructure( nW, nL );
00951     // if the neighbour is a road structure
00952     // then add this new road structure as its new neighbour
00953     // we do the same with the new road structure
00954         if ( (pstructNeighbour != NULL)
00955            &&(pstructNeighbour->GetCode() == enumStructCode)) {
00956 //debug cout << "found 1 neighbour in the North" << endl;
00957             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
00958             ppathstructNeighbour->AddNeighbour(
00959                 *pNewStructure, OC_DIR_S );
00960             pNewStructure->AddNeighbour(
00961                 *ppathstructNeighbour, OC_DIR_N );
00962         }
00963     }
00964 
00965 // Get the neighbour in the South
00966     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nL, OC_DIR_S ) == true) {
00967         pstructNeighbour = BuildingLayer::GetStructure( nW, nL );
00968         if ( (pstructNeighbour != NULL)
00969            &&(pstructNeighbour->GetCode() == enumStructCode)) {
00970             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
00971             ppathstructNeighbour->AddNeighbour(
00972                 *pNewStructure, OC_DIR_N );
00973             pNewStructure->AddNeighbour(
00974                 *ppathstructNeighbour, OC_DIR_S );
00975         }
00976     }
00977 
00978 // Get the neighbour in the West
00979     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nL, OC_DIR_W ) == true) {
00980         pstructNeighbour = BuildingLayer::GetStructure( nW, nL );
00981         if ( (pstructNeighbour != NULL)
00982            &&(pstructNeighbour->GetCode() == enumStructCode)) {
00983             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
00984             ppathstructNeighbour->AddNeighbour(
00985                 *pNewStructure, OC_DIR_E );
00986             pNewStructure->AddNeighbour(
00987                 *ppathstructNeighbour, OC_DIR_W );
00988         }
00989     }
00990 
00991 // Get the neighbour in the East
00992     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nL, OC_DIR_E ) == true) {
00993         pstructNeighbour = BuildingLayer::GetStructure( nW, nL );
00994     // if the neighbour is a road structure
00995     // then add this new road structure as its new neighbour
00996     // we do the same with the new road structure
00997         if ( (pstructNeighbour != NULL)
00998            &&(pstructNeighbour->GetCode() == enumStructCode)) {
00999             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
01000             ppathstructNeighbour->AddNeighbour(
01001                 *pNewStructure, OC_DIR_W );
01002             pNewStructure->AddNeighbour(
01003                 *ppathstructNeighbour, OC_DIR_E );
01004         }
01005     }
01006 }
01007 
01008 
01009    /*=====================================================================*/
01010 const OPENCITY_ERR_CODE
01011 BuildingLayer::_BuildRCIStructure(
01012     uint W1, uint L1,
01013     uint W2, uint L2,
01014     const OPENCITY_STRUCTURE_CODE & enumStructCode,
01015     uint& rCost )
01016 {
01017     OPENCITY_DEBUG( "I'm building some RCI structures" );
01018 
01019     static uint w, l;
01020     static uint linearIndex;
01021     static int cost;
01022 
01023 
01024     OPENCITY_SWAP( W1, W2, uint );
01025     OPENCITY_SWAP( L1, L2, uint );
01026 
01027 //debug testing
01028 //cout << "size of RCIStructure is: " << sizeof( RCIStructure ) << endl;
01029 
01030     rCost = 0;
01031     cost = gVars.gpPropertyMgr->Get( OC_BUILD_COST, enumStructCode );
01032 
01033 // Let's GO !
01034     l = L1;
01035     while (l <= L2) {
01036         linearIndex = (l*_uiLayerWidth) + W1;
01037         w = W1;
01038         while (w <= W2) {
01039             if ((_tabpStructure[ linearIndex ] == NULL)
01040              && (gVars.gpMapMgr->IsSquarePlane(w, l) == true )) {
01041                 _tabpStructure[ linearIndex ] = new RCIStructure(enumStructCode);
01042                 rCost += cost;
01043             }
01044             w++;
01045             linearIndex++;
01046         } // while w
01047         l++;
01048     } // while l
01049 
01050     return (rCost > 0) ? OC_ERR_FREE : OC_ERR_SOMETHING;
01051 }
01052 
01053 
01054    /*=====================================================================*/
01055 const OPENCITY_ERR_CODE
01056 BuildingLayer::_BuildFloraStructure(
01057     uint W1, uint L1,
01058     uint W2, uint L2,
01059     const OPENCITY_STRUCTURE_CODE & enumStructCode,
01060     uint& rCost )
01061 {
01062     OPENCITY_DEBUG( "I'm building some flora structures" );
01063 
01064     static uint w, l;
01065     static uint linearIndex;
01066     static int cost;
01067 
01068 
01069     OPENCITY_SWAP( W1, W2, uint );
01070     OPENCITY_SWAP( L1, L2, uint );
01071 
01072 //debug testing
01073 //cout << "size of RCIStructure is: " << sizeof( RCIStructure ) << endl;
01074 
01075     rCost = 0;
01076     cost = gVars.gpPropertyMgr->Get( OC_BUILD_COST, enumStructCode );
01077 
01078 // Let's GO !
01079     l = L1;
01080     while (l <= L2) {
01081         linearIndex = (l*_uiLayerWidth) + W1;
01082         w = W1;
01083         while (w <= W2) {
01084             if ((_tabpStructure[ linearIndex ] == NULL)
01085              && (gVars.gpMapMgr->IsSquarePlane(w, l) == true )) {
01086                 _tabpStructure[ linearIndex ] = new TreeStructure(enumStructCode);
01087                 rCost += cost;
01088             }
01089             w++;
01090             linearIndex++;
01091         } // while w
01092         l++;
01093     } // while l
01094 
01095     return (rCost > 0) ? OC_ERR_FREE : OC_ERR_SOMETHING;
01096 }
01097 
01098 
01099    /*=====================================================================*/
01100 const OPENCITY_ERR_CODE
01101 BuildingLayer::_BuildWEGStructure(
01102     uint W1, uint L1,
01103     const OPENCITY_STRUCTURE_CODE & enumStructCode,
01104     uint& rCost )
01105 {
01106     OPENCITY_DEBUG( "I'm building some WEG structures" );
01107 
01108     uint W2, L2;
01109     uint sw, sl, sh;                // Structure's width, length and height
01110     OPENCITY_GRAPHIC_CODE gcode;
01111 
01112 // Get the graphic code of the structure
01113     gcode = gVars.gpPropertyMgr->GetGC( enumStructCode );
01114     if ( gcode == OC_EMPTY ) {
01115         OPENCITY_DEBUG( "WARNING: not implemented" );
01116         assert(0);
01117     }
01118 
01119 // Get the corresponding WLH and calculate the range
01120 // NOTE: An coal electric plant is 4x4 size by default
01121     gVars.gpPropertyMgr->GetWLH( gcode, sw, 4, sl, 4, sh, 1 );
01122     W2 = W1 + sw - 1;
01123     L2 = L1 + sl - 1;
01124 
01125 // Isn't there enough space ?
01126 // OR is there already something on the surface ?
01127     if (IsConstructive(W1, L1, W2, L2, enumStructCode) == false) {
01128         return OC_ERR_SOMETHING;
01129     }
01130 
01131 // Let's do it
01132     _BuildWEGStructure( W1, L1, W2, L2, enumStructCode, rCost );
01133 
01134     return OC_ERR_FREE;
01135 }
01136 
01137 
01138    /*=====================================================================*/
01139 void
01140 BuildingLayer::_BuildWEGStructure(
01141     uint W1, uint L1,
01142     uint W2, uint L2,
01143     const OPENCITY_STRUCTURE_CODE & enumStructCode,
01144     uint& rCost )
01145 {
01146     uint w, l;
01147     Structure* pNewStructure, *pMainStructure;
01148     uint linearIndex;
01149 
01150 // Create the main structure first, but we don't insert it
01151     pMainStructure = new WEGStructure( enumStructCode );
01152     rCost = gVars.gpPropertyMgr->Get( OC_BUILD_COST, enumStructCode );
01153 
01154 // Create all the area as parts of a bigger main structure
01155     l = L1;
01156     while (l <= L2) {
01157         linearIndex = (l*_uiLayerWidth) + W1;
01158         w = W1;
01159         while (w <= W2) {
01160         // Build new WEG as a structure part
01161             _tabpStructure[ linearIndex++ ] =
01162                 new Structure( OC_STRUCTURE_PART, pMainStructure );
01163 //              new WEGStructure( OC_STRUCTURE_PART, pMainStructure );
01164             w++;
01165             // linearIndex++; already done
01166         }
01167         l++;
01168     }
01169 
01170 // Delete the part structure at the coordinates W1,L1
01171     linearIndex = (L1*_uiLayerWidth) + W1;
01172     pNewStructure = _tabpStructure[ linearIndex ];
01173     delete pNewStructure;
01174 // Put the main structure upon it
01175     _tabpStructure[ linearIndex ] = pMainStructure;
01176 }
01177 
01178 
01179    /*=====================================================================*/
01180 void
01181 BuildingLayer::_LoadStructure(
01182     const uint & w1,
01183     const uint & l1,
01184     Structure* pMainStruct )
01185 {
01186     OPENCITY_DEBUG( "Loading some structures" );
01187 
01188     uint w = 0, l = 0, w2 = 0, l2 = 0;
01189     uint sw = 0, sl = 0, sh = 0;                // Structure's width, length and height
01190     OPENCITY_GRAPHIC_CODE gcode = OC_EMPTY;
01191     uint linearIndex = 0;
01192 
01193 // Get the graphic code of the structure
01194     gcode = pMainStruct->GetGraphicCode();
01195     if ( gcode == OC_EMPTY ) {
01196         OPENCITY_DEBUG( "WARNING: not implemented" );
01197         assert(0);
01198     }
01199 
01200 // Get the corresponding WLH and calculate the range
01201 // NOTE: An coal electric plant is 4x4 size by default
01202     gVars.gpPropertyMgr->GetWLH( gcode, sw, 1, sl, 1, sh, 1 );
01203     w2 = w1 + sw - 1;
01204     l2 = l1 + sl - 1;
01205 
01206 // Create all the area as parts of a bigger main structure
01207     if (sw > 1 || sl > 1 || sh > 1) {
01208         l = l1;
01209         while (l <= l2) {
01210             linearIndex = (l*_uiLayerWidth) + w1;
01211             w = w1;
01212             while (w <= w2) {
01213             // Build new WEG as a structure part
01214                 _tabpStructure[ linearIndex++ ] =
01215                     new Structure( OC_STRUCTURE_PART, pMainStruct );
01216                 w++;
01217                 // linearIndex++; already done
01218             }
01219             l++;
01220         }
01221     
01222     // Delete the part structure at the coordinates W1, L1
01223         delete _tabpStructure[ (l1*_uiLayerWidth) + w1 ];
01224     }
01225 
01226 // Put the main structure at W1, L1
01227     _tabpStructure[ (l1*_uiLayerWidth) + w1 ] = pMainStruct;
01228 }
01229 
01230 
01231    /*=====================================================================*/
01232 const OPENCITY_ERR_CODE
01233 BuildingLayer::_DestroyStructure(
01234     const uint & w,
01235     const uint & l,
01236     uint& rCost )
01237 {
01238     uint linearIndex = (l*_uiLayerWidth) + w;
01239     Structure* pstruct, *pstructMain;
01240     uint dw1 = w, dl1 = l, dw2 = w, dl2 = l;
01241     uint tempW, tempL;
01242     uint sw, sl, sh;                // Structure's width, length and height
01243     OPENCITY_ERR_CODE errCode;
01244 
01245 // The fund used to destroy this structure
01246     rCost = 0;
01247 
01248 // Get the structure, if there is nothing, we return error
01249     pstruct = _tabpStructure[ linearIndex ];
01250     if ( pstruct == NULL )
01251         return OC_ERR_SOMETHING;
01252 
01253     rCost = gVars.gpPropertyMgr->Get( OC_DESTROY_COST, pstruct->GetCode(), pstruct );
01254 
01255 // The main structure is pstruct itself
01256     pstructMain = pstruct;
01257     errCode = OC_ERR_FREE;
01258     switch ( pstruct->GetCode() ) {
01259         case OC_STRUCTURE_PART:
01260         // We get the main structure otherwise
01261             pstructMain = pstruct->GetMain();
01262         case OC_STRUCTURE_RES:
01263         case OC_STRUCTURE_COM:
01264         case OC_STRUCTURE_IND:
01265 
01266         case OC_STRUCTURE_PARK:
01267         case OC_STRUCTURE_FLORA:
01268         case OC_STRUCTURE_TEST:
01269         case OC_STRUCTURE_FIREDEPT:
01270         case OC_STRUCTURE_POLICEDEPT:
01271         case OC_STRUCTURE_HOSPITALDEPT:
01272         case OC_STRUCTURE_EDUCATIONDEPT:
01273         case OC_STRUCTURE_EPLANT_COAL:
01274         // Get the width, length and height of the main structure
01275         // WARNING: invalid default values given.
01276             gVars.gpPropertyMgr->GetWLH( pstructMain->GetGraphicCode(), sw, 0, sl, 0, sh, 0 );
01277             assert( (sw != 0) && (sl != 0) );
01278             sw--; sl--;         // We calculate the range
01279 
01280         // Calculate the possible area to limit cpu usage
01281             gVars.gpMapMgr->GetPossibleWH( dw1, dl1, -sw, -sl );
01282             gVars.gpMapMgr->GetPossibleWH( dw2, dl2,  sw,  sl );
01283         // Now search for all STRUCTURE_PART and the main structure, destroy em
01284             for ( tempL = dl1; tempL <= dl2; tempL++ ) {
01285                 linearIndex = tempL*_uiLayerWidth + dw1;
01286                 for ( tempW = dw1; tempW <= dw2; tempW++ ) {
01287 //debug cout << "Hi coco " << endl;
01288                 // WARNING: pointer comparaison !
01289                     pstruct = _tabpStructure[ linearIndex ];
01290                     if ( pstruct != NULL )
01291                     if (( pstruct->GetMain() == pstructMain )
01292                      || (pstruct == pstructMain)) {
01293                         _tabpStructure[ linearIndex ] = NULL;
01294                         delete pstruct;
01295 //debug cout << "coco died" << endl;
01296                     }
01297                     linearIndex++;
01298                 }
01299             }
01300             break;
01301 
01302         case OC_STRUCTURE_ELINE:
01303         case OC_STRUCTURE_ROAD:
01304             errCode = _DestroyPathStructure(
01305                     w, l, pstruct->GetCode() );
01306             break;
01307 
01308         default:
01309             errCode = OC_ERR_SOMETHING;
01310             OPENCITY_DEBUG( "WARNING: game design error" );
01311             assert( 0 );
01312     }
01313 
01314     return errCode;
01315 }
01316 
01317 
01318    /*=====================================================================*/
01319 const OPENCITY_ERR_CODE
01320 BuildingLayer::_DestroyPathStructure(
01321     uint w, uint l,
01322     const OPENCITY_STRUCTURE_CODE & enumStructCode )
01323 {
01324     Structure* pstruct, *pstructNeighbour;
01325     PathStructure* ppathstructNeighbour, *ppathstruct;
01326     uint nW, nH;
01327 
01328     pstruct = _tabpStructure[ l*_uiLayerWidth + w ];
01329 // this is not necessary because it's already checked by the user "Destroy"
01330     if (pstruct == NULL)
01331         return OC_ERR_SOMETHING;
01332 
01333     ppathstruct = (PathStructure*)pstruct;
01334 // get the neighbour in the North
01335     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nH, OC_DIR_N ) == true) {
01336         pstructNeighbour = BuildingLayer::GetStructure( nW, nH );
01337     // if the neighbour is a path structure
01338         if ( (pstructNeighbour != NULL)
01339            &&(pstructNeighbour->GetCode() == enumStructCode)) {
01340             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
01341             ppathstructNeighbour->RemoveNeighbour( *ppathstruct, OC_DIR_S );
01342         }
01343     }
01344 
01345 // get the neighbour in the South
01346     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nH, OC_DIR_S ) == true) {
01347         pstructNeighbour = BuildingLayer::GetStructure( nW, nH );
01348         if ( (pstructNeighbour != NULL)
01349            &&(pstructNeighbour->GetCode() == enumStructCode)) {
01350             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
01351             ppathstructNeighbour->RemoveNeighbour( *ppathstruct, OC_DIR_N );
01352         }
01353     }
01354 
01355 // get the neighbour in the West
01356     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nH, OC_DIR_W ) == true) {
01357         pstructNeighbour = BuildingLayer::GetStructure( nW, nH );
01358         if ( (pstructNeighbour != NULL)
01359            &&(pstructNeighbour->GetCode() == enumStructCode)) {
01360             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
01361             ppathstructNeighbour->RemoveNeighbour( *ppathstruct, OC_DIR_E );
01362         }
01363     }
01364 
01365 // get the neighbour in the East
01366     if (gVars.gpMapMgr->GetNeighbourWH( w, l, nW, nH, OC_DIR_E ) == true) {
01367         pstructNeighbour = BuildingLayer::GetStructure( nW, nH );
01368         if ( (pstructNeighbour != NULL)
01369            &&(pstructNeighbour->GetCode() == enumStructCode)) {
01370             ppathstructNeighbour = (PathStructure*)pstructNeighbour;
01371             ppathstructNeighbour->RemoveNeighbour( *ppathstruct, OC_DIR_W );
01372         }
01373     }
01374 
01375     delete pstruct;
01376     _tabpStructure[ l*_uiLayerWidth + w ] = NULL;
01377 
01378     return OC_ERR_FREE;
01379 }
01380 
01381 
01382 
01383 
01384 
01385 
01386 
01387 
01388 
01389 
01390 
01391 
01392 
01393 
01394 
01395 
01396 
01397 
01398 
01399 
01400 
01401 
01402 
01403 
01404 
01405 
01406 
01407 
01408 
01409 
01410 
01411 
01412 
01413 
01414 
01415 
01416 

Generated on Sat Nov 11 10:21:09 2006 for OpenCity by  doxygen 1.4.2