Advanced Strategic Command
replay.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  replay.cpp - description
3  -------------------
4  begin : Sun Jan 21 2001
5  copyright : (C) 2001 by Martin Bickel
6  email : bickel@asc-hq.org
7  ***************************************************************************/
8 
16 /***************************************************************************
17  * *
18  * This program is free software; you can redistribute it and/or modify *
19  * it under the terms of the GNU General Public License as published by *
20  * the Free Software Foundation; either version 2 of the License, or *
21  * (at your option) any later version. *
22  * *
23  ***************************************************************************/
24 
25 #include <stdarg.h>
26 #include "replay.h"
27 #include "typen.h"
28 #include "buildingtype.h"
29 #include "vehicletype.h"
30 #include "spfst.h"
31 #include "controls.h"
32 #include "dialog.h"
33 #include "gameoptions.h"
34 #include "viewcalculation.h"
35 #include "itemrepository.h"
36 #include "containercontrols.h"
37 #include "resourcenet.h"
38 #include "guiiconhandler.h"
39 #include "guifunctions.h"
40 #include "cannedmessages.h"
41 #include "spfst-legacy.h"
42 #include "replaymapdisplay.h"
43 #include "asc-mainscreen.h"
44 #include "loaders.h"
45 #include "turncontrol.h"
46 #include "widgets/textrenderer.h"
48 #include "reactionfire.h"
49 #include "gameeventsystem.h"
50 #include "sdl/graphicsqueue.h"
51 #include "video/videorecorder.h"
52 #include "iconrepository.h"
53 #include "dialogs/replayrecorder.h"
54 #include "sg.h"
55 #include "actions/action.h"
63 #include "actions/consumeammo.h"
68 #include "researchexecution.h"
69 
71 
73 
74 
137 
138 
139 
140 class ReplayRecorder;
141 
143  ReplayRecorder* recorder;
144  public:
145  ReplayRecorderWatcherGlobal() : recorder( NULL ) {};
146  void set( ReplayRecorder* rec ) {
147  recorder = rec;
148  }
149 
152 
153 
154  class ReplayRecorder : public sigc::trackable {
155 
156  VideoRecorder* rec;
157  sigc::connection connection;
158  bool movieModeStorage;
159  ASCString lastFilename;
160 
161  public:
162  ReplayRecorder() : rec (NULL)
163  {
164  movieModeStorage = CGameOptions::Instance()->replayMovieMode;
166  }
167 
168  void start( const ASCString& filename, bool append, int framerate, int ascFramerateLimit, int quality )
169  {
170  lastFilename = filename;
171  movieModeStorage = CGameOptions::Instance()->replayMovieMode;
173  ASCString newFilename = constructFileName( 0, "", filename );
174  if ( !rec || !append || newFilename != rec->getFilename() ) {
175  delete rec;
176  rec = new VideoRecorder( newFilename, PG_Application::GetScreen(), framerate, ascFramerateLimit, quality );
177  }
178 
179  if ( !connection.connected() )
180  connection = postScreenUpdate.connect( sigc::mem_fun( *this, &ReplayRecorder::screenUpdate ));
181  }
182 
183  void pause()
184  {
185  if ( connection.connected() )
186  connection.disconnect();
187  CGameOptions::Instance()->replayMovieMode = movieModeStorage;
188  }
189 
190  void close()
191  {
192  pause();
193  delete rec;
194  rec = NULL;
195  }
196 
197  bool isRunning()
198  {
199  return connection.connected() && rec;
200  }
201 
202  bool isOpen()
203  {
204  return rec != NULL;
205  }
206 
208  {
209  return lastFilename;
210  }
211 
212  private:
213  void screenUpdate( const SDL_Surface* surf )
214  {
215  if ( rec )
216  rec->storeFrame( surf );
217  }
218 };
219 
221  ReplayRecorder* recorder;
222  public:
223  ReplayRecorderWatcherLocal( ReplayRecorder* rec ) : recorder( rec ) {};
225  {
226  if ( recorder )
227  recorder->pause();
228  }
229 };
230 
231 
233 {
234  if ( recorder )
235  recorder->pause();
236 }
237 
238 
240 
241 
242 
243 namespace ReplayGuiFunctions {
244 
245 class ReplayPlay : public GuiFunction
246 {
247  public:
248  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
249  {
250  if ( runreplay.status == 1 )
251  return true;
252 
253  return false;
254  };
255 
256  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
257  {
258  runreplay.status = 2;
259  updateFieldInfo();
260  }
261 
262  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
263  {
264  return IconRepository::getIcon("replay-play.png");
265  };
266 
267  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
268  {
269  return "start re~p~lay";
270  };
271 
272  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
273  {
274  return ( key->keysym.unicode == 'p' );
275  };
276 
277 };
278 
279 
280 class ReplayPause : public GuiFunction
281 {
282  public:
283  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
284  {
285  if ( runreplay.status == 2 )
286  return true;
287 
288  return false;
289  };
290 
291  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
292  {
293  runreplay.status = 1;
294  updateFieldInfo();
295  }
296 
297  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
298  {
299  return IconRepository::getIcon("replay-pause.png");
300  };
301 
302  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
303  {
304  return "~p~ause replay";
305  };
306 
307  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
308  {
309  return ( key->keysym.unicode == 'p' );
310  };
311 
312 };
313 
314 
315 
316 class ReplayFaster : public GuiFunction
317 {
318  public:
319  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
320  {
321  if ( runreplay.status == 2 )
322  if ( CGameOptions::Instance()->replayspeed > 0 )
323  return true;
324 
325  return false;
326  };
327 
328  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
329  {
330  if ( CGameOptions::Instance()->replayspeed > 20 )
332  else
334 
336  displaymessage2 ( "delay set to %d / 100 sec", CGameOptions::Instance()->replayspeed );
337  updateFieldInfo();
338  }
339 
340  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
341  {
342  return IconRepository::getIcon("replay-faster.png");
343  };
344 
345  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
346  {
347  return "increase replay speed (~+~)";
348  };
349 
350  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
351  {
352  return ( key->keysym.unicode == '+' || key->keysym.sym == SDLK_KP_PLUS);
353  };
354 
355 };
356 
357 
358 class ReplaySlower : public GuiFunction
359 {
360  public:
361  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
362  {
363  if ( runreplay.status == 2 )
364  return true;
365 
366  return false;
367  };
368 
369  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
370  {
373  displaymessage2 ( "delay set to %d / 100 sec", CGameOptions::Instance()->replayspeed );
374  updateFieldInfo();
375  }
376 
377  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
378  {
379  return IconRepository::getIcon("replay-slow.png");
380  };
381 
382  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
383  {
384  return "decrease replay speed (~-~)";
385  };
386 
387  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
388  {
389  return ( key->keysym.unicode == '-' || key->keysym.sym == SDLK_KP_MINUS);
390  };
391 
392 };
393 
394 
395 class ReplayRewind : public GuiFunction
396 {
397  public:
398  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
399  {
400  if ( runreplay.status == 1 || runreplay.status == 10 )
401  return true;
402 
403  return false;
404  };
405 
406  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
407  {
408  runreplay.status = 101;
409  updateFieldInfo();
410  }
411 
412  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
413  {
414  return IconRepository::getIcon("replay-back.png");
415  };
416 
417  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
418  {
419  return "~r~estart replay";
420  };
421 
422  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
423  {
424  return ( key->keysym.unicode == 'r' );
425  };
426 
427 };
428 
429 
430 class ReplayExit : public GuiFunction
431 {
432  public:
433  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
434  {
435  if ( runreplay.status == 1 || runreplay.status == 10 || runreplay.status == 11 )
436  return true;
437 
438  return false;
439  };
440 
441  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
442  {
443  runreplay.status = 100;
444  updateFieldInfo();
445  }
446 
447  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
448  {
449  return IconRepository::getIcon("replay-exit.png");
450  };
451 
452  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
453  {
454  return "e~x~it replay";
455  };
456 
457  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
458  {
459  return ( key->keysym.unicode == 'x' );
460  };
461 
462 };
463 
464 class ReplayRecord : public GuiFunction
465 {
466  public:
467  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
468  {
469  if ( runreplay.status == 1 )
470  return true;
471 
472  return false;
473  };
474 
475  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
476  {
477  ASCString filename;
478  bool open = false;
479  if ( replayRecorder ) {
480  filename = replayRecorder->getLastFilename();
481  open = replayRecorder->isOpen();
482  }
483 
484  ReplayRecorderDialog rrd( filename, open );
485  rrd.Show();
486  rrd.RunModal();
487  rrd.Hide();
488 
489  if ( !replayRecorder )
490  replayRecorder = new ReplayRecorder();
491  replayRecorder->start( rrd.getFilename(), rrd.getAppend(), rrd.getFramerate(), rrd.getASCFramerateLimit(), rrd.getQuality() );
492 
493  runreplay.status = 2;
494  updateFieldInfo();
495  }
496 
497  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
498  {
499  return IconRepository::getIcon("replay-record.png");
500  };
501 
502  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
503  {
504  return "record to ~v~ideo";
505  };
506 
507  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
508  {
509  return ( key->keysym.unicode == 'v' );
510  };
511 
512 };
513 
515 {
516  public:
517  bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
518  {
519  if ( replayRecorder && replayRecorder->isOpen() && (runreplay.status == 1 || runreplay.status == 10 || runreplay.status == 11) )
520  return true;
521 
522  return false;
523  };
524 
525  void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
526  {
527  replayRecorder->close();
528  runreplay.status = 100;
529  updateFieldInfo();
530  }
531 
532  Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
533  {
534  return IconRepository::getIcon("replay-record-stop.png");
535  };
536 
537  ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
538  {
539  return "exit replay and ~c~lose recording";
540  };
541 
542  bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
543  {
544  return ( key->keysym.unicode == 'c' );
545  };
546 
547 };
548 
549 
550 }
551 
553 {
555 #ifdef XVIDEXPORT
557 #endif
562 #ifdef XVIDEXPORT
564 #endif
566 }
567 
568 
569 
571  static GuiIconHandler* replayIconHandler;
572  bool active;
573  public:
575  {
576  if ( !replayIconHandler ) {
577  replayIconHandler = new GuiIconHandler();
578  registerReplayGuiFunctions( *replayIconHandler );
579  }
580 
581  if ( NewGuiHost::getIconHandler() != replayIconHandler ) {
582  active = true;
583  NewGuiHost::pushIconHandler( replayIconHandler );
584  } else
585  active = false;
586  };
587 
589  {
590  if ( active )
592  };
593 };
594 GuiIconHandler* ReplayGuiIconHandleHandler::replayIconHandler = NULL;
595 
596 
597 
598 
599 
600 void runSpecificReplay( int player, int viewingplayer, bool performEndTurnOperations )
601 {
602  if ( actmap->replayinfo->map[player] && actmap->replayinfo->guidata[player] ) {
603  try {
604  int t;
605  do {
606  t = runreplay.run ( player, viewingplayer, performEndTurnOperations );
607  } while ( t ); /* enddo */
608  }
609 
610  catch ( const ActionResult& res ) {
611  // displayActionError( res );
612  delete actmap;
613  actmap = NULL;
614  throw NoMapLoaded();
615  }
616 
617 #ifndef ASC_DEBUG
618  catch ( ... ) { // this will catch NullPointer-Exceptions and stuff like that, which we want to pass to the debugger in debug mode
619 #else
620  catch ( GameMap m ) { // will never be thrown, but we need catch statement for the try block
621 #endif
622  errorMessage("An unrecognized error occured during the replay");
623  delete actmap;
624  actmap = NULL;
625  throw NoMapLoaded();
626  }
627  }
628 }
629 
630 void viewOwnReplay( Player& player )
631 {
632  if ( player.stat == Player::human || player.stat == Player::supervisor )
633  if ( CGameOptions::Instance()->debugReplay && player.getParentMap()->replayinfo )
634  if (choice_dlg("run replay of your turn ?","~y~es","~n~o") == 1) {
635  // cursor.gotoxy( actmap->cursorpos.position[oldplayer].cx, actmap->cursorpos.position[oldplayer].cy );
636  runSpecificReplay ( player.getPosition(), player.getPosition(), false );
637  }
638 }
639 
640 
642 {
643  if ( !actmap->replayinfo )
644  return;
645 
646  int rpnum = 0;
647  int s = actmap->actplayer + 1;
648  if ( s >= 8 )
649  s = 0;
650  while ( s != actmap->actplayer ) {
651  if ( actmap->replayinfo->map[s] && actmap->replayinfo->guidata[s] )
652  rpnum++;
653 
654  if ( s < 7 )
655  s++;
656  else
657  s = 0;
658  }
659 
660 
662  if (choice_dlg("run replay of last turn ?","~y~es","~n~o") == 1) {
663 
665  ReplayGuiIconHandleHandler guiIconHandler;
666 
667  int s = actmap->actplayer + 1;
668  if ( s >= 8 )
669  s = 0;
670  while ( s != actmap->actplayer ) {
671  if ( s >= 8 )
672  s = 0;
673 
675 
676  if ( s < 7 )
677  s++;
678  else
679  s = 0;
680  }
681 
682 
683  }
684 }
685 
686 
687 void initReplayLogging( Player& player )
688 {
689  GameMap* gamemap = player.getParentMap();
690 
691  if ( startreplaylate ) {
692  gamemap->replayinfo = new GameMap::ReplayInfo;
693  startreplaylate = 0;
694  }
695 
696  if ( gamemap->replayinfo && player.stat != Player::off ) {
697  if ( gamemap->replayinfo->actmemstream )
698  fatalError( "actmemstream already open at begin of turn " );
699 
700  if ( gamemap->replayinfo->guidata[ player.getPosition() ] ) {
701  delete gamemap->replayinfo->guidata[ player.getPosition() ];
702  gamemap->replayinfo->guidata[ player.getPosition() ] = NULL;
703  }
704 
705  savereplay ( gamemap, player.getPosition() );
706 
707  gamemap->replayinfo->guidata[ player.getPosition() ] = new MemoryStreamStorage;
708  gamemap->replayinfo->actmemstream = new MemoryStream ( gamemap->replayinfo->guidata[ player.getPosition() ], tnstream::writing );
709  }
710 }
711 
712 
714  : ri ( _ri )
715 {
717 }
718 
720 {
722 }
723 
724 
726 {
727  Resources res = veh->getTank();
728  for ( ContainerBase::Cargo::const_iterator i = veh->getCargo().begin(); i != veh->getCargo().end(); ++i )
729  if ( *i )
730  res += getUnitResourceCargo ( *i );
731  return res;
732 }
733 
735  GameMap* gamemap;
736  public:
737  LogActionIntoReplayInfo( GameMap* map ) : gamemap( map ) {
738 
739  };
740 
741  void saveCommand( const Command& cmd )
742  {
743  if ( gamemap->replayinfo && gamemap->replayinfo->actmemstream && !gamemap->replayinfo->stopRecordingActions) {
744  tnstream* stream = gamemap->replayinfo->actmemstream;
745 
746  stream->writeUint8( rpl_runCommandAction );
747 
748  MemoryStreamStorage buff;
749  {
750  MemoryStream stream2( &buff, tnstream::writing );
751  cmd.write( stream2 );
752  }
753 
754  // size is counted in 4 Byte chunks, so we need padding bytes
755  int size = (buff.getSize()+3)/4;
756  stream->writeInt( size + 1 );
757 
758  int padding = size*4 - buff.getSize();
759  stream->writeInt( padding );
760 
761  buff.writetostream( stream );
762  for ( int i = 0; i < padding;++i )
763  stream->writeUint8( 255-i );
764  }
765  }
766 };
767 
768 static void logActionToReplay( GameMap* map, Command& command)
769 {
770  LogActionIntoReplayInfo lairi( map );
771  lairi.saveCommand( command );
772 }
773 
774 
776 {
777  Context context;
778 
779  context.gamemap = actmap;
780  context.actingPlayer = &actmap->getPlayer( actmap->actplayer );
781  context.parentAction = NULL;
782 
783  if ( !replayMapDisplay )
784  replayMapDisplay = new ReplayMapDisplay( &getDefaultMapDisplay() );
785 
786  context.display = replayMapDisplay;
787  context.viewingPlayer = actmap->getPlayerView();
788  context.actionContainer = &actmap->actions;
789  return context;
790 }
791 
792 
793 
794 
796 {
797  replayMapDisplay = NULL;
798  status = -1;
799  movenum = 0;
800 }
801 
803 {
804  delete replayMapDisplay;
805 }
806 
807 void trunreplay::error( const ActionResult& res )
808 {
809  error( ASCString(getmessage(res.getCode() )) + res.getMessage() );
810 }
811 
812 void trunreplay::error( const MapCoordinate& pos, const ASCString& message )
813 {
814  error( message );
815 }
816 
817 
818 void trunreplay::error( const MapCoordinate& pos, const char* message, ... )
819 {
820  if ( CGameOptions::Instance()->replayMovieMode )
821  return;
822 
823  va_list paramlist;
824  va_start ( paramlist, message );
825  char tempbuf[1000];
826  int lng = vsprintf( tempbuf, message, paramlist );
827 
828  assert(lng < 1000);
829  error( tempbuf );
830  // error( message + "\nPosition: " + pos.toString() );
831 }
832 
833 void trunreplay::error( const char* message, ... )
834 {
835  if ( CGameOptions::Instance()->replayMovieMode )
836  return;
837 
838  if ( message != lastErrorMessage ) {
839  va_list paramlist;
840  va_start ( paramlist, message );
841 
842  char tempbuf[1000];
843 
844  int lng = vsprintf( tempbuf, message, paramlist );
845  if ( lng >= 1000 )
846  displaymessage ( "trunreplay::error: String to long !\nPlease report this error", 1 );
847 
848  va_end ( paramlist );
849 
850  displaymessage(tempbuf, 1 );
851  lastErrorMessage = message;
852  }
853 }
854 
855 void trunreplay::error( const ASCString& message )
856 {
857  if ( CGameOptions::Instance()->replayMovieMode )
858  return;
859 
860  if ( message != lastErrorMessage ) {
861  displaymessage(message.c_str(), 1 );
862  lastErrorMessage = message;
863  }
864 }
865 
866 
867 
868 
869 void trunreplay :: wait ( int t )
870 {
871 // if ( fieldvisiblenow ( getactfield(), actmap->playerView ))
872  while ( ticker < t + CGameOptions::Instance()->replayspeed && !keypress()) {
873  /*
874  tkey input;
875  while (keypress ()) {
876  input = r_key ( );
877  if ( input == ct_'+' )
878  }
879  */
881  }
882 }
883 
885 {
886  if ( fieldvisiblenow ( actmap->getField ( pos ), actmap->getPlayerView() ))
887  wait();
888 }
889 
891 {
893  wait();
894 }
895 
896 
897 /*
898 void trunreplay :: setcursorpos ( int x, int y )
899 {
900  int i = fieldvisiblenow ( getfield ( x, y ), actmap->playerview );
901  cursor.gotoxy ( x, y, i );
902  if( i ) {
903  lastvisiblecursorpos.x = x;
904  lastvisiblecursorpos.y = y;
905  }
906 }
907 */
908 
909 
910 void trunreplay :: displayActionCursor ( int x1, int y1, int x2, int y2, int secondWait )
911 {
913  rmd.setCursorDelay ( CGameOptions::Instance()->replayspeed );
914  rmd.displayActionCursor ( x1, y1, x2, y2, secondWait );
915 }
916 
918 {
920  rmd.removeActionCursor ( );
921 }
922 
923 
925 {
926 
927  static int lastTicker = ticker;
928 
929  if ( lastTicker + 10 < ticker ) {
930  displayLogMessage( 8, "executing replay move %d\n", movenum );
931  lastTicker = ticker;
932  }
933 
934  if ( !replayRecorder || !replayRecorder->isRunning())
935  displaymessage2("executing replay move %d\n", movenum );
936 
937  movenum++;
938  int actaction = nextaction;
939  if ( nextaction != rpl_finished ) {
940  switch ( nextaction ) {
941  case rpl_move: {
942  stream->readInt(); // size
943  int x1 = stream->readInt();
944  int y1 = stream->readInt();
945  int x2 = stream->readInt();
946  int y2 = stream->readInt();
947  int nwid = stream->readInt();
948  readnextaction();
949 
950  Vehicle* eht = actmap->getUnit ( x1, y1, nwid );
951  if ( eht ) {
953 
954 
955  auto_ptr<MoveUnitCommand> muc ( new MoveUnitCommand( eht ));
956  muc->setDestination( MapCoordinate(x2,y2) );
957 
958  int t = ticker;
959  wait( MapCoordinate(x1,y1), MapCoordinate(x2,y2), t );
960 
961  ActionResult res = muc->execute( createReplayContext() );
962  if ( res.successful() )
963  muc.release();
964  else
965  error("severe replay inconsistency:\nerror for move1 command at " + MapCoordinate(x1,y1).toString() );
966  }
967 
968  if ( !eht )
969  error("severe replay inconsistency:\nno vehicle for move1 command at " + MapCoordinate(x1,y1).toString() );
970  }
971  break;
972  case rpl_move5:
973  case rpl_move4:
974  case rpl_move3:
975  case rpl_move2: {
976  stream->readInt(); // size
977  int x1 = stream->readInt();
978  int y1 = stream->readInt();
979  int x2 = stream->readInt();
980  int y2 = stream->readInt();
981  int nwid = stream->readInt();
982  int height = stream->readInt();
983 
985  stream->readInt(); // noInterrupt
986 
987  int destDamage;
988  if ( nextaction == rpl_move5 )
989  destDamage = stream->readInt();
990  else
991  destDamage = -1;
992 
993  readnextaction();
994 
995  Vehicle* eht = actmap->getUnit ( x1, y1, nwid );
996  if ( eht ) {
997  auto_ptr<MoveUnitCommand> muc ( new MoveUnitCommand( eht ));
998 
999  int t = ticker;
1000  wait( MapCoordinate(x1,y1), MapCoordinate(x2,y2), t );
1001 
1002  MapCoordinate3D dest ( x2,y2, 0 );
1003  dest.setNumericalHeight(height);
1004  muc->setDestination( dest );
1005 
1006  ActionResult res = muc->execute( createReplayContext());
1007  if ( res.successful() )
1008  muc.release();
1009  else {
1010  if ( CGameOptions::Instance()->replayMovieMode ) {
1011 
1012  MapField* fld = eht->getMap()->getField(x1,y1);
1013  if ( fld->vehicle == eht ) {
1014  fld->vehicle = NULL;
1015  } else {
1016  if ( fld->getContainer() )
1017  fld->getContainer()->removeUnitFromCargo( eht, true );
1018  }
1019 
1020  if ( eht->isViewing() )
1021  eht->removeview();
1022 
1023 
1024  eht->setnewposition(x2,y2);
1025  if ( height >= 0 )
1026  eht->height = 1 << height;
1027 
1028  MapField* fld2 = eht->getMap()->getField(x2,y2);
1029  if ( !fld2->getContainer() ) {
1030  fld2->vehicle = eht;
1031  eht->addview();
1032  } else
1033  fld2->getContainer()->addToCargo( eht );
1034  }
1035  eht = NULL;
1036 
1037  }
1038 
1039  if ( destDamage >= 0 ) {
1040  int realDamage;
1041  Vehicle* veh = actmap->getUnit( nwid );
1042  if ( veh )
1043  realDamage = veh->damage;
1044  else
1045  realDamage = 100;
1046 
1047  if ( destDamage != realDamage )
1048  error( MapCoordinate(x1,y1), "severe replay inconsistency:\ndamage after movement differs: recorded=%d, actual=%d", destDamage, realDamage );
1049  }
1050  }
1051 
1052  if ( !eht )
1053  error("severe replay inconsistency:\nno vehicle for move2 command at " + MapCoordinate(x1,y1).toString() );
1054  }
1055  break;
1056  case rpl_attack: {
1057  stream->readInt(); // size
1058  int x1 = stream->readInt();
1059  int y1 = stream->readInt();
1060  int x2 = stream->readInt();
1061  int y2 = stream->readInt();
1062  int ad1 = stream->readInt();
1063  int ad2 = stream->readInt();
1064  int dd1 = stream->readInt();
1065  int dd2 = stream->readInt();
1066  int wpnum = stream->readInt();
1067  readnextaction();
1068 
1069  MapField* fld = getfield ( x1, y1 );
1070  MapField* targ = getfield ( x2, y2 );
1071  int attackvisible = fieldvisiblenow ( fld, actmap->getPlayerView() ) || fieldvisiblenow ( targ, actmap->getPlayerView() );
1072  if ( fld && targ && fld->vehicle ) {
1073  if ( fieldvisiblenow ( targ, fld->vehicle->getOwner() )) {
1074  if ( targ->vehicle ) {
1075  tunitattacksunit battle ( fld->vehicle, targ->vehicle, 1, wpnum );
1076  battle.av.damage = ad1;
1077  battle.dv.damage = dd1;
1078  if ( attackvisible ) {
1079  displayActionCursor ( x1, y1, x2, y2, 0 );
1081  rmd.showBattle( battle );
1083  } else {
1084  battle.calc ();
1085  }
1086  if ( battle.av.damage < ad2 || battle.dv.damage > dd2 )
1087  error(MapCoordinate(x2,y2), "severe replay inconsistency:\nresult of attack differ !\nexpected target damage: %d ; recorded target damage: %d\nexpected attacker damage: %d ; recorded attacker damage: %d", battle.av.damage,ad2 ,battle.dv.damage, dd2);
1088  battle.setresult ( createReplayContext() );
1089 
1090  if ( battle.av.damage >= 100 || battle.dv.damage >= 100 )
1091  computeview( actmap );
1092 
1093  updateFieldInfo();
1094 
1095  } else
1096  if ( targ->building ) {
1097  tunitattacksbuilding battle ( fld->vehicle, x2, y2 , wpnum );
1098  battle.av.damage = ad1;
1099  battle.dv.damage = dd1;
1100  if ( attackvisible ) {
1101  displayActionCursor ( x1, y1, x2, y2, 0 );
1103  rmd.showBattle( battle );
1105  } else {
1106  battle.calc ();
1107  /*battle.av.damage = ad2;
1108  battle.dv.damage = dd2; */
1109  }
1110  if ( battle.av.damage != ad2 || battle.dv.damage != dd2 )
1111  error(MapCoordinate(x2,y2), "severe replay inconsistency:\nresult of attack differ !\nexpected target damage: %d ; recorded target damage: %d\nexpected attacker damage: %d ; recorded attacker damage: %d", battle.av.damage,ad2 ,battle.dv.damage, dd2);
1112  battle.setresult ( createReplayContext() );
1113 
1114  if ( battle.av.damage >= 100 || battle.dv.damage >= 100 )
1115  computeview( actmap );
1116  updateFieldInfo();
1117  } else
1118  if ( !targ->objects.empty() ) {
1119  tunitattacksobject battle ( fld->vehicle, x2, y2, wpnum );
1120  if ( attackvisible ) {
1121  displayActionCursor ( x1, y1, x2, y2, 0 );
1123  rmd.showBattle( battle );
1125  } else {
1126  battle.calc ();
1127  //battle.av.damage = ad2;
1128  //battle.dv.damage = dd2;
1129  }
1130  if ( battle.av.damage != ad2 || battle.dv.damage != dd2 )
1131  error(MapCoordinate(x2,y2), "severe replay inconsistency:\nresult of attack differ !\nexpected target damage: %d ; recorded target damage: %d\nexpected attacker damage: %d ; recorded attacker damage: %d", battle.av.damage,ad2 ,battle.dv.damage, dd2);
1132  battle.setresult ( createReplayContext() );
1133 
1134  if ( battle.av.damage >= 100 || battle.dv.damage >= 100 )
1135  computeview( actmap );
1136 
1137  updateFieldInfo();
1138  }
1139  displaymap();
1140  } else
1141  error(MapCoordinate(x2,y2), "severe replay inconsistency:\nthe attacking unit can't view the target field!" );
1142 
1143  } else
1144  error(MapCoordinate(x1,y1), "severe replay inconsistency:\nno vehicle for attack command !" );
1145 
1146  }
1147  break;
1148  case rpl_changeheight2:
1149  case rpl_changeheight: {
1150  stream->readInt(); // size
1151  int x1 = stream->readInt();
1152  int y1 = stream->readInt();
1153  int x2 = stream->readInt();
1154  int y2 = stream->readInt();
1155  int nwid = stream->readInt();
1156  stream->readInt(); // oldheight
1157  int newheight = stream->readInt();
1158 
1159  if ( nextaction == rpl_changeheight2 )
1160  stream->readInt(); // noInterrupt
1161 
1162 
1163  readnextaction();
1164 
1165  Vehicle* eht = actmap->getUnit ( x1, y1, nwid );
1166  if ( eht ) {
1168 
1169  auto_ptr<MoveUnitCommand> muc ( new MoveUnitCommand( eht ));
1170  muc->setDestination( MapCoordinate3D( x2,y2, newheight ));
1171 
1172  wait( MapCoordinate(x1,y1), MapCoordinate(x2,y2) );
1173 
1174  ActionResult res = muc->execute( createReplayContext() );
1175 
1176  if ( res.successful() )
1177  muc.release();
1178  else
1179  eht = NULL;
1180 
1181  }
1182 
1183  if ( !eht )
1184  error(MapCoordinate(x1,y1), "severe replay inconsistency:\nno vehicle for changeheight command !");
1185 
1186 
1187  }
1188  break;
1189  case rpl_convert:
1190  case rpl_convert2: {
1191  stream->readInt(); // size
1192  int x = stream->readInt();
1193  int y = stream->readInt();
1194  int col = stream->readInt();
1195  if ( nextaction == rpl_convert2 ) {
1196  int nwid = stream->readInt();
1197  readnextaction();
1198 
1199  Vehicle* veh = actmap->getUnit( x,y, nwid );
1200  if ( veh )
1201  veh->convert(col);
1202  else
1203  error(MapCoordinate(x,y), "severe replay inconsistency:\nno vehicle for convert command !");
1204  } else {
1205  readnextaction();
1206 
1207  MapField* fld = getfield ( x, y );
1208  if ( fld ) {
1209  displayActionCursor ( x, y );
1210  if ( fld->vehicle )
1211  fld->vehicle->convert ( col );
1212  else
1213  if ( fld->building )
1214  fld->building->convert ( col );
1215 
1216  computeview( actmap );
1217  displaymap();
1218  wait( MapCoordinate(x,y) );
1220  } else
1221  error(MapCoordinate(x,y), "severe replay inconsistency:\nno vehicle for convert command !");
1222  }
1223  }
1224  break;
1225  case rpl_remobj:
1226  case rpl_buildobj:
1227  case rpl_remobj2:
1228  case rpl_buildobj2: {
1229  stream->readInt(); // size
1230  int x = stream->readInt();
1231  int y = stream->readInt();
1232  int id = stream->readInt();
1233  int unit = -1;
1234  if ( actaction == rpl_remobj2 || actaction == rpl_buildobj2 )
1235  unit = stream->readInt();
1236 
1237  readnextaction();
1238 
1239  ObjectType* obj = objectTypeRepository.getObject_byID ( id );
1240 
1241  MapField* fld = getfield ( x, y );
1242  if ( obj && fld ) {
1243  displayActionCursor ( x, y );
1244 
1245  Resources cost;
1246  int movecost;
1247 
1248  RecalculateAreaView rav ( actmap, MapCoordinate(x,y), maxViewRange / maxmalq + 1, NULL );
1249 
1250  bool objectAffectsVisibility = obj->basicjamming_plus || obj->viewbonus_plus || obj->viewbonus_abs != -1 || obj->basicjamming_abs != -1;
1251  if ( objectAffectsVisibility )
1252  rav.removeView();
1253 
1254 
1255  if ( actaction == rpl_remobj || actaction == rpl_remobj2 ) {
1256  cost = obj->removecost;
1257  fld->removeObject ( obj );
1258  movecost = obj->remove_movecost;
1259  } else {
1260  cost = obj->buildcost;
1261  fld->addobject ( obj );
1262  movecost = obj->build_movecost;
1263  }
1264 
1265  if ( objectAffectsVisibility )
1266  rav.addView();
1267 
1268 
1269  if ( unit > 0 ) {
1270  Vehicle* veh = actmap->getUnit(unit);
1271  if ( veh ) {
1272  if ( veh->getMovement() < movecost )
1273  error(MapCoordinate(x,y), "not enough movement to construct/remove object !");
1274  veh->decreaseMovement( movecost );
1275  Resources res2 = static_cast<ContainerBase*>(veh)->getResource( cost, 0, 1 );
1276  for ( int r = 0; r < 3; r++ )
1277  if ( res2.resource(r) < cost.resource(r) && cost.resource(r) > 0 )
1278  error("Resource mismatch: not enough resources to construct/remove object !\nPosition: " + MapCoordinate(x,y).toString());
1279 
1280  } else
1281  error(MapCoordinate(x,y), "replay inconsistency:\nCannot find Unit to build/remove Object !");
1282  }
1283 
1284  if ( fieldvisiblenow ( fld, actmap->getPlayerView() ))
1285  displaymap();
1286 
1287  wait(MapCoordinate(x,y));
1289  } else
1290  error(MapCoordinate(x,y), "severe replay inconsistency:\nCannot find Object to build/remove !");
1291 
1292  }
1293  break;
1294  case rpl_buildtnk:
1295  case rpl_buildtnk2:
1296  case rpl_buildtnk3:
1297  case rpl_buildtnk4: {
1298  stream->readInt(); // size
1299  int x = stream->readInt();
1300  int y = stream->readInt();
1301  int id = stream->readInt();
1302  int col = stream->readInt();
1303  int constx = -1;
1304  int consty = -1;
1305  int height = -1;
1306  if ( nextaction == rpl_buildtnk2 )
1307  stream->readInt(); // networkid
1308 
1310  constx = stream->readInt();
1311  consty = stream->readInt();
1312  if ( nextaction == rpl_buildtnk4 )
1313  height = stream->readInt();
1314  }
1315 
1316  readnextaction();
1317 
1318  MapField* fld = getfield ( x, y );
1319 
1320  VehicleType* tnk = vehicleTypeRepository.getObject_byID ( id );
1321 
1322  if ( fld && tnk && !fld->vehicle ) {
1323  displayActionCursor ( x, y );
1324  Vehicle* v = new Vehicle ( tnk, actmap, col );
1325  v->xpos = x;
1326  v->ypos = y;
1327  fld->vehicle = v;
1328  if ( height >= 0 )
1329  v->height = height;
1330 
1331  if ( constx >= 0 && consty >= 0 ) {
1332  MapField* constructorField = getfield(constx, consty );
1333  if ( constructorField->vehicle ) {
1334  Resources r ( 0, tnk->productionCost.material, tnk->productionCost.energy ); // = constructorField->vehicle->getProductionCost(tnk );
1335  Resources rr = constructorField->getContainer()->getResource( r, 0 );
1336  if ( rr < r ) {
1337  displayActionCursor ( x, y );
1338  error(MapCoordinate(x,y), "severe replay inconsistency: \nNot enough resources to produce unit %s !\nRequired: %d/%d/%d ; Available: %d/%d/%d", v->typ->description.c_str(), r.energy, r.material, r.fuel, rr.energy, rr.material, rr.fuel);
1339  }
1340  } else
1341  error(MapCoordinate(x,y), "severe replay inconsistency: could not find constructor !");
1342 
1343  }
1344 
1345  computeview( actmap );
1346  displaymap();
1347  wait(MapCoordinate(x,y) );
1349  } else
1350  error(MapCoordinate(x,y), "severe replay inconsistency:\nCannot find Vehicle to build !");
1351 
1352  }
1353  break;
1354  case rpl_putbuilding2:
1355  case rpl_putbuilding : {
1356  int size = stream->readInt(); // size
1357  int x = stream->readInt();
1358  int y = stream->readInt();
1359  int id = stream->readInt();
1360  stream->readInt(); // color ; we are using the vehicle's color
1361  int networkid = 0;
1362  if ( size == 5 )
1363  networkid = stream->readInt();
1364 
1365  readnextaction();
1366 
1367  MapField* fld = getfield ( x, y );
1368 
1369  BuildingType* bld = buildingTypeRepository.getObject_byID ( id );
1370 
1371  if ( bld && fld && networkid && actmap->getUnit( networkid ) ) {
1372  displayActionCursor ( x, y );
1373  auto_ptr<ConstructBuildingCommand> cbc ( new ConstructBuildingCommand( actmap->getUnit( networkid ) ));
1374  cbc->setBuildingType( bld );
1375  cbc->setTargetPosition( MapCoordinate(x,y));
1376  ActionResult res = cbc->execute( createReplayContext());
1377  if ( res.successful() )
1378  cbc.release();
1379  else
1380  error( MapCoordinate(x,y), "severe replay inconsistency, could not construct building; Code=" + ASCString::toString( res.getCode() ));
1381 
1382  wait(MapCoordinate(x,y));
1384  } else
1385  error(MapCoordinate(x,y), "severe replay inconsistency:\nCannot find building to build/remove building!" );
1386  }
1387  break;
1388  case rpl_putmine:
1389  case rpl_putmine2: {
1390  stream->readInt(); // size
1391  int x = stream->readInt();
1392  int y = stream->readInt();
1393  int col = stream->readInt();
1394  int typ = stream->readInt();
1395  int strength = stream->readInt();
1396  int nwid = -1;
1397  if ( nextaction == rpl_putmine2)
1398  nwid = stream->readInt();
1399 
1400  readnextaction();
1401 
1402  MapField* fld = getfield ( x, y );
1403  if ( fld ) {
1404  displayActionCursor ( x, y );
1405  fld -> putmine ( col, MineTypes(typ), strength );
1406  if ( nwid >= 0 ) {
1407  Vehicle* veh = actmap->getUnit( nwid );
1408  if ( veh ) {
1409  ConsumeAmmo ca ( veh, cwminen, -1, 1 );
1411  if ( !res.successful() )
1412  error(MapCoordinate(x,y), "could not obtain ammo for mine placement");
1413 
1414  } else
1415  error(MapCoordinate(x,y), "could not find unit for mine placement");
1416  }
1417  computeview( actmap );
1418  if ( fieldvisiblenow ( actmap->getField(x,y), actmap->getPlayerView() )) {
1419  displaymap();
1420  wait();
1421  }
1423  } else
1424  error(MapCoordinate(x,y), "severe replay inconsistency:\nno field for putmine command !");
1425 
1426  }
1427  break;
1428  case rpl_removemine: {
1429  stream->readInt(); // size
1430  int x = stream->readInt();
1431  int y = stream->readInt();
1432  readnextaction();
1433 
1434  MapField* fld = getfield ( x, y );
1435  if ( fld ) {
1436  displayActionCursor ( x, y );
1437  fld -> removemine ( -1 );
1438  computeview( actmap );
1439  if ( fieldvisiblenow ( actmap->getField(x,y), actmap->getPlayerView() )) {
1440  displaymap();
1441  wait();
1442  }
1443  removeActionCursor ( );
1444  } else
1445  error(MapCoordinate(x,y), "severe replay inconsistency:\nno field for remove mine command !");
1446 
1447  }
1448  break;
1449  case rpl_removebuilding2:
1450  case rpl_removebuilding3:
1451  case rpl_removebuilding: {
1452  stream->readInt(); // size
1453  int x = stream->readInt();
1454  int y = stream->readInt();
1455  int nwid = -1;
1457  nwid = stream->readInt();
1458 
1459  Resources res;
1460  if ( nextaction == rpl_removebuilding3 ) {
1461  res.energy = stream->readInt();
1462  res.material = stream->readInt();
1463  res.fuel = stream->readInt();
1464  }
1465 
1466  readnextaction();
1467 
1468  MapField* fld = getfield ( x, y );
1469  if ( fld && fld->building ) {
1470  displayActionCursor ( x, y );
1471  if ( nwid >= 0 ) {
1472  Vehicle* veh = actmap->getUnit( nwid );
1473  if ( veh ) {
1475  dbc->setTargetPosition( MapCoordinate( x,y ));
1476  dbc->execute( createReplayContext());
1477 
1478  } else
1479  error(MapCoordinate(x,y), "severe replay inconsistency:\nfailed to obtain vehicle for removebuilding command !");
1480  } else
1481  error(MapCoordinate(x,y), "no vehicle for removebuilding command !");
1482 
1483  computeview( actmap );
1484  displaymap();
1485  wait();
1487  } else
1488  error(MapCoordinate(x,y), "severe replay inconsistency:\nno building for removebuilding command !");
1489 
1490  }
1491  break;
1492  case rpl_produceunit : {
1493  stream->readInt(); // size
1494  int id = stream->readInt();
1495  int col = stream->readInt();
1496  int x = stream->readInt();
1497  int y = stream->readInt();
1498  stream->readInt(); // class
1499  int nwid = stream->readInt();
1500  readnextaction();
1501 
1502  MapField* fld = getfield ( x, y );
1503 
1504  VehicleType* tnk = vehicleTypeRepository.getObject_byID ( id );
1505  if ( tnk && fld) {
1506 
1507  #if 0
1508  printf("produced unit: pos %d / %d; nwid %d; typ id %d; typ %s \n", x,y,nwid,id,tnk->description.c_str() );
1509  #endif
1510 
1511  Vehicle* eht = new Vehicle ( tnk, actmap, col / 8 );
1512  eht->xpos = x;
1513  eht->ypos = y;
1514  eht->networkid = nwid;
1515 
1516  if ( fld->building ) {
1517  Resources cost = fld->building->getProductionCost(tnk);
1518  Resources r = fld->building->getResource( cost, 0 );
1519  if ( r < cost ) {
1520  displayActionCursor ( x, y );
1521  error(MapCoordinate(x,y), "severe replay inconsistency: \nNot enough resources to produce unit %s !\nRequired: %d/%d/%d ; Available: %d/%d/%d", eht->typ->description.c_str(), cost.energy, cost.material, cost.fuel, r.energy, r.material, r.fuel);
1522  }
1523  fld->building->addToCargo( eht );
1524  } else {
1525  displayActionCursor ( x, y );
1526  fld->vehicle = eht;
1527  computeview( actmap );
1528  displaymap();
1529  wait( MapCoordinate(x,y) );
1531  }
1532  } else
1533  error(MapCoordinate(x,y), "severe replay inconsistency:\nCannot find vehicle to build/remove !");
1534 
1535  }
1536  break;
1537  case rpl_removeunit : {
1538  stream->readInt(); // size
1539  int x = stream->readInt();
1540  int y = stream->readInt();
1541  int nwid = stream->readInt();
1542  readnextaction();
1543  MapField* fld = getfield(x,y);
1544  if ( (!fld->vehicle || fld->vehicle->networkid != nwid) && fld->building ) {
1545  auto_ptr<RecycleUnitCommand> ruc ( new RecycleUnitCommand( fld->building ));
1546  ruc->setUnit( actmap->getUnit( nwid ) );
1547  ActionResult res = ruc->execute( createReplayContext());
1548  if ( res.successful() )
1549  ruc.release();
1550  else
1551  displayActionError(res);
1552  } else
1553  if ( !fld->getContainer() || !fld->getContainer()->removeUnitFromCargo ( nwid, true ))
1554  displaymessage ( "severe replay inconsistency:\nCould not remove unit %d!", 1, nwid );
1555  }
1556  break;
1557  case rpl_trainunit:{
1558  stream->readInt(); // size
1559  int x = stream->readInt();
1560  int y = stream->readInt();
1561  stream->readInt(); // experience
1562  int nwid = stream->readInt();
1563  readnextaction();
1564 
1565  Vehicle* eht = actmap->getUnit ( x, y, nwid );
1566  Building* bld = actmap->getField ( x, y )->building;
1567  if ( eht && bld ) {
1568  auto_ptr<TrainUnitCommand> tuc ( new TrainUnitCommand( bld ));
1569  tuc->setUnit( eht );
1570  ActionResult res = tuc->execute( createReplayContext());
1571  if ( res.successful())
1572  tuc.release();
1573  else
1574  displayActionError(res);
1575  } else
1576  error(MapCoordinate(x,y), "severe replay inconsistency:\nno vehicle for trainunit command !");
1577 
1578 
1579  }
1580  break;
1581  /*
1582  case rpl_shareviewchange: {
1583  int size = stream->readInt();
1584  GameMap::Shareview* sv = new GameMap::Shareview;
1585  if ( size ) {
1586  for ( int a = 0; a < 8; a++ )
1587  for ( int b = 0; b < 8; b++)
1588  sv->mode[a][b] = stream->readUint8();
1589  sv->recalculateview = stream->readInt();
1590 
1591  if ( actmap->shareview )
1592  delete actmap->shareview;
1593  actmap->shareview = sv;
1594  actmap->shareview->recalculateview = 0;
1595  } else
1596  if ( actmap->shareview ) {
1597  delete actmap->shareview;
1598  actmap->shareview = NULL;
1599  }
1600 
1601  readnextaction();
1602  computeview( actmap );
1603  displaymap();
1604  }
1605  break;
1606  */
1607  case rpl_alliancechange2: {
1608  stream->readInt(); // size
1609  int actingPlayer = stream->readInt();
1610  int targetPlayer = stream->readInt();
1611  int state = stream->readInt();
1612  actmap->player[actingPlayer].diplomacy.setState( targetPlayer, DiplomaticStates( state ));
1613 
1614  readnextaction();
1615  }
1616  break;
1617  case rpl_refuel :
1618  case rpl_refuel2 : {
1619  stream->readInt(); // size
1620  int x = stream->readInt();
1621  int y = stream->readInt();
1622  int nwid = stream->readInt();
1623  int pos = stream->readInt();
1624  int amnt = stream->readInt();
1625  int old = -2;
1626  if ( nextaction == rpl_refuel2 )
1627  old = stream->readInt();
1628 
1629  readnextaction();
1630 
1631  Vehicle* eht = actmap->getUnit ( x, y, nwid );
1632  if ( eht ) {
1633  if ( pos < 16 ) {
1634  if ( old >= 0 && old != eht->ammo[pos] )
1635  error(MapCoordinate(x,y), "severe replay inconsistency:\nthe ammo of unit not matching. \nrecorded: %d , expected: %d !", old, eht->ammo[pos] );
1636  eht->ammo[pos] = amnt;
1637  } else {
1638  int res = pos - 1000;
1639  int avl = eht->getTank().resource(res);
1640  if ( avl != old && old >= 0 )
1641  error(MapCoordinate(x,y), "severe replay inconsistency:\nthe resources of unit not matching. \nrecorded: %d , expected: %d !", old, avl);
1642  eht->getResource ( avl - amnt, res, false );
1643  }
1644  } else
1645  error(MapCoordinate(x,y), "severe replay inconsistency:\nno vehicle for refuel-unit command !");
1646  }
1647  break;
1648  case rpl_refuel3 : {
1649  stream->readInt(); // size
1650  int id = stream->readInt();
1651  int type = stream->readInt();
1652  int delta = stream->readInt();
1653  readnextaction();
1654 
1655  ContainerBase* cb = actmap->getContainer ( id );
1656  if ( cb ) {
1657  if ( type >= 1000 ) {
1658  Resources res;
1659  res.resource(type-1000) = delta;
1660  ConsumeResource cr ( cb, res );
1661  ActionResult result = cr.execute( createReplayContext() );
1662  if ( !result.successful())
1663  error("severe replay inconsistency:\nthe resources of container not matching. ");
1664 
1665  } else {
1666  ConsumeAmmo ca ( cb, type, -1, delta );
1667  ActionResult result = ca.execute( createReplayContext() );
1668  if ( !result.successful())
1669  error("severe replay inconsistency:\nthe resources of container not matching. ");
1670  }
1671  } else
1672  error("severe replay inconsistency:\nno vehicle for refuel3 command !");
1673  }
1674  break;
1675  case rpl_bldrefuel : {
1676  stream->readInt(); // size
1677  int x = stream->readInt();
1678  int y = stream->readInt();
1679  int pos = stream->readInt();
1680  int amnt = stream->readInt();
1681  readnextaction();
1682 
1683  Building* bld = actmap->getField(x,y)->building;
1684  if ( bld ) {
1685  if ( pos < 16 )
1686  bld->ammo[pos] = amnt;
1687  else
1688  bld->getResource ( amnt, pos-1000, 0 );
1689  } else
1690  error(MapCoordinate(x,y), "severe replay inconsistency:\nno building for refuel-unit command !");
1691  }
1692  break;
1693  case rpl_moveUnitUpDown: {
1694  stream->readInt(); // size
1695  int x = stream->readInt();
1696  int y = stream->readInt();
1697  stream->readInt(); // dummy(basegfx_0)
1698  int nwid_to = stream->readInt();
1699  int nwid_moving = stream->readInt();
1700 
1701  readnextaction();
1702 
1703  ContainerBase* b = actmap->getField(x,y)->getContainer();
1704  if ( b ) {
1705  b->removeUnitFromCargo( nwid_moving, true );
1706 
1707  Vehicle* veh_targ = actmap->getUnit( nwid_to );
1708  Vehicle* veh_moving = actmap->getUnit( nwid_moving );
1709  if ( veh_targ && veh_moving )
1710  veh_targ->addToCargo( veh_moving );
1711  else
1712  error ( MapCoordinate(x,y), "Could not locate unit for MoveToInnerTransport");
1713  } else
1714  error( MapCoordinate(x,y), "severe replay inconsistency in MoveUnitUp !");
1715 
1716  }
1717  break;
1718  case rpl_moveUnitUp: {
1719  stream->readInt(); // size
1720  int x = stream->readInt();
1721  int y = stream->readInt();
1722  int nwid = stream->readInt();
1723 
1724  readnextaction();
1725 
1726  Vehicle* eht = actmap->getUnit ( x, y, nwid );
1727  if ( eht ) {
1728  CargoMoveCommand* cmc = new CargoMoveCommand( eht );
1730  ActionResult res = cmc->execute( createReplayContext() );
1731  if ( !res.successful())
1732  error(MapCoordinate(x,y), "severe replay inconsistency in MoveUnitUp !");
1733  } else
1734  error(MapCoordinate(x,y), "Unit not found for MoveUnitUp !");
1735 
1736  }
1737  break;
1738  case rpl_repairUnit : {
1739  stream->readInt(); // size
1740  int nwid = stream->readInt();
1741  int destnwid = stream->readInt();
1742  int amount = stream->readInt();
1743  int matremain = stream->readInt();
1744  int fuelremain = stream->readInt();
1745 
1746  readnextaction();
1747 
1748  Vehicle* eht = actmap->getUnit ( nwid );
1749  Vehicle* dest = actmap->getUnit ( destnwid );
1750  if ( eht && dest ) {
1751  eht->repairItem ( dest, amount );
1752  if ( eht->getTank().fuel != fuelremain || eht->getTank().material != matremain )
1753  error("severe replay inconsistency:\nthe resources of unit not matching for repair operation!");
1754  } else
1755  error("severe replay inconsistency:\nno vehicle for repair-unit command !");
1756  }
1757  break;
1758  case rpl_repairUnit2 : {
1759  stream->readInt(); // size
1760  int x = stream->readInt();
1761  int y = stream->readInt();
1762  int destnwid = stream->readInt();
1763  int amount = stream->readInt();
1764 
1765  readnextaction();
1766 
1767  ContainerBase* bld = getfield(x,y)->getContainer();
1768  Vehicle* dest = actmap->getUnit ( destnwid );
1769  if ( bld && dest ) {
1770  bld->repairItem ( dest, amount );
1771  } else
1772  error(MapCoordinate(x,y), "severe replay inconsistency:\nno vehicle for repair-unit command !");
1773  }
1774  break;
1775  case rpl_repairUnit3 : {
1776  stream->readInt(); // size
1777  int serviceNWID = stream->readInt();
1778  int destnwid = stream->readInt();
1779  int amount = stream->readInt();
1780 
1781  readnextaction();
1782 
1783  ContainerBase* bld = actmap->getContainer( serviceNWID );
1784  Vehicle* dest = actmap->getUnit ( destnwid );
1785  if ( bld && dest ) {
1786  bld->repairItem ( dest, amount );
1787  } else
1788  error("severe replay inconsistency:\nno vehicle for repair-unit command !");
1789  }
1790  break;
1791  case rpl_repairBuilding : {
1792  stream->readInt(); // size
1793  int x = stream->readInt();
1794  int y = stream->readInt();
1795  stream->readInt(); // int destnwid =
1796  int amount = stream->readInt();
1797 
1798  readnextaction();
1799 
1800  ContainerBase* bld = getfield(x,y)->getContainer();
1801  if ( bld ) {
1802  bld->repairItem ( bld, amount );
1803  } else
1804  error(MapCoordinate(x,y), "severe replay inconsistency:\nno building for repair-building command !");
1805  }
1806  break;
1807  case rpl_produceAmmo : {
1808  stream->readInt(); // size
1809  int x = stream->readInt();
1810  int y = stream->readInt();
1811  int weaptype = stream->readInt();
1812  int n = stream->readInt();
1813  readnextaction();
1814  Building* bld = getfield(x,y)->building;
1815  if ( bld ) {
1816 
1817  bld->getResource ( Resources( ammoProductionCost[weaptype][0] * n, ammoProductionCost[weaptype][1] * n, ammoProductionCost[weaptype][2] * n ), false );
1818  bld->putAmmo ( weaptype, n, false );
1819 
1820  } else
1821  error(MapCoordinate(x,y), "severe replay inconsistency:\nno building for produce ammo command !");
1822 
1823  }
1824  break;
1825  case rpl_buildProdLine : {
1826  stream->readInt(); // size
1827  int building = stream->readInt();
1828  int vehicleid = stream->readInt();
1829  readnextaction();
1830  Building* bld = dynamic_cast<Building*>( actmap->getContainer(building));
1831  VehicleType* veh = actmap->getvehicletype_byid ( vehicleid );
1832  if ( bld && veh ) {
1833  if ( veh->techDependency.available( actmap->player[ bld->getOwner()].research )) {
1834  auto_ptr<BuildProductionLineCommand> bplc ( new BuildProductionLineCommand( bld ));
1835  bplc->setProduction( veh );
1836  ActionResult res = bplc->execute( createReplayContext() );
1837  if ( res.successful() )
1838  bplc.release();
1839  else
1840  error("severe replay inconsistency:\ncould not build production line!");
1841  } else
1842  error("severe replay inconsistency:\ntechnology for building production line not available!");
1843 
1844  } else
1845  error("severe replay inconsistency:\nno building for build production line command !");
1846 
1847  }
1848  break;
1849  case rpl_removeProdLine : {
1850  stream->readInt(); // size
1851  int building = stream->readInt();
1852  int vehicleid = stream->readInt();
1853  readnextaction();
1854  Building* bld = dynamic_cast<Building*>( actmap->getContainer(building));
1855  VehicleType* veh = actmap->getvehicletype_byid ( vehicleid );
1856  if ( bld && veh ) {
1857  auto_ptr<RemoveProductionLineCommand> rplc ( new RemoveProductionLineCommand( bld ));
1858  rplc->setRemoval( veh );
1859  ActionResult res = rplc->execute( createReplayContext());
1860  if ( res.successful())
1861  rplc.release();
1862  else
1863  error("severe replay inconsistency:\ncould not remove production line!");
1864 
1865  } else
1866  error("severe replay inconsistency:\nno building for remove production line command !");
1867 
1868  }
1869  break;
1870  case rpl_setResearch : {
1871  stream->readInt(); // size
1872  int building = stream->readInt();
1873  int amount = stream->readInt();
1874  readnextaction();
1875  Building* bld = dynamic_cast<Building*>( actmap->getContainer(building));
1876  if ( bld )
1877  bld->researchpoints = amount;
1878  else
1879  error("severe replay inconsistency:\nno building for set research command !");
1880 
1881  }
1882  break;
1883  case rpl_techResearched: {
1884  stream->readInt(); // size
1885  int techID = stream->readInt();
1886  int player = stream->readInt();
1887  readnextaction();
1888  Technology* tech = technologyRepository.getObject_byID( techID );
1889  if ( tech ) {
1890  actmap->player[player].research.addanytechnology( tech );
1891  actmap->player[player].research.progress -= tech->researchpoints;
1892  } else
1893  error("severe replay inconsistency:\nno technology for tech researched command !");
1894  }
1895  break;
1896  case rpl_setGeneratorStatus : {
1897  stream->readInt();
1898  int nwid = stream->readInt();
1899  int status = stream->readInt();
1900 
1901  readnextaction();
1902 
1903  Vehicle* eht = actmap->getUnit ( nwid );
1904  if ( eht )
1905  eht->setGeneratorStatus( status );
1906  else
1907  error("severe replay inconsistency:\nvehicle for generator switching not found !");
1908  }
1909 
1910 
1911  break;
1912  case rpl_cutFromGame: {
1913  stream->readInt();
1914  int vehid = stream->readInt();
1915  Vehicle* veh = actmap->getUnit ( vehid );
1916  Resources res;
1917  res.energy = stream->readInt();
1918  res.material = stream->readInt();
1919  res.fuel = stream->readInt();
1920 
1921  readnextaction();
1922 
1923  if ( veh && res == getUnitResourceCargo ( veh )) {
1924  veh->prepareForCleanRemove();
1925  delete veh;
1926  computeview( actmap );
1927  displaymap();
1928  } else
1929  error ( "resource mismatch at cut unit operation! ");
1930  }
1931  break;
1933  stream->readInt();
1934  int x = stream->readInt();
1935  int y = stream->readInt();
1936  Resources p;
1937  p.energy = stream->readInt();
1938  p.material = stream->readInt();
1939  p.fuel = stream->readInt();
1940  readnextaction();
1941  Building* bld = actmap->getField(x,y)->building;
1942  if ( bld ) {
1943  for ( int r = 0; r< 3; ++r )
1944  if ( abs(p.resource(r)) > abs(bld->typ->maxplus.resource(r)) )
1945  error (MapCoordinate(x,y), "Building can not produ ");
1946  bld->plus = p;
1947  } else
1948  error (MapCoordinate(x,y), "Building not found on for rpl_setResourceProcessingAmount ");
1949  }
1950  break;
1951  case rpl_netcontrol: {
1952  stream->readInt();
1953  int x = stream->readInt();
1954  int y = stream->readInt();
1955  stream->readInt(); // int cat =
1956  stream->readInt(); // int stat =
1957  readnextaction();
1958 
1959  Building* bld = actmap->getField(x,y)->building;
1960  if ( bld ) {
1961  // not supported
1962  /*
1963  cbuildingcontrols bc;
1964  bc.init( bld );
1965  bc.netcontrol.setnetmode( cat, stat );
1966  bld->execnetcontrol();
1967  */
1968  } else
1969  error (MapCoordinate(x,y), "Building not found on for rpl_setResourceProcessingAmount ");
1970  }
1971  break;
1972  case rpl_jump: {
1973  stream->readInt();
1974  int nwid = stream->readInt();
1975  int x = stream->readInt();
1976  int y = stream->readInt();
1977  readnextaction();
1978 
1979  Vehicle* veh = actmap->getUnit(nwid);
1980  if ( veh ) {
1981  if ( JumpDriveCommand::available( veh ).ready()) {
1982  auto_ptr<JumpDriveCommand> jd( new JumpDriveCommand(veh) );
1983  displayActionCursor ( veh->getPosition().x , veh->getPosition().x, x, y, 0 );
1984  jd->setDestination( MapCoordinate(x,y));
1985  ActionResult res = jd->execute( createReplayContext() );
1986  if ( !res.successful() )
1987  error(MapCoordinate(x,y), "Unit cannot jump to this position");
1988  else
1989  jd.release();
1990 
1991  } else
1992  error(MapCoordinate(x,y), "Unit cannot jump");
1993  } else
1994  error (MapCoordinate(x,y), "Unit not found for Jump ");
1995 
1996 
1997  }
1998  break;
1999  case rpl_recycleUnit : {
2000  stream->readInt(); // size
2001  int building = stream->readInt();
2002  int vehicleid = stream->readInt();
2003  readnextaction();
2004  Building* bld = dynamic_cast<Building*>( actmap->getContainer(building));
2005  Vehicle* veh = actmap->getUnit ( vehicleid );
2006  if ( bld && veh ) {
2007  auto_ptr<RecycleUnitCommand> ruc ( new RecycleUnitCommand( bld ));
2008  ruc->setUnit( veh );
2009  ActionResult res = ruc->execute( createReplayContext() );
2010  if ( res.successful() )
2011  ruc.release();
2012  else
2013  displayActionError(res);
2014  } else
2015  error("severe replay inconsistency:\nno unit for recycle command !");
2016  }
2017  break;
2018  case rpl_transferTribute: {
2019  stream->readInt();
2020  int player = stream->readInt();
2021  readnextaction();
2023  }
2024  break;
2025 
2026  case rpl_reactionFireOn:
2027  case rpl_reactionFireOff: {
2028  stream->readInt();
2029  int nwid = stream->readInt();
2030  readnextaction();
2031  Vehicle* v = actmap->getUnit( nwid );
2032  if ( v ) {
2033  if ( actaction == rpl_reactionFireOn ) {
2034  int res = v->reactionfire.enable();
2035  if ( res < 0 )
2036  error("severe enabling reactionfire for unit !");
2037  } else
2038  v->reactionfire.disable();
2039  } else
2040  error("severe replay inconsistency:\nno unit for reactionfire command !");
2041  }
2042  break;
2043  case rpl_selfdestruct: {
2044  stream->readInt();
2045  int nwid = stream->readInt();
2046  readnextaction();
2047  ContainerBase* c = actmap->getContainer( nwid );
2048  if ( DestructUnitCommand::avail( c )) {
2049  auto_ptr<DestructUnitCommand> duc ( new DestructUnitCommand( c ));
2050  ActionResult res = duc->execute( createReplayContext() );
2051  if ( !res.successful() )
2052  error("severe replay inconsistency:\nno container for selfdestruct command !");
2053  else
2054  duc.release();
2055  } else
2056  error("severe replay inconsistency:\nno container for selfdestruct command !");
2057  }
2058  break;
2059  case rpl_cancelResearch :
2060  {
2061  stream->readInt();
2062  readnextaction();
2063 
2064  auto_ptr<CancelResearchCommand> crc ( new CancelResearchCommand( actmap ));
2065  crc->setPlayer( actmap->player[actmap->actplayer] );
2066  ActionResult res = crc->execute( createReplayContext() );
2067  if ( res.successful() )
2068  crc.release();
2069  else
2070  error( res );
2071  }
2072  break;
2073 
2074  case rpl_runCommandAction:
2075  {
2076  stream->readInt();
2077  int padding = stream->readInt();
2078  MemoryStreamStorage buffer;
2079  buffer.readfromstream( stream );
2080 
2081  MemoryStream memstream( &buffer, tnstream::reading );
2082 
2083  auto_ptr<GameAction> readaction ( GameAction::readFromStream( memstream, actmap ));
2084 
2085  Command* a = dynamic_cast<Command*> ( readaction.get() );
2086 
2087  for ( int i = 0; i < padding;++i ) {
2088  Uint8 c = stream->readUint8();
2089  if ( c != 255-i )
2090  error("invalid padding bytes in command action storage buffer");
2091  }
2092  readnextaction();
2093 
2094  if ( a ) {
2095  try {
2096  ActionResult res = a->redo( createReplayContext() );
2097  if ( !res.successful() )
2098  error("action " + a->getDescription() + " failed\n" + getmessage(res.getCode()));
2099  } catch ( const ActionResult & res ) {
2100  error("action " + a->getDescription() + " failed\n" + getmessage(res.getCode()));
2101  throw res;
2102  }
2103 
2104  } else
2105  error("could not read Command action from replay stream" );
2106  }
2107  break;
2108 
2109  default:{
2110  int size = stream->readInt();
2111  for ( int i = 0; i< size; i++ )
2112  stream->readInt();
2113 
2114  readnextaction();
2115 
2116  }
2117  break;
2118  } /* endswitch */
2119 
2120  } else {
2121  status = 10;
2122  updateFieldInfo();
2123  }
2124 
2125 }
2126 
2128 {
2129  if ( stream->dataavail () )
2131  else
2133 }
2134 
2135 
2136 
2137 int trunreplay :: run ( int player, int viewingplayer, bool performEndTurnOperations )
2138 {
2139  ReplayRecorderWatcherLocal rrw( replayRecorder );
2140 
2141  if ( status < 0 )
2142  firstinit ( );
2143 
2144  lastErrorMessage = "";
2145 
2146  movenum = 0;
2147 
2149 
2150  orgmap = actmap;
2151  actmap = loadreplay ( orgmap->replayinfo->map[player] );
2152  if ( !actmap ) {
2153  displaymessage("error loading replay", 1 );
2154  actmap = orgmap;
2155  return 0;
2156  }
2158 
2159  actmap->setPlayerView ( viewingplayer );
2160  actmap->getCursor() = orgmap->getCursor();
2161 
2164 
2165  MemoryStream guidatastream ( orgmap->replayinfo->guidata [ player ], tnstream::reading );
2166  stream = &guidatastream;
2167 
2168  if ( stream->dataavail () )
2170  else
2172 
2173 // orgmap.replayinfo->actmemstream = stream;
2174 
2175 
2176  ReplayGuiIconHandleHandler guiIconHandler;
2177 
2178  if ( stream->dataavail () ) {
2180  status = 2;
2181  else
2182  status = 1;
2183  } else
2184  status = 11;
2185 
2186  // force completion of overview map rendering
2188 
2189  computeview( actmap );
2190  displaymap ();
2191 
2192  updateFieldInfo();
2193 
2195 
2196 // cursor.show();
2197 
2198 // cursor.checkposition( getxpos(), getypos() );
2199 
2200  bool resourcesCompared = false;
2201  do {
2202  if ( status == 2 ) {
2203  execnextreplaymove ( );
2205  /*
2206  if ( getxpos () != lastvisiblecursorpos.x || getypos () != lastvisiblecursorpos.y )
2207  setcursorpos ( lastvisiblecursorpos.x, lastvisiblecursorpos.y );
2208  */
2209  } else {
2210  PG_Application::GetApp()->sigAppIdle( PG_Application::GetApp() );
2211  releasetimeslice();
2212  }
2213 
2214  if (nextaction == rpl_finished || status != 2 ) {
2215  if ( CGameOptions::Instance()->replayMovieMode && status != 1 && !(replayRecorder && replayRecorder->isRunning()) )
2216  status = 100;
2217  else {
2218  if ( nextaction == rpl_finished && !resourcesCompared ) {
2219 
2220  if ( replayRecorder )
2221  replayRecorder->pause();
2222 
2223  displaymessage2("running final comparison" );
2224 
2225  int replayedplayer = actmap->actplayer;
2226  actmap->endTurn();
2227  int nextplayer = findNextPlayer( actmap );
2228  if ( nextplayer < actmap->actplayer && performEndTurnOperations )
2229  actmap->endRound();
2230 
2231  actmap->getCursor() = orgmap->getCursor();
2232 
2233  resourcesCompared = true;
2234  ASCString resourceComparisonResult;
2235  GameMap* comparisonMap = NULL;
2236  GameMap* nextPlayerMap = NULL;
2237 
2238  if ( replayedplayer == orgmap->actplayer )
2239  comparisonMap = orgmap;
2240  else
2241  comparisonMap = nextPlayerMap = loadreplay ( orgmap->replayinfo->map[nextplayer] );
2242 
2243  if ( !CGameOptions::Instance()->replayMovieMode ) {
2244  if ( comparisonMap ) {
2245  if ( compareMapResources( comparisonMap, actmap, player, &resourceComparisonResult)) {
2246  ViewFormattedText vft( "warning", resourceComparisonResult, PG_Rect( -1, -1, 500, 550 ) );
2247  vft.Show();
2248  vft.RunModal();
2249  }
2250 
2251  } else
2252  error("Replay: no map to compare to!");
2253  }
2254 
2255  delete nextPlayerMap;
2256  }
2257  }
2258  }
2259 
2260  for ( int i = 0; i < 5; ++i )
2262 
2263  } while ( status > 0 && status < 100 ) ;
2264 
2265  delete actmap;
2266  actmap = orgmap;
2267 
2268  int st = status;
2269  status = 0;
2270 
2271  updateFieldInfo();
2272 
2273  if ( st == 101 )
2274  return 1;
2275  else
2276  return 0;
2277 }
2278 
2280 {
2281  status = 0;
2282 }
2283 
2284 
2286 {
2287  ActionContainer::commitCommand.connect( sigc::ptr_fun( &logActionToReplay ));
2288 }
void viewOwnReplay(Player &player)
runs the replay of the current player. This is used primarily for debugging the replay system ...
Definition: replay.cpp:630
void saveCommand(const Command &cmd)
Definition: replay.cpp:741
int fuel
Definition: typen.h:101
int viewbonus_plus
units standing on this object will get a bonus to their view
Definition: objecttype.h:94
const ASCString getFilename()
void displaymap()
Definition: spfst.cpp:58
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:537
Player * actingPlayer
Definition: context.h:37
An in-memory storage of streamed data.
Definition: basestrm.h:172
static void logActionToReplay(GameMap *map, Command &command)
Definition: replay.cpp:768
ItemRepositoryLoader< ObjectType > objectTypeRepository("objecttype")
void prepareForCleanRemove()
Definition: vehicle.h:406
void setTargetPosition(const MapCoordinate &pos)
Player & getPlayer(PlayerID p)
Definition: gamemap.h:257
MapCoordinate & getCursor()
Definition: gamemap.cpp:933
MapDisplayInterface & getDefaultMapDisplay()
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
void showBattle(tfight &battle)
int computeview(GameMap *gamemap, int player_fieldcount_mask, bool disableShareView, const Context *context)
completely computes the view
map accessing and usage routines used by ASC and the mapeditor
const BuildingType * typ
Definition: buildings.h:48
trunreplay runreplay
Definition: replay.cpp:70
struct tfight::tavalues dv
DiplomaticStates
Definition: player.h:53
int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)
Definition: vehicle.cpp:328
int getSize() const
Definition: basestrm.h:195
class ReplayRecorderWatcherGlobal replayRecorderWatcherGlobal
static GameAction * readFromStream(tnstream &stream, GameMap *map)
Definition: action.cpp:150
int damage
Damage. 0 is no damage, when damage reaches 100 the container is destroyed.
Vehicle * vehicle
Definition: mapfield.h:89
int energy
Definition: typen.h:99
int findNextPlayer(GameMap *actmap, AbstractPlayerProcessing *playerProcessor)
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:272
void setnewposition(int x, int y)
checks whether the unit can construct a building of the given type.
Definition: vehicle.cpp:808
Everything that happens on the main screen of ASC.
void initReplayLogging(Player &player)
Initialized the replay logging at the beginning of a players or the ai's turn.
Definition: replay.cpp:687
void registerUserFunction(GuiFunction *function)
registers a user function.
int repairItem(ContainerBase *item, int newDamage=0, bool autoRepair=false)
struct tfight::tavalues av
void execnextreplaymove(void)
Definition: replay.cpp:924
Instanciating this class will disable the Controls for interacting with the map or the main menu...
bool isViewing() const
returns true if the units view is currently added to the maps global visibility.
Definition: vehicle.h:342
int dataavail(void)
Definition: basestrm.cpp:2408
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:297
void error(const char *message,...)
Definition: replay.cpp:833
int ammo[16]
Definition: vehicle.h:87
TechAdapterDependency techDependency
void displayActionCursor(int x1, int y1, int x2=-1, int y2=-1, int secondWait=0)
Definition: replay.cpp:910
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
int getPosition() const
Definition: player.h:112
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:452
const GameMap * getParentMap() const
Definition: player.h:114
DiplomaticStateVector diplomacy
Definition: player.h:209
void pause()
Definition: replay.cpp:183
int getOwner() const
returns the number of the player this vehicle/building belongs to
bool isRunning()
Definition: replay.cpp:197
MemoryStreamStorage * guidata[8]
Definition: gamemap.h:374
ContainerBase * getContainer(int nwid)
Definition: gamemap.cpp:1231
virtual ASCString getDescription() const =0
Context createReplayContext()
Definition: replay.cpp:775
int build_movecost
The movement points that are needed to build this object.
Definition: objecttype.h:113
void set(ReplayRecorder *rec)
Definition: replay.cpp:146
void readnextaction(void)
Definition: replay.cpp:2127
trpl_actions
Definition: replay.cpp:75
static bool avail(const ContainerBase *unit)
int status
Definition: replay.h:62
void processEvent()
Definition: paradialog.cpp:436
void runSpecificReplay(int player, int viewingplayer, bool performEndTurnOperations)
runs the replay for the given player
Definition: replay.cpp:600
vector< ASCString > addanytechnology(const Technology *tech)
adds the technology to the list of available technologies
Definition: research.cpp:849
const Surface & getOverviewMap(bool complete=true)
returns the overview surface for the map.
Definition: gamemap.cpp:180
MapCoordinate3D getPosition() const
returns the units position
Definition: vehicle.cpp:1552
void storeFrame(const SDL_Surface *surf)
LogActionIntoReplayInfo(GameMap *map)
Definition: replay.cpp:737
ReplayRecorderWatcherLocal(ReplayRecorder *rec)
Definition: replay.cpp:223
ItemRepositoryLoader< BuildingType > buildingTypeRepository("buildingtype")
ContainerBase * getContainer()
returns a pointer to the ContainerBase of the field or NULL if there is none
Definition: mapfield.cpp:331
ASCString toString(bool coordinates=false) const
Definition: typen.cpp:304
void setGeneratorStatus(bool status)
sets the status of the unit's energy generator
Definition: vehicle.cpp:385
The interface for all kinds of IO stream.
bool isOpen()
Definition: replay.cpp:202
Resources getTank() const
returns the resources that the unit is carrying
Definition: vehicle.cpp:378
a single field of the map
Definition: mapfield.h:26
void setMode(Mode mode)
A Command is an action that the player initiates.
Definition: command.h:114
int run(int player, int viewingplayer, bool performEndTurnOperations)
Definition: replay.cpp:2137
ItemRepositoryLoader< Technology > technologyRepository("technology")
virtual Uint8 readUint8(void)
Reads a 8 bit unsigned Integer.
Definition: basestrm.cpp:305
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void writetostream(tnstream *stream)
persist the contents in another stream
Definition: basestrm.cpp:2303
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:369
ASCString getMessage() const
ASCString description
short description of the units role, for example "strategic bomber"
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:302
const char * getmessage(int id)
returns a pointer to the message id. The messages must have been loaded with loadmessages ...
void checktimedevents(GameMap *gamemap, MapDisplayInterface *md)
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:507
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:350
void calc(void)
Performs the calculation of the attack. The result is only stored in the av and dv structures and is ...
Definition: attack.cpp:178
Handling the connection of buildings by pipelines, powerlines etc.
int height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
void setNumericalHeight(int nh)
Definition: typen.h:243
int basicjamming_abs
basicjamming_abs replaces the current basicjamming of the field by a new one. A value < 0 won't affect...
Definition: objecttype.h:91
int getPlayerView() const
the player which is currently viewing the map.
Definition: gamemap.cpp:1007
MapField * getfield(int x, int y)
returns the field at the given coordinates
Definition: spfst.cpp:199
static void popIconHandler()
trunreplay()
Definition: replay.cpp:795
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:502
~trunreplay()
Definition: replay.cpp:802
void registerReplayGuiFunctions(GuiIconHandler &handler)
Definition: replay.cpp:552
Interface for various global functions and variables.
int remove_movecost
The movement points that are needed to remove this object.
Definition: objecttype.h:116
bool fieldvisiblenow(const MapField *pe, Vehicle *veh, int player)
{@
Definition: spfst.cpp:399
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:815
MineTypes
Definition: objects.h:70
LockReplayRecording(GameMap::ReplayInfo &_ri)
Definition: replay.cpp:713
The class describing properties that are common to all vehicles of a certain kind.
Definition: vehicletype.h:177
Resources buildcost
The resources required to construct the object with a unit; Note that units usually don't have any en...
Definition: objecttype.h:107
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
class Vehicle::ReactionFire reactionfire
#define maxmalq
Constants that specify the layout of ASC.
Definition: typen.h:429
ASC_PG_App & getPGApplication()
Definition: paradialog.cpp:294
void setState(PlayerID towardsPlayer, DiplomaticStates s)
Definition: player.cpp:115
virtual int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)=0
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:412
The class describing properties that are common to all buildings of a certain kind.
Definition: buildingtype.h:35
void setChanged(bool flag=true)
Definition: gameoptions.h:272
ActionResult execute(const Context &context)
Definition: action.cpp:41
bool replayMovieMode
Definition: gameoptions.h:203
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:377
ItemRepositoryLoader< VehicleType > vehicleTypeRepository("vehicletype")
void wait(int t=ticker)
Definition: replay.cpp:869
int enable()
enables the reaction fire or returns an error code ( result < 0 = -errorNr )
Definition: vehicle.cpp:689
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:447
void endRound()
called between endTurn() of player 7 and the next turn of player 0
Definition: gamemap.cpp:1357
int stopRecordingActions
if stopRecordingActions > 0 then no actions will be recorded.
Definition: gamemap.h:379
static GuiIconHandler * getIconHandler()
Interface for recording and playing replays.
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:406
Resources getProductionCost(const VehicleType *unit) const
enum Player::PlayerStatus stat
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:441
void removeActionCursor(void)
Definition: replay.cpp:917
const int ammoProductionCost[weaponTypeNum][3]
Definition: vehicletype.cpp:75
void displayLogMessage(int msgVerbosity, const char *message,...)
An object that can be placed on fields. Roads, pipelines and ditches are examples of objects...
Definition: objecttype.h:30
static ActionAvailability available(const Vehicle *unit)
Coordinate on the twodimensional map.
Definition: typen.h:202
GameAction * parentAction
Definition: context.h:38
Reads data from or writes data to a MemoryStreamStorage This allows a completely volatile storage of ...
Definition: basestrm.h:204
const int maxViewRange
Definition: typen.h:558
void displayActionCursor(int x1, int y1, int x2, int y2, int secondWait)
void displaymessage(const char *formatstring, int num,...)
displays a dialog box with a message
Definition: dlg_box.cpp:1849
virtual void writeUint8(Uint8 c)
Writes a 8 bit unsigned Integer.
Definition: basestrm.cpp:380
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:422
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:398
int ammo[waffenanzahl]
the ammo that is stored in the building
Definition: buildings.h:50
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:517
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:345
The interface for the buildingtype class.
void decreaseMovement(int movement)
reduces the movement by the given amount.
Definition: vehicle.cpp:572
MemoryStream * stream
Definition: replay.h:40
sigc::signal< void, Player & > sigPlayerTurnBegins
Definition: gamemap.h:493
void write(tnstream &stream) const
Definition: action.cpp:145
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:328
void removeview()
removes the units view to the map.
Definition: vehicle.cpp:1006
ASCString getLastFilename()
Definition: replay.cpp:207
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:596
void setresult(const Context &context)
Writes the result of the attack calculation to the actual units.
Definition: attack.cpp:445
void close()
Definition: replay.cpp:190
char * constructFileName(char *buf, int directoryLevel, const char *path, const char *filename)
Definition: basestrm.cpp:873
bool addobject(const ObjectType *obj, int dir=-1, bool force=false, ObjectRemovalStrategy *objectRemovalStrategy=NULL)
add an object to the field
Definition: mapfield.cpp:212
void removeActionCursor(void)
int material
Definition: typen.h:100
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:307
int viewingPlayer
Definition: context.h:40
sigc::signal< void > updateFieldInfo
Definition: spfst.cpp:47
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:340
GameMap * loadreplay(MemoryStreamStorage *streambuf)
Definition: loaders.cpp:1495
int putAmmo(int type, int num, bool queryOnly)
Definition: buildings.cpp:737
void checkforreplay()
checks if there is replay information and -if there is any- runs the replay
Definition: replay.cpp:641
int keypress(void)
Definition: events.cpp:146
signed char actplayer
the player who is currently making his moves (may be human or AI)
Definition: gamemap.h:232
MemoryStreamStorage * map[8]
Definition: gamemap.h:375
int nextaction
Definition: replay.h:52
void start(const ASCString &filename, bool append, int framerate, int ascFramerateLimit, int quality)
Definition: replay.cpp:168
int releasetimeslice(void)
Definition: events.cpp:209
VehicleType * getvehicletype_byid(int id)
Definition: gamemap.cpp:1794
bool successful() const
int actplayer
Definition: replay.h:44
ActionResult redo(const Context &context)
Definition: command.cpp:65
#define cwminen
Definition: vehicletype.h:67
Vehicle * getUnit(int x, int y, int nwid)
Definition: gamemap.cpp:1215
MapDisplayInterface * display
Definition: context.h:39
Player player[9]
Definition: gamemap.h:253
Resources plus
the Resources that are produced each turn
void errorMessage(const ASCString &string)
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
void firstinit()
Definition: replay.cpp:2279
static sigc::signal< void, GameMap *, Command & > commitCommand
The command, which has already been executed, is finally commited and will not be undone any more Thi...
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:497
sigc::signal< void, const SDL_Surface * > postScreenUpdate
Definition: events.cpp:392
GameMap * gamemap
Definition: context.h:36
Cargo Move is moving a unit between different carriers that are nested.
ActionContainer * actionContainer
Definition: context.h:41
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:267
void setCursorDelay(int time)
OverviewMapHolder overviewMapHolder
Definition: gamemap.h:532
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:542
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:283
Resources getUnitResourceCargo(Vehicle *veh)
Definition: replay.cpp:725
void displaymessage2(const char *formatstring,...)
displays a message in the status line of ASC
Interface for all the dialog boxes used by the game and the mapeditor.
void convert(int player, bool recursive=true)
changes the building's owner.
Definition: buildings.cpp:105
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:387
Research research
the status of the scientific research
Definition: player.h:142
int & resource(int type)
Definition: typen.h:105
int xpos
the position on the map
Definition: vehicle.h:124
int viewbonus_abs
units standing on this object will get a bonus to their view
Definition: objecttype.h:96
void convert(int player, bool recursive=true)
converts the unit so it is owned by 'player'.
Definition: vehicle.cpp:843
procedure for loading and writing savegames, maps etc.
void addToCargo(Vehicle *veh, int position=-1)
adds the unit to the cargo
const VehicleType * typ
Definition: vehicle.h:83
void hookReplayToSystem()
initialized the replay system at program startup
Definition: replay.cpp:2285
static Surface & getIcon(const ASCString &name)
ActionContainer actions
Records all action that have been done for undo/redo purposes.
Definition: gamemap.h:390
int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)
Definition: controls.cpp:243
int startreplaylate
a hack to enable the replay in a game that was started without replays
Definition: replay.cpp:72
Coordinate on the map including height.
Definition: typen.h:238
void readfromstream(tnstream *stream)
read persisted contents from another stream
Definition: basestrm.cpp:2316
Building * building
Definition: mapfield.h:102
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:475
ASC_MainScreenWidget * mainScreenWidget
GameMap * actmap
Definition: spfst.cpp:64
Interface to the event handling of ASC.
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:433
GameMap * getMap() const
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:291
bool checkForKey(const SDL_KeyboardEvent *key, int modifier, int num)
Definition: replay.cpp:457
enum GameMap::State state
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
int researchpoints
Definition: research.h:135
An actual building on the map, which references a BuildingType Buildings have an owner,.
Definition: buildings.h:38
the different players in ASC. There may be 8 players (0..7) and neutral units (8) ...
Definition: player.h:99
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:256
void savereplay(GameMap *gamemap, int num)
writes all replay relevant map information of player num to the replay variable of actmap ...
Definition: loaders.cpp:1470
void setPlayerView(int player)
Definition: gamemap.cpp:1017
int movenum
Definition: replay.h:37
Resources are basically the currency of ASC.
Definition: typen.h:97
void displayActionError(const ActionResult &result, const ASCString &additionalInfo)
Definition: dialog.cpp:2168
bool available(const Research &research) const
Definition: research.cpp:412
void transfer_all_outstanding_tribute(Player &player)
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:417
int basicjamming_plus
this is added to the current basicjamming of the field to form the new jamming.
Definition: objecttype.h:89
int researchpoints
the current amount of research that the building conducts every turn
void execute(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:525
bool removeUnitFromCargo(Vehicle *veh, bool recursive=false)
removes the given unit from the container.
int choice_dlg(const ASCString &title, const ASCString &leftButton, const ASCString &rightButton)
Definition: dialog.cpp:616
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:467
GameMap * orgmap
Definition: replay.h:39
const Cargo & getCargo() const
int getCode() const
Definition: actionresult.h:43
bool compareMapResources(GameMap *currentMap, GameMap *replaymap, int player, ASCString *log)
Resources removecost
The resources required to remove the object with a unit; Note that units usually don't have any energ...
Definition: objecttype.h:110
int ypos
Definition: vehicle.h:124
void fatalError(const ASCString &string)
bool removeObject(const ObjectType *obj, bool force=false, ObjectRemovalStrategy *objectRemovalStrategy=NULL)
removes all objects of the given type from the field
Definition: mapfield.cpp:256
ASCString getName(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:382
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:532
int progress
Definition: research.h:189
ReplayRecorder * replayRecorder
Definition: replay.cpp:239
int networkid
a unique identification of the unit that is used everywhere in ASC (and not only the network protocol...
Definition: vehicle.h:140
void endTurn()
called after a player ends his turn
Definition: gamemap.cpp:1281
static void pushIconHandler(GuiIconHandler *iconHandler)
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:319
int getMovement(bool checkFuel=true, bool checkRF=true) const
returns the movement points the unit has left for this turn. CheckFuel should almost always be true...
Definition: vehicle.cpp:558
Surface & getImage(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:262
void addview()
adds the units view to the map.
Definition: vehicle.cpp:990
ReplayInfo * replayinfo
Definition: gamemap.h:396
MemoryStream * actmemstream
Definition: gamemap.h:376
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:248
ObjectContainer objects
Definition: mapfield.h:124
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182
volatile int ticker
Definition: events.cpp:234
bool available(const MapCoordinate &pos, ContainerBase *subject, int num)
Definition: replay.cpp:361
MapField * getField(int x, int y)
Definition: gamemap.h:465