00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "city.h"
00021 #include "vehicle.h"
00022 #include "mainsim.h"
00023 #include "structure.h"
00024 #include "buildinglayer.h"
00025 #include "guibutton.h"
00026 #include "guicontainer.h"
00027 #include "agentpolice.h"
00028 #include "agentdemonstrator.h"
00029 #include "agentrobber.h"
00030
00031 #include "globalvar.h"
00032 extern GlobalVar gVars;
00033
00034 #include <sstream>
00035
00036 #define OC_ACTION_FACTOR 10
00037
00038
00039
00040 City::City(
00041 const uint width,
00042 const uint length,
00043 const OC_DATE foundedDate,
00044 const int difficulty ):
00045 strCityName("OpenCity"),
00046 iDifficulty( difficulty ),
00047 strFileName(""),
00048 cityFoundedDate( foundedDate ),
00049 _liCityFund( OC_FUND_START ),
00050 boolModified( false ),
00051
00052 _uiDay( 1 ),
00053 _uiMonth( 1 ),
00054 _uiYear( 0 ),
00055
00056 _cTool('N'),
00057 _uiWidth( width ),
00058 _uiLength( length ),
00059
00060 boolLMBPressed( false ),
00061 enumCurrentLayer( BUILDING_LAYER ),
00062 enumCurrentSpeed( NORMAL_SPEED ),
00063 enumCurrentTool( OC_NONE )
00064 {
00065 OPENCITY_DEBUG( "City ctor - default parameters" );
00066
00067
00068 iWinWidth = SDL_GetVideoSurface()->w;
00069 iWinHeight = SDL_GetVideoSurface()->h;
00070
00071
00072 ocSetNewUI( this );
00073
00074
00075 for (int i = 0; i < KEY_NUMBER; i++)
00076 this->booltabKeyPressed[i] = false;
00077
00078
00079 ptabLayer[ BUILDING_LAYER ] = new BuildingLayer( *this );
00080 gVars.gpMapMgr->SetLayer( ptabLayer[BUILDING_LAYER] );
00081
00082
00083 gVars.gpPathFinder = new PathFinder(
00084 gVars.gpmutexSim,
00085 (BuildingLayer*)ptabLayer[ BUILDING_LAYER ],
00086 gVars.gpMapMgr,
00087 _uiWidth, _uiLength );
00088
00089
00090 boolPathGo = false;
00091 uiPathStartW = 0; uiPathStartH = 0;
00092 uiPathStopW = 0; uiPathStopH = 0;
00093 pctrPath = new GUIContainer( 100, 100, 140, 140 );
00094 pbtnPathStart = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/raise" ));
00095 pbtnPathStop1 = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/lower" ));
00096 pbtnPathStop2 = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/lower" ));
00097 pbtnTestBuilding = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/residential" ));
00098 pctrPath->Add( pbtnPathStart );
00099 pctrPath->Add( pbtnPathStop1 );
00100 pctrPath->Add( pbtnPathStop2 );
00101 pctrPath->Add( pbtnTestBuilding );
00102 pvehicle = NULL;
00103
00104
00105
00106 _CreateSimulator();
00107
00108
00109 _CreateGUI();
00110 }
00111
00112
00113
00114 City::~City( ){
00115 OPENCITY_DEBUG( "City dtor" );
00116
00117
00118 _DeleteGUI();
00119
00120
00121 _DeleteSimulator();
00122
00123
00124 delete pctrPath;
00125 delete pbtnTestBuilding;
00126 delete pbtnPathStart;
00127 delete pbtnPathStop1;
00128 delete pbtnPathStop2;
00129 delete gVars.gpPathFinder;
00130 gVars.gpPathFinder = NULL;
00131
00132
00133
00134
00135 delete ptabLayer[ BUILDING_LAYER ];
00136
00137
00138 }
00139
00140
00141
00142 void
00143 City::SaveTo( std::fstream& rfs )
00144 {
00145 OPENCITY_DEBUG( __PRETTY_FUNCTION__ << "saving" );
00146
00147 rfs << _liCityFund << std::ends;
00148 rfs << _uiDay << std::ends;
00149 rfs << _uiMonth << std::ends;
00150 rfs << _uiYear << std::ends;
00151 rfs << _uiWidth << std::ends;
00152 rfs << _uiLength << std::ends;
00153 }
00154
00155
00156
00157 void
00158 City::LoadFrom( std::fstream& rfs )
00159 {
00160 OPENCITY_DEBUG( __PRETTY_FUNCTION__ << "loading" );
00161
00162 rfs >> _liCityFund; rfs.ignore();
00163 rfs >> _uiDay; rfs.ignore();
00164 rfs >> _uiMonth; rfs.ignore();
00165 rfs >> _uiYear; rfs.ignore();
00166 rfs >> _uiWidth; rfs.ignore();
00167 rfs >> _uiLength; rfs.ignore();
00168 }
00169
00170
00171
00172 void City::SetCurrentLayer( OPENCITY_CITY_LAYER enumNewLayer )
00173 {}
00174
00175
00176
00177 void City::Run( OPENCITY_CITY_SPEED enumSpeed )
00178 {
00179 static uint uiNumberFrame = 0;
00180 static ostringstream ossStatus;
00181 static bool boolKeyDown;
00182 static int iMouseX, iMouseY;
00183
00184
00185 if (enumSpeed != LAST_SPEED) {
00186 enumCurrentSpeed = enumSpeed;
00187 }
00188
00189
00190 boolKeyDown = _HandleKeyPressed();
00191
00192
00193 _HandleMouseXY();
00194
00195
00196
00197
00198
00199 if ((this->boolLMBPressed == true)
00200 && (enumCurrentTool != OC_NONE )) {
00201
00202 if ( SDL_GetMouseState( &iMouseX, &iMouseY ) & SDL_BUTTON(1) ) {
00203 gVars.gpRenderer->GetSelectedWHFrom(
00204 iMouseX, iMouseY,
00205 this->uiMapW2, this->uiMapL2,
00206 gVars.gpMapMgr, this->ptabLayer[ enumCurrentLayer ] );
00207
00208
00209 gVars.gpRenderer->DisplayHighlight(
00210 gVars.gpMapMgr, ptabLayer[ enumCurrentLayer ],
00211 this->uiMapW1, this->uiMapL1,
00212 this->uiMapW2, this->uiMapL2,
00213 enumCurrentTool );
00214
00215 goto cityrun_swap;
00216 }
00217 }
00218
00219
00220
00221
00222 gVars.gpRenderer->Display( gVars.gpMapMgr, ptabLayer[ enumCurrentLayer ] );
00223
00224
00225 cityrun_swap:
00226
00227 _BuildPreview();
00228
00229
00230 ossStatus.str("");
00231 ossStatus << _liCityFund << " @";
00232 gVars.gpRenderer->DisplayText( 10, this->iWinHeight-15, OC_WHITE_COLOR, ossStatus.str() );
00233
00234 ossStatus.str("");
00235 ossStatus << _pMSim->GetValue(MainSim::OC_MICROSIM_RES);
00236 gVars.gpRenderer->DisplayText( 120, this->iWinHeight-15, OC_GREEN_COLOR, ossStatus.str() );
00237
00238 ossStatus.str("");
00239 ossStatus << _pMSim->GetValue(MainSim::OC_MICROSIM_COM);
00240 gVars.gpRenderer->DisplayText( 180, this->iWinHeight-15, OC_BLUE_COLOR, ossStatus.str() );
00241
00242 ossStatus.str("");
00243 ossStatus << _pMSim->GetValue(MainSim::OC_MICROSIM_IND);
00244 gVars.gpRenderer->DisplayText( 240, this->iWinHeight-15, OC_YELLOW_COLOR, ossStatus.str() );
00245
00246 ossStatus.str("");
00247 ossStatus << _pMSim->GetValue(MainSim::OC_MICROSIM_ELE);
00248 gVars.gpRenderer->DisplayText( 300, this->iWinHeight-15, OC_PINK_COLOR, ossStatus.str() );
00249
00250
00251 ossStatus.str("");
00252 ossStatus << "Tool: " << _cTool;
00253 gVars.gpRenderer->DisplayText( 550, this->iWinHeight-15, OC_WHITE_COLOR, ossStatus.str() );
00254
00255
00256 ossStatus.str("");
00257 ossStatus << _uiDay << "/" << _uiMonth << "/" << _uiYear;
00258 gVars.gpRenderer->DisplayText( 650, this->iWinHeight-15, OC_WHITE_COLOR, ossStatus.str() );
00259
00260
00261
00262 gVars.gpMoveMgr->Move();
00263 gVars.gpMoveMgr->Display();
00264
00265
00266
00267
00268
00269 pctr->Display();
00270
00271
00272 SDL_GL_SwapBuffers();
00273
00274
00275 if ( ++uiNumberFrame*gVars.guiMsPerFrame > OC_MS_PER_DAY ) {
00276
00277 if ( ++_uiDay > 30 ) {
00278
00279 _uiDay = 1;
00280 if ( ++_uiMonth > 12 ) {
00281
00282 _uiMonth = 1;
00283 _uiYear++;
00284 _DoBill( OC_INCOME );
00285 }
00286 else {
00287 _DoBill( OC_MAINTENANCE_COST );
00288 }
00289 }
00290 uiNumberFrame = 0;
00291
00292
00293 if (gVars.gpAudioMgr->PlayingMusic() == false) {
00294 gVars.gpAudioMgr->PlayNextMusic();
00295 }
00296 }
00297
00298 }
00299
00300
00301
00302 Layer*
00303 City::GetLayer( OPENCITY_CITY_LAYER enumLayer ) const
00304 {
00305 return this->ptabLayer[ enumLayer ];
00306 }
00307
00308
00309
00310 const void
00311 City::GetWL(
00312 uint & w, uint & l ) const
00313 {
00314 w = _uiWidth;
00315 l = _uiLength;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 void City::uiKeyboard(
00327 const SDL_KeyboardEvent & rcsSDLKeyboardEvent )
00328 {
00329
00330
00331
00332 if (rcsSDLKeyboardEvent.type == SDL_KEYDOWN) {
00333
00334 if (rcsSDLKeyboardEvent.keysym.mod & KMOD_ALT) {
00335 this->booltabKeyPressed[KEY_ALT] = true;
00336 }
00337
00338
00339 switch (rcsSDLKeyboardEvent.keysym.sym) {
00340 case SDLK_PAGEUP:
00341 this->booltabKeyPressed[KEY_PAGEUP] = true;
00342 break;
00343 case SDLK_PAGEDOWN:
00344 this->booltabKeyPressed[KEY_PAGEDOWN] = true;
00345 break;
00346
00347 case SDLK_UP:
00348 this->booltabKeyPressed[KEY_UP] = true;
00349 break;
00350 case SDLK_DOWN:
00351 this->booltabKeyPressed[KEY_DOWN] = true;
00352 break;
00353 case SDLK_RIGHT:
00354 this->booltabKeyPressed[KEY_RIGHT] = true;
00355 break;
00356 case SDLK_LEFT:
00357 this->booltabKeyPressed[KEY_LEFT] = true;
00358 break;
00359
00360
00361 case SDLK_t:
00362 OPENCITY_NET_CODE netCode;
00363 netCode = gVars.gpNetworking->Open( gVars.gsZenServer );
00364 switch (netCode) {
00365 case OC_NET_CLIENT_CONNECTED:
00366 OPENCITY_INFO( "OpenCity is already connected to a server." );
00367 break;
00368 case OC_NET_CLIENT_ACCEPTED:
00369 OPENCITY_INFO( "The connection request has been accepted." );
00370 break;
00371 case OC_NET_CLIENT_REJECTED:
00372 OPENCITY_INFO( "The connection request has been rejected. Is the server full ?" );
00373 break;
00374 default:
00375 OPENCITY_INFO( "The connection to \"" << gVars.gsZenServer << "\" has failed." );
00376 }
00377 break;
00378
00379 case SDLK_n:
00380 enumCurrentTool = OC_NONE;
00381 _cTool = 'N';
00382 break;
00383 case SDLK_r:
00384 enumCurrentTool = OC_ZONE_RES;
00385 _cTool = 'R';
00386 break;
00387 case SDLK_c:
00388 enumCurrentTool = OC_ZONE_COM;
00389 _cTool = 'C';
00390 break;
00391 case SDLK_i:
00392 enumCurrentTool = OC_ZONE_IND;
00393 _cTool = 'I';
00394 break;
00395
00396 case SDLK_p:
00397 enumCurrentTool = OC_BUILD_ROAD;
00398 _cTool = 'P';
00399 break;
00400 case SDLK_l:
00401 enumCurrentTool = OC_BUILD_ELINE;
00402 _cTool = 'L';
00403 break;
00404 case SDLK_e:
00405 enumCurrentTool = OC_BUILD_EPLANT;
00406 _cTool = 'E';
00407 break;
00408
00409 case SDLK_u:
00410 enumCurrentTool = OC_HEIGHT_UP;
00411 _cTool = 'U';
00412 break;
00413 case SDLK_d:
00414 enumCurrentTool = OC_HEIGHT_DOWN;
00415 _cTool = 'D';
00416 break;
00417 case SDLK_q:
00418 enumCurrentTool = OC_QUERY;
00419 _cTool = 'Q';
00420 break;
00421
00422
00423 case SDLK_g:
00424 gVars.gpRenderer->ToggleGrid();
00425 break;
00426 case SDLK_k:
00427 gVars.gpRenderer->ToggleCompass();
00428 break;
00429 case SDLK_f:
00430 gVars.gpRenderer->ToggleWireFrame();
00431 break;
00432 case SDLK_o:
00433 gVars.gpRenderer->ToggleProjection();
00434 break;
00435
00436
00437 case SDLK_INSERT:
00438 this->booltabKeyPressed[KEY_INSERT] = true;
00439 break;
00440 case SDLK_DELETE:
00441 this->booltabKeyPressed[KEY_DELETE] = true;
00442 break;
00443
00444 case SDLK_x:
00445 enumCurrentTool = OC_DESTROY;
00446 _cTool = 'X';
00447 break;
00448
00449
00450
00451 case SDLK_b:
00452 gVars.gpAudioMgr->PlayNextMusic();
00453 break;
00454
00455 case SDLK_z:
00456 gVars.gpAudioMgr->PlayPreviousMusic();
00457 break;
00458
00459 case SDLK_s:
00460 gVars.gpAudioMgr->ToggleSound();
00461 break;
00462
00463 case SDLK_m:
00464 gVars.gpAudioMgr->ToggleMusic();
00465 break;
00466
00467
00468
00469 case SDLK_F2:
00470 _Save( ocSaveDirPrefix( "opencity.save" ) );
00471 break;
00472
00473 case SDLK_F6:
00474 _Load( ocSaveDirPrefix( "opencity.save" ) );
00475 break;
00476
00477
00478 case SDLK_h:
00479 gVars.gpRenderer->Home();
00480 break;
00481 case SDLK_ESCAPE:
00482
00483 ocQuit();
00484 break;
00485
00486 #ifndef NDEBUG
00487
00488 case SDLK_a:
00489 pctr->ResetAttribute(
00490 OC_GUIMAIN_CLICKED | OC_GUIMAIN_MOUSEOVER );
00491
00492 if ( pctr == pctrQ ) {
00493 pctr = NULL;
00494 delete pctrQ;
00495 pctrQ = NULL;
00496 }
00497
00498
00499 if ( pctr == pctrPath ) {
00500 pctr = pctrMain;
00501 }
00502 else {
00503 pctr = pctrPath;
00504 }
00505 if ( pctr->IsSet( OC_GUIMAIN_VISIBLE ) == false ) {
00506 pctr->Set( OC_GUIMAIN_VISIBLE );
00507 }
00508 break;
00509
00510
00511 case SDLK_v:
00512 pctr->ResetAttribute(
00513 OC_GUIMAIN_CLICKED | OC_GUIMAIN_MOUSEOVER );
00514
00515 if ( pctr == pctrQ ) {
00516 pctr = NULL;
00517 delete pctrQ;
00518 pctrQ = NULL;
00519 }
00520
00521
00522 if ( pctr == pctrMAS ) {
00523 pctr = pctrMain;
00524 }
00525 else {
00526 pctr = pctrMAS;
00527 }
00528 if ( pctr->IsSet( OC_GUIMAIN_VISIBLE ) == false ) {
00529 pctr->Set( OC_GUIMAIN_VISIBLE );
00530 }
00531 break;
00532 #endif
00533
00534 default:
00535 break;
00536 }
00537 }
00538
00539 else {
00540
00541 if (!(rcsSDLKeyboardEvent.keysym.mod & KMOD_ALT)) {
00542 this->booltabKeyPressed[KEY_ALT] = false;
00543 }
00544
00545
00546 switch (rcsSDLKeyboardEvent.keysym.sym) {
00547
00548 case SDLK_PAGEUP:
00549 this->booltabKeyPressed[KEY_PAGEUP] = false;
00550 break;
00551 case SDLK_PAGEDOWN:
00552 this->booltabKeyPressed[KEY_PAGEDOWN] = false;
00553 break;
00554
00555 case SDLK_UP:
00556 this->booltabKeyPressed[KEY_UP] = false;
00557 break;
00558 case SDLK_DOWN:
00559 this->booltabKeyPressed[KEY_DOWN] = false;
00560 break;
00561 case SDLK_RIGHT:
00562 this->booltabKeyPressed[KEY_RIGHT] = false;
00563 break;
00564 case SDLK_LEFT:
00565 this->booltabKeyPressed[KEY_LEFT] = false;
00566 break;
00567
00568 case SDLK_INSERT:
00569 this->booltabKeyPressed[KEY_INSERT] = false;
00570 break;
00571 case SDLK_DELETE:
00572 this->booltabKeyPressed[KEY_DELETE] = false;
00573 break;
00574
00575 default:
00576 break;
00577 }
00578 }
00579
00580 }
00581
00582
00583
00584 void
00585 City::uiMouseMotion(
00586 const SDL_MouseMotionEvent & rcsSDLMouseMotionEvent )
00587 {
00588
00589 pctr->uiMouseMotion( rcsSDLMouseMotionEvent );
00590 }
00591
00592
00593
00594 void
00595 City::uiMouseButton(
00596 const SDL_MouseButtonEvent & rcsMBE )
00597 {
00598
00599
00600
00601 pctr->uiMouseButton( rcsMBE );
00602 if ( pctr->GetClick() != 0 ) {
00603
00604
00605 _HandleGUIClick();
00606 this->boolLMBPressed = false;
00607 return;
00608 }
00609
00610
00611 switch (rcsMBE.state) {
00612 case SDL_PRESSED: {
00613 this->boolLMBPressed = false;
00614 if ((rcsMBE.button == SDL_BUTTON_LEFT)
00615 && (gVars.gpRenderer->GetSelectedWHFrom(
00616 rcsMBE.x, rcsMBE.y,
00617 this->uiMapW1, this->uiMapL1,
00618 gVars.gpMapMgr,
00619 this->ptabLayer[ enumCurrentLayer ] ) == true ))
00620 {
00621 this->boolLMBPressed = true;
00622
00623
00624
00625
00626 }
00627
00628
00629
00630
00631
00632
00633 if (rcsMBE.button == SDL_BUTTON_RIGHT) {
00634
00635
00636 if (pctr == pctrQ) {
00637 pctr = pctrMain;
00638
00639
00640
00641 pctr->Set( OC_GUIMAIN_VISIBLE );
00642 delete pctrQ;
00643 pctrQ = NULL;
00644 }
00645
00646 if (pctr->IsSet( OC_GUIMAIN_VISIBLE ) == true) {
00647 pctr->Unset( OC_GUIMAIN_VISIBLE );
00648 }
00649 else {
00650 pctr->SetLocation(
00651 rcsMBE.x - 70,
00652 iWinHeight - rcsMBE.y - 70 );
00653 pctr->Set( OC_GUIMAIN_VISIBLE );
00654 }
00655 }
00656
00657
00658 if (rcsMBE.button == 4) {
00659
00660 if (SDL_GetModState() & KMOD_CTRL)
00661 gVars.gpRenderer->MoveRight();
00662
00663
00664 if (SDL_GetModState() & KMOD_SHIFT)
00665 gVars.gpRenderer->MoveUp();
00666
00667
00668 if (!(SDL_GetModState() & (KMOD_SHIFT | KMOD_CTRL)))
00669 gVars.gpRenderer->ZoomIn();
00670 }
00671
00672
00673 if (rcsMBE.button == 5) {
00674
00675 if (SDL_GetModState() & KMOD_CTRL)
00676 gVars.gpRenderer->MoveLeft();
00677
00678
00679 if (SDL_GetModState() & KMOD_SHIFT)
00680 gVars.gpRenderer->MoveDown();
00681
00682
00683 if (!(SDL_GetModState() & (KMOD_SHIFT | KMOD_CTRL)))
00684 gVars.gpRenderer->ZoomOut();
00685 }
00686
00687 break;
00688 }
00689
00690
00691 case SDL_RELEASED: {
00692
00693
00694
00695
00696 if (!(SDL_GetModState() & KMOD_CTRL)
00697 && (this->boolLMBPressed == true)
00698 && gVars.gpRenderer->GetSelectedWHFrom(
00699 rcsMBE.x, rcsMBE.y,
00700 this->uiMapW2, this->uiMapL2,
00701 gVars.gpMapMgr,
00702 this->ptabLayer[ enumCurrentLayer ] ))
00703 {
00704
00705
00706
00707
00708 _TestPathfinding();
00709 _DoTool( rcsMBE );
00710 }
00711 boolLMBPressed = false;
00712 break;
00713
00714 }
00715
00716 }
00717 }
00718
00719
00720
00721 void
00722 City::uiExpose(
00723 const SDL_ExposeEvent & rcsSDLExposeEvent )
00724 {
00725 OPENCITY_DEBUG( "Expose event received" );
00726
00727 gVars.gpRenderer->Display( gVars.gpMapMgr, ptabLayer[ enumCurrentLayer ] );
00728 pctr->uiExpose( rcsSDLExposeEvent );
00729
00730 SDL_GL_SwapBuffers();
00731 }
00732
00733
00734
00735 void City::uiResize( const SDL_ResizeEvent & rcsSDLResizeEvent )
00736 {
00737 OPENCITY_DEBUG( "Resize event received" );
00738
00739 iWinWidth = rcsSDLResizeEvent.w;
00740 iWinHeight = rcsSDLResizeEvent.h;
00741
00742
00743 gVars.gpRenderer->SetWinSize( iWinWidth, iWinHeight );
00744
00745
00746
00747
00748
00749
00750 pctrMain->uiResize( rcsSDLResizeEvent );
00751 pctrL->uiResize( rcsSDLResizeEvent );
00752 pctrT->uiResize( rcsSDLResizeEvent );
00753 pctrZ->uiResize( rcsSDLResizeEvent );
00754 pctrG->uiResize( rcsSDLResizeEvent );
00755 pctrN->uiResize( rcsSDLResizeEvent );
00756 pctrS->uiResize( rcsSDLResizeEvent );
00757 pctrPath->uiResize( rcsSDLResizeEvent );
00758 pctrMAS->uiResize( rcsSDLResizeEvent );
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 void City::_CreateSimulator()
00787 {
00788
00789 _pMSim = new MainSim( gVars.gpmutexSim, (BuildingLayer*)ptabLayer[ BUILDING_LAYER ], gVars.gpMapMgr );
00790
00791
00792 _pthreadMSim = SDL_CreateThread( Simulator::ThreadWrapper, _pMSim );
00793
00794
00795
00796
00797
00798
00799
00800 _pMSim->Run();
00801 }
00802
00803
00804
00805 void
00806 City::_DeleteSimulator()
00807 {
00808 int iStatus;
00809
00810
00811 _pMSim->Return();
00812
00813
00814 SDL_WaitThread( _pthreadMSim, &iStatus );
00815
00816
00817 delete _pMSim;
00818 }
00819
00820
00821
00822 void
00823 City::_CreateGUI()
00824 {
00825
00826 pbtnZ = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/residential" ));
00827 pbtnS = new GUIButton( 100, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/save" ));
00828 pbtnL = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/power" ));
00829 pbtnP = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/road" ));
00830 pbtnX = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/bulldozer" ));
00831 pbtnG = new GUIButton( 60, 100, 30, 30, ocHomeDirPrefix( "graphism/gui/government" ));
00832
00833 pctrMain = new GUIContainer( 100, 100, 140, 140 );
00834 pctrMain->Add( pbtnZ );
00835 pctrMain->Add( pbtnS );
00836 pctrMain->Add( pbtnL );
00837 pctrMain->Add( pbtnP );
00838 pctrMain->Add( pbtnX );
00839 pctrMain->Add( pbtnG );
00840
00841
00842
00843 pbtnZB = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/back" ));
00844 pbtnZR = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/residential" ));
00845 pbtnZC = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/commercial" ));
00846 pbtnZI = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/industrial" ));
00847
00848 pctrZ = new GUIContainer( 100, 100, 140, 140 );
00849 pctrZ->Add( pbtnZB );
00850 pctrZ->Add( pbtnZR );
00851 pctrZ->Add( pbtnZC );
00852 pctrZ->Add( pbtnZI );
00853
00854
00855
00856 pbtnLB = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/back" ));
00857 pbtnLL = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/power_line" ));
00858 pbtnLE = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/power_plant" ));
00859
00860 pctrL = new GUIContainer( 100, 100, 140, 140 );
00861 pctrL->Add( pbtnLB );
00862 pctrL->Add( pbtnLL );
00863 pctrL->Add( pbtnLE );
00864
00865
00866
00867 pbtnTU = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/raise" ));
00868 pbtnTD = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/lower" ));
00869 pbtnTB = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/back" ));
00870 pbtnTX = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/destroy" ));
00871 pbtnTQ = new GUIButton( 100, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/query" ));
00872
00873 pctrT = new GUIContainer( 100, 100, 140, 140 );
00874 pctrT->Add( pbtnTB );
00875 pctrT->Add( pbtnTU );
00876 pctrT->Add( pbtnTD );
00877 pctrT->Add( pbtnTX );
00878 pctrT->Add( pbtnTQ );
00879
00880
00881
00882 pbtnGB = new GUIButton( 60, 100, 30, 30, ocHomeDirPrefix( "graphism/gui/back" ));
00883 pbtnGP = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/park" ));
00884 pbtnGE = new GUIButton( 100, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/education" ));
00885 pbtnGH = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/hospital" ));
00886 pbtnGL = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/police" ));
00887 pbtnGF = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/fire" ));
00888
00889 pctrG = new GUIContainer( 100, 100, 140, 140 );
00890 pctrG->Add( pbtnGB );
00891 pctrG->Add( pbtnGP );
00892 pctrG->Add( pbtnGE );
00893 pctrG->Add( pbtnGH );
00894 pctrG->Add( pbtnGL );
00895 pctrG->Add( pbtnGF );
00896
00897
00898
00899 pbtnNB = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/back" ));
00900 pbtnNP = new GUIButton( 60, 100, 30, 30, ocHomeDirPrefix( "graphism/gui/park" ));
00901 pbtnNT = new GUIButton( 100, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/tree" ));
00902
00903 pctrN = new GUIContainer( 100, 100, 140, 140 );
00904 pctrN->Add( pbtnNB );
00905 pctrN->Add( pbtnNP );
00906 pctrN->Add( pbtnNT );
00907
00908
00909
00910 pbtnSL = new GUIButton( 20, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/save_load" ));
00911 pbtnSS = new GUIButton( 60, 100, 30, 30, ocHomeDirPrefix( "graphism/gui/save_save" ));
00912 pbtnSB = new GUIButton( 100, 80, 30, 30, ocHomeDirPrefix( "graphism/gui/back" ));
00913
00914 pctrS = new GUIContainer( 100, 100, 140, 140 );
00915 pctrS->Add( pbtnSB );
00916 pctrS->Add( pbtnSS );
00917 pctrS->Add( pbtnSL );
00918
00919
00920
00921 pctrMAS = new GUIContainer( 100, 100, 140, 140 );
00922 pbtnMASPolice = new GUIButton( 20, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/police" ));
00923 pbtnMASDemonstrator = new GUIButton( 60, 0, 30, 30, ocHomeDirPrefix( "graphism/gui/demonstrator" ));
00924 pbtnMASRobber = new GUIButton( 100, 20, 30, 30, ocHomeDirPrefix( "graphism/gui/robber" ));
00925 pctrMAS->Add( pbtnMASPolice );
00926 pctrMAS->Add( pbtnMASDemonstrator );
00927 pctrMAS->Add( pbtnMASRobber );
00928
00929 pbtnMASRobber->Unset( OC_GUIMAIN_VISIBLE );
00930
00931
00932 pctr = pctrMain;
00933
00934
00935 pctrQ = NULL;
00936 }
00937
00938
00939
00940 void
00941 City::_DeleteGUI()
00942 {
00943
00944 if (pctrQ != NULL)
00945 delete pctrQ;
00946
00947
00948 delete pctrMAS;
00949 delete pbtnMASRobber;
00950 delete pbtnMASDemonstrator;
00951 delete pbtnMASPolice;
00952
00953
00954 delete pctrS;
00955 delete pbtnSB;
00956 delete pbtnSS;
00957 delete pbtnSL;
00958
00959
00960 delete pctrN;
00961 delete pbtnNB;
00962 delete pbtnNP;
00963 delete pbtnNT;
00964
00965
00966 delete pctrG;
00967 delete pbtnGB;
00968 delete pbtnGP;
00969 delete pbtnGE;
00970 delete pbtnGH;
00971 delete pbtnGL;
00972 delete pbtnGF;
00973
00974
00975 delete pctrT;
00976 delete pbtnTB;
00977 delete pbtnTU;
00978 delete pbtnTD;
00979 delete pbtnTX;
00980 delete pbtnTQ;
00981
00982
00983 delete pctrL;
00984 delete pbtnLB;
00985 delete pbtnLL;
00986 delete pbtnLE;
00987
00988
00989 delete pctrZ;
00990 delete pbtnZB;
00991 delete pbtnZR;
00992 delete pbtnZC;
00993 delete pbtnZI;
00994
00995
00996 delete pctrMain;
00997 delete pbtnZ;
00998 delete pbtnS;
00999 delete pbtnL;
01000 delete pbtnP;
01001 delete pbtnX;
01002 delete pbtnG;
01003 }
01004
01005
01006
01007 void
01008 City::_DoTool(
01009 const SDL_MouseButtonEvent & sdlMBEvent )
01010 {
01011 if ( enumCurrentTool == OC_NONE )
01012 return;
01013
01014 static uint cost;
01015 static OPENCITY_ERR_CODE enumErrCode;
01016 static int w1, h1, w2, h2;
01017
01018 Structure* pstruct = NULL;
01019
01020 cost = 0;
01021 w1 = uiMapW1;
01022 h1 = uiMapL1;
01023 w2 = uiMapW2;
01024 h2 = uiMapL2;
01025 OPENCITY_SWAP( w1, w2, int );
01026 OPENCITY_SWAP( h1, h2, int );
01027
01028
01029
01030 if (_liCityFund < 0)
01031 return;
01032
01033
01034
01035 SDL_LockMutex( gVars.gpmutexSim );
01036
01037 switch (this->enumCurrentTool) {
01038 case OC_ZONE_RES:
01039 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01040 BuildStructure(
01041 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01042 OC_STRUCTURE_RES, cost )) == OC_ERR_FREE) {
01043 gVars.gpAudioMgr->PlaySound( OC_SOUND_RCI );
01044 }
01045 break;
01046
01047 case OC_ZONE_COM:
01048 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01049 BuildStructure(
01050 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01051 OC_STRUCTURE_COM, cost )) == OC_ERR_FREE) {
01052 gVars.gpAudioMgr->PlaySound( OC_SOUND_RCI );
01053 }
01054 break;
01055
01056 case OC_ZONE_IND:
01057 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01058 BuildStructure(
01059 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01060 OC_STRUCTURE_IND, cost )) == OC_ERR_FREE) {
01061 gVars.gpAudioMgr->PlaySound( OC_SOUND_RCI );
01062 }
01063 break;
01064
01065 case OC_BUILD_ROAD:
01066 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01067 BuildStructure(
01068 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01069 OC_STRUCTURE_ROAD, cost )) == OC_ERR_FREE) {
01070 gVars.gpAudioMgr->PlaySound( OC_SOUND_ROAD );
01071 }
01072 break;
01073
01074 case OC_BUILD_ELINE:
01075 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01076 BuildStructure(
01077 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01078 OC_STRUCTURE_ELINE, cost )) == OC_ERR_FREE) {
01079 gVars.gpAudioMgr->PlaySound( OC_SOUND_ELINE );
01080 }
01081 break;
01082
01083 case OC_BUILD_EPLANT:
01084 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01085 BuildStructure(
01086 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01087 OC_STRUCTURE_EPLANT_COAL, cost )) == OC_ERR_FREE) {
01088 _pMSim->AddStructure( uiMapW1, uiMapL1, uiMapW2, uiMapL2, MainSim::OC_MICROSIM_ELE );
01089 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01090 }
01091 break;
01092
01093 case OC_BUILD_PARK:
01094 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01095 BuildStructure(
01096 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01097 OC_STRUCTURE_PARK, cost )) == OC_ERR_FREE) {
01098 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01099 }
01100 break;
01101
01102 case OC_BUILD_FLORA:
01103 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01104 BuildStructure(
01105 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01106 OC_STRUCTURE_FLORA, cost )) == OC_ERR_FREE) {
01107 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01108 }
01109 break;
01110
01111 case OC_BUILD_FIRE:
01112 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01113 BuildStructure(
01114 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01115 OC_STRUCTURE_FIREDEPT, cost )) == OC_ERR_FREE) {
01116
01117 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01118 }
01119 break;
01120
01121 case OC_BUILD_POLICE:
01122 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01123 BuildStructure(
01124 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01125 OC_STRUCTURE_POLICEDEPT, cost )) == OC_ERR_FREE) {
01126
01127 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01128 }
01129 break;
01130
01131 case OC_BUILD_HOSPITAL:
01132 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01133 BuildStructure(
01134 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01135 OC_STRUCTURE_HOSPITALDEPT, cost )) == OC_ERR_FREE) {
01136
01137 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01138 }
01139 break;
01140
01141 case OC_BUILD_EDUCATION:
01142 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01143 BuildStructure(
01144 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01145 OC_STRUCTURE_EDUCATIONDEPT, cost )) == OC_ERR_FREE) {
01146
01147 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01148 }
01149 break;
01150
01151 case OC_BUILD_TEST_BUILDING:
01152 if ((enumErrCode = ptabLayer[ enumCurrentLayer ]->
01153 BuildStructure(
01154 uiMapW1, uiMapL1, uiMapW2, uiMapL2,
01155 OC_STRUCTURE_TEST, cost )) == OC_ERR_FREE) {
01156 gVars.gpAudioMgr->PlaySound( OC_SOUND_EPLANT );
01157 }
01158 break;
01159
01160 case OC_BUILD_AGENT_POLICE:
01161 pstruct = ptabLayer[ BUILDING_LAYER ]->GetStructure( uiMapW1, uiMapL1 );
01162 if ((pstruct != NULL) && (pstruct->GetCode() == OC_STRUCTURE_ROAD))
01163 new AgentPolice(*gVars.gpKernel, *gVars.gpEnvironment, uiMapW1, uiMapL1);
01164 break;
01165
01166 case OC_BUILD_AGENT_DEMONSTRATOR:
01167 pstruct = ptabLayer[ BUILDING_LAYER ]->GetStructure( uiMapW1, uiMapL1 );
01168 if ((pstruct != NULL) && (pstruct->GetCode() == OC_STRUCTURE_ROAD))
01169 new AgentDemonstrator(*gVars.gpKernel, *gVars.gpEnvironment, uiMapW1, uiMapL1);
01170 break;
01171
01172 case OC_BUILD_AGENT_ROBBER:
01173 pstruct = ptabLayer[ BUILDING_LAYER ]->GetStructure( uiMapW1, uiMapL1 );
01174 if ((pstruct != NULL) && (pstruct->GetCode() == OC_STRUCTURE_ROAD))
01175 new AgentRobber(*gVars.gpKernel, *gVars.gpEnvironment, uiMapW1, uiMapL1);
01176 break;
01177
01178
01179 case OC_HEIGHT_UP:
01180 enumErrCode = gVars.gpMapMgr->ChangeHeight( uiMapW1, uiMapL1, OC_MAP_UP );
01181 if ( enumErrCode == OC_ERR_FREE ) {
01182 gVars.gpRenderer->boolHeightChange = true;
01183 cost = 5;
01184 }
01185 break;
01186
01187 case OC_HEIGHT_DOWN:
01188 enumErrCode = gVars.gpMapMgr->ChangeHeight( uiMapW1, uiMapL1, OC_MAP_DOWN );
01189 if ( enumErrCode == OC_ERR_FREE ) {
01190 gVars.gpRenderer->boolHeightChange = true;
01191 cost = 5;
01192 }
01193 break;
01194
01195 case OC_QUERY:
01196
01197
01198
01199 if (pctrQ != NULL)
01200 delete pctrQ;
01201
01202
01203 pctrQ = ptabLayer[ enumCurrentLayer ]->
01204 QueryStructure( uiMapW1, uiMapL1 );
01205
01206 pctr->ResetAttribute(
01207 OC_GUIMAIN_CLICKED | OC_GUIMAIN_MOUSEOVER );
01208 pctr->Unset( OC_GUIMAIN_VISIBLE );
01209
01210 pctr = pctrQ;
01211 pctr->SetLocation(
01212 sdlMBEvent.x - 70,
01213 iWinHeight - sdlMBEvent.y - 70 );
01214 pctr->Set( OC_GUIMAIN_VISIBLE );
01215 enumErrCode = OC_ERR_SOMETHING;
01216 break;
01217
01218 case OC_DESTROY:
01219
01220
01221
01222
01223 _pMSim->RemoveStructure( uiMapW1, uiMapL1, uiMapW2, uiMapL2 );
01224
01225 enumErrCode = ptabLayer[ enumCurrentLayer ]->
01226 DestroyStructure( uiMapW1, uiMapL1, uiMapW2, uiMapL2, cost );
01227 break;
01228
01229 default:
01230 enumErrCode = OC_ERR_SOMETHING;
01231 }
01232
01233
01234 SDL_UnlockMutex( gVars.gpmutexSim );
01235
01236 if (enumErrCode == OC_ERR_FREE) {
01237 _liCityFund -= cost;
01238 }
01239 }
01240
01241
01242
01243 bool
01244 City::_HandleKeyPressed()
01245 {
01246 static int actionFactor = 1;
01247 int key;
01248 bool boolKeyDown;
01249
01250 if (this->booltabKeyPressed[KEY_ALT] == true) {
01251 actionFactor = OC_ACTION_FACTOR;
01252 }
01253 else {
01254 actionFactor = 1;
01255 }
01256
01257
01258 boolKeyDown = false;
01259
01260
01261 for (key = KEY_UP; key < KEY_NUMBER; key++) {
01262 if (this->booltabKeyPressed[key] == true) {
01263 switch (key) {
01264 case KEY_UP:
01265 gVars.gpRenderer->MoveDown(actionFactor);
01266 break;
01267 case KEY_DOWN:
01268 gVars.gpRenderer->MoveUp(actionFactor);
01269 break;
01270 case KEY_RIGHT:
01271 gVars.gpRenderer->MoveLeft(actionFactor);
01272 break;
01273 case KEY_LEFT:
01274 gVars.gpRenderer->MoveRight(actionFactor);
01275 break;
01276
01277 case KEY_PAGEUP:
01278 gVars.gpRenderer->RotateLeft(actionFactor);
01279 break;
01280 case KEY_PAGEDOWN:
01281 gVars.gpRenderer->RotateRight(actionFactor);
01282 break;
01283
01284 case KEY_INSERT:
01285 gVars.gpRenderer->ZoomIn();
01286 break;
01287 case KEY_DELETE:
01288 gVars.gpRenderer->ZoomOut();
01289 break;
01290 }
01291
01292
01293 boolKeyDown = true;
01294 }
01295 }
01296
01297
01298 return boolKeyDown;
01299 }
01300
01301
01302
01303 void
01304 City::_DoBill(
01305 const OPENCITY_PROPERTY_CODE & enumProperty )
01306 {
01307 uint maintenance;
01308 uint index, surface;
01309 Structure* pStruct;
01310 static uint income = 0;
01311
01312 surface = _uiWidth * _uiLength;
01313 maintenance = 0;
01314 for (index = 0; index < surface; index++) {
01315 pStruct = ptabLayer[ BUILDING_LAYER ]->GetLinearStructure( index );
01316 if (pStruct != NULL)
01317 maintenance += gVars.gpPropertyMgr->Get(
01318 OC_MAINTENANCE_COST, pStruct->GetCode() );
01319 }
01320
01321 _liCityFund -= maintenance;
01322
01323
01324 income += (_pMSim->GetValue(MainSim::OC_MICROSIM_RES) * OC_R_INCOME_TAX / 100)
01325 + (_pMSim->GetValue(MainSim::OC_MICROSIM_COM) * OC_C_INCOME_TAX / 100)
01326 + (_pMSim->GetValue(MainSim::OC_MICROSIM_IND) * OC_I_INCOME_TAX / 100);
01327
01328
01329 if (enumProperty == OC_INCOME ) {
01330
01331 income += income * OC_INCOME_HELP / 100;
01332
01333 _liCityFund += income;
01334 income = 0;
01335 }
01336 }
01337
01338
01339
01340 void
01341 City::_HandleGUIClick()
01342 {
01343 uint uiObject;
01344 GUIContainer* pctrOld;
01345 int iX, iY;
01346
01347 pctrOld = pctr;
01348 uiObject = this->pctr->GetClick();
01349
01350
01351 if (pctr == pctrMain)
01352 switch (uiObject) {
01353 case 1:
01354 pctr = pctrZ;
01355 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01356 break;
01357 case 2:
01358 pctr = pctrS;
01359 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01360 break;
01361 case 3:
01362 pctr = pctrL;
01363 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01364 break;
01365 case 4:
01366 enumCurrentTool = OC_BUILD_ROAD;
01367 _cTool = 'P';
01368 break;
01369 case 5:
01370 pctr = pctrT;
01371 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01372 break;
01373 case 6:
01374 pctr = pctrG;
01375 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01376 break;
01377
01378 default:
01379 OPENCITY_DEBUG( "WARNING: What's going wrong ?" );
01380 assert(0);
01381 break;
01382 }
01383
01384
01385 else if (pctr == pctrZ )
01386 switch (uiObject) {
01387 case 1:
01388 pctr = pctrMain;
01389 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01390 break;
01391 case 2:
01392 enumCurrentTool = OC_ZONE_RES;
01393 _cTool = 'R';
01394 break;
01395 case 3:
01396 enumCurrentTool = OC_ZONE_COM;
01397 _cTool = 'C';
01398 break;
01399 case 4:
01400 enumCurrentTool = OC_ZONE_IND;
01401 _cTool = 'I';
01402 break;
01403
01404 default:
01405 OPENCITY_DEBUG("Design error");
01406 assert( 0 );
01407 break;
01408 }
01409
01410
01411 else if (pctr == pctrL)
01412 switch (uiObject) {
01413 case 1:
01414 pctr = pctrMain;
01415
01416 pctr->Set( 3, OC_GUIMAIN_MOUSEOVER );
01417 break;
01418 case 2:
01419 enumCurrentTool = OC_BUILD_ELINE;
01420 _cTool = 'L';
01421 break;
01422 case 3:
01423 enumCurrentTool = OC_BUILD_EPLANT;
01424 _cTool = 'E';
01425 break;
01426
01427 default:
01428 OPENCITY_DEBUG( "WARNING: What's going wrong ?" );
01429 assert(0);
01430 break;
01431 }
01432
01433
01434 else if (pctr == pctrT)
01435 switch (uiObject) {
01436 case 1:
01437 pctr = pctrMain;
01438 pctr->Set( 5, OC_GUIMAIN_MOUSEOVER );
01439 break;
01440 case 2:
01441 enumCurrentTool = OC_HEIGHT_UP;
01442 _cTool = 'U';
01443 break;
01444 case 3:
01445 enumCurrentTool = OC_HEIGHT_DOWN;
01446 _cTool = 'D';
01447 break;
01448 case 4:
01449 enumCurrentTool = OC_DESTROY;
01450 _cTool = 'X';
01451 break;
01452 case 5:
01453 enumCurrentTool = OC_QUERY;
01454 _cTool = 'Q';
01455 break;
01456
01457 default:
01458 OPENCITY_DEBUG( "WARNING: What's going wrong ?" );
01459 assert(0);
01460 break;
01461 }
01462
01463
01464 else if (pctr == pctrG)
01465 switch (uiObject) {
01466 case 1:
01467 pctr = pctrMain;
01468 pctr->Set( 6, OC_GUIMAIN_MOUSEOVER );
01469 break;
01470 case 2:
01471 pctr = pctrN;
01472 pctr->Set( 1, OC_GUIMAIN_MOUSEOVER );
01473 break;
01474 case 3:
01475 enumCurrentTool = OC_BUILD_EDUCATION;
01476 _cTool = '?';
01477 break;
01478 case 4:
01479 enumCurrentTool = OC_BUILD_HOSPITAL;
01480 _cTool = '?';
01481 break;
01482 case 5:
01483 enumCurrentTool = OC_BUILD_POLICE;
01484 _cTool = '?';
01485 break;
01486 case 6:
01487 enumCurrentTool = OC_BUILD_FIRE;
01488 _cTool = '?';
01489 break;
01490
01491 default:
01492 OPENCITY_DEBUG( "WARNING: Unknown command" );
01493 assert(0);
01494 break;
01495 }
01496
01497
01498 else if (pctr == pctrN)
01499 switch (uiObject) {
01500 case 1:
01501 pctr = pctrG;
01502 pctr->Set( 2, OC_GUIMAIN_MOUSEOVER );
01503 break;
01504 case 2:
01505 enumCurrentTool = OC_BUILD_PARK;
01506 _cTool = '?';
01507 break;
01508 case 3:
01509 enumCurrentTool = OC_BUILD_FLORA;
01510 _cTool = '?';
01511 break;
01512
01513 default:
01514 OPENCITY_DEBUG( "WARNING: Unknown tool" );
01515 assert(0);
01516 break;
01517 }
01518
01519
01520 else if (pctr == pctrS)
01521 switch (uiObject) {
01522 case 1:
01523 pctr = pctrMain;
01524 pctr->Set( 5, OC_GUIMAIN_MOUSEOVER );
01525 break;
01526 case 2:
01527 _Save( ocSaveDirPrefix( "opencity.save" ) );
01528 break;
01529 case 3:
01530 _Load( ocSaveDirPrefix( "opencity.save" ) );
01531 break;
01532
01533 default:
01534 OPENCITY_DEBUG( "WARNING: Unknown command" );
01535 assert(0);
01536 break;
01537 }
01538
01539
01540 else if (pctr == pctrPath)
01541 switch (uiObject) {
01542 case 1:
01543 _cTool = 'N';
01544 enumCurrentTool = OC_NONE;
01545 boolPathGo = false;
01546
01547 break;
01548 case 2:
01549 _cTool = 'N';
01550 enumCurrentTool = OC_NONE;
01551 boolPathGo = true;
01552 this->uiVehicleType = Vehicle::VEHICLE_BUS;
01553 break;
01554 case 3:
01555 _cTool = 'N';
01556 enumCurrentTool = OC_NONE;
01557 boolPathGo = true;
01558 this->uiVehicleType = Vehicle::VEHICLE_SPORT;
01559
01560 break;
01561 case 4:
01562 enumCurrentTool = OC_BUILD_TEST_BUILDING;
01563 _cTool = '?';
01564 break;
01565 default:
01566 break;
01567 }
01568
01569
01570 else if (pctr == pctrMAS)
01571 switch (uiObject) {
01572 case 1:
01573 _cTool = 'N';
01574 enumCurrentTool = OC_BUILD_AGENT_POLICE;
01575 break;
01576 case 2:
01577 _cTool = 'N';
01578 enumCurrentTool = OC_BUILD_AGENT_DEMONSTRATOR;
01579 break;
01580 case 3:
01581 _cTool = 'N';
01582 enumCurrentTool = OC_BUILD_AGENT_ROBBER;
01583 break;
01584
01585 default:
01586 break;
01587 }
01588
01589
01590
01591
01592
01593 if (pctr != pctrOld) {
01594 pctrOld->ResetAttribute(
01595 OC_GUIMAIN_CLICKED | OC_GUIMAIN_MOUSEOVER );
01596 pctrOld->GetLocation( iX, iY );
01597 pctr->SetLocation( iX, iY );
01598 pctr->Set( OC_GUIMAIN_VISIBLE );
01599 }
01600 else {
01601 pctrOld->ResetAttribute(
01602 OC_GUIMAIN_CLICKED );
01603 }
01604 pctrOld->Unset( OC_GUIMAIN_VISIBLE );
01605 }
01606
01607
01608
01609 void
01610 City::_HandleMouseXY()
01611 {
01612 #define OC_MOUSE_AUTOSCROLL 15
01613
01614 static int mouseX, mouseY;
01615
01616
01617 if (!(SDL_GetAppState() & SDL_APPMOUSEFOCUS ))
01618 return;
01619
01620 SDL_GetMouseState( &mouseX, &mouseY );
01621
01622
01623 if ((mouseX < OC_MOUSE_AUTOSCROLL) && !(mouseY < OC_MOUSE_AUTOSCROLL))
01624 gVars.gpRenderer->MoveRight();
01625 if ((mouseX >= iWinWidth-OC_MOUSE_AUTOSCROLL) && !(mouseY < OC_MOUSE_AUTOSCROLL))
01626 gVars.gpRenderer->MoveLeft();
01627
01628
01629 if (!(mouseX < OC_MOUSE_AUTOSCROLL)
01630 &&!(mouseX >= iWinWidth-OC_MOUSE_AUTOSCROLL) && (mouseY < OC_MOUSE_AUTOSCROLL))
01631 gVars.gpRenderer->MoveDown();
01632 if ((mouseY >= iWinHeight-OC_MOUSE_AUTOSCROLL))
01633 gVars.gpRenderer->MoveUp();
01634
01635
01636 if ((mouseX < OC_MOUSE_AUTOSCROLL) && (mouseY < OC_MOUSE_AUTOSCROLL))
01637 gVars.gpRenderer->RotateLeft();
01638
01639 if ((mouseY < OC_MOUSE_AUTOSCROLL) && (mouseX >= iWinWidth-OC_MOUSE_AUTOSCROLL))
01640 gVars.gpRenderer->RotateRight();
01641 }
01642
01643
01644
01645 void
01646 City::_TestPathfinding() {
01647 if (pctr == pctrPath)
01648 if (this->boolPathGo == false) {
01649 this->uiPathStartW = this->uiMapW2;
01650 this->uiPathStartH = this->uiMapL2;
01651 }
01652 else {
01653
01654 vector<Destination> vdest;
01655
01656 this->uiPathStopW = this->uiMapW2;
01657 this->uiPathStopH = this->uiMapL2;
01658
01659
01660 if (this->uiVehicleType == Vehicle::VEHICLE_BUS) {
01661 gVars.gpPathFinder->findShortestPath(
01662 uiPathStartW, uiPathStartH,
01663 uiPathStopW, uiPathStopH,
01664 vdest,
01665 PathFinder::OC_DISTANCE );
01666 }
01667
01668 else if (this->uiVehicleType == Vehicle::VEHICLE_SPORT) {
01669 gVars.gpPathFinder->findShortestPath(
01670 uiPathStartW, uiPathStartH,
01671 uiPathStopW, uiPathStopH,
01672 vdest,
01673 PathFinder::OC_TRAFFIC );
01674 }
01675
01676
01677 if ( vdest.size() > 0 ) {
01678 pvehicle = new Vehicle(
01679 (Vehicle::VEHICLE_TYPE)this->uiVehicleType );
01680 pvehicle->SetPath( vdest );
01681 pvehicle->Start();
01682 if (gVars.gpMoveMgr->Add( pvehicle ) < 0) {
01683 OPENCITY_DEBUG("MoveMgr full");
01684 delete pvehicle;
01685 }
01686 }
01687 }
01688
01689
01690
01691
01692
01693 }
01694
01695
01696
01697 void
01698 City::_BuildPreview()
01699 {
01700 static OPENCITY_STRUCTURE_CODE scode = OC_STRUCTURE_UNDEFINED;
01701 static OPENCITY_GRAPHIC_CODE gcode = OC_EMPTY;
01702 static OPENCITY_TOOL_CODE tcode = OC_NONE;
01703 static OPENCITY_ERR_CODE ecode = OC_ERR_FREE;
01704
01705
01706
01707 if (tcode != this->enumCurrentTool) {
01708 tcode = this->enumCurrentTool;
01709 switch (tcode) {
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728 case OC_BUILD_EPLANT:
01729 scode = OC_STRUCTURE_EPLANT_COAL;
01730 break;
01731 case OC_BUILD_PARK:
01732 scode = OC_STRUCTURE_PARK;
01733 break;
01734 case OC_BUILD_FLORA:
01735 scode = OC_STRUCTURE_FLORA;
01736 break;
01737 case OC_BUILD_FIRE:
01738 scode = OC_STRUCTURE_FIREDEPT;
01739 break;
01740 case OC_BUILD_POLICE:
01741 scode = OC_STRUCTURE_POLICEDEPT;
01742 break;
01743 case OC_BUILD_HOSPITAL:
01744 scode = OC_STRUCTURE_HOSPITALDEPT;
01745 break;
01746 case OC_BUILD_EDUCATION:
01747 scode = OC_STRUCTURE_EDUCATIONDEPT;
01748 break;
01749
01750 case OC_BUILD_TEST_BUILDING:
01751 scode = OC_STRUCTURE_TEST;
01752 break;
01753
01754 default:
01755 scode = OC_STRUCTURE_UNDEFINED;
01756 break;
01757 }
01758 }
01759
01760
01761 if ((scode != OC_STRUCTURE_UNDEFINED)
01762 && (this->boolLMBPressed == true)) {
01763 ecode = ptabLayer[ enumCurrentLayer ]->
01764 BuildPreview( uiMapW1, uiMapL1, scode, gcode );
01765
01766 if (ecode == OC_ERR_FREE) {
01767 gVars.gpRenderer->DisplayBuildPreview(
01768 uiMapW1, uiMapL1, OC_GREEN_COLOR, gcode );
01769 }
01770 else {
01771 gVars.gpRenderer->DisplayBuildPreview(
01772 uiMapW1, uiMapL1, OC_RED_COLOR, gcode );
01773 }
01774 }
01775 }
01776
01777
01778
01779 bool
01780 City::_Save( const string& strFilename )
01781 {
01782 fstream fs;
01783
01784 fs.open( strFilename.c_str(), ios_base::out | ios_base::binary | ios_base::trunc );
01785 if (!fs.good()) {
01786 OPENCITY_DEBUG( "File opening error: " << strFilename );
01787 return false;
01788 }
01789
01790
01791 SDL_LockMutex( gVars.gpmutexSim );
01792
01793
01794 this->SaveTo( fs );
01795
01796
01797 gVars.gpMapMgr->SaveTo( fs );
01798
01799
01800 ptabLayer[ BUILDING_LAYER ]->SaveTo( fs );
01801
01802
01803 _pMSim->SaveTo( fs );
01804
01805
01806 SDL_UnlockMutex( gVars.gpmutexSim );
01807
01808 fs.close();
01809 return true;
01810 }
01811
01812
01813
01814 bool
01815 City::_Load( const string& strFilename )
01816 {
01817 fstream fs;
01818 uint w, l;
01819
01820 fs.open( strFilename.c_str(), ios_base::in | ios_base::binary );
01821 if (!fs.good()) {
01822 OPENCITY_DEBUG( "File opening error" << strFilename );
01823 return false;
01824 }
01825
01826
01827 SDL_LockMutex( gVars.gpmutexSim );
01828
01829
01830 gVars.gpMoveMgr->Remove();
01831
01832
01833 this->LoadFrom( fs );
01834
01835
01836 gVars.gpMapMgr->LoadFrom( fs );
01837 gVars.gpRenderer->boolHeightChange = true;
01838
01839
01840 ptabLayer[ BUILDING_LAYER ]->LoadFrom( fs );
01841
01842
01843 _pMSim->LoadFrom( fs );
01844
01845
01846 for ( w = 0; w < _uiWidth; w++ ) {
01847 for ( l = 0; l < _uiLength; l++ ) {
01848 _pMSim->AddStructure( w, l, w, l );
01849 }
01850 }
01851
01852
01853 _pMSim->RefreshSimValue();
01854
01855
01856 SDL_UnlockMutex( gVars.gpmutexSim );
01857
01858 fs.close();
01859 return true;
01860 }
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896