00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "directresearchcommand.h"
00023
00024 #include "action-registry.h"
00025 #include "../gamemap.h"
00026 #include "../itemrepository.h"
00027 #include "../researchexecution.h"
00028
00029 bool DirectResearchCommand::available( const Player& player )
00030 {
00031 return player.research.activetechnology==NULL
00032 && player.research.goal == NULL
00033 && player.research.progress >0;
00034
00035 }
00036
00037
00038 DirectResearchCommand::DirectResearchCommand( Player& player )
00039 : Command( player.getParentMap() ), researchProgress(-1), targetTechnologyID(-1)
00040 {
00041 this->player = player.getPosition();
00042 }
00043
00044
00045 static const int directResearchCommandStreamVersion = 1;
00046
00047 void DirectResearchCommand::readData ( tnstream& stream )
00048 {
00049 Command::readData( stream );
00050 int version = stream.readInt();
00051 if ( version < 1 || version > directResearchCommandStreamVersion )
00052 throw tinvalidversion ( "directResearchCommandStreamVersion", directResearchCommandStreamVersion, version );
00053
00054 researchProgress = stream.readInt();
00055 targetTechnologyID = stream.readInt();
00056 player = stream.readInt();
00057 readClassContainer( immediatelyResearchedTechnologies, stream );
00058 readClassContainer( techAdaptersMadeAvailable, stream );
00059 }
00060
00061
00062 void DirectResearchCommand::writeData ( tnstream& stream ) const
00063 {
00064 Command::writeData( stream );
00065 stream.writeInt( directResearchCommandStreamVersion );
00066 stream.writeInt( researchProgress );
00067 stream.writeInt( targetTechnologyID );
00068 stream.writeInt( player );
00069 writeClassContainer( immediatelyResearchedTechnologies, stream );
00070 writeClassContainer( techAdaptersMadeAvailable, stream );
00071 }
00072
00073
00074 vector<const Technology*> DirectResearchCommand::getAvailableTechnologies( bool longTerm )
00075 {
00076 vector<const Technology*> techs;
00077
00078 Player& p = getMap()->getPlayer(player);
00079
00080 for (int i = 0; i < technologyRepository.getNum(); i++) {
00081 const Technology* tech = technologyRepository.getObject_byPos( i );
00082 if ( tech ) {
00083 if ( longTerm ) {
00084 if ( tech->eventually_available( p.research, NULL ))
00085 techs.push_back( tech );
00086 } else {
00087 ResearchAvailabilityStatus a = p.research.techAvailable ( tech );
00088 if ( a == Available )
00089 techs.push_back ( tech );
00090 }
00091 }
00092 }
00093 return techs;
00094 }
00095
00096
00097 void DirectResearchCommand::setTechnology( const Technology* tech )
00098 {
00099 targetTechnologyID = tech->id;
00100 setState( SetUp );
00101 }
00102
00103
00104 ActionResult DirectResearchCommand::go ( const Context& context )
00105 {
00106 if ( getState() != SetUp )
00107 return ActionResult(22000);
00108
00109 if ( !available( getMap()->getPlayer( player ) ))
00110 return ActionResult( 23201 );
00111
00112 vector<const Technology*> techs = getAvailableTechnologies(true);
00113 const Technology* newTech = technologyRepository.getObject_byID( targetTechnologyID );
00114 if ( find ( techs.begin(), techs.end(), newTech ) == techs.end() )
00115 return ActionResult(23200);
00116
00117 Research& research = getMap()->getPlayer( player ).research;
00118
00119 if ( newTech->techDependency.available( research )) {
00120 research.activetechnology = newTech;
00121 research.goal = NULL;
00122 } else {
00123 list<const Technology*> techs;
00124 if ( newTech->eventually_available( research, &techs )) {
00125 research.activetechnology = *techs.begin();
00126 research.goal = newTech;
00127 } else
00128 return ActionResult( 23202 );
00129 }
00130
00131
00132 vector<const Technology*> researched;
00133 techAdaptersMadeAvailable.clear();
00134 runResearch( getMap()->getPlayer( player ), &researched, &techAdaptersMadeAvailable );
00135 for ( vector<const Technology*>::iterator i = researched.begin(); i != researched.end(); i++ )
00136 immediatelyResearchedTechnologies.push_back( (*i)->id );
00137
00138
00139 setState( Finished );
00140
00141 return ActionResult(0);
00142 }
00143
00144
00145 ActionResult DirectResearchCommand::undoAction( const Context& context )
00146 {
00147 if ( getState() != Finished )
00148 return ActionResult(22000);
00149
00150 Research& research = getMap()->getPlayer( player ).research;
00151
00152 for ( vector<int>::const_iterator i = immediatelyResearchedTechnologies.begin(); i != immediatelyResearchedTechnologies.end(); ++i ) {
00153
00154 Technology* t = technologyRepository.getObject_byID( *i );
00155 if ( !t )
00156 return ActionResult(21005, ASCString::toString(*i));
00157
00158 vector<int>::iterator j = find( research.developedTechnologies.begin(), research.developedTechnologies.end(), *i );
00159 if ( j != research.developedTechnologies.end() )
00160 research.developedTechnologies.erase(j);
00161 else
00162 return ActionResult(21204, t->name );
00163
00164 research.progress += t->researchpoints;
00165 }
00166
00167 for ( vector<ASCString>::iterator i = techAdaptersMadeAvailable.begin(); i != techAdaptersMadeAvailable.end(); ++i ) {
00168 Research::TriggeredTechAdapter::iterator ta = find( research.triggeredTechAdapter.begin(), research.triggeredTechAdapter.end(), *i );
00169 if ( ta == research.triggeredTechAdapter.end() )
00170 return ActionResult(21203, *i );
00171 else
00172 research.triggeredTechAdapter.erase( *i );
00173 }
00174
00175 return Command::undoAction(context);
00176 }
00177
00178
00179 ASCString DirectResearchCommand :: getCommandString() const
00180 {
00181 ASCString c;
00182 c.format("setResearchGoal ( map, %d, %d )", player, targetTechnologyID );
00183 return c;
00184 }
00185
00186 GameActionID DirectResearchCommand::getID() const
00187 {
00188 return ActionRegistry::DirectResearchCommand;
00189 }
00190
00191 ASCString DirectResearchCommand::getDescription() const
00192 {
00193 ASCString s = "Choose technology " + ASCString::toString(targetTechnologyID) + " for player " + ASCString::toString(player);
00194 return s;
00195 }
00196
00197
00198 namespace {
00199 const bool r1 = registerAction<DirectResearchCommand> ( ActionRegistry::DirectResearchCommand );
00200 }
00201