Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

internalAmmoTransferDialog.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003      Copyright (C) 1994-1999  Martin Bickel  and  Marc Schellenberger
00004  
00005      This program is free software; you can redistribute it and/or modify
00006      it under the terms of the GNU General Public License as published by
00007      the Free Software Foundation; either version 2 of the License, or
00008      (at your option) any later version.
00009  
00010      This program is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013      GNU General Public License for more details.
00014  
00015      You should have received a copy of the GNU General Public License
00016      along with this program; see the file COPYING. If not, write to the 
00017      Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00018      Boston, MA  02111-1307  USA
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 ]; // weapon ammo when done; might need to have *AmmoInTransfer added
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 //std::cout << "weaponAmmoTransferable: " << i << ", " << j << endl;
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         // zuerst die munition von speziellen waffentypen verteilen, die noch in transfer ist
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         // dann die munition in transfer auf servicewaffen aufteilen
00239         for( int i=0; i<cwaffentypennum; i++ )
00240         {
00241                 if( serviceWeaponAmmoInTransfer[ i ] > 0 )
00242                 {
00243                         // zuerst den servicewaffen zuweisen
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                         // ... dann den anderen waffen zuteilen
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         // munition sollte jetzt im "legalen" bereich sein, 
00289         // und alles was im transfer war den echten waffen zugewiesen,
00290         // also jetzt dem fahrzeug zuweisen
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       //ContainerBase* second;
00385       //TransferHandler handler;
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 )//, second( destination ), handler( source, destination )
00416 {
00417         int ypos = 30;
00418         int border = 10;
00419         
00420         img1 = IconRepository::getIcon( "container.png" );//source->getImage();
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 void ammoTransferWindow ( VehicleService* serviceAction, ContainerBase* destination )
00469 {
00470 
00471 }*/

Generated on Tue Jun 24 01:27:44 2008 for Advanced Strategic Command by  doxygen 1.4.2