repairunitcommand.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-2010  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 
00022 #include "repairunitcommand.h"
00023 
00024 #include "../vehicle.h"
00025 #include "../mapfield.h"
00026 #include "../gamemap.h"
00027 #include "../viewcalculation.h"
00028 #include "../spfst.h"
00029 #include "../mapdisplayinterface.h"
00030 #include "action-registry.h"
00031 #include "changeunitproperty.h"
00032 #include "changecontainerproperty.h"
00033 #include "servicing.h"
00034 #include "consumeresource.h"
00035 
00036 
00037 bool RepairUnitCommand :: availInternally ( const ContainerBase* servicer )
00038 {
00039    return servicer->baseType->hasFunction( ContainerBaseType::InternalUnitRepair );
00040 }
00041 
00042       
00043 bool RepairUnitCommand :: avail ( const ContainerBase* servicer )
00044 {
00045    if ( !servicer )
00046       return false;
00047    
00048    if ( availInternally( servicer ))
00049       return true;
00050    
00051    const Vehicle* v = dynamic_cast<const Vehicle*>(servicer);
00052    if ( v ) 
00053       return availExternally( v );
00054    else
00055       return false;
00056 }
00057 
00058 
00059 bool RepairUnitCommand :: availExternally ( const Vehicle* veh )
00060 {
00061    if ( !veh )
00062       return false;
00063    
00064    if ( veh && !veh->attacked && veh->reactionfire.getStatus() == Vehicle::ReactionFire::off ) 
00065       if ( veh->typ->hasFunction( ContainerBaseType::ExternalRepair  ))
00066          for ( int i = 0; i < veh->typ->weapons.count; i++ )
00067             if ( veh->typ->weapons.weapon[i].service() )
00068                return true;
00069 
00070    return false;
00071 }
00072 
00073 
00074 
00075 RepairUnitCommand :: RepairUnitCommand ( ContainerBase* container )
00076    : ContainerCommand ( container )
00077 {
00078 }
00079 
00080 
00081 
00082 vector<Vehicle*> RepairUnitCommand :: getExternalTargets()
00083 {
00084    ServiceTargetSearcher sts( getContainer(), ServiceTargetSearcher::checkRepair );
00085    sts.startSearch();
00086    externalTargets.clear();
00087    
00088    for ( ServiceTargetSearcher::Targets::const_iterator i = sts.getTargets().begin(); i != sts.getTargets().end(); ++i )
00089       if ( !(*i)->getCarrier() ) {
00090          Vehicle* v = dynamic_cast<Vehicle*>(*i);
00091          if ( v )
00092             externalTargets.push_back( v );
00093       }
00094    
00095    return externalTargets;
00096 }
00097 
00098 vector<Vehicle*> RepairUnitCommand :: getInternalTargets()
00099 {
00100    ServiceTargetSearcher sts( getContainer(), ServiceTargetSearcher::checkRepair );
00101    sts.startSearch();
00102    
00103    internalTargets.clear();
00104    
00105    for ( ServiceTargetSearcher::Targets::const_iterator i = sts.getTargets().begin(); i != sts.getTargets().end(); ++i )
00106       if ( (*i)->getCarrier() == getContainer() ) {
00107          Vehicle* v = dynamic_cast<Vehicle*>(*i);
00108          if ( v )
00109             internalTargets.push_back( v );
00110       }
00111    
00112    return internalTargets;
00113 }
00114 
00115 
00116 bool RepairUnitCommand::validTarget( const Vehicle* target )
00117 {
00118    ServiceTargetSearcher sts( getContainer(), ServiceTargetSearcher::checkRepair );
00119    sts.startSearch();
00120    for ( ServiceTargetSearcher::Targets::const_iterator i = sts.getTargets().begin(); i != sts.getTargets().end(); ++i )
00121       if ( target == *i ) 
00122          return true;
00123    
00124    return false;
00125 }
00126 
00127 void RepairUnitCommand::setTarget( Vehicle* target )
00128 {
00129    if ( !target )
00130       return;
00131      
00132    if ( validTarget(target) ) {
00133       targetNWid = target->networkid;
00134       setState( SetUp );
00135    }
00136 }
00137 
00138 
00139 
00140 ActionResult RepairUnitCommand::go ( const Context& context )
00141 {
00142    if ( getState() != SetUp )
00143       return ActionResult(22000);
00144 
00145    ContainerBase* servicer = getContainer();
00146    if ( !avail( servicer ))
00147       return ActionResult( 22401 );
00148    
00149    Vehicle* target = getMap()->getUnit( targetNWid );
00150    if ( !target )
00151       return ActionResult( 22400 );
00152    
00153    if ( !validTarget(target))
00154       return ActionResult( 22402 );
00155    
00156    
00157    Resources cost;
00158    int oldDamage = target->damage;
00159    int newDamage = servicer->getMaxRepair ( target, 0, cost );
00160    
00161    auto_ptr<ChangeContainerProperty> propChange ( new ChangeContainerProperty( target, ChangeContainerProperty::Damage, newDamage ));
00162    ActionResult res = propChange->execute( context );
00163    if ( res.successful() )
00164       propChange.release();
00165    else
00166       return res;
00167    
00168    int experience = target->experience;
00169    for ( int i = 0; i < experienceDecreaseDamageBoundaryNum; i++)
00170       if ( oldDamage > experienceDecreaseDamageBoundaries[i] && newDamage < experienceDecreaseDamageBoundaries[i] )
00171          if ( experience > 0 )
00172             experience-=1;
00173    
00174    if ( experience != target->experience ) {
00175       auto_ptr<ChangeUnitProperty> expChange ( new ChangeUnitProperty( target, ChangeUnitProperty::Experience, experience ));
00176       ActionResult res = expChange->execute( context );
00177       if ( res.successful() )
00178          expChange.release();
00179       else
00180          return res;
00181    }
00182    
00183    auto_ptr<ConsumeResource> resource ( new ConsumeResource( getContainer(), cost ));
00184    res = resource->execute( context );
00185    if ( res.successful() )
00186       resource.release();
00187       
00188    
00189    return res;
00190 }
00191 
00192 
00193 
00194 static const int RepairUnitCommandVersion = 1;
00195 
00196 void RepairUnitCommand :: readData ( tnstream& stream )
00197 {
00198    ContainerCommand::readData( stream );
00199    int version = stream.readInt();
00200    if ( version > RepairUnitCommandVersion )
00201       throw tinvalidversion ( "RepairUnitCommand", RepairUnitCommandVersion, version );
00202    targetNWid = stream.readInt();
00203 }
00204 
00205 void RepairUnitCommand :: writeData ( tnstream& stream ) const
00206 {
00207    ContainerCommand::writeData( stream );
00208    stream.writeInt( RepairUnitCommandVersion );
00209    stream.writeInt( targetNWid );
00210 }
00211 
00212 
00213 ASCString RepairUnitCommand :: getCommandString() const
00214 {
00215    ASCString c;
00216    c.format("repairUnit ( map, %d, %d )", getContainerID(), targetNWid );
00217    return c;
00218 
00219 }
00220 
00221 GameActionID RepairUnitCommand::getID() const
00222 {
00223    return ActionRegistry::RepairUnitCommand;
00224 }
00225 
00226 ASCString RepairUnitCommand::getDescription() const
00227 {
00228    ASCString s = "Repair unit " + ASCString::toString( targetNWid );
00229    
00230    if ( getContainer( false ))
00231       s += " with " + getContainer()->getName();
00232    
00233    return s;
00234 }
00235 
00236 ActionResult RepairUnitCommand::checkExecutionPrecondition() const
00237 {
00238    if ( getMap()->getCurrentPlayer().diplomacy.isAllied( getContainer() ))
00239       return ActionResult(0);
00240    else
00241       return ActionResult(101);
00242 }
00243 
00244 
00245 namespace
00246 {
00247    const bool r1 = registerAction<RepairUnitCommand> ( ActionRegistry::RepairUnitCommand );
00248 }
00249 

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