Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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-2007  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 "unitctrl.h"
00032 #include "controls.h"
00033 #include "dialog.h"
00034 #include "gameoptions.h"
00035 #include "iconrepository.h"
00036 #include "replay.h"
00037 #include "attack.h"
00038 #include "graphics/blitter.h"
00039 #include "viewcalculation.h"
00040 #include "spfst.h"
00041 // #include "gamedlg.h"
00042 #include "dialogs/cargodialog.h"
00043 #include "dialogs/ammotransferdialog.h"
00044 #include "mapdisplay.h"
00045 #include "sg.h"
00046 #include "loaders.h"
00047 #include "itemrepository.h"
00048 #include "turncontrol.h"
00049 #include "dialogs/buildingtypeselector.h"
00050 #include "dialogs/internalAmmoTransferDialog.h"
00051 #include "actions/jumpdrive.h"
00052 #include "actions/selfdestruct.h"
00053 
00054 
00055 namespace GuiFunctions
00056 {
00057 
00058 
00059 
00060 class AttackGui : public GuiIconHandler, public GuiFunction, public SigC::Object {
00061      VehicleAttack* attackEngine;
00062 
00063      pair<pattackweap, int> getEntry( const MapCoordinate& pos, int num );
00064 
00065       void mapDeleted( GameMap& map )
00066       {
00067          if ( NewGuiHost::getIconHandler() == this )
00068             NewGuiHost::popIconHandler();
00069       }
00070 
00071    protected:
00072       bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00073       void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00074       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00075       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00076       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00077 
00078    public:
00079       AttackGui() : attackEngine( NULL ) 
00080       {
00081          GameMap::sigMapDeletion.connect( SigC::slot( *this, &AttackGui::mapDeleted )); 
00082       };
00083       void setupWeapons( VehicleAttack* va ) { attackEngine = va; };
00084       void eval( const MapCoordinate& mc, ContainerBase* subject );
00085 
00086 };
00087 
00088 bool AttackGui :: checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00089 {
00090    if ( key->keysym.sym == SDLK_ESCAPE || key->keysym.unicode == 'c' ) {
00091       // execute( actmap->getCursor(), actmap->getField( actmap->getCursor())->getContainer() , -1 );
00092       return true;
00093    }
00094    return false;
00095 }
00096 
00097 
00098 pair<pattackweap, int> AttackGui::getEntry( const MapCoordinate& pos, int num )
00099 {
00100    int counter = 0;
00101    
00102    AttackFieldList* afl = NULL;
00103    for ( int i = 0; i < 3; ++i ) {
00104       switch ( i ) {
00105          case 0: afl = &attackEngine->attackableVehicles; break;
00106          case 1: afl = &attackEngine->attackableBuildings; break;
00107          case 2: afl = &attackEngine->attackableObjects; break;
00108       }
00109       
00110       if ( afl->isMember( pos )) {
00111          pattackweap aw = &afl->getData(pos.x, pos.y);
00112          for ( int a = 0; a < aw->count; ++a ) {
00113             if ( counter == num )
00114                return make_pair( aw, a );
00115                
00116             ++counter;
00117          }
00118       }   
00119    }
00120    return make_pair( pattackweap(NULL), 0 );
00121 }
00122 
00123 
00124 bool AttackGui::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00125 {
00126    if ( num == -1 )
00127       return true;
00128       
00129    if ( getEntry(pos,num).first )
00130       return true;
00131    else
00132       return false;
00133 }
00134 
00135 void AttackGui::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00136 {
00137    if ( num != -1 ) {
00138    
00139       pair<pattackweap, int> p = getEntry(pos,num);
00140       if ( p.first ) {
00141          int res = pendingVehicleActions.attack->execute ( NULL, pos.x, pos.y, 2, 0, p.first->num[p.second] );
00142          if ( res < 0 )
00143             dispmessage2 ( -res, NULL );
00144 
00145       }
00146    }   
00147    setupWeapons( NULL );
00148    delete pendingVehicleActions.attack;
00149    actmap->cleartemps();
00150    NewGuiHost::popIconHandler();
00151    repaintMap();
00152    updateFieldInfo();
00153 }
00154 
00155 Surface& AttackGui::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00156 {
00157    if ( num == -1 )
00158       return IconRepository::getIcon("cancel.png");
00159       
00160    pair<pattackweap, int> p = getEntry(pos,num);
00161    switch ( p.first->typ[p.second] ) {
00162       case cwcruisemissileb: return IconRepository::getIcon("weap-cruisemissile.png");
00163       case cwbombb: return IconRepository::getIcon("weap-bomb.png");
00164       case cwlargemissileb: return IconRepository::getIcon("weap-bigmissile.png");
00165       case cwsmallmissileb: return IconRepository::getIcon("weap-smallmissile.png");
00166       case cwtorpedob: return IconRepository::getIcon("weap-torpedo.png");
00167       case cwmachinegunb: return IconRepository::getIcon("weap-machinegun.png");
00168       case cwcannonb: return IconRepository::getIcon("weap-cannon.png");
00169       default: return IconRepository::getIcon("weap-laser.png");
00170    };
00171 }
00172 
00173 ASCString AttackGui::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00174 {
00175    if ( num == -1 )
00176       return "cancel";
00177 
00178    Vehicle* attacker = attackEngine->getAttacker();
00179 
00180    tfight* battle = NULL;
00181 
00182    pair<pattackweap, int> p = getEntry(pos,num);
00183    
00184 
00185    if ( p.first->target == AttackWeap::vehicle )
00186       battle = new tunitattacksunit ( attacker, actmap->getField(pos)->vehicle, true, p.first->num[p.second] );
00187    else
00188    if ( p.first->target == AttackWeap::building )
00189       battle = new tunitattacksbuilding ( attacker, pos.x, pos.y, p.first->num[p.second] );
00190    else
00191    if ( p.first->target == AttackWeap::object )
00192       battle = new tunitattacksobject ( attacker, pos.x, pos.y, p.first->num[p.second] );
00193 
00194 
00195    int dd = battle->dv.damage;
00196    int ad = battle->av.damage;
00197    battle->calc ( );
00198 
00199    ASCString result;
00200    result.format( "%s; eff strength: %d; damage inflicted to enemy: %d, making a total of ~%d~; own damage will be +%d = %d", cwaffentypen[log2(p.first->typ[p.second])], battle->av.strength, battle->dv.damage-dd, battle->dv.damage, battle->av.damage-ad, battle->av.damage );
00201    return result;
00202 }
00203 
00204 
00205 void AttackGui::eval( const MapCoordinate& mc, ContainerBase* subject )
00206 {
00207    
00208    int num = 0;
00209    while ( getEntry( mc, num).first ) {
00210        GuiButton* b = host->getButton(num);
00211        b->registerFunc( this, mc, subject, num );
00212        b->Show();
00213        ++num;
00214    }
00215 
00216    GuiButton* b = host->getButton(num);
00217    b->registerFunc( this, mc, subject, -1 );
00218    b->Show();
00219    ++num;
00220 
00221    host->disableButtons(num);
00222 }
00223 
00224 
00225 
00226 AttackGui attackGui;
00227 
00228 
00229 
00230 bool Cancel::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00231 {
00232    return moveparams.movestatus || pendingVehicleActions.action;
00233 };
00234 
00235 void Cancel::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00236 {
00237    if ( moveparams.movestatus || pendingVehicleActions.action ) {
00238       moveparams.movestatus = 0;
00239       if ( pendingVehicleActions.action )
00240          delete pendingVehicleActions.action;
00241 
00242       actmap->cleartemps(7);
00243       updateFieldInfo();
00244       displaymap();
00245    }
00246 };
00247 
00248 bool Cancel::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00249 {
00250    return ( key->keysym.sym == SDLK_ESCAPE || key->keysym.unicode == 'c' );
00251 };
00252 
00253 
00254 Surface& Cancel::getImage( const MapCoordinate& po, ContainerBase* subject, int nums )
00255 {
00256    return IconRepository::getIcon("cancel.png");
00257 };
00258 
00259 ASCString Cancel::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00260 {
00261    return "~c~ancel";
00262 };
00263 
00264 
00265 
00266 bool Movement::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00267 {
00268    return ( key->keysym.sym == SDLK_SPACE );
00269 };
00270 
00271 Surface& Movement::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00272 {
00273    return IconRepository::getIcon("movement.png");
00274 };
00275 
00276 ASCString Movement::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00277 {
00278    return "move unit (~space~)";
00279 };
00280 
00281 
00282 bool Movement::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00283 {
00284    if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing ) {
00285       Vehicle* eht = actmap->getField(pos)->vehicle;
00286       if ( eht )
00287          if ( eht->color == actmap->actplayer * 8)
00288             return VehicleMovement::avail ( eht );
00289    } else
00290       if ( pendingVehicleActions.actionType == vat_move ) {
00291          switch ( pendingVehicleActions.move->getStatus() ) {
00292             case 2:
00293                return pendingVehicleActions.move->reachableFields.isMember ( pos.x, pos.y );
00294             case 3:
00295                return pendingVehicleActions.move->path.rbegin()->x == pos.x && pendingVehicleActions.move->path.rbegin()->y == pos.y;
00296          } /* endswitch */
00297       }
00298 
00299    return false;
00300 }
00301 
00302 void Movement::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00303 {
00304    if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing ) {
00305       new VehicleMovement ( &getDefaultMapDisplay(), &pendingVehicleActions );
00306 
00307       int mode = 0;
00308       if (  skeypress( ct_lshift ) ||  skeypress ( ct_rshift ))
00309          mode |= VehicleMovement::DisableHeightChange;
00310 
00311       int res = pendingVehicleActions.move->execute ( actmap->getField(pos)->vehicle, -1, -1, 0, -1, mode );
00312       if ( res < 0 ) {
00313          dispmessage2 ( -res, NULL );
00314          delete pendingVehicleActions.action;
00315          return;
00316       }
00317       for ( int i = 0; i < pendingVehicleActions.move->reachableFields.getFieldNum(); i++ )
00318          pendingVehicleActions.move->reachableFields.getField( i ) ->a.temp = 1;
00319 
00320       // if ( !CGameOptions::Instance()->dontMarkFieldsNotAccessible_movement )
00321       for ( int j = 0; j < pendingVehicleActions.move->reachableFieldsIndirect.getFieldNum(); j++ )
00322          pendingVehicleActions.move->reachableFieldsIndirect.getField( j ) ->a.temp2 = 2;
00323       displaymap();
00324       updateFieldInfo();
00325    } else {
00326       if ( !pendingVehicleActions.move )
00327          return;
00328 
00329       int ms = pendingVehicleActions.move->getStatus();
00330       if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_move &&  (ms == 2 || ms == 3 )) {
00331          int res;
00332          res = pendingVehicleActions.move->execute ( NULL, pos.x, pos.y, pendingVehicleActions.move->getStatus(), -1, 0 );
00333          if ( res >= 0 && CGameOptions::Instance()->fastmove && ms == 2 ) {
00334             actmap->cleartemps(7);
00335             displaymap();
00336             MapDisplayPG::CursorHiding ch;
00337             res = pendingVehicleActions.move->execute ( NULL, pos.x, pos.y, pendingVehicleActions.move->getStatus(), -1, 0 );
00338          } else {
00339             if ( ms == 2 ) {
00340                actmap->cleartemps(7);
00341                for ( int i = 0; i < pendingVehicleActions.move->path.size(); i++ )
00342                   actmap->getField( pendingVehicleActions.move->path[i]) ->a.temp = 1;
00343                displaymap();
00344             } else {
00345                actmap->cleartemps(7);
00346                displaymap();
00347             }
00348          }
00349 
00350 
00351          if ( res < 0 ) {
00352             dispmessage2 ( -res, NULL );
00353             delete pendingVehicleActions.action;
00354             return;
00355          }
00356 
00357          if ( pendingVehicleActions.move->getStatus() == 1000 ) {
00358             delete pendingVehicleActions.move;
00359 /*
00360             if ( CGameOptions::Instance()->smallguiiconopenaftermove ) {
00361                actgui->painticons();
00362                actgui->paintsmallicons ( CGameOptions::Instance()->mouse.smallguibutton, 0 );
00363             }
00364             */
00365          }
00366          updateFieldInfo();
00367 
00368       }
00369    }
00370 }
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 class Ascend : public GuiFunction
00380 {
00381    public:
00382       bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00383       void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00384       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00385       {
00386          return ( key->keysym.unicode == 's' );
00387       };
00388       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00389       {
00390          return IconRepository::getIcon("ascend-airplane.png");
00391       };
00392       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00393       {
00394          return "a~s~cend";
00395       };
00396 };
00397 
00398 bool Ascend::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00399 {
00400    if ( moveparams.movestatus == 0 && !pendingVehicleActions.action ) {
00401       Vehicle* eht = actmap->getField(pos)->vehicle;
00402       if ( !eht )
00403          return false;
00404       if (eht->color == actmap->actplayer * 8)
00405          return IncreaseVehicleHeight::avail ( eht );
00406    } else
00407       if ( pendingVehicleActions.actionType == vat_ascent ) {
00408          switch ( pendingVehicleActions.ascent->getStatus() ) {
00409            case 2: return pendingVehicleActions.ascent->reachableFields.isMember ( pos.x, pos.y );
00410            case 3: return pendingVehicleActions.ascent->path.rbegin()->x == pos.x && pendingVehicleActions.ascent->path.rbegin()->y == pos.y;
00411          } /* endswitch */
00412       }
00413    return false;
00414 }
00415 
00416 void Ascend::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00417 {
00418    if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing ) {
00419       new IncreaseVehicleHeight ( &getDefaultMapDisplay(), &pendingVehicleActions );
00420 
00421       bool simpleMode = false;
00422       if (  skeypress( ct_lshift ) ||  skeypress ( ct_rshift ))
00423          simpleMode = true;
00424 
00425       int res = pendingVehicleActions.ascent->execute ( actmap->getField(pos)->vehicle, -1, -1, 0, actmap->getField(pos)->vehicle->height << 1, simpleMode );
00426       if ( res < 0 ) {
00427          dispmessage2 ( -res, NULL );
00428          delete pendingVehicleActions.action;
00429          return;
00430       }
00431 
00432       if ( res == 1000 )
00433          delete pendingVehicleActions.action;
00434       else {
00435          for ( int i = 0; i < pendingVehicleActions.ascent->reachableFields.getFieldNum(); i++ )
00436             pendingVehicleActions.ascent->reachableFields.getField( i ) ->a.temp = 1;
00437          displaymap();
00438       }
00439 
00440    } else
00441      if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_ascent &&  (pendingVehicleActions.ascent->getStatus() == 2 || pendingVehicleActions.ascent->getStatus() == 3 )) {
00442         int xdst = pos.x;
00443         int ydst = pos.y;
00444         int res = pendingVehicleActions.ascent->execute ( NULL, xdst, ydst, pendingVehicleActions.ascent->getStatus(), -1, 0 );
00445         if ( res >= 0 && CGameOptions::Instance()->fastmove ) {
00446            actmap->cleartemps(7);
00447            displaymap();
00448            // if the status is 1000 at this position, the unit has been shot down by reactionfire before initiating the height change
00449            if ( res < 1000 )
00450               res = pendingVehicleActions.ascent->execute ( NULL, xdst, ydst, pendingVehicleActions.ascent->getStatus(), -1, 0 );
00451         } else {
00452            actmap->cleartemps(7);
00453            if ( res < 1000 )
00454               for ( int i = 0; i < pendingVehicleActions.ascent->path.size(); i++ )
00455                  actmap->getField( pendingVehicleActions.ascent->path[i]) ->a.temp = 1;
00456            displaymap();
00457         }
00458 
00459         if ( res < 0 ) {
00460            dispmessage2 ( -res, NULL );
00461            delete pendingVehicleActions.action;
00462            updateFieldInfo();
00463            return;
00464         }
00465 
00466         if ( pendingVehicleActions.ascent->getStatus() == 1000 ) {
00467            delete pendingVehicleActions.ascent;
00468 
00469         }
00470      }
00471 
00472    updateFieldInfo();
00473 }
00474 
00475 
00476 
00477 
00478 
00479 class Descend : public GuiFunction
00480 {
00481    public:
00482       bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00483       void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00484       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00485       {
00486          return ( key->keysym.unicode == 'd' );
00487       };
00488       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00489       {
00490          return IconRepository::getIcon("descent-airplane.png");
00491       };
00492       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00493       {
00494          return "~d~escend";
00495       };
00496 };
00497 
00498 bool Descend::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00499 {
00500    if ( moveparams.movestatus == 0 && !pendingVehicleActions.action ) {
00501       Vehicle* eht = actmap->getField(pos)->vehicle;
00502       if ( !eht )
00503          return false;
00504 
00505       if (eht->color == actmap->actplayer * 8)
00506          return DecreaseVehicleHeight::avail ( eht );
00507    } else
00508       if ( pendingVehicleActions.actionType == vat_descent ) {
00509          switch ( pendingVehicleActions.descent->getStatus() ) {
00510            case 2: return pendingVehicleActions.descent->reachableFields.isMember ( pos.x, pos.y );
00511            case 3: return pendingVehicleActions.descent->path.rbegin()->x == pos.x && pendingVehicleActions.descent->path.rbegin()->y == pos.y;
00512          } /* endswitch */
00513       }
00514    return false;
00515 }
00516 
00517 void Descend::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00518 {
00519    if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing ) {
00520       new DecreaseVehicleHeight ( &getDefaultMapDisplay(), &pendingVehicleActions );
00521 
00522 
00523       bool simpleMode = false;
00524       if (  skeypress( ct_lshift ) ||  skeypress ( ct_rshift ))
00525          simpleMode = true;
00526 
00527       int res = pendingVehicleActions.descent->execute ( actmap->getField(pos)->vehicle, -1, -1, 0, actmap->getField(pos)->vehicle->height >> 1, simpleMode );
00528       if ( res < 0 ) {
00529          dispmessage2 ( -res, NULL );
00530          delete pendingVehicleActions.action;
00531          return;
00532       }
00533 
00534       if ( res == 1000 )
00535          delete pendingVehicleActions.action;
00536       else {
00537          for ( int i = 0; i < pendingVehicleActions.descent->reachableFields.getFieldNum(); i++ )
00538             pendingVehicleActions.descent->reachableFields.getField( i ) ->a.temp = 1;
00539          displaymap();
00540       }
00541 
00542    } else
00543      if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_descent &&  (pendingVehicleActions.descent->getStatus() == 2 || pendingVehicleActions.descent->getStatus() == 3 )) {
00544         int res = pendingVehicleActions.descent->execute ( NULL, pos.x, pos.y, pendingVehicleActions.descent->getStatus(), -1, 0 );
00545         if ( res >= 0 && CGameOptions::Instance()->fastmove ) {
00546            actmap->cleartemps(7);
00547            displaymap();
00548            // if the status is 1000 at this position, the unit has been shot down by reactionfire before initiating the height change
00549            if ( res < 1000 )
00550               res = pendingVehicleActions.descent->execute ( NULL, pos.x, pos.y, pendingVehicleActions.descent->getStatus(), -1, 0 );
00551         } else {
00552            actmap->cleartemps(7);
00553            if ( res < 1000 )
00554               for ( int i = 0; i < pendingVehicleActions.descent->path.size(); i++ )
00555                  actmap->getField( pendingVehicleActions.descent->path[i]) ->a.temp = 1;
00556            displaymap();
00557         }
00558 
00559 
00560         if ( res < 0 ) {
00561            dispmessage2 ( -res, NULL );
00562            delete pendingVehicleActions.action;
00563            updateFieldInfo();
00564            return;
00565         }
00566 
00567         if ( pendingVehicleActions.descent->getStatus() == 1000 ) {
00568            delete pendingVehicleActions.descent;
00569 
00570 /*           if ( CGameOptions::Instance()->smallguiiconopenaftermove ) {
00571               actgui->painticons();
00572               actgui->paintsmallicons ( CGameOptions::Instance()->mouse.smallguibutton, 0 );
00573            }
00574            */
00575         }
00576      }
00577    updateFieldInfo();
00578 }
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 class EndTurn : public GuiFunction
00589 {
00590    public:
00591       bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00592       void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00593       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00594       {
00595          return ( key->keysym.unicode == 'e' );
00596       };
00597       Surface& getImage( const MapCoordinate& po, ContainerBase* subject, int nums )
00598       {
00599          return IconRepository::getIcon("endturn.png");
00600       };
00601       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00602       {
00603          return "~e~nd turn";
00604       };
00605 };
00606 
00607 bool EndTurn::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00608 {
00609    if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing)
00610       if (actmap->levelfinished == false)
00611          return true;
00612    return false;
00613 }
00614 
00615 
00616 void EndTurn::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00617 {
00618    if ( !CGameOptions::Instance()->endturnquestion || (choice_dlg("do you really want to end your turn ?","~y~es","~n~o") == 1)) {
00619 
00620       static int autosave = 0;
00621       ASCString name = ASCString("autosave") + strrr( autosave ) + &savegameextension[1];
00622 
00623       savegame ( name );
00624 
00625       autosave = !autosave;
00626 
00627       actmap->sigPlayerUserInteractionEnds( actmap->player[actmap->actplayer] );
00628 
00629       next_turn();
00630 
00631       displaymap();
00632    }
00633 }
00634 
00635 
00636 class Attack : public GuiFunction
00637 {
00638    public:
00639       bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00640       void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00641       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00642       {
00643          return ( key->keysym.unicode == 'a' );
00644       };
00645       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00646       {
00647          return IconRepository::getIcon("attack.png");
00648       };
00649       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00650       {
00651          return "~a~ttack";
00652       };
00653 };
00654 
00655 
00656 bool Attack::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00657 {
00658    if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing ) {
00659       Vehicle* eht = actmap->getField(pos)->vehicle;
00660       if ( eht )
00661          if ( eht->color == actmap->actplayer * 8)
00662             return VehicleAttack::avail ( eht );
00663    }
00664    return false;
00665 }
00666 
00667 void Attack::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
00668 {
00669    if ( moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing ) {
00670       new VehicleAttack ( &getDefaultMapDisplay(), &pendingVehicleActions );
00671 
00672       int res;
00673       res = pendingVehicleActions.attack->execute ( actmap->getField(pos)->vehicle, -1, -1, 0, 0, -1 );
00674       if ( res < 0 ) {
00675          dispmessage2 ( -res, NULL );
00676          delete pendingVehicleActions.action;
00677          return;
00678       }
00679 
00680       int i;
00681       for ( i = 0; i < pendingVehicleActions.attack->attackableVehicles.getFieldNum(); i++ )
00682          pendingVehicleActions.attack->attackableVehicles.getField( i ) ->a.temp = 1;
00683       for ( i = 0; i < pendingVehicleActions.attack->attackableBuildings.getFieldNum(); i++ )
00684          pendingVehicleActions.attack->attackableBuildings.getField( i ) ->a.temp = 1;
00685       for ( i = 0; i < pendingVehicleActions.attack->attackableObjects.getFieldNum(); i++ )
00686          pendingVehicleActions.attack->attackableObjects.getField( i ) ->a.temp = 1;
00687 
00688       displaymap();
00689       attackGui.setupWeapons( pendingVehicleActions.attack );
00690       NewGuiHost::pushIconHandler( &attackGui );
00691    }
00692 }
00693 
00694 
00695 
00696 
00697 
00698 class PowerOn : public GuiFunction
00699 {
00700    public:
00701       bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
00702       {
00703          if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing )  {
00704             tfield* fld = actmap->getField ( pos );
00705             if ( fld->vehicle )
00706                if ( fld->vehicle->color == actmap->actplayer*8  &&
00707                      ( fld->vehicle->typ->hasFunction( ContainerBaseType::MatterConverter  )))
00708                   if ( !fld->vehicle->getGeneratorStatus() )
00709                      return true;
00710 
00711          }
00712          return false;
00713       };
00714 
00715       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00716       {
00717          return ( key->keysym.unicode == 'p' );
00718       };
00719       void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00720       {
00721          Vehicle* veh = actmap->getField(pos)->vehicle;
00722          veh->setGeneratorStatus ( true );
00723          logtoreplayinfo ( rpl_setGeneratorStatus, veh->networkid, int(1) );
00724          updateFieldInfo();
00725       }
00726 
00727       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00728       {
00729          return IconRepository::getIcon("poweron.png");
00730       };
00731 
00732       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00733       {
00734          return "enable ~p~ower generation";
00735       };
00736 };
00737 
00738 
00739 class PowerOff : public GuiFunction
00740 {
00741    public:
00742       bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
00743       {
00744          if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing )  {
00745             tfield* fld = actmap->getField ( pos );
00746             if ( fld->vehicle )
00747                if ( fld->vehicle->color == actmap->actplayer*8  &&
00748                     ( fld->vehicle->typ->hasFunction( ContainerBaseType::MatterConverter)))
00749                   if ( fld->vehicle->getGeneratorStatus() )
00750                      return true;
00751 
00752          }
00753          return false;
00754       };
00755       
00756       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00757       {
00758          return ( key->keysym.unicode == 'p' );
00759       };
00760       void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00761       {
00762          Vehicle* veh = actmap->getField(pos)->vehicle;
00763          veh->setGeneratorStatus ( false );
00764          logtoreplayinfo ( rpl_setGeneratorStatus, veh->networkid, int(0) );
00765          updateFieldInfo();
00766       }
00767 
00768       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00769       {
00770          return IconRepository::getIcon("poweroff.png");
00771       };
00772 
00773       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00774       {
00775          return "disable ~p~ower generation";
00776       };
00777 };
00778 
00779 
00780 
00781 class UnitInfo : public GuiFunction
00782 {
00783    public:
00784       bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00785       void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) { execUserAction_ev(ua_vehicleinfo);};
00786       Surface& getImage( const MapCoordinate& po, ContainerBase* subject, int nums )
00787       {
00788          return IconRepository::getIcon("unitinfo.png");
00789       };
00790       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00791       {
00792          return "unit ~i~nfo";
00793       };
00794       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00795       {
00796          return ( key->keysym.unicode == 'i' );
00797       };
00798 };
00799 
00800 bool UnitInfo::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00801 {
00802    tfield* fld = actmap->getField(pos);
00803    if ( fld && fld->vehicle )
00804       if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing)
00805          if ( fld->vehicle != NULL)
00806             if (fieldvisiblenow( fld ))
00807                return true;
00808    return false;
00809 }
00810 
00811 
00812 
00813 
00814 
00815 
00816 class DestructBuilding : public GuiFunction
00817 {
00818       bool cancel;
00819    public:
00820       DestructBuilding() : cancel(false) {};
00821 
00822       bool available( const MapCoordinate& pos, ContainerBase* subject, int num ) ;
00823       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00824       {
00825          if ( key->keysym.sym == SDLK_ESCAPE ) {
00826             cancel = true;
00827             return true;
00828          } else return false;
00829       };
00830       void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00831       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00832       {
00833          return IconRepository::getIcon("destructbuilding.png");
00834       };
00835       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00836       {
00837          return "destruct building";
00838       };
00839 };
00840 
00841 
00842 bool DestructBuilding::available( const MapCoordinate& pos, ContainerBase* subject, int num )
00843 {
00844     if ( cancel )
00845        return true;
00846 
00847     tfield* fld = actmap->getField(pos);
00848     if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing) {
00849        if ( fld->vehicle )
00850           if ( fld->vehicle->attacked == false && !fld->vehicle->hasMoved() )
00851              if (fld->vehicle->color == actmap->actplayer * 8)
00852                 if ( fld->vehicle->typ->hasFunction( ContainerBaseType::ConstructBuildings  ) || !fld->vehicle->typ->buildingsBuildable.empty() )
00853                   if ( fld->vehicle->getTank().fuel >= destruct_building_fuel_usage * fld->vehicle->typ->fuelConsumption )
00854                      return true;
00855     }
00856     else
00857        if (moveparams.movestatus == 115) {
00858           if (fld->a.temp == 20)
00859              return true;
00860        }
00861 
00862     return false;
00863 }
00864 
00865 void DestructBuilding::execute(  const MapCoordinate& pos, ContainerBase* subject, int num )
00866 {
00867    if( cancel ) {
00868       actmap->cleartemps(7);
00869       moveparams.movestatus = 0;
00870       cancel = false;
00871       updateFieldInfo();
00872       return;
00873    }
00874 
00875    if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing) {
00876       destructbuildinglevel1( pos.x, pos.y );
00877       displaymap();
00878       updateFieldInfo();
00879    }
00880    else
00881       if (moveparams.movestatus == 115) {
00882          destructbuildinglevel2( pos.x, pos.y );
00883          updateFieldInfo();
00884          displaymap();
00885       }
00886 }
00887 
00888 
00889 /*
00890 class SearchForMineralResources : public GuiFunction
00891 {
00892    public:
00893       bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
00894       {
00895          tfield* fld = actmap->getField(pos);
00896          if (fld->vehicle != NULL)
00897             if (fld->vehicle->color == actmap->actplayer * 8)
00898                if ( (fld->vehicle->typ->functions &  cfmanualdigger) && !(fld->vehicle->typ->functions &  cfautodigger) )
00899                   if (moveparams.movestatus == 0 && pendingVehicleActions.actionType == vat_nothing)
00900                      if ( actmap->_resourcemode == 0 ) 
00901                         return fld->vehicle->searchForMineralResourcesAvailable();
00902          return false;
00903       };
00904 
00905       void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00906       {
00907           actmap->getField(pos)->vehicle->searchForMineralResources( ) ;
00908 
00909           MapDisplayPG* mapDisplay = dynamic_cast<MapDisplayPG*>( ASC_PG_App::GetWidgetById( ASC_PG_App::mapDisplayID ));
00910           if ( mapDisplay )
00911              mapDisplay->activateMapLayer("resources", true);
00912           
00913           updateFieldInfo();
00914           repaintMap();
00915       }
00916 
00917       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00918       {
00919          return IconRepository::getIcon("dig.png");
00920       };
00921 
00922       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00923       {
00924          return "search for mineral resources";
00925       };
00926 };
00927 */
00928 
00929 class OpenContainer : public GuiFunction
00930 {
00931      static int containeractive;
00932    public:
00933       bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
00934       {
00935         tfield* fld = actmap->getField(pos);
00936         if ( fieldvisiblenow ( fld ) && fld->getContainer() ) {
00937            if ( !containeractive && !moveparams.movestatus && pendingVehicleActions.actionType == vat_nothing && !pendingVehicleActions.action ) {
00938               Player& player = fld->getContainer()->getMap()->player[fld->getContainer()->getOwner()];
00939               if ( fld->building && ( player.diplomacy.isAllied( actmap->actplayer) || actmap->getNeutralPlayerNum() == fld->building->getOwner() )) {
00940                  if ( fld->building->getCompletion() == fld->building->typ->construction_steps-1 )
00941                     return true;
00942               }  else {
00943                   if ( fld->vehicle && fld->vehicle->typ->maxLoadableUnits  &&  player.diplomacy.isAllied( actmap->actplayer)  )
00944                     return true;
00945               }
00946            }
00947         }
00948         return false;
00949       };
00950 
00951       void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00952       {
00953           tfield* fld = actmap->getField(pos);
00954           
00955           cargoDialog( fld->getContainer() );
00956           
00957           updateFieldInfo();
00958           repaintMap();
00959       }
00960 
00961       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
00962       {
00963          return IconRepository::getIcon("container.png");
00964       };
00965 
00966       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
00967       {
00968          return ( key->keysym.unicode == 'l' );
00969       };
00970       
00971       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
00972       {
00973          return "view ~l~oaded units";
00974       };
00975 };
00976 
00977 int OpenContainer::containeractive = 0;
00978 
00979 
00980 
00981 
00982 class EnableReactionfire : public GuiFunction
00983 {
00984    public:
00985       bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
00986       {
00987          Vehicle* eht = actmap->getField(pos)->vehicle;
00988          if ( eht ) 
00989             if ( eht->color == actmap->actplayer * 8)
00990                if ( !eht->baseType->hasFunction(ContainerBaseType::NoReactionfire ))
00991                   if ( eht->reactionfire.getStatus() == Vehicle::ReactionFire::off )
00992                      if ( moveparams.movestatus == 0  && pendingVehicleActions.actionType == vat_nothing)
00993                         if ( eht->weapexist() )
00994                            for ( int i = 0; i < eht->typ->weapons.count; ++i )
00995                               if ( eht->typ->weapons.weapon[i].offensive() && eht->typ->weapons.weapon[i].reactionFireShots )
00996                                  return true;
00997 
00998          return false;
00999       };
01000       bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
01001       {
01002          return ( key->keysym.unicode == 'x' );
01003       };
01004 
01005       void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
01006       {
01007          int res = actmap->getField(pos)->vehicle->reactionfire.enable();
01008          if ( res < 0 )
01009             dispmessage2 ( -res, NULL );
01010          else
01011             logtoreplayinfo ( rpl_reactionFireOn, actmap->getField(pos)->vehicle->networkid );
01012          updateFieldInfo();
01013       }
01014 
01015       Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
01016       {
01017          return IconRepository::getIcon("enable-reactionfire.png");
01018       };
01019 
01020       ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num )
01021       {
01022          return "enable reaction fire (~x~)";
01023       };
01024 };
01025 
01026 class DisableReactionfire : public GuiFunction
01027 {
01028    public:
01029       bool