guifunctions.cpp

Go to the documentation of this file.
00001 
00005 /*
00006     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00007     Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with this program; see the file COPYING. If not, write to the
00021     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00022     Boston, MA  02111-1307  USA
00023 */
00024 
00025 #include <stdio.h>
00026 #include <cstring>
00027 #include <stdlib.h>
00028 
00029 #include "guifunctions.h"
00030 #include "guifunctions-interface.h"
00031 #include "controls.h"
00032 #include "dialog.h"
00033 #include "gameoptions.h"
00034 #include "iconrepository.h"
00035 #include "attack.h"
00036 #include "graphics/blitter.h"
00037 #include "viewcalculation.h"
00038 #include "spfst.h"
00039 #include "dialogs/cargodialog.h"
00040 #include "dialogs/ammotransferdialog.h"
00041 #include "mapdisplay.h"
00042 #include "sg.h"
00043 #include "loaders.h"
00044 #include "itemrepository.h"
00045 #include "turncontrol.h"
00046 #include "spfst-legacy.h"
00047 #include "dialogs/buildingtypeselector.h"
00048 #include "dialogs/internalAmmoTransferDialog.h"
00049 #include "dialogs/vehicleproductionselection.h"
00050 #include "actions/jumpdrivecommand.h"
00051 #include "actions/destructunitcommand.h"
00052 #include "actions/attackcommand.h"
00053 #include "actions/moveunitcommand.h"
00054 #include "actions/putobjectcommand.h"
00055 #include "actions/putminecommand.h"
00056 #include "actions/constructunitcommand.h"
00057 #include "actions/servicecommand.h"
00058 #include "actions/reactionfireswitchcommand.h"
00059 #include "actions/repairunitcommand.h"
00060 #include "actions/constructbuildingcommand.h"
00061 #include "actions/destructbuildingcommand.h"
00062 #include "actions/powergenerationswitchcommand.h"
00063 #include "actions/internalammotransfercommand.h"
00064 
00065 bool commandPending()
00066 {
00067     return NewGuiHost::pendingCommand;
00068 }
00069 
00070 namespace GuiFunctions
00071 {
00072 
00073 
00074 
00075 class AttackGui : public GuiIconHandler, public GuiFunction, public SigC::Object
00076 {
00077     pair<const AttackWeap*, int> getEntry( const MapCoordinate& pos, int num );
00078 
00079     void mapDeleted( GameMap& map ) {
00080         if ( NewGuiHost::getIconHandler() == this )
00081             NewGuiHost::popIconHandler();
00082     }
00083 
00084 protected:
00085     bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00086     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00087     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00088     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00089     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00090 
00091 public:
00092     AttackGui() {
00093         GameMap::sigMapDeletion.connect( SigC::slot( *this, &AttackGui::mapDeleted ));
00094     };
00095     void setupWeapons( AttackCommand* va ) {
00096         delete NewGuiHost::pendingCommand;
00097         NewGuiHost::pendingCommand = va;
00098     };
00099     void eval( const MapCoordinate& mc, ContainerBase* subject );
00100 
00101 };
00102 
00103 bool AttackGui :: checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00104 {
00105     if ( key->keysym.sym == SDLK_ESCAPE || key->keysym.unicode == 'c' ) {
00106         // execute( actmap->getCursor(), actmap->getField( actmap->getCursor())->getContainer() , -1 );
00107         return true;
00108     }
00109     return false;
00110 }
00111 
00112 
00113 pair<const AttackWeap*, int> AttackGui::getEntry( const MapCoordinate& pos, int num )
00114 {
00115     int counter = 0;
00116 
00117     AttackCommand* attackEngine = dynamic_cast<AttackCommand*>(NewGuiHost::pendingCommand );
00118     if ( attackEngine ) {
00119         const AttackCommand::FieldList* afl = NULL;
00120         for ( int i = 0; i < 3; ++i ) {
00121             switch ( i ) {
00122             case 0:
00123                 afl = &attackEngine->getAttackableUnits();
00124                 break;
00125             case 1:
00126                 afl = &attackEngine->getAttackableBuildings();
00127                 break;
00128             case 2:
00129                 afl = &attackEngine->getAttackableObjects();
00130                 break;
00131             }
00132 
00133             AttackCommand::FieldList::const_iterator it = afl->find( pos );
00134             if ( it != afl->end() ) {
00135                 const AttackWeap* aw = &(it->second);
00136                 for ( int a = 0; a < aw->count; ++a ) {
00137                     if ( counter == num )
00138                         return make_pair( aw, a );
00139 
00140                     ++counter;
00141                 }
00142             }
00143         }
00144     }
00145     return make_pair( (AttackWeap*)(NULL), 0 );
00146 }
00147 
00148 
00149 bool AttackGui::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00150 {
00151     if ( num == -1 )
00152         return true;
00153 
00154     if ( getEntry(pos,num).first )
00155         return true;
00156     else
00157         return false;
00158 }
00159 
00160 void AttackGui::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00161 {
00162     if ( num != -1 ) {
00163 
00164         pair<const AttackWeap*, int> p = getEntry(pos,num);
00165         if ( p.first ) {
00166             AttackCommand* attack = dynamic_cast<AttackCommand*>(NewGuiHost::pendingCommand);
00167             if ( attack ) {
00168                 attack->setTarget ( pos, p.first->num[p.second] );
00169                 ActionResult res = attack->execute( createContext( actmap ));
00170                 if ( !res.successful()  ) {
00171                     dispmessage2 ( res );
00172                     delete NewGuiHost::pendingCommand;
00173                 }
00174             }
00175 
00176         }
00177     }
00178     NewGuiHost::pendingCommand = NULL;
00179 
00180     actmap->cleartemps();
00181     NewGuiHost::popIconHandler();
00182     repaintMap();
00183     updateFieldInfo();
00184 }
00185 
00186 Surface& AttackGui::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00187 {
00188     if ( num == -1 )
00189         return IconRepository::getIcon("cancel.png");
00190 
00191     pair<const AttackWeap*, int> p = getEntry(pos,num);
00192     switch ( p.first->typ[p.second] ) {
00193     case cwcruisemissileb:
00194         return IconRepository::getIcon("weap-cruisemissile.png");
00195     case cwbombb:
00196         return IconRepository::getIcon("weap-bomb.png");
00197     case cwlargemissileb:
00198         return IconRepository::getIcon("weap-bigmissile.png");
00199     case cwsmallmissileb:
00200         return IconRepository::getIcon("weap-smallmissile.png");
00201     case cwtorpedob:
00202         return IconRepository::getIcon("weap-torpedo.png");
00203     case cwmachinegunb:
00204         return IconRepository::getIcon("weap-machinegun.png");
00205     case cwcannonb:
00206         return IconRepository::getIcon("weap-cannon.png");
00207     default:
00208         return IconRepository::getIcon("weap-laser.png");
00209     };
00210 }
00211 
00212 ASCString AttackGui::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00213 {
00214 
00215     AttackCommand* attackEngine = dynamic_cast<AttackCommand*>(NewGuiHost::pendingCommand);
00216 
00217     if ( num == -1 || attackEngine == NULL )
00218         return "cancel";
00219 
00220     Vehicle* attacker = attackEngine->getAttacker();
00221 
00222     tfight* battle = NULL;
00223 
00224     pair<const AttackWeap*, int> p = getEntry(pos,num);
00225 
00226 
00227     if ( p.first->target == AttackWeap::vehicle )
00228         battle = new tunitattacksunit ( attacker, actmap->getField(pos)->vehicle, true, p.first->num[p.second] );
00229     else if ( p.first->target == AttackWeap::building )
00230         battle = new tunitattacksbuilding ( attacker, pos.x, pos.y, p.first->num[p.second] );
00231     else if ( p.first->target == AttackWeap::object )
00232         battle = new tunitattacksobject ( attacker, pos.x, pos.y, p.first->num[p.second] );
00233 
00234 
00235     int dd = battle->dv.damage;
00236     int ad = battle->av.damage;
00237     battle->calc ( );
00238 
00239     ASCString result;
00240     result.format( "%s; eff strength: %d; damage inflicted to enemy: %d, making a total of ~%d~; own damage will be +%d = %d", cwaffentypen[getFirstBit(p.first->typ[p.second])], battle->av.strength, battle->dv.damage-dd, battle->dv.damage, battle->av.damage-ad, battle->av.damage );
00241     return result;
00242 }
00243 
00244 
00245 void AttackGui::eval( const MapCoordinate& mc, ContainerBase* subject )
00246 {
00247 
00248     int num = 0;
00249     while ( getEntry( mc, num).first ) {
00250         GuiButton* b = host->getButton(num);
00251         b->registerFunc( this, mc, subject, num );
00252         b->Show();
00253         ++num;
00254     }
00255 
00256     GuiButton* b = host->getButton(num);
00257     b->registerFunc( this, mc, subject, -1 );
00258     b->Show();
00259     ++num;
00260 
00261     host->disableButtons(num);
00262 }
00263 
00264 
00265 
00266 AttackGui attackGui;
00267 
00268 
00269 
00270 bool Cancel::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00271 {
00272     return commandPending();
00273 };
00274 
00275 void Cancel::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00276 {
00277     if ( NewGuiHost::pendingCommand ) {
00278         delete NewGuiHost::pendingCommand;
00279         NewGuiHost::pendingCommand = NULL;
00280     }
00281 
00282     actmap->cleartemps(7);
00283     updateFieldInfo();
00284     displaymap();
00285 };
00286 
00287 bool Cancel::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00288 {
00289     return ( key->keysym.sym == SDLK_ESCAPE || key->keysym.unicode == 'c' );
00290 };
00291 
00292 
00293 Surface& Cancel::getImage( const MapCoordinate& po, ContainerBase* subject, int nums )
00294 {
00295     return IconRepository::getIcon("cancel.png");
00296 };
00297 
00298 ASCString Cancel::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00299 {
00300     return "~c~ancel";
00301 };
00302 
00303 
00304 
00305 bool Movement::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00306 {
00307     return ( key->keysym.sym == SDLK_SPACE );
00308 };
00309 
00310 Surface& Movement::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00311 {
00312     return IconRepository::getIcon("movement.png");
00313 };
00314 
00315 ASCString Movement::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00316 {
00317     return "move unit (~space~)";
00318 };
00319 
00320 
00321 bool MovementBase::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00322 {
00323     if ( !commandPending() ) {
00324         Vehicle* eht = actmap->getField(pos)->vehicle;
00325         if ( eht )
00326             if ( eht->getOwner() == actmap->actplayer)
00327                 return MoveUnitCommand::avail ( eht );
00328     } else {
00329         if ( !NewGuiHost::pendingCommand )
00330             return false;
00331 
00332         MoveUnitCommand* moveCommand = dynamic_cast<MoveUnitCommand*>(NewGuiHost::pendingCommand);
00333         if ( moveCommand && moveCommand->getVerticalDirection() == getVerticalDirection() ) {
00334             const AStar3D::Path& path = moveCommand->getPath();
00335             if ( path.size() ==  0 )
00336                 return moveCommand->isFieldReachable(pos, true );
00337             else
00338                 return path.rbegin()->x == pos.x && path.rbegin()->y == pos.y;
00339         }
00340     }
00341     return false;
00342 }
00343 
00344 void Movement::parametrizePathFinder( AStar3D& pathFinder )
00345 {
00346 }
00347 
00348 bool Movement::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00349 {
00350     if ( !commandPending() ) {
00351         return MovementBase::available( pos, subject, num );
00352     } else {
00353         MoveUnitCommand* moveCommand = dynamic_cast<MoveUnitCommand*>(NewGuiHost::pendingCommand);
00354         if ( moveCommand && moveCommand->getVerticalDirection() == getVerticalDirection() ) {
00355             bool avail = MovementBase::available( pos, subject, num );
00356             if ( avail )
00357                 return true;
00358             else {
00359                 return moveCommand->longDistAvailable( pos );
00360             }
00361         }
00362     }
00363     return false;
00364 }
00365 
00366 
00367 
00368 
00369 void MovementBase::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00370 {
00371     if ( !commandPending() ) {
00372         // This situation should have already been covered by MovementBase::available(), but there were crash reports with vehicle being NULL
00373         if ( !actmap->getField(pos)->vehicle )
00374            return;
00375 
00376        
00377         MoveUnitCommand* move = new MoveUnitCommand( actmap->getField(pos)->vehicle );
00378 
00379         move->setVerticalDirection( getVerticalDirection() );
00380 
00381         int mode = 0;
00382         if (  isKeyPressed( SDLK_LSHIFT ) ||  isKeyPressed( SDLK_RSHIFT )) {
00383             if ( getVerticalDirection() == 0 )
00384                 mode |= MoveUnitCommand::DisableHeightChange;
00385             else
00386                 mode |= MoveUnitCommand::ShortestHeightChange;
00387         }
00388 
00389         ActionResult res = move->searchFields ( -1, mode );
00390         if ( !res.successful() ) {
00391             dispmessage2 ( res.getCode(), NULL );
00392             delete move;
00393             return;
00394         }
00395 
00396         for ( set<MapCoordinate3D>::const_iterator i = move->getReachableFields().begin(); i != move->getReachableFields().end(); ++i )
00397             actmap->getField( *i)->a.temp = 1;
00398 
00399         // if ( !CGameOptions::Instance()->dontMarkFieldsNotAccessible_movement )
00400         for ( set<MapCoordinate3D>::const_iterator i = move->getReachableFieldsIndirect().begin(); i != move->getReachableFieldsIndirect().end(); ++i )
00401             actmap->getField( *i)->a.temp2 = 2;
00402         displaymap();
00403         NewGuiHost::pendingCommand = move;
00404         updateFieldInfo();
00405 
00406 
00407     } else {
00408         MoveUnitCommand* move = dynamic_cast<MoveUnitCommand*>(NewGuiHost::pendingCommand);
00409         if ( !move || move->getVerticalDirection() != getVerticalDirection() )
00410             return;
00411 
00412         move->setDestination( pos );
00413 
00414         if ( CGameOptions::Instance()->fastmove || move->getPath().size() ) {
00415             move->calcPath();
00416             actmap->cleartemps(7);
00417             displaymap();
00418             MapDisplayPG::CursorHiding ch;
00419             ActionResult res = move->execute( createContext(actmap));
00420             NewGuiHost::pendingCommand = NULL;
00421             if ( !res.successful() ) {
00422                 delete move;
00423                 dispmessage2(res);
00424                 updateFieldInfo();
00425                 return;
00426             }
00427         } else {
00428             move->calcPath();
00429             actmap->cleartemps(7);
00430             for ( AStar3D::Path::const_iterator i = move->getPath().begin(); i != move->getPath().end(); ++i )
00431                 actmap->getField( *i ) ->a.temp = 1;
00432             displaymap();
00433         }
00434         updateFieldInfo();
00435     }
00436 }
00437 
00438 
00439 
00440 
00441 
00442 class Ascend : public MovementBase
00443 {
00444 protected:
00445     virtual void parametrizePathFinder( AStar3D& pathFinder ) {};
00446 public:
00447     // void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00448     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00449         return ( key->keysym.unicode == 's' );
00450     };
00451     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00452         return IconRepository::getIcon("ascend-airplane.png");
00453     };
00454     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00455         return "a~s~cend";
00456     };
00457     int getVerticalDirection() {
00458         return 1;
00459     };
00460 
00461     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00462         if ( !commandPending() ) {
00463             Vehicle* eht = actmap->getField(pos)->vehicle;
00464             if ( eht )
00465                 if ( eht->getOwner() == actmap->actplayer)
00466                     return MoveUnitCommand::ascendAvail ( eht );
00467             return false;
00468         } else
00469             return MovementBase::available( pos, subject, num );
00470     }
00471 
00472 };
00473 
00474 
00475 
00476 
00477 
00478 
00479 class Descend : public MovementBase
00480 {
00481 protected:
00482     int getVerticalDirection() {
00483         return -1;
00484     };
00485 public:
00486     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00487         return ( key->keysym.unicode == 'd' );
00488     };
00489     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00490         return IconRepository::getIcon("descent-airplane.png");
00491     };
00492     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00493         return "~d~escend";
00494     };
00495 
00496     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00497         if ( !commandPending() ) {
00498             Vehicle* eht = actmap->getField(pos)->vehicle;
00499             if ( eht )
00500                 if ( eht->getOwner() == actmap->actplayer)
00501                     return MoveUnitCommand::descendAvail ( eht );
00502             return false;
00503         } else
00504             return MovementBase::available( pos, subject, num );
00505     }
00506 
00507 };
00508 
00509 
00510 
00511 
00512 
00513 class EndTurn : public GuiFunction
00514 {
00515 public:
00516     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00517     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00518     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00519         return ( key->keysym.unicode == 'e' );
00520     };
00521     Surface& getImage( const MapCoordinate& po, ContainerBase* subject, int nums ) {
00522         return IconRepository::getIcon("endturn.png");
00523     };
00524     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00525         return "~e~nd turn";
00526     };
00527 };
00528 
00529 bool EndTurn::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00530 {
00531     if (!commandPending() )
00532         if (actmap->levelfinished == false)
00533             return true;
00534     return false;
00535 }
00536 
00537 
00538 void EndTurn::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00539 {
00540     if ( !CGameOptions::Instance()->endturnquestion || (choice_dlg("do you really want to end your turn ?","~y~es","~n~o") == 1)) {
00541 
00542         Player& player = actmap->player[actmap->actplayer];
00543         ASCString message = "The following units are about to crash\n\n";
00544         bool crashWarning = checkUnitsForCrash( player, message );
00545         if ( crashWarning ) {
00546             if ( choiceDialog( message, "continue", "cancel", "AircraftCrashWarning" ) == 2 )
00547                 return;
00548 
00549         }
00550 
00551 
00552         static int autosave = 0;
00553         ASCString name = ASCString("autosave") + strrr( autosave ) + &savegameextension[1];
00554 
00555         savegame ( name, actmap );
00556 
00557 
00558 
00559         autosave = !autosave;
00560 
00561         actmap->sigPlayerUserInteractionEnds( player );
00562 
00563         next_turn( actmap, NextTurnStrategy_AskUser(), &getDefaultMapDisplay() );
00564 
00565         displaymap();
00566     }
00567 }
00568 
00569 
00570 class Attack : public GuiFunction
00571 {
00572 public:
00573     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00574     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00575     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00576         return ( key->keysym.unicode == 'a' );
00577     };
00578     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00579         return IconRepository::getIcon("attack.png");
00580     };
00581     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00582         return "~a~ttack";
00583     };
00584 };
00585 
00586 
00587 bool Attack::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00588 {
00589     if ( !commandPending() ) {
00590         Vehicle* eht = actmap->getField(pos)->vehicle;
00591         if ( eht )
00592             if ( eht->color == actmap->actplayer * 8)
00593                 return AttackCommand::avail ( eht );
00594     }
00595     return false;
00596 }
00597 
00598 void Attack::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
00599 {
00600     AttackCommand* attack = new AttackCommand( actmap->getField(pos)->vehicle );
00601 
00602     ActionResult result = attack->searchTargets();
00603     if ( !result.successful() ) {
00604         dispmessage2 ( result );
00605         return;
00606     }
00607 
00608     AttackCommand::FieldList::const_iterator i;
00609     for ( i = attack->getAttackableUnits().begin(); i != attack->getAttackableUnits().end(); i++ )
00610         actmap->getField( i->first )->a.temp = 1;
00611     for ( i = attack->getAttackableBuildings().begin(); i != attack->getAttackableBuildings().end(); i++ )
00612         actmap->getField( i->first )->a.temp = 1;
00613     for ( i = attack->getAttackableObjects().begin(); i != attack->getAttackableObjects().end(); i++ )
00614         actmap->getField( i->first )->a.temp = 1;
00615 
00616     displaymap();
00617     attackGui.setupWeapons( attack );
00618     NewGuiHost::pushIconHandler( &attackGui );
00619 }
00620 
00621 
00622 
00623 
00624 class PowerSwitch : public GuiFunction
00625 {
00626 private:
00627     bool newState;
00628 public:
00629 
00630     PowerSwitch( bool state ) : newState( state ) {};
00631 
00632     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00633         if (!commandPending() )  {
00634             MapField* fld = actmap->getField ( pos );
00635             if ( fld->vehicle )
00636                 return PowerGenerationSwitchCommand::avail( fld->vehicle, newState );
00637 
00638         }
00639         return false;
00640     };
00641 
00642     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00643         return ( key->keysym.unicode == 'p' );
00644     };
00645     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00646         auto_ptr<PowerGenerationSwitchCommand> pgsc ( new PowerGenerationSwitchCommand( actmap->getField(pos)->vehicle));
00647         pgsc->setNewState( newState );
00648         ActionResult res = pgsc->execute( createContext( actmap ));
00649         if ( !res.successful() )
00650             displayActionError( res );
00651         else
00652             pgsc.release();
00653 
00654         updateFieldInfo();
00655     }
00656 };
00657 
00658 
00659 
00660 class PowerOn : public PowerSwitch
00661 {
00662 public:
00663     PowerOn() : PowerSwitch( true ) {};
00664 
00665     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00666         return IconRepository::getIcon("poweron.png");
00667     };
00668 
00669     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00670         return "enable ~p~ower generation";
00671     };
00672 };
00673 
00674 
00675 class PowerOff : public PowerSwitch
00676 {
00677 public:
00678     PowerOff() : PowerSwitch( false ) {};
00679 
00680     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00681         return ( key->keysym.unicode == 'p' );
00682     };
00683 
00684     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00685         return IconRepository::getIcon("poweroff.png");
00686     };
00687 
00688     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00689         return "disable ~p~ower generation";
00690     };
00691 };
00692 
00693 
00694 
00695 class UnitInfo : public GuiFunction
00696 {
00697 public:
00698     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00699     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00700         executeUserAction(ua_vehicleinfo);
00701     };
00702     Surface& getImage( const MapCoordinate& po, ContainerBase* subject, int nums ) {
00703         return IconRepository::getIcon("unitinfo.png");
00704     };
00705     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00706         return "unit ~i~nfo";
00707     };
00708     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00709         return ( key->keysym.unicode == 'i' );
00710     };
00711 };
00712 
00713 bool UnitInfo::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00714 {
00715     MapField* fld = actmap->getField(pos);
00716     if ( fld && fld->vehicle )
00717         if ( !commandPending() )
00718             if ( fld->vehicle != NULL)
00719                 if (fieldvisiblenow( fld ))
00720                     return true;
00721     return false;
00722 }
00723 
00724 
00725 
00726 
00727 
00728 
00729 class DestructBuilding : public GuiFunction
00730 {
00731 public:
00732     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00733     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00734     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00735         return IconRepository::getIcon("destructbuilding.png");
00736     };
00737     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00738         return "destruct building";
00739     };
00740 };
00741 
00742 
00743 bool DestructBuilding::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00744 {
00745     MapField* fld = actmap->getField(pos);
00746     if (!commandPending()) {
00747         if ( fld->vehicle )
00748             return DestructBuildingCommand::avail( fld->vehicle );
00749     } else {
00750         DestructBuildingCommand* dbc = dynamic_cast<DestructBuildingCommand*>( NewGuiHost::pendingCommand );
00751         if ( dbc ) {
00752             return dbc->isFieldUsable(pos);
00753         }
00754     }
00755     return false;
00756 }
00757 
00758 void DestructBuilding::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
00759 {
00760     DestructBuildingCommand* dbc = dynamic_cast<DestructBuildingCommand*>( NewGuiHost::pendingCommand );
00761     if ( !dbc ) {
00762                 Vehicle* unit = actmap->getField(pos)->vehicle;
00763                 if ( !unit )
00764                         return;
00765 
00766         auto_ptr<DestructBuildingCommand> db ( new DestructBuildingCommand( unit ));
00767 
00768         vector<MapCoordinate> fields = db->getFields();
00769 
00770         if ( fields.empty() ) {
00771             dispmessage2( 306, NULL );
00772             return;
00773         }
00774         for ( vector<MapCoordinate>::iterator i = fields.begin(); i != fields.end(); ++i )
00775             actmap->getField(*i)->a.temp = 1;
00776 
00777         repaintMap();
00778 
00779         NewGuiHost::pendingCommand = db.release();
00780 
00781         updateFieldInfo();
00782 
00783     } else {
00784         dbc->setTargetPosition( pos );
00785         actmap->cleartemps();
00786 
00787         ActionResult res = dbc->execute( createContext( actmap ));
00788         if ( !res.successful() ) {
00789             displayActionError(res);
00790             delete NewGuiHost::pendingCommand;
00791         }
00792         NewGuiHost::pendingCommand = NULL;
00793 
00794         repaintMap();
00795         updateFieldInfo();
00796     }
00797 }
00798 
00799 
00800 class OpenContainer : public GuiFunction
00801 {
00802     static int containeractive;
00803 public:
00804     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00805         MapField* fld = actmap->getField(pos);
00806         if ( fieldvisiblenow ( fld ) && fld->getContainer() ) {
00807             if ( !containeractive && !commandPending() ) {
00808                 Player& player = fld->getContainer()->getMap()->player[fld->getContainer()->getOwner()];
00809                 if ( fld->building && ( player.diplomacy.isAllied( actmap->actplayer) || actmap->getNeutralPlayerNum() == fld->building->getOwner() || actmap->getCurrentPlayer().stat==Player::supervisor )) {
00810                     if ( fld->building->getCompletion() == fld->building->typ->construction_steps-1 )
00811                         return true;
00812                 }  else {
00813                     if ( fld->vehicle && fld->vehicle->typ->maxLoadableUnits  &&  (player.diplomacy.isAllied( actmap->actplayer)  || actmap->getCurrentPlayer().stat==Player::supervisor) )
00814                         return true;
00815                 }
00816             }
00817         }
00818         return false;
00819     };
00820 
00821     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00822         MapField* fld = actmap->getField(pos);
00823 
00824         cargoDialog( fld->getContainer() );
00825 
00826         updateFieldInfo();
00827         repaintMap();
00828     }
00829 
00830     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00831         return IconRepository::getIcon("container.png");
00832     };
00833 
00834     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00835         return ( key->keysym.unicode == 'l' );
00836     };
00837 
00838     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00839         return "view ~l~oaded units";
00840     };
00841 };
00842 
00843 int OpenContainer::containeractive = 0;
00844 
00845 
00846 
00847 
00848 class EnableReactionfire : public GuiFunction
00849 {
00850 public:
00851     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00852         Vehicle* eht = actmap->getField(pos)->vehicle;
00853         if ( !commandPending() )
00854             if ( eht )
00855                 if ( eht->getOwner() == actmap->actplayer )
00856                     return ReactionFireSwitchCommand::avail( eht, true );
00857 
00858         return false;
00859     };
00860     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00861         return ( key->keysym.unicode == 'x' );
00862     };
00863 
00864     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00865         Vehicle* eht = actmap->getField(pos)->vehicle;
00866         auto_ptr<ReactionFireSwitchCommand> rf ( new ReactionFireSwitchCommand( eht ));
00867         rf->setNewState( true );
00868         ActionResult res = rf->execute( createContext( actmap ));
00869         if ( res.successful() )
00870             rf.release();
00871         else
00872             displayActionError( res );
00873 
00874         updateFieldInfo();
00875     }
00876 
00877     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00878         return IconRepository::getIcon("enable-reactionfire.png");
00879     };
00880 
00881     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00882         return "enable reaction fire (~x~)";
00883     };
00884 };
00885 
00886 class DisableReactionfire : public GuiFunction
00887 {
00888 public:
00889     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00890         Vehicle* eht = actmap->getField(pos)->vehicle;
00891         if ( !commandPending() )
00892             if ( eht )
00893                 if ( eht->getOwner() == actmap->actplayer )
00894                     return ReactionFireSwitchCommand::avail( eht, false );
00895 
00896         return false;
00897     };
00898 
00899     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00900         return ( key->keysym.unicode == 'x' );
00901     };
00902     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00903         Vehicle* eht = actmap->getField(pos)->vehicle;
00904         auto_ptr<ReactionFireSwitchCommand> rf ( new ReactionFireSwitchCommand( eht ));
00905         rf->setNewState( false );
00906         ActionResult res = rf->execute( createContext( actmap ));
00907         if ( res.successful() )
00908             rf.release();
00909         else
00910             displayActionError( res );
00911 
00912         repaintMap();
00913         updateFieldInfo();
00914     }
00915 
00916     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00917         return IconRepository::getIcon("disable-reactionfire.png");
00918     };
00919 
00920     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00921         return "disable reaction fire (~x~)";
00922     };
00923 };
00924 
00925 
00926 class JumpDriveIcon : public GuiFunction, public SigC::Object
00927 {
00928 public:
00929     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00930         if ( !commandPending() ) {
00931 
00932             Vehicle* eht = actmap->getField(pos)->vehicle;
00933             if ( eht )
00934                 if ( eht->getOwner() == actmap->actplayer )
00935                     return JumpDriveCommand::available(eht).getAvailability() >= ActionAvailability::partially;
00936         } else {
00937             JumpDriveCommand* jdc = dynamic_cast<JumpDriveCommand*>(NewGuiHost::pendingCommand);
00938             if ( jdc ) {
00939                 if ( jdc->fieldReachable( pos ))
00940                     return true;
00941             }
00942         }
00943 
00944         return false;
00945     };
00946 
00947     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
00948         return ( key->keysym.unicode == 'j' );
00949     };
00950 
00951     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00952         if ( !commandPending() ) {
00953             Vehicle* eht = actmap->getField(pos)->vehicle;
00954             if ( !eht )
00955                 return;
00956 
00957             ActionAvailability aa = JumpDriveCommand::available(eht);
00958             if ( !aa.ready() ) {
00959                warningMessage( aa.getMessage() );
00960                return;
00961             }
00962             
00963             auto_ptr<JumpDriveCommand> jdc ( new JumpDriveCommand( eht ));
00964 
00965             vector<MapCoordinate> fields = jdc->getDestinations();
00966             for ( vector<MapCoordinate>::const_iterator i = fields.begin(); i != fields.end(); ++i )
00967                 actmap->getField(*i)->a.temp = 1;
00968 
00969             if ( fields.size() ) {
00970                 repaintMap();
00971                 NewGuiHost::pendingCommand = jdc.release();
00972                 updateFieldInfo();
00973             } else
00974                 dispmessage2( 22602 );
00975         } else {
00976             JumpDriveCommand* jdc = dynamic_cast<JumpDriveCommand*>(NewGuiHost::pendingCommand);
00977             if ( jdc ) {
00978                NewGuiHost::pendingCommand = NULL;
00979                jdc->setDestination( pos );
00980                 actmap->cleartemps(7);
00981                 ActionResult res = jdc->execute( createContext( actmap ));;
00982                 mapChanged( actmap );
00983 
00984                 if ( !res.successful() ) {
00985                     delete NewGuiHost::pendingCommand;
00986                     displayActionError( res );
00987                 }
00988                 updateFieldInfo();
00989             }
00990         }
00991     }
00992 
00993     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00994         return IconRepository::getIcon("jumpdrive.png");
00995     };
00996 
00997     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00998         return "activate jump drive (~j~)";
00999     };
01000 };
01001 
01002 
01003 
01004 class RepairUnit : public GuiFunction
01005 {
01006 public:
01007     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01008         MapField* fld = actmap->getField(pos);
01009         if (!commandPending()) {
01010             if ( fld && fld->vehicle )
01011                 if (fld->vehicle->getOwner() == actmap->actplayer )
01012                     if ( RepairUnitCommand::availExternally ( fld->vehicle ) )
01013                         return true;
01014         } else {
01015             if ( NewGuiHost::pendingCommand ) {
01016                 RepairUnitCommand* service = dynamic_cast<RepairUnitCommand*>(NewGuiHost::pendingCommand);
01017                 if ( service && fld->vehicle )
01018                     return service->validTarget( fld->vehicle );
01019             }
01020         }
01021         return false;
01022     };
01023 
01024     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
01025         return ( key->keysym.unicode == 'r' );
01026     };
01027     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01028         if ( !commandPending()  ) {
01029             auto_ptr<RepairUnitCommand> rp ( new RepairUnitCommand( actmap->getField(pos)->vehicle ));
01030 
01031             vector<Vehicle*> targets = rp->getExternalTargets();
01032 
01033             int fieldCount = 0;
01034             for ( vector<Vehicle*>::iterator i = targets.begin(); i != targets.end(); ++i  ) {
01035                 actmap->getField ( (*i)->getPosition() )->a.temp = 1;
01036                 fieldCount++;
01037             }
01038             if ( !fieldCount ) {
01039                 dispmessage2 ( 211 );
01040             } else {
01041                 NewGuiHost::pendingCommand = rp.release();
01042                 repaintMap();
01043                 updateFieldInfo();
01044             }
01045         } else {
01046             if ( NewGuiHost::pendingCommand ) {
01047                 RepairUnitCommand* service = dynamic_cast<RepairUnitCommand*>(NewGuiHost::pendingCommand);
01048                 if ( service ) {
01049                     MapField* fld = actmap->getField(pos);
01050                     if ( fld->vehicle ) {
01051                         service->setTarget( fld->vehicle );
01052                         ActionResult res = service->execute( createContext ( actmap ));
01053                         if ( !res.successful() ) {
01054                             displayActionError(res);
01055                             delete NewGuiHost::pendingCommand;
01056                         }
01057                         NewGuiHost::pendingCommand = NULL;
01058 
01059                         actmap->cleartemps(7);
01060                         repaintMap();
01061                         updateFieldInfo();
01062                     }
01063                 }
01064             }
01065         }
01066     }
01067 
01068     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01069         return IconRepository::getIcon("repair.png");
01070     };
01071 
01072     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01073         MapField* fld = actmap->getField(pos);
01074         if ( fld && fld->vehicle && NewGuiHost::pendingCommand  ) {
01075             RepairUnitCommand* service = dynamic_cast<RepairUnitCommand*>(NewGuiHost::pendingCommand);
01076             if ( service ) {
01077                 Resources r;
01078                 service->getRepairingUnit( )->getMaxRepair ( fld->vehicle, 0, r);
01079                 return "~r~epair unit (cost: " + r.toString() + ")";
01080             }
01081         }
01082         return "~r~epair a unit";
01083     };
01084 };
01085 
01086 
01087 
01088 
01089 class RefuelUnitCommand : public GuiFunction
01090 {
01091 public:
01092     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01093         MapField* fld = actmap->getField(pos);
01094         if (!commandPending()) {
01095             if ( fld && fld->getContainer() )
01096                 if (fld->getContainer()->getOwner() == actmap->actplayer )
01097                     if ( ServiceCommand::availExternally ( fld->getContainer() ) )
01098                         return true;
01099         } else {
01100             if ( NewGuiHost::pendingCommand ) {
01101                 ServiceCommand* service = dynamic_cast<ServiceCommand*>(NewGuiHost::pendingCommand);
01102                 if ( service && fld->getContainer() ) {
01103                     const ServiceTargetSearcher::Targets& destinations = service->getDestinations();
01104                     return find( destinations.begin(), destinations.end(), fld->getContainer() ) != destinations.end();
01105                 }
01106             }
01107         }
01108         return false;
01109 
01110     };
01111     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
01112         return ( key->keysym.unicode == 'f' );
01113     };
01114 
01115     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01116         if ( !NewGuiHost::pendingCommand ) {
01117             auto_ptr<ServiceCommand> service ( new ServiceCommand( subject ));
01118 
01119             MapCoordinate srcPos = subject->getPosition();
01120             int fieldCount = 0;
01121 
01122             const ServiceTargetSearcher::Targets& destinations = service->getDestinations();
01123             for ( ServiceTargetSearcher::Targets::const_iterator i = destinations.begin(); i != destinations.end(); ++i ) {
01124                 MapCoordinate targetPos = (*i)->getPosition();
01125                 if ( targetPos != srcPos ) {
01126                     MapField* fld = subject->getMap()->getField ( targetPos );
01127                     fieldCount++;
01128                     fld->a.temp = 1;
01129                 }
01130             }
01131             if ( !fieldCount ) {
01132                 dispmessage2 ( 211 );
01133                 return;
01134             }
01135 
01136             NewGuiHost::pendingCommand = service.release();
01137             displaymap();
01138             updateFieldInfo();
01139 
01140         } else {
01141             ServiceCommand* service = dynamic_cast<ServiceCommand*>(NewGuiHost::pendingCommand);
01142 
01143             service->setDestination( subject );
01144             service->getTransferHandler().fillDest();
01145             service->saveTransfers();
01146             ActionResult res = service->execute( createContext( actmap ));
01147             if ( !res.successful() ) {
01148                 dispmessage2( res );
01149                 delete NewGuiHost::pendingCommand;
01150             }
01151 
01152             NewGuiHost::pendingCommand = NULL;
01153             actmap->cleartemps ( 7 );
01154             displaymap();
01155             updateFieldInfo();
01156         }
01157     }
01158 
01159     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01160         return IconRepository::getIcon("refuel.png");
01161     };
01162 
01163     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01164         return "re~f~uel a unit";
01165     };
01166 };
01167 
01168 
01169 class RefuelUnitDialogCommand : public GuiFunction
01170 {
01171 public:
01172     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01173         if ( NewGuiHost::pendingCommand ) {
01174             ServiceCommand* service = dynamic_cast<ServiceCommand*>(NewGuiHost::pendingCommand);
01175             MapField* fld = actmap->getField(pos);
01176             if ( service && fld->getContainer() ) {
01177                 const ServiceTargetSearcher::Targets& destinations = service->getDestinations();
01178                 return find( destinations.begin(), destinations.end(), fld->getContainer() ) != destinations.end();
01179             }
01180         }
01181         return false;
01182     };
01183     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
01184         return ( key->keysym.unicode == 'f' && (modifier & KMOD_SHIFT)  );
01185     };
01186 
01187     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01188         ServiceCommand* service = dynamic_cast<ServiceCommand*>(NewGuiHost::pendingCommand);
01189         MapField* fld = actmap->getField(pos);
01190         service->setDestination( fld->getContainer() );
01191         ammoTransferWindow( service->getRefueller(), actmap->getField(pos)->getContainer(), service );
01192 
01193         if ( service->getState() != Command::Finished )
01194             delete NewGuiHost::pendingCommand;
01195 
01196         NewGuiHost::pendingCommand = NULL;
01197         actmap->cleartemps ( 7 );
01198         displaymap();
01199         updateFieldInfo();
01200     }
01201 
01202     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01203         return IconRepository::getIcon("refuel-dialog.png");
01204     };
01205 
01206     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01207         return "re~F~uel dialog ";
01208     };
01209 };
01210 
01211 
01212 
01213 class PutMine : public GuiFunction
01214 {
01215 public:
01216     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01217         MapField* fld = actmap->getField(pos);
01218         if ( !commandPending())
01219             if ( fld->vehicle )
01220                 return PutMineCommand::avail(fld->vehicle);
01221         return false;
01222     };
01223 
01224     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
01225         return ( key->keysym.unicode == 'm' );
01226     };
01227 
01228     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01229         MapField* fld = actmap->getField(pos);
01230         if ( fld->vehicle ) {
01231             auto_ptr<PutMineCommand> poc ( new PutMineCommand( actmap->getField(pos)->vehicle ));
01232             ActionResult res = poc->searchFields();
01233             if ( res.successful() ) {
01234                 vector<MapCoordinate> fields = poc->getFields();
01235                 for ( vector<MapCoordinate>::iterator i = fields.begin(); i != fields.end(); ++i )
01236                     actmap->getField(*i)->a.temp = 1;
01237 
01238                 NewGuiHost::pendingCommand = poc.get();
01239                 poc.release();
01240 
01241                 repaintMap();
01242                 updateFieldInfo();
01243             } else
01244                 MessagingHub::Instance().statusInformation("can't build or remove any objects here");
01245         }
01246     }
01247 
01248     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01249         return IconRepository::getIcon("putmine.png");
01250     };
01251 
01252     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01253         return "put / remove ~m~ines";
01254     };
01255 };
01256 
01257 
01258 class PutMineStage2 : public GuiFunction
01259 {
01260 private:
01261     MineTypes type;
01262 protected:
01263     PutMineStage2( MineTypes type ) {
01264         this->type = type;
01265     };
01266 
01267 public:
01268     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01269         if ( !NewGuiHost::pendingCommand )
01270             return false;
01271 
01272         PutMineCommand* pmc = dynamic_cast<PutMineCommand*>( NewGuiHost::pendingCommand );
01273         if ( pmc ) {
01274             const vector<MineTypes>& mines = pmc->getCreatableMines( pos );
01275             for ( vector<MineTypes>::const_iterator i = mines.begin(); i != mines.end(); ++i )
01276                 if ( *i == type )
01277                     return true;
01278         }
01279         return false;
01280     };
01281 
01282     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01283         PutMineCommand* pmc = dynamic_cast<PutMineCommand*>( NewGuiHost::pendingCommand );
01284         if ( pmc ) {
01285             actmap->cleartemps();
01286             pmc->setCreationTarget( pos, type );
01287             ActionResult res = pmc->execute( createContext( actmap ));
01288             if ( !res.successful() ) {
01289                 displayActionError(res);
01290                 delete NewGuiHost::pendingCommand;
01291             }
01292             NewGuiHost::pendingCommand = NULL;
01293             updateFieldInfo();
01294         }
01295     }
01296 };
01297 
01298 class PutAntiTankMine : public PutMineStage2
01299 {
01300 public:
01301 
01302     PutAntiTankMine() : PutMineStage2( cmantitankmine ) {};
01303 
01304     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01305         return IconRepository::getIcon("putantitankmine.png");
01306     };
01307 
01308     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01309         return "put anti-tank mine";
01310     };
01311 };
01312 
01313 class PutAntiPersonalMine : public PutMineStage2
01314 {
01315 public:
01316 
01317     PutAntiPersonalMine() : PutMineStage2( cmantipersonnelmine ) {};
01318 
01319     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01320         return IconRepository::getIcon("putantipersonalmine.png");
01321     };
01322 
01323     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01324         return "put anti-personnel mine";
01325     };
01326 };
01327 
01328 
01329 
01330 
01331 class PutAntiShipMine : public PutMineStage2
01332 {
01333 public:
01334     PutAntiShipMine() : PutMineStage2( cmfloatmine ) {};
01335 
01336     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01337         return IconRepository::getIcon("putantishipmine.png");
01338     };
01339 
01340     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01341         return "put anti-ship mine";
01342     };
01343 };
01344 
01345 class PutAntiSubMine : public PutMineStage2
01346 {
01347 public:
01348     PutAntiSubMine() : PutMineStage2( cmmooredmine ) {};
01349 
01350     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01351         return IconRepository::getIcon("putantisubmine.png");
01352     };
01353 
01354     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01355         return "put anti-submarine mine";
01356     };
01357 };
01358 
01359 
01360 class RemoveMine : public GuiFunction
01361 {
01362 public:
01363     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01364         if ( !NewGuiHost::pendingCommand )
01365             return false;
01366 
01367         PutMineCommand* pmc = dynamic_cast<PutMineCommand*>( NewGuiHost::pendingCommand );
01368         if ( pmc )
01369             return pmc->getRemovableMines(pos);
01370 
01371         return false;
01372     };
01373 
01374     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01375         PutMineCommand* pmc = dynamic_cast<PutMineCommand*>( NewGuiHost::pendingCommand );
01376         if ( pmc ) {
01377             pmc->setRemovalTarget( pos );
01378             actmap->cleartemps();
01379             ActionResult res = pmc->execute( createContext( actmap ));
01380             if ( !res.successful() ) {
01381                 displayActionError(res);
01382                 delete NewGuiHost::pendingCommand;
01383             }
01384             NewGuiHost::pendingCommand = NULL;
01385             updateFieldInfo();
01386         }
01387     }
01388 
01389     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01390         return IconRepository::getIcon("removemine.png");
01391     };
01392 
01393     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01394         return "remove mine";
01395     };
01396 };
01397 
01398 
01399 
01400 
01401 
01402 
01403 class ObjectBuildingGui : public GuiIconHandler, public GuiFunction, public SigC::Object
01404 {
01405     Vehicle* veh;
01406 
01407     void mapDeleted( GameMap& map ) {
01408         if ( NewGuiHost::getIconHandler() == this )
01409             NewGuiHost::popIconHandler();
01410     }
01411 
01412 protected:
01413     enum Mode { Build, Remove };
01414 
01415     bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
01416     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
01417     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
01418     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
01419 
01420     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
01421 
01422     void addButton( int &num, const MapCoordinate& mc, ContainerBase* subject, int id );
01423 
01424 public:
01425     ObjectBuildingGui() : veh( NULL ) {
01426         GameMap::sigMapDeletion.connect( SigC::slot( *this, &ObjectBuildingGui::mapDeleted ));
01427     };
01428 
01429     bool init( Vehicle* vehicle );
01430     void eval( const MapCoordinate& mc, ContainerBase* subject );
01431 
01432 };
01433 
01434 
01435 bool ObjectBuildingGui::init( Vehicle* vehicle )
01436 {
01437     veh = vehicle;
01438     return true;
01439 }
01440 
01441 
01442 bool ObjectBuildingGui::available( const MapCoordinate& pos, ContainerBase* subject, int num )
01443 {
01444     return true;
01445     /*
01446     if ( num == 0 )
01447        return true;
01448 
01449     checkObject
01450 
01451     if ( getEntry(pos,num).first )
01452        return true;
01453     else
01454        return false;
01455        */
01456 }
01457 
01458 void ObjectBuildingGui::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
01459 {
01460     PutObjectCommand* poc = dynamic_cast<PutObjectCommand*>(NewGuiHost::pendingCommand);
01461     actmap->cleartemps();
01462     if ( num && poc ) {
01463         poc->setTarget( pos, abs(num) );
01464         ActionResult res = poc->execute( createContext( actmap ));
01465         if ( !res.successful()) {
01466             displayActionError(res);
01467             delete NewGuiHost::pendingCommand;
01468         }
01469     } else {
01470         delete NewGuiHost::pendingCommand;
01471     }
01472     repaintMap();
01473 
01474     NewGuiHost::pendingCommand = NULL;
01475 
01476     NewGuiHost::popIconHandler();
01477     updateFieldInfo();
01478 }
01479 
01480 
01481 Surface buildGuiIcon( const Surface& image, bool remove = false )
01482 {
01483     const Surface& cancelIcon = IconRepository::getIcon("empty-pressed.png" ); //  "cancel.png"
01484     Surface s = Surface::createSurface( cancelIcon.w(), cancelIcon.h(), 32, 0 );
01485 
01486     const Surface& o = image;
01487     if ( o.GetPixelFormat().BitsPerPixel() == 32 ) {
01488         MegaBlitter<4,4,ColorTransform_None, ColorMerger_PlainOverwrite, SourcePixelSelector_DirectZoom> blitter;
01489         blitter.setSize( o.w(), o.h(), s.w(), s.h() );
01490         blitter.blit( o, s, SPoint(int((s.w() - blitter.getZoomX() * o.w())/2), int((s.h() - blitter.getZoomY() * o.h())/2)));
01491     } else {
01492         MegaBlitter<1,4,ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_DirectZoom> blitter;
01493         blitter.setSize( o.w(), o.h(), s.w(), s.h() );
01494         blitter.blit( o, s, SPoint(int((s.w() - blitter.getZoomX() * o.w())/2), int((s.h() - blitter.getZoomY() * o.h())/2)));
01495     }
01496 
01497     if ( remove ) {
01498         MegaBlitter<4,4,ColorTransform_None, ColorMerger_AlphaOverwrite> blitter;
01499         Surface& removegui = IconRepository::getIcon( "cancel-addon.png" );
01500         blitter.blit( removegui, s,  SPoint((s.w() - removegui.w())/2, (s.h() - removegui.h())/2));
01501     }
01502     return s;
01503 }
01504 
01505 
01506 bool ObjectBuildingGui::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
01507 {
01508     if ( num > 0 )
01509         return false;
01510     else
01511         return ( key->keysym.sym == SDLK_ESCAPE || key->keysym.unicode == 'c' );
01512 }
01513 
01514 Surface& ObjectBuildingGui::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
01515 {
01516     if ( num == 0 )
01517         return IconRepository::getIcon("cancel.png");
01518 
01519     ObjectType* objtype = objectTypeRepository.getObject_byID( abs(num) );
01520 
01521     if ( !objtype )
01522         return IconRepository::getIcon("cancel.png");
01523 
01524     static map<int,Surface> removeIconRepository;
01525 
01526     if ( removeIconRepository.find( num ) != removeIconRepository.end() )
01527         return removeIconRepository[num];
01528 
01529     removeIconRepository[num] = buildGuiIcon( objtype->getPicture(), num < 0 );
01530     return removeIconRepository[num];
01531 }
01532 
01533 
01534 ASCString ObjectBuildingGui::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
01535 {
01536     if ( num == 0 )
01537         return "~c~ancel";
01538 
01539     ObjectType* objtype = objectTypeRepository.getObject_byID( abs(num) );
01540     if ( !objtype )
01541         return "";
01542 
01543     ASCString result;
01544     if ( num >= 0 ) {
01545         result.format( "Build %s (%d Material, %d Fuel, %d Movepoints)", objtype->name.c_str(), objtype->buildcost.material, objtype->buildcost.fuel, objtype->build_movecost );
01546         // num = -num;
01547     } else
01548         result.format( "Remove %s (%d Material, %d Fuel, %d Movepoints)", objtype->name.c_str(), objtype->removecost.material, objtype->removecost.fuel, objtype->remove_movecost );
01549 
01550     return result;
01551 }
01552 
01553 
01554 
01555 void ObjectBuildingGui::addButton( int &num, const MapCoordinate& mc, ContainerBase* subject, int id )
01556 {
01557     GuiButton* b = host->getButton(num);
01558     b->registerFunc( this, mc, subject, id );
01559     b->Show();
01560     ++num;
01561 }
01562 
01563 
01564 
01565 void ObjectBuildingGui::eval( const MapCoordinate& mc, ContainerBase* subject )
01566 {
01567     PutObjectCommand* poc = dynamic_cast<PutObjectCommand*>(NewGuiHost::pendingCommand);
01568 
01569     if ( poc ) {
01570         int num = 0;
01571         const vector<int>& creatable = poc->getCreatableObjects( mc );
01572         for ( vector<int>::const_iterator i = creatable.begin(); i != creatable.end(); ++i ) {
01573             addButton(num, mc, veh, *i);
01574         }
01575 
01576 
01577         const vector<int>& removable = poc->getRemovableObjects( mc );
01578         for ( vector<int>::const_iterator i = removable.begin(); i != removable.end(); ++i ) {
01579             addButton(num, mc, veh, -(*i));
01580         }
01581 
01582         GuiButton* b = host->getButton(num);
01583         b->registerFunc( this, mc, subject, 0 );
01584         b->Show();
01585         ++num;
01586 
01587         host->disableButtons(num);
01588     }
01589 
01590 }
01591 
01592 
01593 
01594 ObjectBuildingGui objectBuildingGui;
01595 
01596 
01597 class BuildObject : public GuiFunction
01598 {
01599 public:
01600     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
01601     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
01602     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01603         return IconRepository::getIcon("buildobjects.png");
01604     };
01605     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01606         return "~c~onstruct / remove objects";
01607     };
01608     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
01609         return ( key->keysym.unicode == 'c' );
01610     };
01611 };
01612 
01613 
01614 bool BuildObject::available( const MapCoordinate& pos, ContainerBase* subject, int num )
01615 {
01616     MapField* fld = actmap->getField(pos);
01617     if (!commandPending())
01618         if ( fld && fld->vehicle )
01619             return PutObjectCommand::avail(fld->vehicle );
01620     return false;
01621 }
01622 
01623 void BuildObject::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
01624 {
01625     MapField* fld = actmap->getField(pos);
01626     if ( fld->vehicle ) {
01627         auto_ptr<PutObjectCommand> poc ( new PutObjectCommand( actmap->getField(pos)->vehicle ));
01628         ActionResult res =poc->searchFields();
01629         if ( res.successful() ) {
01630             vector<MapCoordinate> fields = poc->getFields();
01631             for ( vector<MapCoordinate>::iterator i = fields.begin(); i != fields.end(); ++i )
01632                 actmap->getField(*i)->a.temp = 1;
01633 
01634             NewGuiHost::pendingCommand = poc.get();
01635             poc.release();
01636             NewGuiHost::pushIconHandler( &objectBuildingGui );
01637 
01638             repaintMap();
01639             updateFieldInfo();
01640         } else
01641             MessagingHub::Instance().statusInformation("can't build or remove any objects here");
01642     }
01643 }
01644 
01645 
01646 
01647 
01648 
01649 class BuildVehicleCommand : public GuiFunction
01650 {
01651 public:
01652     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
01653     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
01654     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01655         return IconRepository::getIcon("constructunit.png");
01656     };
01657     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01658         return "Unit construction Command";
01659     };
01660 };
01661 
01662 
01663 bool BuildVehicleCommand::available( const MapCoordinate& pos, ContainerBase* subject, int num )
01664 {
01665     MapField* fld = actmap->getField(pos);
01666     if (!commandPending())
01667         if ( fld && fld->vehicle )
01668             if (fld->vehicle->getOwner() == actmap->actplayer )
01669                 return ConstructUnitCommand::externalConstructionAvail( fld->vehicle );
01670 
01671     if ( NewGuiHost::pendingCommand ) {
01672         ConstructUnitCommand* construct = dynamic_cast<ConstructUnitCommand*>(NewGuiHost::pendingCommand);
01673         if ( construct )
01674             return construct->isFieldUsable(pos);
01675 
01676     }
01677     return false;
01678 }
01679 
01680 void BuildVehicleCommand::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
01681 {
01682 
01683     ConstructUnitCommand* construct = dynamic_cast<ConstructUnitCommand*>(NewGuiHost::pendingCommand);
01684     if ( !construct  ) {
01685         delete construct;
01686         auto_ptr<ConstructUnitCommand> constructCommand ( new ConstructUnitCommand( subject ));
01687         constructCommand->setMode( ConstructUnitCommand::external);
01688         ConstructUnitCommand::Producables buildables = constructCommand->getProduceableVehicles();
01689 
01690         VehicleProduction_SelectionWindow fsw( NULL, PG_Rect( 10, 10, 450, 550 ), subject, buildables, false );
01691         fsw.Show();
01692         fsw.RunModal();
01693         const VehicleType* v = fsw.getVehicletype();
01694         if ( v ) {
01695 
01696             for ( ConstructUnitCommand::Producables::const_iterator i = buildables.begin(); i != buildables.end(); ++i )
01697                 if ( i->type == v ) {
01698                     if ( i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Energy  | ConstructUnitCommand::Lack::Material | ConstructUnitCommand::Lack::Fuel )) {
01699                         warningMessage("Not enough resources to build unit");
01700                         return;
01701                     }
01702 
01703                     if ( i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Movement )) {
01704                         ASCString message = "Not enough movement to build unit";
01705                         Vehicle* constructor = dynamic_cast<Vehicle*>(subject);
01706                         if ( constructor )
01707                             message += "\nRequired: " + ASCString::toString(constructor->typ->unitConstructionMoveCostPercentage * constructor->maxMovement() / 100 ) + " points";
01708                         warningMessage(message);
01709                         return;
01710                     }
01711 
01712                     if ( i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Research )) {
01713                         warningMessage("This unit has not been researched yet");
01714                         return;
01715                     }
01716                 }
01717 
01718 
01719             constructCommand->setVehicleType( v );
01720             vector<MapCoordinate> fields = constructCommand->getFields();
01721 
01722             if ( fields.size() ) {
01723                 for ( vector<MapCoordinate>::const_iterator i = fields.begin(); i != fields.end(); ++i )
01724                     subject->getMap()->getField( *i )->a.temp = 1;
01725 
01726                 repaintMap();
01727 
01728                 NewGuiHost::pendingCommand = constructCommand.release();
01729 
01730                 updateFieldInfo();
01731 
01732             } else {
01733                 warningMessage("no fields to construct unit.\n" + v->terrainaccess.toString());
01734             }
01735         }
01736     } else {
01737         actmap->cleartemps();
01738         construct->setTargetPosition( pos );
01739         ActionResult res = construct->execute ( createContext( actmap ) );
01740         if ( !res.successful() ) {
01741             delete NewGuiHost::pendingCommand;
01742             repaintMap();
01743             dispmessage2( res );
01744         }
01745         NewGuiHost::pendingCommand = NULL;
01746         updateFieldInfo();
01747     }
01748 
01749 }
01750 
01751 
01752 
01753 Surface generate_gui_build_icon ( BuildingType* bld )
01754 {
01755     Surface s = Surface::createSurface(500,500,32, 0);
01756 
01757     int minx = 1000;
01758     int miny = 1000;
01759     int maxx = 0;
01760     int maxy = 0;
01761 
01762     for (int y = 0; y <= 5; y++)
01763         for (int x = 0; x <= 3; x++)
01764             if (bld->fieldExists( BuildingType::LocalCoordinate(x,y) ) ) {
01765                 int xp = fielddistx * x  + fielddisthalfx * ( y & 1);
01766                 int yp = fielddisty * y ;
01767                 if ( xp < minx )
01768                     minx = xp;
01769                 if ( yp < miny )
01770                     miny = yp;
01771                 if ( xp > maxx )
01772                     maxx = xp;
01773                 if ( yp > maxy )
01774                     maxy = yp;
01775 
01776                 // bld->paintSingleField( s, SPoint(xp,yp), BuildingType::LocalCoordinate(x,y) );
01777                 bld->paintSingleField( s, SPoint(xp,yp),BuildingType::LocalCoordinate(x,y) );
01778             }
01779     maxx += fieldxsize;
01780     maxy += fieldysize;
01781 
01782     /*
01783     Surface sc = Surface::Wrap( PG_Application::GetScreen() );
01784     sc.Blit( s, SPoint(0,0 ));
01785     PG_Application::UpdateRect( PG_Application::GetScreen(), 0,0,0,0);
01786     */
01787 
01788     Surface s2 = Surface::createSurface(maxx-minx+1,maxy-miny+1,32,0);
01789     // s2.Blit( s, SDLmm::SRect(SPoint(minx,miny), SPoint(maxx,maxy) ), SPoint(0,0));
01790 
01791     MegaBlitter<4,4,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_Rectangle> blitter;
01792     blitter.setSrcRectangle( SPoint( minx, miny ), maxx-minx, maxy-miny );
01793     blitter.blit ( s, s2, SPoint(0,0) );
01794 
01795     /*
01796 
01797     MegaBlitter<4,4,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_Zoom> blitter;
01798 
01799     blitter.setSize( s2.w(), s2.h(), s3.w(), s3.h() );
01800     blitter.initSource ( s2 );
01801     blitter.blit ( s2, s3, SPoint((s3.w() - blitter.getWidth())/2, (s3.h() - blitter.getHeight())/2) );
01802     */
01803 
01804     return s2;
01805 }
01806 
01807 
01808 class ConstructBuilding : public GuiFunction
01809 {
01810 public:
01811     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
01812     void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
01813     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01814         return IconRepository::getIcon("constructbuilding.png");
01815     };
01816     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01817         ConstructBuildingCommand* build = dynamic_cast<ConstructBuildingCommand*>(NewGuiHost::pendingCommand );
01818         if ( !build )
01819             return "Building construction";
01820         else {
01821             return "Select building entrance position";
01822         }
01823     };
01824 };
01825 
01826 
01827 bool ConstructBuilding::available( const MapCoordinate& pos, ContainerBase* subject, int num )
01828 {
01829     MapField* fld = actmap->getField(pos);
01830     if (!commandPending()) {
01831         if ( fld->vehicle )
01832             if ( ConstructBuildingCommand::avail( fld->vehicle ))
01833                 if (fld->vehicle->getOwner() == actmap->actplayer )
01834                     return true;
01835     }
01836 
01837     ConstructBuildingCommand* build = dynamic_cast<ConstructBuildingCommand*>(NewGuiHost::pendingCommand );
01838     if ( build )
01839         return build->isFieldUsable( pos );
01840 
01841     return false;
01842 }
01843 
01844 
01845 class BuildingConstructionSelection : public BuildingTypeSelectionItemFactory
01846 {
01847 private:
01848     const BuildingType* selectedType;
01849 protected:
01850     void BuildingTypeSelected( const BuildingType* type ) {
01851         selectedType = type;
01852     };
01853 public:
01854     BuildingConstructionSelection ( Resources plantResources, const Container& types, const Player& player ) : BuildingTypeSelectionItemFactory(plantResources, types, player ), selectedType(NULL) {};
01855     const BuildingType* getSelectedType() {
01856         return selectedType;
01857     };
01858 };
01859 
01860 void ConstructBuilding::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
01861 {
01862 
01863     ConstructBuildingCommand* build = dynamic_cast<ConstructBuildingCommand*>(NewGuiHost::pendingCommand );
01864 
01865     if ( !build  ) {
01866         MapField* fld = actmap->getField(pos);
01867 
01868 
01869         auto_ptr<ConstructBuildingCommand> cbc ( new ConstructBuildingCommand( fld->vehicle ));
01870 
01871         ConstructBuildingCommand::Producables producables = cbc->getProduceableBuildings();
01872 
01873         BuildingConstructionSelection::Container buildings;
01874         for ( ConstructBuildingCommand::Producables::const_iterator i = producables.begin(); i != producables.end(); ++i )
01875             if ( !( i->prerequisites.getValue() & (ConstructBuildingCommand::Lack::Research | ConstructBuildingCommand::Lack::Level )))
01876                 buildings.push_back( i->type );
01877 
01878         if ( buildings.empty() ) {
01879             dispmessage2( 303, NULL );
01880             return;
01881         }
01882 
01883 
01884         BuildingConstructionSelection* bcs = new BuildingConstructionSelection ( fld->vehicle->getResource( Resources(maxint, maxint, maxint), true ), buildings, fld->vehicle->getOwningPlayer() );
01885         ItemSelectorWindow isw ( NULL, PG_Rect( -1, -1, 550, 650), "Select Building", bcs);
01886         isw.Show();
01887         isw.RunModal();
01888         isw.Hide();
01889 
01890         if ( bcs->getSelectedType() && cbc->buildingProductionPrerequisites( bcs->getSelectedType()).ok() ) {
01891 
01892             cbc->setBuildingType( bcs->getSelectedType() );
01893 
01894             vector<MapCoordinate> fields = cbc->getFields();
01895             if ( fields.size() == 0 ) {
01896                 dispmessage2(301, NULL );
01897                 return;
01898             }
01899 
01900             for ( vector<MapCoordinate>::iterator i = fields.begin(); i != fields.end(); ++i )
01901                 actmap->getField(*i)->a.temp = 1;
01902 
01903             repaintMap();
01904 
01905             NewGuiHost::pendingCommand = cbc.release();
01906 
01907             updateFieldInfo();
01908         }
01909     } else {
01910         actmap->cleartemps();
01911         build->setTargetPosition( pos );
01912         ActionResult res = build->execute( createContext( actmap ));
01913 
01914         if ( !res.successful() ) {
01915             displayActionError(res);
01916             delete NewGuiHost::pendingCommand;
01917         }
01918 
01919         NewGuiHost::pendingCommand = NULL;
01920 
01921 
01922         updateFieldInfo();
01923     }
01924 }
01925 
01926 
01927 
01928 
01929 
01930 
01931 class InternalAmmoTransferDialog : public GuiFunction
01932 {
01933 public:
01934     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01935 
01936         // deactivated, because there shouldn't be any units left which need this function
01937         return false;
01938 
01939         if ( subject && subject->getMap()->getPlayer(subject).diplomacy.isAllied( subject->getMap()->actplayer ))
01940             if (!commandPending()) {
01941                 Vehicle* v = dynamic_cast<Vehicle*>(subject);
01942                 if ( v )
01943                     return InternalAmmoTransferCommand::avail( v );
01944             }
01945 
01946         return false;
01947     };
01948 
01949     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
01950         return ( key->keysym.unicode == 't' && (modifier & KMOD_SHIFT)  );
01951     };
01952 
01953     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01954         internalAmmoTransferWindow( (Vehicle*) subject );
01955         displaymap();
01956         updateFieldInfo();
01957     }
01958 
01959     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01960         return IconRepository::getIcon("internalAmmoTransfer-dialog.png");
01961     };
01962 
01963     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01964         return "internal Ammo ~T~ransfer dialog ";
01965     };
01966 };
01967 
01968 class SelfDestructIcon : public GuiFunction
01969 {
01970     static int containeractive;
01971 public:
01972     bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01973         MapField* fld = actmap->getField(pos);
01974         ContainerBase* c = fld->getContainer();
01975         if ( fieldvisiblenow ( fld ) && c && !commandPending() && actmap->getPlayer(c).diplomacy.isAllied(actmap->actplayer))
01976             return DestructUnitCommand::avail( c );
01977         else
01978             return false;
01979     };
01980 
01981     void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01982         MapField* fld = actmap->getField(pos);
01983         if (choice_dlg("do you really want to destruct this unit?","~y~es","~n~o") == 1) {
01984             auto_ptr<DestructUnitCommand> destructor ( new  DestructUnitCommand( fld->getContainer() ));
01985             ActionResult res = destructor->execute( createContext( actmap ) );
01986             if ( res.successful() )
01987                 destructor.release();
01988             else
01989                 displayActionError( res );
01990             updateFieldInfo();
01991             repaintMap();
01992         }
01993     }
01994 
01995     Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num ) {
01996         return IconRepository::getIcon("self-destruct.png");
01997     };
01998 
01999     bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num ) {
02000         return false;
02001     };
02002 
02003     ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num ) {
02004         return "self destruct";
02005     };
02006 };
02007 
02008 
02009 
02010 GuiIconHandler primaryGuiIcons;
02011 
02012 
02013 
02014 
02015 
02016 
02017 } // namespace GuiFunctions
02018 
02019 
02020 
02021 void registerGuiFunctions( GuiIconHandler& handler )
02022 {
02023     handler.registerUserFunction( new GuiFunctions::Movement() );
02024     handler.registerUserFunction( new GuiFunctions::UnitInfo() );
02025     handler.registerUserFunction( new GuiFunctions::Attack() );
02026     handler.registerUserFunction( new GuiFunctions::JumpDriveIcon() );
02027     handler.registerUserFunction( new GuiFunctions::PowerOn() );
02028     handler.registerUserFunction( new GuiFunctions::PowerOff() );
02029     handler.registerUserFunction( new GuiFunctions::BuildObject() );
02030     handler.registerUserFunction( new GuiFunctions::BuildVehicleCommand() );
02031     handler.registerUserFunction( new GuiFunctions::ConstructBuilding() );
02032     handler.registerUserFunction( new GuiFunctions::DestructBuilding() );
02033 //   handler.registerUserFunction( new GuiFunctions::SearchForMineralResources() );
02034     handler.registerUserFunction( new GuiFunctions::OpenContainer() );
02035     handler.registerUserFunction( new GuiFunctions::EnableReactionfire() );
02036     handler.registerUserFunction( new GuiFunctions::DisableReactionfire() );
02037     handler.registerUserFunction( new GuiFunctions::Ascend );
02038     handler.registerUserFunction( new GuiFunctions::Descend );
02039     handler.registerUserFunction( new GuiFunctions::RepairUnit );
02040     handler.registerUserFunction( new GuiFunctions::RefuelUnitCommand );
02041     handler.registerUserFunction( new GuiFunctions::RefuelUnitDialogCommand );
02042     // handler.registerUserFunction( new GuiFunctions::ViewMap );
02043     handler.registerUserFunction( new GuiFunctions::PutMine );
02044     handler.registerUserFunction( new GuiFunctions::PutAntiTankMine );
02045     handler.registerUserFunction( new GuiFunctions::PutAntiPersonalMine );
02046     handler.registerUserFunction( new GuiFunctions::PutAntiShipMine );
02047     handler.registerUserFunction( new GuiFunctions::PutAntiSubMine );
02048     handler.registerUserFunction( new GuiFunctions::RemoveMine );
02049     handler.registerUserFunction( new GuiFunctions::InternalAmmoTransferDialog );
02050 
02051     handler.registerUserFunction( new GuiFunctions::EndTurn() );
02052     handler.registerUserFunction( new GuiFunctions::SelfDestructIcon() );
02053     handler.registerUserFunction( new GuiFunctions::Cancel() );
02054 
02055 }
02056 

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