Advanced Strategic Command
servicecommand.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.de
3  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 
22 #include "servicecommand.h"
23 
24 #include "../vehicle.h"
25 #include "../mapfield.h"
26 #include "../gamemap.h"
27 #include "../viewcalculation.h"
28 #include "../spfst.h"
29 #include "../mapdisplayinterface.h"
30 #include "action-registry.h"
31 #include "../itemrepository.h"
32 #include "../containercontrols.h"
33 #include "consumeresource.h"
34 #include "servicing.h"
35 #include "changeunitmovement.h"
36 #include "consumeammo.h"
37 
38 
40 {
42  return sts.externallyAvailable();
43 }
44 
46 {
47  if ( target->getCarrier() == source ) {
48  ServiceCommand sc( source );
50 
51  return find( dest.begin(), dest.end(), target ) != dest.end();
52 
53  } else {
55  if ( !sts.externallyAvailable())
56  return false;
57 
58  return find( sts.getTargets().begin(), sts.getTargets().end(), target ) != sts.getTargets().end();
59  }
60 }
61 
62 
63 ServiceCommand :: ServiceCommand ( ContainerBase* container )
64  : ContainerCommand ( container ), targetSearcher(NULL), transferHandler(NULL),destinationSpecified(false), destinationContainerID(0)
65 {
66 
67 }
68 
70 {
71  delete targetSearcher;
73  targetSearcher->startSearch();
74  return targetSearcher->getTargets();
75 }
76 
78 {
79  destinationSpecified = true;
80  destinationContainerID = destination->getIdentification();
81 }
82 
83 
84 ContainerBase* ServiceCommand::getDestination()
85 {
86  if ( !destinationSpecified )
87  return NULL;
88 
89  return getMap()->getContainer( destinationContainerID );
90 }
91 
92 
94 {
95  delete transferHandler;
96  transferHandler = NULL;
97  if ( !getDestination() )
98  throw ActionResult( 22002 );
99 
100  transferHandler = new TransferHandler( getContainer(), getDestination() );
101 
102  orgValues.clear();
103  TransferHandler::Transfers& transfers = transferHandler->getTransfers();
104  for ( TransferHandler::Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
105  orgValues[ (*i)->getID()] = (*i)->getAmount( (*i)->getDstContainer() );
106 
107  return *transferHandler;
108 }
109 
111 {
112  values.clear();
113  if ( transferHandler ) {
114  TransferHandler::Transfers& transfers = transferHandler->getTransfers();
115  for ( TransferHandler::Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
116  values[ (*i)->getID()] = (*i)->getAmount( (*i)->getDstContainer() );
117 
118  setState( SetUp );
119  }
120 }
121 
122 
124 {
125  if ( getState() != SetUp )
126  return ActionResult(22000);
127 
128 
129  TransferHandler& handler = getTransferHandler();
130 
131  for ( Values::iterator i = values.begin(); i != values.end(); ++i ) {
132  TransferHandler::Transfers& transfers = handler.getTransfers();
133  for ( TransferHandler::Transfers::iterator t = transfers.begin(); t != transfers.end(); ++t )
134  if ( (*t)->getID() == i->first ) {
135  if ( !(*t)->setDestAmount( i->second ) )
136  return ActionResult( 22001, (*t)->getName() );
137  (*t)->commit( context );
138  }
139  }
140 
141  setState( Finished );
142 
143 /*
144  ActionResult res = (new ConsumeResource(getContainer(), cost ))->execute( context );
145 
146  if ( context.display )
147  context.display->repaintDisplay();
148 
149  if ( res.successful() )
150  setState( Completed );
151  else
152  setState( Failed );
153 
154  return res;*/
155  ActionResult res(0);
156  return res;
157 }
158 
159 
160 static const int ServiceCommandVersion = 2;
161 
163 {
164  ContainerCommand::readData( stream );
165  int version = stream.readInt();
166  if ( version > ServiceCommandVersion )
167  throw tinvalidversion ( "ServiceCommand", ServiceCommandVersion, version );
168 
169  destinationSpecified = stream.readInt();
170  destinationContainerID = stream.readInt();
171 
172  int size = stream.readInt();
173  for ( int i = 0; i < size; ++i ) {
174  int key = stream.readInt();
175  int value = stream.readInt();
176  values[key] = value;
177  }
178 
179  orgValues.clear();
180  if ( version >= 2 ) {
181  int size = stream.readInt();
182  for ( int i = 0; i < size; ++i ) {
183  int key = stream.readInt();
184  int value = stream.readInt();
185  orgValues[key] = value;
186  }
187  }
188 }
189 
190 void ServiceCommand :: writeData ( tnstream& stream ) const
191 {
192  ContainerCommand::writeData( stream );
193  stream.writeInt( ServiceCommandVersion );
194 
195  stream.writeInt( destinationSpecified );
196  stream.writeInt( destinationContainerID );
197 
198  stream.writeInt( values.size() );
199  for ( Values::const_iterator i = values.begin(); i != values.end(); ++i ) {
200  stream.writeInt( i->first );
201  stream.writeInt( i->second );
202  }
203 
204  stream.writeInt( orgValues.size() );
205  for ( Values::const_iterator i = orgValues.begin(); i != orgValues.end(); ++i ) {
206  stream.writeInt( i->first );
207  stream.writeInt( i->second );
208  }
209 
210 }
211 
212 
214 {
215  ASCString c;
216  for ( Values::const_iterator i = values.begin(); i != values.end(); ++i ) {
217  if ( orgValues.find(i->first)==orgValues.end() || i->second != orgValues.find(i->first)->second) {
218  ASCString s;
219  s.format("serviceCommand ( map, %d, %d, %d, %d)", getContainerID(), destinationContainerID, i->first, i->second );
220 
221  if ( c.length() )
222  c += "\n";
223 
224  c += s;
225  }
226  }
227  return c;
228 }
229 
231 {
233 }
234 
236 {
237  ASCString s = "Service ";
238 
239  if ( getContainer(true) ) {
240  s += " by " + getContainer()->getName();
241  }
242  return s;
243 }
244 
246 {
247  if ( getMap()->getCurrentPlayer().diplomacy.isAllied( getContainer() ))
248  return ActionResult(0);
249  else
250  return ActionResult(101);
251 }
252 
253 
255 {
256  delete targetSearcher;
257  delete transferHandler;
258 }
259 
260 namespace
261 {
262  const bool r1 = registerAction<ServiceCommand> ( ActionRegistry::ServiceCommand );
263 }
264 
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
int GameActionID
Definition: action.h:35
static const int checkAmmo
Definition: servicing.h:139
the command is totally done
Definition: command.h:120
virtual ASCString getName() const =0
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
void setDestination(ContainerBase *destination)
static const int checkResources
Definition: servicing.h:140
ContainerBase * getContainer(int nwid)
Definition: gamemap.cpp:1231
virtual int getIdentification() const =0
State getState() const
Definition: command.h:125
GameMap * getMap()
Definition: action.h:92
GameActionID getID() const
The interface for all kinds of IO stream.
ASCString & format(const charT *pFormat,...)
Definition: ascstring.cpp:78
void writeData(tnstream &stream) const
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
int getContainerID() const
void readData(tnstream &stream)
void setState(State state)
Definition: command.cpp:44
static const int ServiceCommandVersion
void writeData(tnstream &stream) const
TransferHandler & getTransferHandler()
each call to getTransferHandler will deallocate the previous handler and create a new one Make sure t...
static bool avail(ContainerBase *source, ContainerBase *target)
ContainerBase * getCarrier() const
if this is a unit and it is inside a building or transport, returns the transport. NULL otherwise.
ContainerBase * getContainer(bool dontThrow=false)
ActionResult go(const Context &context)
ActionResult checkExecutionPrecondition() const
vector< ContainerBase * > Targets
Definition: servicing.h:129
ASCString getCommandString() const
void readData(tnstream &stream)
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
const Targets & getTargets() const
Definition: servicing.h:145
ASCString getDescription() const
Transfers & getTransfers()
Definition: servicing.cpp:840
static bool availExternally(ContainerBase *source)
const ServiceTargetSearcher::Targets & getDestinations()