productionanalysis.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           cargodialog.cpp  -  description
00003                              -------------------
00004     begin                : Tue Oct 24 2000
00005     copyright            : (C) 2000 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 
00019 #include "../containerbasetype.h"
00020 #include "../vehicletype.h"
00021 #include "../player.h"
00022 #include "../gamemap.h"
00023 #include "../itemrepository.h"
00024 
00025 #include "productionanalysis.h"
00026 #include "vehicletypeselector.h"
00027 #include "../widgets/textrenderer.h"
00028 
00029 class AvailableUnitWindow : public ItemSelectorWindow {
00030    private:
00031       const VehicleType* selectedVehicleType;
00032       
00033       virtual void itemSelected( const SelectionWidget* sw) {
00034          const VehicleTypeBaseWidget* vtcw = dynamic_cast<const VehicleTypeBaseWidget*>(sw);
00035          assert( vtcw );
00036          selectedVehicleType = vtcw->getVehicletype ();
00037          if ( selectedVehicleType )
00038             QuitModal();
00039       };
00040    public:
00041       AvailableUnitWindow ( PG_Widget *parent, const PG_Rect &r , const ASCString& title, SelectionItemFactory* itemFactory ) : ItemSelectorWindow( parent, r, title, itemFactory ), selectedVehicleType(NULL) {};
00042       const VehicleType* getSelected() { return selectedVehicleType; };
00043 };      
00044 
00045 
00046 bool factoryProductionInstanceExists( const ContainerBaseType* potentialFactory, const VehicleType* vt, GameMap* gamemap )
00047 {
00048    Player& p = gamemap->getCurrentPlayer();
00049    for ( Player::BuildingList::const_iterator b = p.buildingList.begin(); b != p.buildingList.end(); ++b )
00050       if ( (*b)->typ == potentialFactory )
00051          if ( (*b)->hasProductionLine(vt))
00052             return true;
00053 
00054    for ( Player::VehicleList::const_iterator v = p.vehicleList.begin(); v != p.vehicleList.end(); ++v )
00055       if ( (*v)->typ == potentialFactory )
00056          if ( (*v)->hasProductionLine(vt))
00057             return true;
00058 
00059    return false;
00060 
00061 }
00062 
00063 int evaluateProduction( const ContainerBaseType* potentialFactory, const VehicleType* vt, GameMap* gamemap )
00064 {
00065    if ( potentialFactory->vehicleFit( vt ) && potentialFactory->hasFunction( ContainerBaseType::InternalVehicleProduction)) {
00066       if ( potentialFactory->vehicleCategoriesProduceable & (1 << vt->movemalustyp))
00067          for ( int h = 0; h < 8; ++h )
00068             if ( potentialFactory->height & (1<<h))
00069                if ( potentialFactory->vehicleUnloadable(vt,h) || potentialFactory->hasFunction( ContainerBaseType::ProduceNonLeavableUnits ))
00070                   if ( !potentialFactory->hasFunction( ContainerBaseType::NoProductionCustomization) || factoryProductionInstanceExists( potentialFactory, vt, gamemap ))
00071                      return 1;
00072    } 
00073    
00074    return 0;
00075 }
00076 
00077 int evaluateProduction( const VehicleType* potentialFactory, const VehicleType* vt, GameMap* gamemap )
00078 {
00079    const ContainerBaseType* cbt = potentialFactory;
00080    int res = evaluateProduction( cbt, vt, gamemap ); 
00081 
00082    // if ( potentialFactory->hasFunction( ContainerBaseType::ExternalVehicleProduction)) 
00083       for ( vector<IntRange>::const_iterator i = potentialFactory->vehiclesBuildable.begin(); i != potentialFactory->vehiclesBuildable.end(); ++i )
00084          if( vt->id >= i->from && vt->id <= i->to ) 
00085             return res | 2;
00086    return res;
00087 }
00088 
00089 
00090 ASCString getProductionString( const ContainerBaseType* potentialFactory, const VehicleType* vt, GameMap* gamemap )
00091 {
00092    ASCString s;
00093    int res = evaluateProduction( potentialFactory, vt, gamemap);
00094    if ( res ) {
00095       s = potentialFactory->getName() + " (" + ASCString::toString(potentialFactory->id) + ") ";
00096       if ( res & 1 )
00097          s += " internally";
00098       if ( res & 2 )
00099          s += " externally";
00100       s += "\n";
00101    }
00102    return s;
00103 }
00104 
00105 
00106 
00107 ASCString getInstances( const ContainerBaseType* evaluatedFactory, const VehicleType* unitsToProduce, GameMap* gamemap, bool lineAvail )
00108 {
00109    ASCString instances;
00110    if ( lineAvail ) {
00111       int count = 0;
00112       ASCString units = evaluatedFactory->getName() + ": ";
00113          
00114       for ( Player::VehicleList::const_iterator j = gamemap->getCurrentPlayer().vehicleList.begin(); j != gamemap->getCurrentPlayer().vehicleList.end(); ++j )
00115          if ( (*j)->typ == evaluatedFactory ) 
00116             for ( Vehicle::Production::const_iterator i = (*j)->getProduction().begin(); i != (*j)->getProduction().end(); ++i)
00117                if ( *i == unitsToProduce ) {
00118                   units += (*j)->getPosition().toString();
00119                   ++count;
00120                }
00121          
00122       if ( count )
00123          instances += units + "\n";
00124 
00125    }
00126    {
00127       int count = 0;
00128       ASCString units = evaluatedFactory->getName() + ": ";
00129          
00130       for ( Player::BuildingList::const_iterator j = gamemap->getCurrentPlayer().buildingList.begin(); j != gamemap->getCurrentPlayer().buildingList.end(); ++j )
00131          if ( (*j)->typ == evaluatedFactory ) {
00132             if ( lineAvail ) {
00133                for ( ContainerBase::Production::const_iterator k = (*j)->getProduction().begin(); k != (*j)->getProduction().end(); ++k )
00134                   if ( *k == unitsToProduce ) {
00135                      units += (*j)->getPosition().toString();
00136                      ++count;
00137                   }
00138             } else {
00139                if ( unitsToProduce->techDependency.available( gamemap->getCurrentPlayer().research ) ) {
00140                   bool found = false;
00141                   for ( ContainerBase::Production::const_iterator k = (*j)->getProduction().begin(); k != (*j)->getProduction().end(); ++k )
00142                      if ( *k == unitsToProduce ) 
00143                         found = true;
00144    
00145                   if ( !found ) {
00146                      units += (*j)->getPosition().toString();
00147                      ++count;
00148                   }
00149                }
00150             }
00151          }
00152       if ( count )
00153          instances += units + "\n";
00154    }
00155 
00156    return instances;
00157 }
00158 
00159 template<typename T>
00160 void checkType( T* t, const VehicleType* evaluatedUnitType, ASCString& instances, ASCString& lineAddable, ASCString& types, GameMap* gamemap, bool checkResearch )
00161 {
00162    if ( evaluateProduction( t, evaluatedUnitType, gamemap)) {
00163       instances += getInstances( t, evaluatedUnitType, gamemap, true );               
00164       lineAddable += getInstances( t, evaluatedUnitType, gamemap, false );
00165       if ( !checkResearch || t->techDependency.available( gamemap->getCurrentPlayer().research )) 
00166          types += getProductionString( t, evaluatedUnitType, gamemap );
00167    }
00168 }
00169 
00170 bool vehicleOwned( const VehicleType* vt, GameMap* gamemap )
00171 {
00172    for ( Player::VehicleList::const_iterator j = gamemap->getCurrentPlayer().vehicleList.begin(); j != gamemap->getCurrentPlayer().vehicleList.end(); ++j )
00173       if ( (*j)->typ == vt )
00174          return true;
00175    return false;
00176 }
00177 
00178 
00179 void unitProductionAnalysis( GameMap* gamemap, bool checkResearch )
00180 {
00181    VehicleTypeSelectionItemFactory::Container c;
00182 
00183    for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i ) {
00184       VehicleType* p = vehicleTypeRepository.getObject_byPos(i);
00185       if ( p ) {
00186          if ( vehicleOwned( p, gamemap ) || !checkResearch || p->techDependency.available( gamemap->getCurrentPlayer().research )  )
00187             c.push_back(p);
00188       }
00189    }
00190 
00191    AvailableUnitWindow auw( NULL, PG_Rect( -1, -1, 400, 400), "Select Vehicle Type", new VehicleTypeSelectionItemFactory(c, gamemap->getCurrentPlayer() ));
00192    auw.Show();
00193    auw.RunModal();
00194    auw.Hide();
00195 
00196 
00197    if ( auw.getSelected() ) {
00198       ASCString types, instances, lineAddable;
00199 
00200       for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i ) 
00201          checkType( vehicleTypeRepository.getObject_byPos(i), auw.getSelected(), instances, lineAddable, types, gamemap, checkResearch );
00202       
00203       for ( int i = 0; i < buildingTypeRepository.getNum(); ++i ) 
00204          checkType( buildingTypeRepository.getObject_byPos(i), auw.getSelected(), instances, lineAddable, types, gamemap, checkResearch );
00205 
00206       if ( types.empty() )
00207          types = "-none-\n";
00208 
00209       if ( instances.empty() )
00210          instances = "-nowhere-\n";
00211 
00212       if ( lineAddable.empty() )
00213          lineAddable = "-nowhere-\n";
00214 
00215       types = "\n#fontsize=18#Vehicle and Building types#fontsize=10#\n(provided that the unit has been researched)\n#fontsize=12#" + types;
00216       instances = "\n#fontsize=18#Production available #fontsize=12#\n" + instances;
00217       lineAddable = "\n#fontsize=18#Production can be added #fontsize=12#\n" + lineAddable;
00218 
00219       ViewFormattedText vft("Unit Production Analysis", instances + lineAddable + types, PG_Rect( -1, -1, 500, 400 ));
00220       vft.Show();
00221       vft.RunModal();
00222    }
00223 }
00224 

Generated on Mon May 21 01:26:36 2012 for Advanced Strategic Command by  doxygen 1.5.1