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
00047
00048 int evaluateProduction( const ContainerBaseType* potentialFactory, const Vehicletype* vt, GameMap* gamemap )
00049 {
00050 if ( potentialFactory->vehicleFit( vt ) && potentialFactory->hasFunction( ContainerBaseType::InternalVehicleProduction))
00051 return 1;
00052 else
00053 return 0;
00054 }
00055
00056 int evaluateProduction( const Vehicletype* potentialFactory, const Vehicletype* vt, GameMap* gamemap )
00057 {
00058 const ContainerBaseType* cbt = potentialFactory;
00059 int res = evaluateProduction( cbt, vt, gamemap );
00060
00061
00062 for ( vector<IntRange>::const_iterator i = potentialFactory->vehiclesBuildable.begin(); i != potentialFactory->vehiclesBuildable.end(); ++i )
00063 if( vt->id >= i->from && vt->id <= i->to )
00064 return res | 2;
00065 return res;
00066 }
00067
00068
00069 ASCString getProductionString( const ContainerBaseType* potentialFactory, const Vehicletype* vt, GameMap* gamemap )
00070 {
00071 ASCString s;
00072 int res = evaluateProduction( potentialFactory, vt, gamemap);
00073 if ( res ) {
00074 s = potentialFactory->getName() + " (" + ASCString::toString(potentialFactory->id) + ") ";
00075 if ( res & 1 )
00076 s += " internally";
00077 if ( res & 2 )
00078 s += " externally";
00079 s += "\n";
00080 }
00081 return s;
00082 }
00083
00084
00085
00086 ASCString getInstances( const ContainerBaseType* evaluatedFactory, const Vehicletype* unitsToProduce, GameMap* gamemap, bool lineAvail )
00087 {
00088 ASCString instances;
00089 if ( lineAvail ) {
00090 int count = 0;
00091 ASCString units = evaluatedFactory->getName() + ": ";
00092
00093 for ( Player::VehicleList::const_iterator j = gamemap->getCurrentPlayer().vehicleList.begin(); j != gamemap->getCurrentPlayer().vehicleList.end(); ++j )
00094 if ( (*j)->typ == evaluatedFactory )
00095 for ( Vehicle::Production::const_iterator i = (*j)->getProduction().begin(); i != (*j)->getProduction().end(); ++i)
00096 if ( *i == unitsToProduce ) {
00097 units += (*j)->getPosition().toString();
00098 ++count;
00099 }
00100
00101 if ( count )
00102 instances += units + "\n";
00103
00104 }
00105 {
00106 int count = 0;
00107 ASCString units = evaluatedFactory->getName() + ": ";
00108
00109 for ( Player::BuildingList::const_iterator j = gamemap->getCurrentPlayer().buildingList.begin(); j != gamemap->getCurrentPlayer().buildingList.end(); ++j )
00110 if ( (*j)->typ == evaluatedFactory )
00111 if ( lineAvail ) {
00112 for ( ContainerBase::Production::const_iterator k = (*j)->getProduction().begin(); k != (*j)->getProduction().end(); ++k )
00113 if ( *k == unitsToProduce ) {
00114 units += (*j)->getPosition().toString();
00115 ++count;
00116 }
00117 } else {
00118 if ( unitsToProduce->techDependency.available( gamemap->getCurrentPlayer().research ) ) {
00119 bool found = false;
00120 for ( ContainerBase::Production::const_iterator k = (*j)->getProduction().begin(); k != (*j)->getProduction().end(); ++k )
00121 if ( *k == unitsToProduce )
00122 found = true;
00123
00124 if ( !found ) {
00125 units += (*j)->getPosition().toString();
00126 ++count;
00127 }
00128 }
00129 }
00130 if ( count )
00131 instances += units + "\n";
00132 }
00133
00134 return instances;
00135 }
00136
00137 template<typename T>
00138 void checkType( T* t, const Vehicletype* evaluatedUnitType, ASCString& instances, ASCString& lineAddable, ASCString& types, GameMap* gamemap, bool checkResearch )
00139 {
00140 if ( evaluateProduction( t, evaluatedUnitType, gamemap)) {
00141 instances += getInstances( t, evaluatedUnitType, gamemap, true );
00142 lineAddable += getInstances( t, evaluatedUnitType, gamemap, false );
00143 if ( !checkResearch || t->techDependency.available( gamemap->getCurrentPlayer().research ))
00144 types += getProductionString( t, evaluatedUnitType, gamemap );
00145 }
00146 }
00147
00148 bool vehicleOwned( const Vehicletype* vt, GameMap* gamemap )
00149 {
00150 for ( Player::VehicleList::const_iterator j = gamemap->getCurrentPlayer().vehicleList.begin(); j != gamemap->getCurrentPlayer().vehicleList.end(); ++j )
00151 if ( (*j)->typ == vt )
00152 return true;
00153 return false;
00154 }
00155
00156
00157 void unitProductionAnalysis( GameMap* gamemap, bool checkResearch )
00158 {
00159 VehicleTypeSelectionItemFactory::Container c;
00160
00161 for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i ) {
00162 Vehicletype* p = vehicleTypeRepository.getObject_byPos(i);
00163 if ( p ) {
00164 if ( vehicleOwned( p, gamemap ) || !checkResearch || p->techDependency.available( gamemap->getCurrentPlayer().research ) )
00165 c.push_back(p);
00166 }
00167 }
00168
00169 AvailableUnitWindow auw( NULL, PG_Rect( -1, -1, 400, 400), "Select Vehicle Type", new VehicleTypeSelectionItemFactory(c, gamemap->getCurrentPlayer() ));
00170 auw.Show();
00171 auw.RunModal();
00172 auw.Hide();
00173
00174
00175 if ( auw.getSelected() ) {
00176 ASCString types, instances, lineAddable;
00177
00178 for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i )
00179 checkType( vehicleTypeRepository.getObject_byPos(i), auw.getSelected(), instances, lineAddable, types, gamemap, checkResearch );
00180
00181 for ( int i = 0; i < buildingTypeRepository.getNum(); ++i )
00182 checkType( buildingTypeRepository.getObject_byPos(i), auw.getSelected(), instances, lineAddable, types, gamemap, checkResearch );
00183
00184 if ( types.empty() )
00185 types = "-none-\n";
00186
00187 if ( instances.empty() )
00188 instances = "-nowhere-\n";
00189
00190 if ( lineAddable.empty() )
00191 lineAddable = "-nowhere-\n";
00192
00193 types = "\n#fontsize=18#Vehicle and Building types#fontsize=10#\n(provided that the unit has been researched)\n#fontsize=12#" + types;
00194 instances = "\n#fontsize=18#Production available #fontsize=12#\n" + instances;
00195 lineAddable = "\n#fontsize=18#Production can be added #fontsize=12#\n" + lineAddable;
00196
00197 ViewFormattedText vft("Unit Production Analysis", instances + lineAddable + types, PG_Rect( -1, -1, 500, 400 ));
00198 vft.Show();
00199 vft.RunModal();
00200 }
00201 }
00202