changeunitmovement.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 <cmath>
00023 
00024 #include "changeunitmovement.h"
00025 #include "changeunitproperty.h"
00026 #include "action-registry.h"
00027 
00028 #include "../vehicle.h"
00029 #include "../gamemap.h"
00030      
00031       
00032 ChangeUnitMovement::ChangeUnitMovement( Vehicle* veh, int movement, bool delta, Recursivity recursive )
00033    : UnitAction( veh->getMap(), veh->networkid ), originalMovement(-1), resultingMovement(-1)
00034 {
00035    this->movement = movement;
00036    this->delta = delta;
00037    this->recursive = recursive;
00038 }
00039       
00040       
00041 ASCString ChangeUnitMovement::getDescription() const
00042 {
00043    ASCString res = "Change movement ";
00044    if ( getUnit(false) ) 
00045       res += " of unit " + getUnit(false)->getName();
00046    
00047    if ( delta )
00048       res += " by ";
00049    else 
00050       res += " to ";
00051    res += ASCString::toString(movement) + " points ";
00052    return  res;
00053 }
00054       
00055 static const int changeUnitMovementStreamVersion = 2;      
00056       
00057 void ChangeUnitMovement::readData ( tnstream& stream ) 
00058 {
00059    UnitAction::readData( stream );
00060    int version = stream.readInt();
00061    if ( version < 1 || version > changeUnitMovementStreamVersion )
00062       throw tinvalidversion ( "ChangeUnitMovement", changeUnitMovementStreamVersion, version );
00063    
00064    movement = stream.readInt();
00065    delta = stream.readInt();
00066    originalMovement = stream.readInt();
00067    resultingMovement = stream.readInt();
00068    if ( version >= 2 )
00069       recursive = (Recursivity) stream.readInt();
00070    else
00071       recursive = NORMAL;
00072 };
00073       
00074       
00075 void ChangeUnitMovement::writeData ( tnstream& stream ) const
00076 {
00077    UnitAction::writeData( stream );
00078    stream.writeInt( changeUnitMovementStreamVersion );
00079    stream.writeInt( movement );
00080    stream.writeInt( delta );
00081    stream.writeInt( originalMovement );
00082    stream.writeInt( resultingMovement );
00083    stream.writeInt( (int) recursive );
00084 };
00085 
00086 
00087 GameActionID ChangeUnitMovement::getID() const
00088 {
00089    return ActionRegistry::ChangeUnitMovement;
00090 }
00091 
00092 void ChangeUnitMovement::decreaseMovement( Vehicle* veh, float fraction, const Context& context )
00093 {
00094    if ( recursive != NONE )
00095       if ( veh->typ->movement[ getFirstBit ( veh->height ) ] ) {
00096          float cargoFraction = fraction;
00097          if ( veh->cargoNestingDepth() == 0 && veh->typ->cargoMovementDivisor != 0 && recursive == NORMAL )
00098             cargoFraction /= veh->typ->cargoMovementDivisor;
00099             
00100          for ( Vehicle::Cargo::const_iterator i = veh->getCargo().begin(); i != veh->getCargo().end(); ++i )
00101             if ( *i ) 
00102                decreaseMovement( *i, cargoFraction, context );
00103       }
00104       
00105    float f = float(veh->maxMovement()) * fraction;
00106    float f2 = ceil(f);
00107    if ( fabs ( f-f2) > 0.999 )
00108            f2 -= 1;
00109    
00110    int i = int( f2 );
00111    int newMovement = veh->getMovement(false,false) - i;
00112    
00113    (new ChangeUnitProperty(veh, ChangeUnitProperty::Movement, newMovement ))->execute( context );
00114 }
00115 
00116 
00117 ActionResult ChangeUnitMovement::runAction( const Context& context )
00118 {
00119    Vehicle* veh = getUnit();
00120    
00121    originalMovement = veh->getMovement( false, false );
00122    
00123    float fraction;
00124    if ( delta ) {
00125       fraction = float(movement) / float( veh->maxMovement());
00126    } else {
00127       fraction = float(originalMovement - movement) / float( veh->maxMovement());
00128    }
00129    
00130    decreaseMovement( veh, fraction, context );
00131    
00132    resultingMovement = veh->getMovement( false, false );
00133    return ActionResult(0);
00134 }
00135 
00136 
00137 ActionResult ChangeUnitMovement::undoAction( const Context& context )
00138 {
00139    return ActionResult(0);
00140 }
00141 
00142 ActionResult ChangeUnitMovement::preCheck()
00143 {
00144    if ( getUnit()->getMovement( false, false ) != originalMovement )
00145       throw ActionResult( 21103, getUnit() );
00146    
00147    return ActionResult(0);
00148 }
00149 
00150 ActionResult ChangeUnitMovement::postCheck()
00151 {
00152    if ( getUnit()->getMovement( false, false ) != resultingMovement )
00153       throw ActionResult( 21103, getUnit() );
00154    
00155    return ActionResult(0);
00156 }
00157 
00158 
00159 namespace {
00160    const bool r1 = registerAction<ChangeUnitMovement> ( ActionRegistry::ChangeUnitMovement );
00161 }

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