spawnobject.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 #include "spawnobject.h"
00022 #include "action-registry.h"
00023 
00024 #include "removeobject.h"
00025 #include "../vehicle.h"
00026 #include "../gamemap.h"
00027      
00028 SpawnObject::SpawnObject( GameMap* gamemap, const MapCoordinate& position, int objectID, int direction )
00029    : GameAction( gamemap ), pos(position)
00030 {
00031    this->objectID = objectID;
00032    this->direction = direction;
00033    objectLaid = false;
00034    
00035    objectAvailableBeforehand = false;
00036    oldObjectDirection = 0;
00037    objectImmediatelyDisappearsAgain = false;
00038 }
00039       
00040       
00041 ASCString SpawnObject::getDescription() const
00042 {
00043    const ObjectType* object = getMap()->getobjecttype_byid( objectID );
00044    ASCString res ;
00045    if ( object )
00046       res = "Spawn Object of type " + object->getName();
00047    else
00048       res = "Spawn Object " ;
00049    res += " at " + pos.toString();
00050    return  res;
00051 }
00052       
00053 static const int spawnObjectStreamVersion = 3;      
00054       
00055 void SpawnObject::readData ( tnstream& stream ) 
00056 {
00057    int version = stream.readInt();
00058    if ( version < 1 || version > spawnObjectStreamVersion )
00059       throw tinvalidversion ( "SpawnObject", spawnObjectStreamVersion, version );
00060    
00061    objectID = stream.readInt();
00062    pos.read( stream );
00063    direction = stream.readInt();
00064    objectLaid = stream.readInt();
00065    if ( version >= 2 ) {
00066       objectAvailableBeforehand = stream.readInt();
00067       oldObjectDirection = stream.readInt();
00068    } else {
00069       objectAvailableBeforehand = false;
00070       oldObjectDirection = 0;
00071    }
00072    
00073    if ( version >= 3 ) 
00074       objectImmediatelyDisappearsAgain = stream.readInt();
00075    else
00076       objectImmediatelyDisappearsAgain = false;
00077 };
00078       
00079       
00080 void SpawnObject::writeData ( tnstream& stream ) const
00081 {
00082    stream.writeInt( spawnObjectStreamVersion );
00083    stream.writeInt( objectID );
00084    pos.write( stream );
00085    stream.writeInt( direction );
00086    stream.writeInt( objectLaid );
00087    stream.writeInt( objectAvailableBeforehand );
00088    stream.writeInt( oldObjectDirection );
00089    stream.writeInt( objectImmediatelyDisappearsAgain );
00090 };
00091 
00092 
00093 GameActionID SpawnObject::getID() const
00094 {
00095    return ActionRegistry::SpawnObject;
00096 }
00097 
00098 class ActionObjectRemovalStrategy : public MapField::ObjectRemovalStrategy {
00099       const Context& context;
00100       const ObjectType* originalObject;
00101       bool immediateRemoval;
00102    public:
00103       ActionObjectRemovalStrategy( const Context& actionContext, const ObjectType* object ) 
00104    : context( actionContext ), originalObject( object ), immediateRemoval(false)
00105       {}
00106       
00107       virtual void removeObject( MapField* fld, const ObjectType* objectType ) {
00108          if ( objectType != originalObject )
00109             (new RemoveObject( fld->getMap(), fld->getPosition(), objectType->id ))->execute( context );
00110          else {
00111             for ( MapField::ObjectContainer::iterator o = fld->objects.begin(); o != fld->objects.end();  ) {
00112                if ( o->typ == objectType ) {
00113                   o = fld->objects.erase( o );
00114                } else
00115                   ++o ;
00116             }
00117             
00118             immediateRemoval = true;
00119          }
00120       };
00121    
00122       bool getImmediateRemoval() 
00123       {
00124          return immediateRemoval;
00125       }
00126 };
00127 
00128 ActionResult SpawnObject::runAction( const Context& context )
00129 {
00130    MapField* fld = getMap()->getField(pos);
00131    if ( !fld )
00132       return ActionResult( 21002, pos );
00133    
00134    const ObjectType* object = getMap()->getobjecttype_byid( objectID );
00135    if ( !object )
00136       return ActionResult( 21201, "Object id is " + ASCString::toString(objectID));
00137    
00138    Object* old = fld->checkForObject( object );
00139    if ( old ) {
00140       objectAvailableBeforehand = true;
00141       oldObjectDirection = old->dir;
00142    } else {
00143       objectAvailableBeforehand = false;
00144       oldObjectDirection = 0;
00145    }
00146    
00147    ActionObjectRemovalStrategy aors( context, object );
00148    objectLaid = fld->addobject( object, direction, false, &aors );
00149    
00150    objectImmediatelyDisappearsAgain = aors.getImmediateRemoval();
00151    return ActionResult(0);
00152 }
00153 
00154 
00155 ActionResult SpawnObject::undoAction( const Context& context )
00156 {
00157    MapField* fld = getMap()->getField(pos);
00158    if ( !fld )
00159       return ActionResult( 21002, pos );
00160    
00161    const ObjectType* object = getMap()->getobjecttype_byid( objectID );
00162    if ( !object )
00163       return ActionResult( 21201, "Object id is " + ASCString::toString(objectID));
00164    
00165    if ( objectAvailableBeforehand ) {
00166       Object* o = fld->checkForObject( object );
00167       if ( !o )
00168          return ActionResult( 21505 );
00169       o->dir = oldObjectDirection;
00170    } else
00171       if ( !objectImmediatelyDisappearsAgain )
00172          fld->removeObject( object, true );
00173       
00174    return ActionResult(0);
00175 }
00176 
00177 ActionResult SpawnObject::verify()
00178 {
00179    return ActionResult(0);
00180 }
00181 
00182 
00183 namespace {
00184    const bool r1 = registerAction<SpawnObject> ( ActionRegistry::SpawnObject );
00185 }
00186 

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