00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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