destructbuildingcommand.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 "destructbuildingcommand.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 "../itemrepository.h"
00032 #include "../containercontrols.h"
00033 #include "changeunitproperty.h"
00034 #include "spawnbuilding.h"
00035 #include "changeunitmovement.h"
00036 #include "consumeresource.h"
00037 #include "destructcontainer.h"
00038 
00039 
00040 
00041 bool DestructBuildingCommand :: avail ( const Vehicle* eht )
00042 {
00043    if ( !eht )
00044       return false;
00045 
00046    if ( eht->attacked == false && !eht->hasMoved() )
00047       if ( eht->getOwner() == eht->getMap()->actplayer )
00048             if ( eht->typ->hasFunction( ContainerBaseType::ConstructBuildings  ) || !eht->typ->buildingsBuildable.empty() )
00049                if ( eht->getTank().fuel >= destruct_building_fuel_usage * eht->typ->fuelConsumption )
00050                   return true;
00051 
00052    return false;
00053 }
00054 
00055 
00056 DestructBuildingCommand :: DestructBuildingCommand ( Vehicle* container )
00057       : UnitCommand ( container )
00058 {
00059 
00060 }
00061 
00062 Resources DestructBuildingCommand::getDestructionCost( const Building* bld) const 
00063 {
00064    Resources r;
00065    r.material = - bld->typ->productionCost.material * (100 - bld->damage) / destruct_building_material_get / 100;
00066    r.fuel = destruct_building_fuel_usage * getUnit()->typ->fuelConsumption;
00067    return r;
00068 }
00069 
00070 
00071 vector<MapCoordinate> DestructBuildingCommand::getFields()
00072 {
00073    vector<MapCoordinate> fields;
00074    Vehicle* veh = getUnit();
00075    for ( int d = 0; d < 6; ++d ) {
00076       MapCoordinate pos = getNeighbouringFieldCoordinate( veh->getPosition(), d );
00077       MapField* fld = getMap()->getField(pos);
00078       if ( fld )
00079          if ( fld->building && getheightdelta( getFirstBit(veh->height), getFirstBit(fld->building->typ->height)) == 0 && !fld->building->typ->buildingNotRemovable ) 
00080             fields.push_back( pos );
00081    }
00082 
00083    return fields;
00084 }
00085 
00086 bool DestructBuildingCommand :: isFieldUsable( const MapCoordinate& pos )
00087 {
00088    vector<MapCoordinate> fields = getFields();
00089    return find( fields.begin(), fields.end(), pos ) != fields.end() ;
00090 }
00091 
00092 
00093 void DestructBuildingCommand :: setTargetPosition( const MapCoordinate& pos )
00094 {
00095    this->target = pos;
00096    MapField* fld = getMap()->getField(target);
00097 
00098    if ( !fld )
00099       throw ActionResult(21002);
00100 
00101    setState( SetUp );
00102 
00103 }
00104 
00105 
00106 
00107 ActionResult DestructBuildingCommand::go ( const Context& context )
00108 {
00109    if ( getState() != SetUp )
00110       return ActionResult(22000);
00111    
00112    
00113    Building* building = getMap()->getField( target )->building;
00114    if ( !building )
00115       return ActionResult(22502);
00116    
00117    const BuildingType* buildingType = building->typ;
00118    
00119    Resources cost = getDestructionCost( building );
00120    
00121    auto_ptr<DestructContainer> dc ( new DestructContainer( building, true ));
00122    ActionResult res = dc->execute( context );
00123    if ( res.successful() )
00124       dc.release();
00125    else
00126       return res;
00127    
00128    auto_ptr<ConsumeResource> cr ( new ConsumeResource( getUnit(), cost ));
00129    res = cr->execute( context );
00130    if ( res.successful() )
00131       cr.release();
00132    else
00133       return res;
00134    
00135    auto_ptr<ChangeUnitMovement> cum ( new ChangeUnitMovement( getUnit(), 0 ));
00136    res = cum->execute( context );
00137    if ( res.successful() )
00138       cum.release();
00139    else
00140       return res;
00141 
00142    auto_ptr<ChangeUnitProperty> cup ( new ChangeUnitProperty( getUnit(), ChangeUnitProperty::AttackedFlag, 1 ));
00143    res = cup->execute( context );
00144    if ( res.successful() )
00145       cup.release();
00146    else
00147       return res;
00148    
00149    evaluateviewcalculation( getMap(), target, buildingType->view, 0, false, &context );
00150 
00151    
00152    if ( context.display )
00153       context.display->repaintDisplay();
00154 
00155    return ActionResult(0);
00156 }
00157 
00158 
00159 
00160 static const int DestructBuildingCommandVersion = 1;
00161 
00162 void DestructBuildingCommand :: readData ( tnstream& stream )
00163 {
00164    UnitCommand::readData( stream );
00165    int version = stream.readInt();
00166    if ( version > DestructBuildingCommandVersion )
00167       throw tinvalidversion ( "DestructBuildingCommand", DestructBuildingCommandVersion, version );
00168    target.read( stream );
00169 }
00170 
00171 void DestructBuildingCommand :: writeData ( tnstream& stream ) const
00172 {
00173    UnitCommand::writeData( stream );
00174    stream.writeInt( DestructBuildingCommandVersion );
00175    target.write( stream );
00176 }
00177 
00178 
00179 
00180 ASCString DestructBuildingCommand :: getCommandString() const
00181 {
00182    ASCString c;
00183    c.format("unitDestructBuilding ( map, %d, asc.MapCoordinate(%d, %d) )", getUnitID(), target.x, target.y );
00184    return c;
00185 }
00186 
00187 GameActionID DestructBuildingCommand::getID() const
00188 {
00189    return ActionRegistry::DestructBuildingCommand;
00190 }
00191 
00192 ASCString DestructBuildingCommand::getDescription() const
00193 {
00194    ASCString s = "Destruct building at "+ target.toString() ;
00195 
00196 
00197    if ( getUnit() ) {
00198       s += " with " + getUnit()->getName();
00199    }
00200    return s;
00201 }
00202 
00203 namespace
00204 {
00205 const bool r1 = registerAction<DestructBuildingCommand> ( ActionRegistry::DestructBuildingCommand );
00206 }
00207 

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