00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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 }
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
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
00361
00362
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 }
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
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 }
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
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
00571
00572
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
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
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