00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "clipboard.h"
00027 #include "vehicle.h"
00028 #include "buildings.h"
00029 #include "gamemap.h"
00030 #include "spfst.h"
00031 #include "dlg_box.h"
00032
00033
00034 const char* clipboardFileExtension = "*.ascclipboard";
00035
00036
00037 ClipBoardBase::ClipBoardBase()
00038 {
00039 objectNum = 0;
00040
00041 }
00042
00043 void ClipBoardBase::clear()
00044 {
00045 buf.clear();
00046 objectNum = 0;
00047 }
00048
00049
00050 void ClipBoardBase::addUnit ( Vehicle* unit )
00051 {
00052 tmemorystream stream ( &buf, tnstream::appending );
00053 stream.writeInt( ClipVehicle );
00054 unit->write ( stream );
00055 objectNum++;
00056 }
00057
00058 void ClipBoardBase::addBuilding ( Building* bld )
00059 {
00060 tmemorystream stream ( &buf, tnstream::appending );
00061 stream.writeInt( ClipBuilding );
00062 bld->write ( stream );
00063 objectNum++;
00064 }
00065
00066
00067 Vehicle* ClipBoardBase::pasteUnit( tnstream& stream )
00068 {
00069 Vehicle* veh = Vehicle::newFromStream( actmap, stream );
00070
00071
00072
00073 return veh;
00074 }
00075
00076 Vehicle* ClipBoardBase::pasteUnit( )
00077 {
00078 if ( !objectNum )
00079 return NULL;
00080
00081 tmemorystream stream ( &buf, tnstream::reading );
00082 Type type = Type(stream.readInt());
00083 if ( type == ClipVehicle )
00084 return pasteUnit ( stream );
00085
00086 return NULL;
00087 }
00088
00089
00090 void ClipBoardBase::place ( const MapCoordinate& pos )
00091 {
00092 if ( !objectNum )
00093 return;
00094
00095 tmemorystream stream ( &buf, tnstream::reading );
00096 Type type = Type(stream.readInt());
00097 if ( type == ClipVehicle ) {
00098 tfield* fld = actmap->getField ( pos );
00099 Vehicle* veh = pasteUnit ( stream );
00100
00101 if ( !fieldAccessible ( fld, veh, -2, NULL, true ) && !actmap->getgameparameter( cgp_movefrominvalidfields) ) {
00102 delete veh;
00103 return;
00104 }
00105
00106 if ( fld->vehicle )
00107 delete fld->vehicle;
00108 fld->vehicle = veh;
00109 veh->setnewposition( pos.x, pos.y );
00110 }
00111 if ( type == ClipBuilding ) {
00112 Building* bld = Building::newFromStream ( actmap, stream, false );
00113
00114 for ( int x = 0; x < 4; x++ )
00115 for ( int y = 0; y < 6; y++ )
00116 if ( bld->typ->fieldExists ( BuildingType::LocalCoordinate( x , y ) )) {
00117 tfield* field = actmap->getField( bld->typ->getFieldCoordinate( pos, BuildingType::LocalCoordinate( x, y) ));
00118 if ( !field ) {
00119 delete bld;
00120 displaymessage("building does not fit here", 1 );
00121 return;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 if ( field->vehicle ) {
00134 delete field->vehicle;
00135 field->vehicle = NULL;
00136 }
00137 if ( field->building ) {
00138 delete field->building;
00139 field->building = NULL;
00140 }
00141 }
00142
00143
00144 bld->chainbuildingtofield( pos );
00145 }
00146 }
00147
00148 static int clipboardVersion = 1;
00149
00150 void ClipBoardBase::write( tnstream& stream )
00151 {
00152 stream.writeInt( clipboardVersion );
00153 stream.writeInt( objectNum );
00154 buf.writetostream ( &stream );
00155 }
00156
00157 void ClipBoardBase::read( tnstream& stream )
00158 {
00159 stream.readInt();
00160 objectNum = stream.readInt();
00161 buf.readfromstream ( &stream );
00162 }
00163