00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sigc++/sigc++.h>
00022 #include <sstream>
00023
00024 #include "internalAmmoTransferDialog.h"
00025
00026 #include "../unitctrl.h"
00027 #include "../containercontrols.h"
00028 #include "../gameoptions.h"
00029 #include "../actions/servicing.h"
00030 #include "../iconrepository.h"
00031 #include "../replay.h"
00032
00033 bool internalAmmoTransferAvailable( ContainerBase* container )
00034 {
00035 if( container == NULL ) return false;
00036 if( container->isBuilding() ) return false;
00037
00038 Vehicle* vehicle = (Vehicle*) container;
00039 for( int i=0; i<vehicle->typ->weapons.count; i++ )
00040 {
00041 const SingleWeapon* weapon = vehicle->getWeapon( i );
00042 if( weapon->canRefuel() ) return true;
00043 for( int j=0; j<i; j++ )
00044 {
00045 const SingleWeapon* otherWeapon = vehicle->getWeapon( j );
00046 if( weapon->equals( otherWeapon ) ) return true;
00047 }
00048 }
00049 return false;
00050 }
00051
00055 class InternalAmmoTransferWidget;
00056 class InternalAmmoTransferHandler
00057 {
00058
00059 int serviceWeaponAmmoInTransfer[ cwaffentypennum ];
00060 int weaponAmmo[ 16 ];
00061 int weaponAmmoInTransfer[ 16 ];
00062 int weaponAmmoTransferSlot[ 16 ];
00063 std::vector<InternalAmmoTransferWidget*> widgets;
00064
00065 bool weaponAmmoTransferable[ 16 ];
00066 bool serviceweaponAmmoTransferable[ cwaffentypennum ];
00067 int equalWeaponsTypeCounter;
00068
00069 Vehicle* _vehicle;
00070
00071 public:
00072 InternalAmmoTransferHandler( Vehicle* vehicle );
00073 bool isAmmoTransferable( int weaponID );
00074 int* weaponAmmoTransferSource( int weaponID );
00075 int* weaponAmmoTransferBuffer( int weaponID );
00076 int getMaxAmmo( int weaponID );
00077 std::string getName( int weaponID );
00078
00079 void addWidget( InternalAmmoTransferWidget* widget );
00080 void updateBufferTexts();
00081
00082 void performTransfer();
00083 };
00084
00085 class InternalAmmoTransferWidget : public PG_Widget
00086 {
00087 PG_Slider* slider;
00088 InternalAmmoTransferHandler* _handler;
00089 int _weaponID;
00090 int* amount;
00091 int* buffer;
00092 PG_Label* bufferAmount;
00093 PG_Label* weaponAmount;
00094
00095 std::string bufferLabel;
00096 std::string unitLabel;
00097
00098 public:
00099 InternalAmmoTransferWidget( PG_Widget* parent, const PG_Rect& pos, InternalAmmoTransferHandler* handler, int weaponID );
00100
00101 bool slide( long amount );
00102 bool slideEnd( long amount );
00103 void updateTexts();
00104 };
00105
00106 InternalAmmoTransferHandler::InternalAmmoTransferHandler( Vehicle* vehicle )
00107 {
00108 _vehicle = vehicle;
00109 equalWeaponsTypeCounter = 0;
00110
00111 for( int i=0; i<16; i++ )
00112 {
00113 weaponAmmo[ i ] = vehicle->ammo[ i ];
00114 weaponAmmoInTransfer[ i ] = 0;
00115 weaponAmmoTransferSlot[ i ] = -1;
00116 weaponAmmoTransferable[ i ] = false;
00117 }
00118
00119 for( int i=0; i<cwaffentypennum; i++ )
00120 {
00121 serviceWeaponAmmoInTransfer[ i ] = 0;
00122 serviceweaponAmmoTransferable[ i ] = false;
00123 }
00124
00125 for( int i=0; i<vehicle->typ->weapons.count; i++ )
00126 {
00127 const SingleWeapon* weapon = vehicle->getWeapon( i );
00128 if( weapon->canRefuel() )
00129 {
00130 serviceweaponAmmoTransferable[ weapon->getScalarWeaponType() ] = true;
00131 weaponAmmoTransferable[ i ] = true;
00132 }
00133 }
00134
00135 for( int i=0; i<vehicle->typ->weapons.count; i++ )
00136 {
00137 const SingleWeapon* weapon = vehicle->getWeapon( i );
00138 if( ! weapon->canRefuel() )
00139 {
00140 if( serviceweaponAmmoTransferable[ weapon->getScalarWeaponType() ] )
00141 {
00142 weaponAmmoTransferable[ i ] = true;
00143 }else
00144 {
00145 for( int j=0; j<i; j++ )
00146 {
00147 if( weapon->equals( vehicle->getWeapon( j ) ) )
00148 {
00149 weaponAmmoTransferable[ i ] = true;
00150 weaponAmmoTransferable[ j ] = true;
00151
00152
00153 if( weaponAmmoTransferSlot[ j ] == -1 )
00154 {
00155 weaponAmmoTransferSlot[ j ] = equalWeaponsTypeCounter;
00156 equalWeaponsTypeCounter++;
00157 }
00158 weaponAmmoTransferSlot[ i ] = weaponAmmoTransferSlot[ j ];
00159 }
00160 }
00161 }
00162 }
00163 }
00164 }
00165
00166 void InternalAmmoTransferHandler::addWidget( InternalAmmoTransferWidget* widget )
00167 {
00168 widgets.push_back( widget );
00169 }
00170
00171 void InternalAmmoTransferHandler::updateBufferTexts()
00172 {
00173 for( int i=0; i<widgets.size(); i++ )
00174 {
00175 widgets.at( i ) -> updateTexts();
00176 }
00177 }
00178
00179
00180 bool InternalAmmoTransferHandler::isAmmoTransferable( int weaponID )
00181 {
00182 return weaponAmmoTransferable[ weaponID ];
00183 }
00184
00185 int* InternalAmmoTransferHandler::weaponAmmoTransferSource( int weaponID )
00186 {
00187 return &weaponAmmo[ weaponID ];
00188 }
00189
00190 int InternalAmmoTransferHandler::getMaxAmmo( int weaponID )
00191 {
00192 return _vehicle->getWeapon( weaponID )->count;
00193 }
00194
00195 std::string InternalAmmoTransferHandler::getName( int weaponID )
00196 {
00197 return _vehicle->getWeapon( weaponID )->getName();
00198 }
00199
00200 int* InternalAmmoTransferHandler::weaponAmmoTransferBuffer( int weaponID )
00201 {
00202 if( weaponAmmoTransferSlot[ weaponID ] >= 0 )
00203 {
00204 return &weaponAmmoInTransfer[ weaponAmmoTransferSlot[ weaponID ] ];
00205 }else
00206 {
00207 return &serviceWeaponAmmoInTransfer[ _vehicle->getWeapon( weaponID )->getScalarWeaponType() ];
00208 }
00209 }
00210
00211 void InternalAmmoTransferHandler::performTransfer()
00212 {
00213
00214 for( int i=0; i<16; i++ )
00215 {
00216 if( weaponAmmoInTransfer[ i ] > 0 )
00217 {
00218 for( int j=0;j<16; j++ )
00219 {
00220 if( weaponAmmoTransferSlot[ j ] == i )
00221 {
00222 const SingleWeapon* weapon = _vehicle->getWeapon( j );
00223 if( weaponAmmo[ j ] < weapon->count )
00224 {
00225 int ammoTransfer = weapon->count - weaponAmmo[ j ];
00226 if( weaponAmmoInTransfer[ i ] < ammoTransfer )
00227 {
00228 ammoTransfer = weaponAmmoInTransfer[ i ];
00229 }
00230 weaponAmmo[ j ] += ammoTransfer;
00231 weaponAmmoInTransfer[ i ] -= ammoTransfer;
00232 }
00233 }
00234 }
00235 }
00236 }
00237
00238
00239 for( int i=0; i<cwaffentypennum; i++ )
00240 {
00241 if( serviceWeaponAmmoInTransfer[ i ] > 0 )
00242 {
00243
00244 for( int j=0; j<_vehicle->typ->weapons.count; j++ )
00245 {
00246 const SingleWeapon* weapon = _vehicle->getWeapon( j );
00247 if( weapon->getScalarWeaponType() == i )
00248 {
00249 if( weapon->canRefuel() )
00250 {
00251 if( weaponAmmo[ j ] < weapon->count )
00252 {
00253 int ammoTransfer = weapon->count - weaponAmmo[ j ];
00254 if( serviceWeaponAmmoInTransfer[ i ] < ammoTransfer )
00255 {
00256 ammoTransfer = serviceWeaponAmmoInTransfer[ i ];
00257 }
00258 weaponAmmo[ j ] += ammoTransfer;
00259 serviceWeaponAmmoInTransfer[ i ] -= ammoTransfer;
00260 }
00261 }
00262 }
00263 }
00264
00265 for( int j=0; j<_vehicle->typ->weapons.count; j++ )
00266 {
00267 const SingleWeapon* weapon = _vehicle->getWeapon( j );
00268 if( weapon->getScalarWeaponType() == i )
00269 {
00270 if( ! weapon->canRefuel() )
00271 {
00272 if( weaponAmmo[ j ] < weapon->count )
00273 {
00274 int ammoTransfer = weapon->count - weaponAmmo[ j ];
00275 if( serviceWeaponAmmoInTransfer[ i ] < ammoTransfer )
00276 {
00277 ammoTransfer = serviceWeaponAmmoInTransfer[ i ];
00278 }
00279 weaponAmmo[ j ] += ammoTransfer;
00280 serviceWeaponAmmoInTransfer[ i ] -= ammoTransfer;
00281 }
00282 }
00283 }
00284 }
00285 }
00286 }
00287
00288
00289
00290
00291 for( int i=0; i<16; i++ )
00292 {
00293 logtoreplayinfo ( rpl_refuel2, _vehicle->xpos, _vehicle->ypos, _vehicle->networkid, i, weaponAmmo[ i ], _vehicle->ammo[ i ] );
00294 _vehicle->ammo[ i ] = weaponAmmo[ i ];
00295 }
00296 }
00297
00298
00299
00300 InternalAmmoTransferWidget::InternalAmmoTransferWidget( PG_Widget* parent, const PG_Rect& pos, InternalAmmoTransferHandler* handler, int weaponID ) : PG_Widget( parent,pos ), slider(NULL), _weaponID( weaponID )
00301 {
00302 _handler = handler;
00303 _handler->addWidget( this );
00304 amount = _handler->weaponAmmoTransferSource( _weaponID );
00305 buffer = _handler->weaponAmmoTransferBuffer( _weaponID );
00306 bufferLabel = "Buffer ";
00307 unitLabel = "Unit ";
00308
00309 slider = new PG_Slider( this, PG_Rect( 0, 25, pos.w, 15 ), PG_ScrollBar::HORIZONTAL );
00310 slider->SetRange( 0, _handler->getMaxAmmo( weaponID ) );
00311 slider->SetPosition( *amount );
00312
00313 slider->sigSlide.connect( SigC::slot( *this, &InternalAmmoTransferWidget::slide ));
00314 slider->sigSlideEnd.connect( SigC::slot( *this, &InternalAmmoTransferWidget::slideEnd));
00315
00316 PG_Rect labels = PG_Rect( 0, 0, pos.w, 20 );
00317 std::stringstream nameStream;
00318 nameStream << handler->getName( weaponID ) << " (" << weaponID << ")";
00319 PG_Label* l = new PG_Label ( this, labels, nameStream.str() );
00320 l->SetAlignment( PG_Label::CENTER );
00321
00322 bufferAmount = new PG_Label ( this, labels );
00323 bufferAmount->SetAlignment( PG_Label::LEFT );
00324
00325 weaponAmount = new PG_Label ( this, labels );
00326 weaponAmount->SetAlignment( PG_Label::RIGHT );
00327
00328 updateTexts();
00329 }
00330
00331
00332 bool InternalAmmoTransferWidget::slide( long newAmount )
00333 {
00334 int difference = newAmount - (*amount);
00335 if( difference > (*buffer) )
00336 {
00337 difference = (*buffer);
00338 }
00339 (*amount) += difference;
00340 (*buffer) -= difference;
00341
00342 if( difference != 0 )
00343 {
00344 _handler->updateBufferTexts();
00345 return true;
00346 }
00347 return false;
00348 }
00349
00350 void InternalAmmoTransferWidget::updateTexts()
00351 {
00352 std::stringstream ssStream;
00353 ssStream << bufferLabel << (*buffer);
00354 bufferAmount->SetText( ssStream.str() );
00355
00356 std::stringstream ssStream2;
00357 ssStream2 << unitLabel << (*amount);
00358 weaponAmount->SetText( ssStream2.str() );
00359 }
00360
00361 bool InternalAmmoTransferWidget::slideEnd( long newAmount )
00362 {
00363 int difference = newAmount - (*amount);
00364 if( difference > (*buffer) )
00365 {
00366 difference = (*buffer);
00367 }
00368 (*amount) += difference;
00369 (*buffer) -= difference;
00370
00371 if( difference != 0 )
00372 {
00373 _handler->updateBufferTexts();
00374 return true;
00375 }
00376 return false;
00377 }
00378
00379
00380 class InternalAmmoTransferWindow : public ASC_PG_Dialog {
00381 private:
00382 Vehicle* vehicle;
00383 InternalAmmoTransferHandler handler;
00384
00385
00386
00387
00388 Surface img1,img2;
00389
00390 bool ok()
00391 {
00392 handler.performTransfer();
00393 QuitModal();
00394 return true;
00395 }
00396
00397 public:
00398 InternalAmmoTransferWindow ( Vehicle* source, PG_Widget* parent );
00399
00400 bool somethingToTransfer() { return internalAmmoTransferAvailable( vehicle ); };
00401
00402 bool eventKeyDown(const SDL_KeyboardEvent* key)
00403 {
00404 if ( key->keysym.sym == SDLK_ESCAPE ) {
00405 QuitModal();
00406 return true;
00407 }
00408 return false;
00409 }
00410
00411
00412 };
00413
00414
00415 InternalAmmoTransferWindow :: InternalAmmoTransferWindow ( Vehicle* source, PG_Widget* parent ) : ASC_PG_Dialog( NULL, PG_Rect( 30, 30, 400, 400 ), "Transfer" ), vehicle( source ), handler( source )
00416 {
00417 int ypos = 30;
00418 int border = 10;
00419
00420 img1 = IconRepository::getIcon( "container.png" );
00421 img2 = source->getImage();
00422
00423 const int singleTransferHeight = 60;
00424
00425 int transferableWeaponsCounter = 0;
00426
00427 for( int i=0; i<16; i++ )
00428 {
00429 if( handler.isAmmoTransferable( i ) ) transferableWeaponsCounter++;
00430 }
00431
00432 int expectedHeight = transferableWeaponsCounter * singleTransferHeight;
00433
00434 int newHeight = min( PG_Application::GetScreen()->h - 60, expectedHeight + 130 );
00435 SizeWidget( w, newHeight );
00436
00437 PG_ScrollWidget* area = new PG_ScrollWidget ( this, PG_Rect( border, ypos, w - border, h - 80 ));
00438 area->SetTransparency( 255 );
00439
00440 (new PG_ThemeWidget( area, PG_Rect( 5,3, fieldsizex, fieldsizey)))->SetBackground( img1.getBaseSurface(), PG_Draw::STRETCH );
00441 (new PG_ThemeWidget( area, PG_Rect( area->Width() - 5 - fieldsizex, 3, fieldsizex, fieldsizey)))->SetBackground( img2.getBaseSurface(), PG_Draw::STRETCH );
00442
00443 ypos = fieldsizex + 5;
00444
00445 for( int i=0; i<16; i++ )
00446 {
00447 if( handler.isAmmoTransferable( i ) )
00448 {
00449 new InternalAmmoTransferWidget( area, PG_Rect( 0, ypos, area->w - 30, 50 ), &handler, i );
00450 ypos += singleTransferHeight;
00451 }
00452 }
00453
00454 int buttonWidth = 150;
00455 PG_Button* b = new PG_Button( this, PG_Rect( w - buttonWidth - border, h - 30 - border, buttonWidth, 30), "OK" );
00456 b->sigClick.connect( SigC::slot( *this, &InternalAmmoTransferWindow::ok ));
00457 }
00458
00459 void internalAmmoTransferWindow ( Vehicle* vehicle )
00460 {
00461 InternalAmmoTransferWindow iatw( vehicle, NULL );
00462 if ( iatw.somethingToTransfer() ) {
00463 iatw.Show();
00464 iatw.RunModal();
00465 }
00466 }
00467
00468
00469
00470
00471