gameevents.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 
00026 
00027 
00028 #include <stdio.h>
00029 
00030 #include <cstring>
00031 
00032 #include "global.h"
00033 #include "buildingtype.h"
00034 #include "vehicletype.h"
00035 #include "typen.h"
00036 
00037 #include "gameevent_dialogs.h"
00038 #include "spfst.h"
00039 #include "loaders.h"
00040 #include "gameevents.h"
00041 #include "dlg_box.h"
00042 #include "dialog.h"
00043 #include "errors.h"
00044 #include "itemrepository.h"
00045 #include "messagedlg.h"
00046 #include "mapdisplayinterface.h"
00047 
00048 #include "actions/diplomacycommand.h"
00049 
00050 #ifdef sgmain
00051 # include "viewcalculation.h"
00052 # include "resourcenet.h"
00053 # include "sg.h"
00054 # include "turncontrol.h"
00055 #endif
00056 
00057 
00058 
00060 // Trigger
00061 
00062 
00063 int versionTest( tnstream& stream, int min, int max )
00064 {
00065    int version = stream.readInt();
00066    if ( version < min || version > max )
00067       throw tinvalidversion( stream.getLocation(), max, version );
00068    return version;
00069 }      
00070 
00071 void TriggerNothing::readData( tnstream& stream )
00072 {
00073    versionTest(stream,1,1);
00074 }
00075 
00076 void TriggerNothing::writeData( tnstream& stream )
00077 {
00078    stream.writeInt(1);
00079 }
00080 
00081 
00082 
00083 EventTrigger::State TurnPassed::getState( int player )
00084 {
00085    if ( gamemap->time.turn() > turn || (gamemap->time.turn() == turn && gamemap->time.move() >= move ))
00086       return finally_fulfilled;
00087    else
00088       return unfulfilled;
00089 }
00090 
00091 
00092 void TurnPassed::arm()
00093 {
00094    GameTime t;
00095    t.set ( turn, move );
00096    gamemap->eventTimes.push_back ( t );
00097    sort( gamemap->eventTimes.begin(), gamemap->eventTimes.end(), GameTime::comp );
00098 }
00099 
00100 void TurnPassed::readData( tnstream& stream )
00101 {
00102    versionTest(stream,1,1);
00103    turn = stream.readInt();
00104    move = stream.readInt();
00105 }
00106 
00107 void TurnPassed::writeData( tnstream& stream )
00108 {
00109    stream.writeInt(1);
00110    stream.writeInt( turn );
00111    stream.writeInt( move );
00112 }
00113 
00114 void TurnPassed::setup()
00115 {
00116    turn = editInt( "turn", turn );
00117    move = editInt( "move", move );
00118 }
00119 
00120 
00121 ASCString TurnPassed::getTypeName() const
00122 {
00123    return "turn passed";
00124 }
00125 
00126 ASCString TurnPassed::getDetailledName() const
00127 {
00128    if ( turn >= 0 ) {
00129       ASCString s;
00130       s.format( "turn %d , move %d passed ", turn, move );
00131       return s; 
00132    } else
00133       return getTypeName();
00134 }
00135 
00136 
00137 
00138 ASCString BuildingPositionTrigger::getName() const
00139 {
00140    ASCString s = "Building ";
00141    if ( gamemap->getField(pos) && gamemap->getField(pos)->building )
00142       s += gamemap->getField(pos)->building->getName();
00143    else
00144       if ( pos.valid() )
00145          s += " <not found> ";
00146 
00147    return s;
00148 }
00149 
00150 void BuildingPositionTrigger::setup()
00151 {
00152    getxy_building( &pos.x, &pos.y );
00153 }
00154 
00155 
00156 
00157 EventTrigger::State BuildingConquered::getState( int player )
00158 {
00159    MapField* fld = gamemap->getField ( pos );
00160    if( !fld ) {
00161       displaymessage ("invalid event - map field not found!", 1);
00162       return finally_failed;
00163    }
00164 
00165    if ( !fld->building )
00166       return finally_failed;
00167 
00168    if ( fld->building->getOwner() == player )
00169       return fulfilled;
00170    else
00171       return unfulfilled;
00172 }
00173 
00174 void BuildingConquered::arm()
00175 {
00176    if( !gamemap->getField ( pos ) ) {
00177       displaymessage ("invalid event - map field not found!", 1);
00178       return;
00179    }
00180 
00181    Building* bld = gamemap->getField ( pos )->building;
00182    if ( bld )
00183       bld->conquered.connect( SigC::slot( *this, &BuildingConquered::triggered ));
00184 }
00185 
00186 void BuildingConquered::triggered()
00187 {
00188    if ( isFulfilled() )
00189       eventReady( gamemap );
00190 }
00191 
00192 
00193 EventTrigger::State BuildingLost::getState( int player )
00194 {
00195    State s = BuildingConquered::getState ( player );
00196    if ( s == fulfilled)
00197       return unfulfilled;
00198    if ( s == unfulfilled )
00199       return fulfilled;
00200    return s;
00201 }
00202 
00203 
00204 void BuildingLost::arm()
00205 {
00206    if( !gamemap->getField ( pos ) ) {
00207       displaymessage ("invalid event - map field not found!", 1);
00208       return;
00209    }
00210 
00211    Building* bld = gamemap->getField ( pos )->building;
00212    if ( bld ) {
00213       bld->conquered.connect( SigC::slot( *this, &BuildingConquered::triggered ));
00214       bld->destroyed.connect( SigC::slot( *this, &BuildingConquered::triggered ));
00215    }
00216 }
00217 
00218 
00219 
00220 void PositionTrigger::readData( tnstream& stream )
00221 {
00222    versionTest(stream,1,1);
00223    pos.read( stream );
00224 }
00225 
00226 
00227 void PositionTrigger::writeData( tnstream& stream )
00228 {
00229    stream.writeInt(1);
00230    pos.write( stream );
00231 }
00232 
00233 EventTrigger::State BuildingDestroyed::getState( int player )
00234 {
00235    if( !gamemap->getField ( pos ) ) {
00236       displaymessage ("invalid event - map field not found!", 1);
00237       return finally_fulfilled;
00238    }
00239 
00240    MapField* fld = gamemap->getField ( pos );
00241    if ( !fld->building )
00242       return finally_fulfilled;
00243    else
00244       return unfulfilled;
00245 }
00246 
00247 
00248 EventTrigger::State BuildingSeen::getState( int player )
00249 {
00250    if( !gamemap->getField ( pos ) ) {
00251       displaymessage ("invalid event - map field not found!", 1);
00252       return finally_fulfilled;
00253    }
00254 
00255    Building* bld = gamemap->getField ( pos )->building;
00256    if ( !bld )
00257       return finally_failed;
00258 
00259    int cnt = 0;
00260    for ( int x = 0; x < 4; x++ )
00261       for ( int y = 0; y < 6; y++ ) {
00262          if ( bld->typ->fieldExists ( BuildingType::LocalCoordinate(x, y) ) ) {
00263             MapField* fld = bld->getField ( BuildingType::LocalCoordinate( x, y) );
00264             if ( fld ) {
00265                int vis = (fld-> visible >> (player*2) ) & 3;
00266                if ( bld->typ->height >= chschwimmend && bld->typ->height <= chhochfliegend ) {
00267                   if ( vis >= visible_now )
00268                      cnt++;
00269                } else {
00270                   if ( vis == visible_all )
00271                      cnt++;
00272                }
00273             }
00274          }
00275       }
00276 
00277    if ( cnt )
00278       return finally_fulfilled;
00279    else
00280       return unfulfilled;
00281 }
00282 
00283 void BuildingSeen::arm()
00284 {
00285    if( !gamemap->getField ( pos ) ) {
00286       displaymessage ("invalid event - map field not found!", 1);
00287       return;
00288    }
00289 
00290    Building* bld = gamemap->getField ( pos )->building;
00291    if ( bld ) {
00292       bld->connection |= cconnection_seen;
00293       #ifdef sgmain
00294       buildingSeen.connect( SigC::slot( *this, &BuildingSeen::triggered ));
00295       #endif
00296    }
00297 }
00298 
00299 void BuildingSeen::triggered()
00300 {
00301    if ( isFulfilled() )
00302       eventReady( gamemap );
00303 }
00304 
00305 
00306 EventTrigger::State AllBuildingsLost::getState( int player )
00307 {
00308    if ( gamemap->player[player].buildingList.empty() )
00309       return fulfilled;
00310    else
00311       return unfulfilled;
00312 }
00313 
00314 ASCString AllBuildingsLost::getTypeName() const
00315 {
00316    return "All Buildings Lost";
00317 }
00318 
00319 ASCString AllBuildingsLost::getDetailledName() const
00320 {
00321    return getTypeName();
00322 }
00323 
00324 
00325 EventTrigger::State AllUnitsLost::getState( int player )
00326 {
00327    if ( gamemap->player[player].vehicleList.empty() )
00328       return fulfilled;
00329    else
00330       return unfulfilled;
00331 }
00332 
00333 ASCString AllUnitsLost::getTypeName() const
00334 {
00335    return "All Units Lost";
00336 }
00337 
00338 ASCString AllUnitsLost::getDetailledName() const
00339 {
00340    return getTypeName();
00341 }
00342 
00343 void UnitTrigger::readData ( tnstream& stream )
00344 {
00345    versionTest(stream,1,1);
00346    unitID = stream.readInt();
00347 }
00348 
00349 
00350 void UnitTrigger::writeData ( tnstream& stream )
00351 {
00352    stream.writeInt(1);
00353    stream.writeInt( unitID );
00354 }
00355 
00356 ASCString UnitTrigger::getName() const
00357 {
00358    ASCString s = "unit ";
00359    if ( gamemap ) {
00360       if ( gamemap->getUnit( unitID ))
00361          s += gamemap->getUnit( unitID )->getName();
00362       else
00363          s += "<not found>";
00364    }
00365    return s;
00366 }
00367 
00368 void UnitTrigger::setup()
00369 {
00370    unitID = selectunit ( unitID );
00371 }
00372 
00373 void UnitTrigger::triggered()
00374 {
00375    state( -1 );
00376    eventReady( gamemap );
00377 }
00378 
00379 
00380 void UnitLost::arm()
00381 {
00382    Vehicle* veh = gamemap->getUnit( unitID );
00383    if ( veh ) {
00384       veh->destroyed.connect( SigC::slot( *this, &UnitLost::triggered ));
00385       veh->conquered.connect( SigC::slot( *this, &UnitLost::triggered ));
00386    }
00387 }
00388 
00389 
00390 EventTrigger::State UnitLost::getState( int player )
00391 {
00392   Vehicle* veh = gamemap->getUnit( unitID );
00393   if ( !veh )
00394      return finally_fulfilled;
00395   if ( veh->getOwner() != player )
00396      return fulfilled;
00397   return unfulfilled;
00398 }
00399 
00400 
00401 ASCString UnitLost::getTypeName() const
00402 {
00403    return "unit lost";
00404 }
00405 
00406 
00407 ASCString UnitLost::getDetailledName() const
00408 {
00409    return UnitTrigger::getName() + " lost";
00410 }
00411 
00412 
00413 
00414 
00415 
00416 EventTrigger::State UnitConquered::getState( int player )
00417 {
00418   Vehicle* veh = gamemap->getUnit( unitID );
00419   if ( !veh )
00420      return finally_failed;
00421   if ( veh->getOwner() == player )
00422      return fulfilled;
00423   return unfulfilled;
00424 
00425 }
00426 
00427 ASCString UnitConquered::getTypeName() const
00428 {
00429    return "unit conquered";
00430 }
00431 
00432 
00433 ASCString UnitConquered::getDetailledName() const
00434 {
00435    return UnitTrigger::getName() + " conquered";
00436 }
00437 
00438 void UnitConquered::arm()
00439 {
00440    Vehicle* veh = gamemap->getUnit( unitID );
00441    if ( veh )
00442       veh->conquered.connect( SigC::slot( *this, &UnitConquered::triggered ));
00443 }
00444 
00445 
00446 
00447 
00448 EventTrigger::State UnitDestroyed::getState( int player )
00449 {
00450   Vehicle* veh = gamemap->getUnit( unitID );
00451   if ( !veh )
00452      return finally_fulfilled;
00453   return unfulfilled;
00454 }
00455 
00456 
00457 ASCString UnitDestroyed::getTypeName() const
00458 {
00459    return "unit destroyed";
00460 }
00461 
00462 ASCString UnitDestroyed::getDetailledName() const
00463 {
00464    return UnitTrigger::getName() + " destroyed";
00465 }
00466 
00467 void UnitDestroyed::arm()
00468 {
00469   Vehicle* veh = gamemap->getUnit( unitID );
00470   if ( veh )
00471      veh->destroyed.connect( SigC::slot( *this, &UnitDestroyed::triggered ));
00472 }
00473 
00474 
00475 
00476 
00477 EventTrigger::State EventTriggered::getState( int player )
00478 {
00479    for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i )
00480       if ( (*i)->id == eventID && (*i)->status == Event::Executed )
00481         return finally_fulfilled;
00482   return unfulfilled;
00483 }
00484 
00485 void EventTriggered::readData ( tnstream& stream )
00486 {
00487    versionTest(stream,1,1);
00488    eventID = stream.readInt();
00489 }
00490 
00491 void EventTriggered::writeData ( tnstream& stream )
00492 {
00493    stream.writeInt(1);
00494    stream.writeInt( eventID );
00495 }
00496 
00497 
00498 Event* EventTriggered::getTargetEventName() const
00499 {
00500    if ( gamemap )
00501       for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i )
00502          if ( (*i)->id == eventID )
00503             return *i;
00504    return NULL;
00505 }
00506 
00507 
00508 ASCString EventTriggered::getTypeName() const
00509 {
00510    return "Event triggered";
00511 }
00512 
00513 ASCString EventTriggered::getDetailledName() const
00514 {
00515    Event* e = getTargetEventName();
00516    if ( e ) {
00517       ASCString s = "Event ";
00518       if ( !e->description.empty() )
00519          s += e->description;
00520       else
00521          s += e->action->getName();
00522       s += " triggered";
00523       return s;
00524    } else
00525       return getTypeName();
00526 }
00527 
00528 void EventTriggered::setup()
00529 {
00530    vector<int> eventIDs;
00531    vector<ASCString> eventnames;
00532    int fnd = -1;
00533    int counter = 0;
00534    for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i ) {
00535       eventnames.push_back( (*i)->action->getName() + " : " + (*i)->description );
00536       eventIDs.push_back ( (*i)->id );
00537       if ( (*i)->id == eventID )
00538          fnd = counter;
00539       ++counter;
00540    }
00541 
00542    int res = chooseString ( "select event", eventnames, fnd );
00543    if ( res >= 0)
00544       eventID = eventIDs[res];
00545 }
00546 
00547 void EventTriggered::arm()
00548 {
00549    Event* e = getTargetEventName();
00550    if ( e )
00551       e->executed.connect( SigC::slot( *this, &EventTriggered::triggered));
00552 }
00553 
00554 void EventTriggered::triggered()
00555 {
00556    state( -1 );
00557    eventReady( gamemap );
00558 }
00559 
00560 
00561 EventTrigger::State AllEnemyUnitsDestroyed::getState( int player )
00562 {
00563    for ( int i = 0; i < 8; i++ )
00564       if ( gamemap->player[player].diplomacy.isHostile(i))
00565          if ( !gamemap->player[i].vehicleList.empty() )
00566             return unfulfilled;
00567 
00568     return fulfilled;
00569 }
00570 
00571 
00572 ASCString AllEnemyUnitsDestroyed::getDetailledName() const
00573 {
00574    return getTypeName();
00575 }
00576 
00577 ASCString AllEnemyUnitsDestroyed::getTypeName() const
00578 {
00579    return "All enemy units destroyed";
00580 }
00581 
00582 void AllEnemyUnitsDestroyed::arm()
00583 {
00584    ContainerBase::anyContainerDestroyed.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyUnitsDestroyed::triggered)));
00585    ContainerBase::anyContainerConquered.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyUnitsDestroyed::triggered)));
00586 }
00587 
00588 void AllEnemyUnitsDestroyed::triggered()
00589 {
00590    if ( isFulfilled() )
00591       eventReady( gamemap );
00592 }
00593 
00594 
00595 EventTrigger::State AllEnemyBuildingsDestroyed::getState( int player )
00596 {
00597    for ( int i = 0; i < 8; i++ )
00598       if ( gamemap->getPlayer(player).diplomacy.isHostile(i))
00599          if ( !gamemap->player[i].buildingList.empty() )
00600             return unfulfilled;
00601 
00602     return fulfilled;
00603 }
00604 
00605 ASCString AllEnemyBuildingsDestroyed::getTypeName() const
00606 {
00607    return "All enemy buildings destroyed";
00608 }
00609 
00610 ASCString AllEnemyBuildingsDestroyed::getDetailledName() const
00611 {
00612    return getTypeName();
00613 }
00614 
00615 
00616 
00617 void AllEnemyBuildingsDestroyed::arm()
00618 {
00619    ContainerBase::anyContainerDestroyed.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyBuildingsDestroyed::triggered)));
00620    ContainerBase::anyContainerConquered.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyBuildingsDestroyed::triggered)));
00621 }
00622 
00623 void AllEnemyBuildingsDestroyed::triggered()
00624 {
00625    if ( isFulfilled() )
00626       eventReady( gamemap );
00627 }
00628 
00629 
00630 EventTrigger::State SpecificUnitEntersPolygon::getState( int player )
00631 {
00632   found = false;
00633   operate();
00634   if ( found )
00635      return fulfilled;
00636   else
00637      return unfulfilled;
00638 }
00639 
00640 void SpecificUnitEntersPolygon::fieldOperator( const MapCoordinate& mc )
00641 {
00642    MapField* fld = gamemap->getField ( mc );
00643    if ( !arming ) {
00644       if ( fld && fld->getVehicle() )
00645          if ( fld->getVehicle()->networkid == unitID || unitID == -1 )
00646             found = true;
00647 
00648       Vehicle* veh = gamemap->getUnit( unitID );
00649       if ( veh )
00650          if ( mc.x == veh->getPosition().x && mc.y == veh->getPosition().y )
00651             found = true;
00652    } else
00653       fld->connection |= cconnection_areaentered_specificunit;
00654 }
00655 
00656 void SpecificUnitEntersPolygon::readData ( tnstream& stream )
00657 {
00658   versionTest(stream,1,1);
00659   readMapModificationData( stream );
00660   unitID = stream.readInt();
00661 }
00662 
00663 void SpecificUnitEntersPolygon::writeData ( tnstream& stream )
00664 {
00665   stream.writeInt(1);
00666   writeMapModificationData( stream );
00667   stream.writeInt( unitID );
00668 }
00669 
00670 ASCString SpecificUnitEntersPolygon::getTypeName() const
00671 {
00672    return "specific unit entered polygon";
00673 }
00674 
00675 
00676 ASCString SpecificUnitEntersPolygon::getDetailledName() const
00677 {
00678    ASCString s;
00679    if ( unitID > 0  && gamemap->getUnit( unitID )) {
00680       s = "unit ";
00681       s += gamemap->getUnit( unitID )->getName();
00682    } else
00683       s = "specific unit";
00684    s += " enters polygon";
00685    return s;
00686 }
00687 
00688 void SpecificUnitEntersPolygon::setup()
00689 {
00690    FieldAddressing::setup();
00691    unitID = selectunit ( unitID );
00692 }
00693 
00694 void SpecificUnitEntersPolygon::arm ()
00695 {
00696    #ifdef sgmain
00697    arming = true;
00698    operate();
00699    arming = false;
00700    fieldCrossed.connect( SigC::slot( *this, &SpecificUnitEntersPolygon::triggered));
00701    Vehicle* veh = gamemap->getUnit( unitID );
00702    if ( veh )
00703       veh->connection |= cconnection_areaentered_specificunit;
00704    #endif
00705 }
00706 
00707 void SpecificUnitEntersPolygon::triggered( const Context& context )
00708 {
00709    if ( isFulfilled() )
00710       eventReady( gamemap );
00711 }
00712 
00713 EventTrigger::State AnyUnitEntersPolygon::getState( int player )
00714 {
00715   found = false;
00716   operate();
00717   if ( found )
00718      return finally_fulfilled;
00719   else
00720      return unfulfilled;
00721 }
00722 
00723 void AnyUnitEntersPolygon::fieldOperator( const MapCoordinate& mc )
00724 {
00725    MapField* fld = gamemap->getField ( mc );
00726    if ( !arming ) {
00727       if ( fld && fld->getVehicle() )
00728          if ( (1 << fld->getVehicle()->getOwner()) & player )
00729             found = true;
00730 
00731       if ( fld && fld->building )
00732          for ( ContainerBase::Cargo::const_iterator i = fld->building->getCargo().begin(); i != fld->building->getCargo().end(); ++i )
00733             if ( *i ) 
00734                if ( (1 << (*i)->getOwner()) & player )
00735                   found = true;
00736 
00737    } else {
00738      fld->connection |= cconnection_areaentered_anyunit;
00739    }
00740 }
00741 
00742 void AnyUnitEntersPolygon::readData ( tnstream& stream )
00743 {
00744   versionTest(stream,1,1);
00745   readMapModificationData( stream );
00746   player = stream.readInt();
00747 }
00748 
00749 void AnyUnitEntersPolygon::writeData ( tnstream& stream )
00750 {
00751   stream.writeInt(1);
00752   writeMapModificationData( stream );
00753   stream.writeInt( player );
00754 }
00755 
00756 ASCString AnyUnitEntersPolygon::getTypeName() const
00757 {
00758    return "Any unit entered polygon";
00759 }
00760 
00761 ASCString AnyUnitEntersPolygon::getDetailledName() const
00762 {
00763    ASCString s = "any unit ";
00764    if ( player ) {
00765       s += "from ";
00766       for ( int i = 0; i < 8; ++i )
00767          if ( player & ( 1 << i)) {
00768             s += gamemap->player[i].getName();
00769             s += " ";
00770          }
00771    }
00772    s += " enters polygon";
00773    return s;
00774 }
00775 
00776 void AnyUnitEntersPolygon::setup()
00777 {
00778    FieldAddressing::setup();
00779    playerselall( &player );
00780 }
00781 
00782 void AnyUnitEntersPolygon::arm()
00783 {
00784    #ifdef sgmain
00785    arming = true;
00786    operate();
00787    arming = false;
00788    fieldCrossed.connect( SigC::slot( *this, &AnyUnitEntersPolygon::triggered));
00789    #endif
00790 }
00791 
00792 void AnyUnitEntersPolygon::triggered(const Context& context )
00793 {
00794    if ( isFulfilled() )
00795       eventReady( gamemap );
00796 }
00797 
00798 
00799 EventTrigger::State ResourceTribute::getState( int player )
00800 {
00801     if ( payingPlayer < 0 || gamemap->tribute.avail[payingPlayer][player] + gamemap->tribute.paid[player][payingPlayer] < demand )
00802        return unfulfilled;
00803     else
00804        return finally_fulfilled;
00805 }
00806 
00807 void ResourceTribute::readData ( tnstream& stream )
00808 {
00809    versionTest(stream,1,1);
00810    payingPlayer = stream.readInt();
00811    demand.read ( stream );
00812 }
00813 
00814 
00815 void ResourceTribute::writeData ( tnstream& stream )
00816 {
00817    stream.writeInt( 1 );
00818    stream.writeInt( payingPlayer );
00819    demand.write ( stream );
00820 }
00821 
00822 
00823 ASCString ResourceTribute::getTypeName() const
00824 {
00825    return "Resource tribute";
00826 }
00827 
00828 ASCString ResourceTribute::getDetailledName() const
00829 {
00830    if ( payingPlayer >= 0 ) {
00831       ASCString s;
00832       s.format ( "Resource tribute: %d E ; %d M ; %d F", demand.energy, demand.material, demand.fuel );
00833       return s;
00834    } else
00835       return getTypeName();
00836 }
00837 
00838 void ResourceTribute::setup()
00839 {
00840    payingPlayer = editInt( "Paying Player", payingPlayer );
00841    demand.energy = editInt( "energy", demand.energy );
00842    demand.material = editInt( "material", demand.material );
00843    demand.fuel = editInt( "fuel", demand.fuel );
00844 }
00845 
00846 void ResourceTribute::arm()
00847 {
00848   #ifdef sgmain
00849    tributeTransferred.connect( SigC::slot( *this, &ResourceTribute::triggered));
00850   #endif 
00851 }
00852 
00853 void ResourceTribute::triggered()
00854 {
00855    if ( isFulfilled() )
00856       eventReady( gamemap );
00857 }
00858 
00860 // Actions
00861 
00862 
00863 void Action_Nothing::readData( tnstream& stream )
00864 {
00865    stream.readInt();
00866 }
00867 
00868 void Action_Nothing::writeData( tnstream& stream )
00869 {
00870    stream.writeInt(1);
00871 }
00872 
00873 
00874 void WindChange::execute( MapDisplayInterface* md )
00875 {
00876    if ( speed != -1 )
00877       gamemap->weather.windSpeed = speed;
00878 
00879    if ( direction != -1 )
00880       gamemap->weather.windDirection = direction;
00881 
00882    if ( md )
00883       md->updateDashboard();
00884 }
00885 
00886 void WindChange::readData( tnstream& stream )
00887 {
00888    versionTest(stream,1,1);
00889    speed = stream.readInt();
00890    direction = stream.readInt();
00891 }
00892 
00893 void WindChange::writeData( tnstream& stream )
00894 {
00895    stream.writeInt(1);
00896    stream.writeInt( speed );
00897    stream.writeInt( direction );
00898 }
00899 
00900 void WindChange::setup()
00901 {
00902    speed     = editInt("Wind Speed", speed, 0, 255);
00903    direction = editInt("Wind Direction", direction, 0, 5);
00904 }
00905 
00906 
00907 
00908 void ChangeGameParameter::execute( MapDisplayInterface* md )
00909 {
00910    if ( parameterNum >= 0 )
00911       if ( gameParameterSettings[parameterNum ].changeableByEvent )
00912          gamemap->setgameparameter( GameParameter(parameterNum) , parameterValue );
00913 }
00914 
00915 void ChangeGameParameter::readData( tnstream& stream )
00916 {
00917    versionTest(stream,1,1);
00918    parameterNum = stream.readInt();
00919    parameterValue = stream.readInt();
00920 }
00921 
00922 void ChangeGameParameter::writeData( tnstream& stream )
00923 {
00924    stream.writeInt(1);
00925    stream.writeInt( parameterNum );
00926    stream.writeInt( parameterValue );
00927 }
00928 
00929 int ChangeGameParameter::selectgameparameter( int para )
00930 {
00931    vector<ASCString> list;
00932    for ( int i = 0; i < gameparameternum; ++i )
00933       list.push_back ( gameParameterSettings[i].name );
00934    return chooseString("Select GameParameter", list, para );
00935 }
00936 
00937 void ChangeGameParameter::setup()
00938 {
00939     int nr = selectgameparameter( parameterNum );
00940     if ( (nr >= 0) && ( nr < gameparameternum) ) {
00941        if ( gameParameterSettings[nr].changeableByEvent ) {
00942           int org = parameterValue;
00943           if ( org < gameParameterSettings[nr].minValue && org > gameParameterSettings[nr].maxValue )
00944              org = gameParameterSettings[nr].defaultValue;
00945           parameterValue = getid("Parameter Val", org, gameParameterSettings[nr].minValue, gameParameterSettings[nr].maxValue);
00946           parameterNum = nr;
00947        } else
00948           displaymessage("This parameter cannot be changed by events",1);
00949     }
00950     
00951 }
00952 
00953 
00954 void  DisplayMessage :: viewtextmessage ( GameMap* actmap, int id, int player )
00955 {
00956    ASCString txt = readtextmessage( id );
00957    if ( !txt.empty() ) {
00958 
00959       int to;
00960       if ( player < 8 )
00961          to = (1 << player);
00962       else
00963          to = 0xff;
00964 
00965       new Message ( txt, actmap, to );
00966 #ifdef sgmain
00967       if ( player == actmap->actplayer )
00968          viewunreadmessages ( actmap->player[ actmap->actplayer ] );
00969 #endif
00970    } else
00971       displaymessage( "Message %d not found", 1, id );
00972 }
00973 
00974 
00975 void DisplayMessage::execute( MapDisplayInterface* md )
00976 {
00977    if ( gamemap->state == GameMap::Replay )
00978       return;
00979 
00980    viewtextmessage ( gamemap, messageNum , gamemap->actplayer );
00981 }
00982 
00983 void DisplayMessage::readData( tnstream& stream )
00984 {
00985    versionTest(stream,1,1);
00986    messageNum = stream.readInt();
00987 }
00988 
00989 void DisplayMessage::writeData( tnstream& stream )
00990 {
00991    stream.writeInt(1);
00992    stream.writeInt( messageNum );
00993 }
00994 
00995 void DisplayMessage::setup()
00996 {
00997   messageNum = editInt ( "Message ID", messageNum );
00998 }
00999 
01000 
01001 
01002 
01003 void FieldAddressing::setpointabs ( int x,  int y  )
01004 {
01005    fieldOperator ( MapCoordinate(x,y) );
01006 }
01007 
01008 void FieldAddressing::operate (  )
01009 {
01010    if ( addressingMode == singleField ) {
01011       for ( Fields::iterator i = fields.begin(); i != fields.end(); ++i )
01012          fieldOperator ( *i );
01013    }
01014    if ( addressingMode == poly ) {
01015       for ( Polygons::iterator i = polygons.begin(); i != polygons.end(); ++i )
01016          paintPolygon ( *i );
01017    }
01018    if ( addressingMode == global ) {
01019       for ( int y = 0; y < gameMap->ysize; ++y )
01020          for ( int x = 0; x < gameMap->xsize; ++x )
01021              fieldOperator ( MapCoordinate ( x, y ));
01022    }
01023 }
01024 
01025 void FieldAddressing::setField ( const MapCoordinate& pos )
01026 {
01027    addressingMode = singleField;
01028    fields.clear();
01029    fields.push_back ( pos );
01030 }
01031 
01032 void FieldAddressing::setPolygon ( const Poly_gon& poly_gon )
01033 {
01034    addressingMode = poly;
01035    polygons.clear();
01036    polygons.push_back ( poly_gon );
01037 }
01038 
01039 void FieldAddressing::setGlobal()
01040 {
01041    addressingMode = global;
01042 }
01043 
01044 
01045 
01046 void FieldAddressing::readMapModificationData ( tnstream& stream )
01047 {
01048    versionTest(stream,1000,1000);
01049    addressingMode = AddressingMode ( stream.readInt() );
01050    if ( addressingMode == singleField )
01051       readClassContainer( fields, stream );
01052 
01053    if ( addressingMode == poly )
01054       readClassContainer( polygons, stream );
01055 }
01056 
01057 
01058 void FieldAddressing::setup ()
01059 {
01060    vector<ASCString> entries;
01061    entries.push_back ( "none" );
01062    entries.push_back ( "Single Fields");
01063    entries.push_back ( "Polygons" );
01064    entries.push_back ( "global");
01065 
01066    int c = chooseString ( "choose operation target", entries, addressingMode );
01067    if ( c < 0 )
01068       return;
01069 
01070    addressingMode = AddressingMode( c );
01071 
01072    if (  addressingMode == singleField )
01073       selectFields( fields );
01074    else
01075       if ( addressingMode == poly ) {
01076          if ( !polygons.size() )
01077             polygons.push_back ( Poly_gon() );
01078          editpolygon ( polygons[0] );
01079       }
01080 }
01081 
01082 
01083 void FieldAddressing::writeMapModificationData ( tnstream& stream )
01084 {
01085    stream.writeInt( 1000 );
01086    stream.writeInt ( addressingMode );
01087 
01088    if ( addressingMode == singleField )
01089       writeClassContainer ( fields, stream );
01090 
01091    if ( addressingMode == poly )
01092       writeClassContainer ( polygons, stream );
01093 }
01094 
01095 void MapModificationEvent::execute( MapDisplayInterface* md )
01096 {
01097    operate();
01098 #ifdef sgmain
01099    computeview( gamemap );
01100 #endif
01101    if ( md ) {
01102       md->displayMap();
01103       md->updateDashboard();
01104    }
01105 }
01106 
01107 
01108 void WeatherChange :: readData ( tnstream& stream )
01109 {
01110    versionTest(stream,1,1);
01111    weather = stream.readInt();
01112    readMapModificationData ( stream );
01113 }
01114 
01115 
01116 void WeatherChange :: writeData ( tnstream& stream )
01117 {
01118    stream.writeInt( 1 );
01119    stream.writeInt( weather );
01120    writeMapModificationData ( stream );
01121 }
01122 
01123 void WeatherChange :: fieldOperator( const MapCoordinate& mc )
01124 {
01125    MapField* field = gamemap->getField ( mc );
01126    if ( field ) 
01127       field->setWeather( weather );
01128 }
01129 
01130 void WeatherChange :: setup ()
01131 {
01132   FieldAddressing::setup();
01133   chooseWeather( weather );
01134 }
01135 
01136 
01137 void MapChange :: readData ( tnstream& stream )
01138 {
01139    versionTest(stream,1,1);
01140    terrainID = stream.readInt();
01141    readMapModificationData ( stream );
01142 }
01143 
01144 
01145 void MapChange :: writeData ( tnstream& stream )
01146 {
01147    stream.writeInt( 1 );
01148    stream.writeInt( terrainID );
01149    writeMapModificationData ( stream );
01150 }
01151 
01152 void MapChange :: fieldOperator( const MapCoordinate& mc )
01153 {
01154    TerrainType* typ = terrainTypeRepository.getObject_byID ( terrainID );
01155    if ( !typ )
01156       return;
01157 
01158    MapField* field = gamemap->getField ( mc );
01159    if ( field ) {
01160       int w = field->getWeather();
01161       if (typ->weather[w] == NULL)
01162          w = 0;
01163 
01164       field->typ = typ->weather[ w ];
01165       field->setparams();
01166    }
01167 }
01168 
01169 void MapChange :: setup ()
01170 {
01171   FieldAddressing::setup();
01172   chooseTerrain( terrainID );
01173 }
01174 
01175 
01176 
01177 void AddObject :: readData ( tnstream& stream )
01178 {
01179    versionTest(stream,1,1);
01180    objectID = stream.readInt();
01181    readMapModificationData ( stream );
01182 }
01183 
01184 
01185 void AddObject :: writeData ( tnstream& stream )
01186 {
01187    stream.writeInt( 1 );
01188    stream.writeInt( objectID );
01189    writeMapModificationData ( stream );
01190 }
01191 
01192 
01193 void AddObject :: fieldOperator( const MapCoordinate& mc )
01194 {
01195    ObjectType* obj = objectTypeRepository.getObject_byID ( objectID );
01196    if ( !obj )
01197       return;
01198 
01199    MapField* field = gamemap->getField ( mc );
01200    if ( field ) {
01201       field->addobject ( obj, -1, true );
01202       field->setparams();
01203     }
01204 }
01205 
01206 void AddObject :: setup ()
01207 {
01208   FieldAddressing::setup();
01209   chooseObject( objectID );
01210 }
01211 
01212 
01213 
01214 
01215 void RemoveAllObjects :: readData ( tnstream& stream )
01216 {
01217    versionTest(stream,1,1);
01218    readMapModificationData ( stream );
01219 }
01220 
01221 
01222 void RemoveAllObjects :: writeData ( tnstream& stream )
01223 {
01224    stream.writeInt( 1 );
01225    writeMapModificationData ( stream );
01226 }
01227 
01228 
01229 void RemoveAllObjects :: fieldOperator( const MapCoordinate& mc )
01230 {
01231    MapField* field = gamemap->getField ( mc );
01232    if ( field ) {
01233       field->objects.clear();
01234       field->setparams();
01235     }
01236 }
01237 
01238 void RemoveAllObjects :: setup ()
01239 {
01240   FieldAddressing::setup();
01241 }
01242 
01243 
01244 
01245 void MapChangeCompleted :: execute( MapDisplayInterface* md )
01246 {
01247    checkobjectsforremoval( gamemap );
01248    checkunitsforremoval ( gamemap );
01249 
01250    if ( md ) {
01251       mapChanged( gamemap );
01252       
01253 #ifdef sgmain
01254       if ( gamemap->getCurrentPlayer().isHuman() )
01255          viewunreadmessages ( gamemap->player[ gamemap->actplayer ] );
01256 #endif
01257       
01258    }
01259 
01260 }
01261 
01262 
01263 void ChangeBuildingDamage::readData ( tnstream& stream )
01264 {
01265    versionTest(stream,1,1);
01266    damage = stream.readInt();
01267    position.read ( stream );
01268 }
01269 
01270 void ChangeBuildingDamage::writeData ( tnstream& stream )
01271 {
01272    stream.writeInt( 1);
01273    stream.writeInt( damage );
01274    position.write ( stream );
01275 }
01276 
01277 void ChangeBuildingDamage::execute( MapDisplayInterface* md )
01278 {
01279    MapField* fld = gamemap->getField ( position );
01280    if ( fld && fld->building ) {
01281       if ( damage >= 100 ) {
01282          delete fld->building;
01283          fld->building = NULL;
01284 
01285          if ( md ) 
01286             mapChanged( gamemap );
01287       
01288       } else {
01289          fld->building->damage  = damage;
01290          if ( md )
01291            md->updateDashboard();
01292       }
01293    }
01294 }
01295 
01296 void ChangeBuildingDamage::setup()
01297 {
01298    getxy_building ( &position.x, &position.y );
01299    damage = editInt("new building damage", damage, 0, 100);
01300 }
01301 
01302 
01303 void NextMap::readData ( tnstream& stream )
01304 {
01305    versionTest(stream,1,1);
01306    mapID = stream.readInt();
01307 }
01308 
01309 void NextMap::writeData ( tnstream& stream )
01310 {
01311    stream.writeInt( 1);
01312    stream.writeInt( mapID );
01313 }
01314 
01315 void NextMap::execute( MapDisplayInterface* md )
01316 {
01317    if ( gamemap->state == GameMap::Replay )
01318       return;
01319 
01320    ASCString name = gamemap->preferredFileNames.mapname[0];
01321    if ( name.find('.') != ASCString::npos )
01322       name.erase( name.find('.') );
01323 
01324    
01325    savegame( "map-" + name + "-completed" + (savegameextension + 1), gamemap );
01326    gamemap->sigMapWon( gamemap->getCurrentPlayer() );
01327    throw  LoadNextMap(mapID);
01328 }
01329 
01330 void NextMap::setup()
01331 {
01332    mapID = editInt("ID of next map", mapID, 0, maxint);
01333 }
01334 
01335 
01336 
01337 void LoseMap::execute( MapDisplayInterface* md )
01338 {
01339    if ( gamemap->state == GameMap::Replay )
01340       return;
01341 
01342    if ( gamemap->getCurrentPlayer().stat != Player::human )
01343       return;
01344 
01345    if ( !gamemap->continueplaying ) {
01346       displaymessage ( "You have been defeated !", 3 );
01347       gamemap->getCurrentPlayer().stat = Player::off;
01348       
01349 #ifdef sgmain
01350       int humanCount = 0;
01351       for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
01352          if ( gamemap->getPlayer(p).isHuman() && gamemap->getPlayer(p).exist() )
01353             humanCount++;
01354       
01355       if ( humanCount > 1 ) {
01356          next_turn( gamemap, NextTurnStrategy_AskUser(), md, -1 );
01357       } else {
01358          delete gamemap;
01359          throw NoMapLoaded();
01360       }
01361 #endif
01362    }
01363 }
01364 
01365 
01366 void DisplayEllipse::readData ( tnstream& stream )
01367 {
01368    versionTest(stream,1,1);
01369    x1 = stream.readInt();
01370    x2 = stream.readInt();
01371    y1 = stream.readInt();
01372    y2 = stream.readInt();
01373    alignRight = stream.readInt();
01374    alignBottom = stream.readInt();
01375 }
01376 
01377 void DisplayEllipse::writeData ( tnstream& stream )
01378 {
01379    stream.writeInt( 1 );
01380    stream.writeInt( x1 );
01381    stream.writeInt( x2 );
01382    stream.writeInt( y1 );
01383    stream.writeInt( y2 );
01384    stream.writeInt( alignRight );
01385    stream.writeInt( alignBottom );
01386 }
01387 
01388 void DisplayEllipse::execute( MapDisplayInterface* md )
01389 {
01390    warningMessage("Ellipses are not supported any more!");
01391    /*
01392    if ( !gamemap->ellipse )
01393       gamemap->ellipse = new EllipseOnScreen;
01394 
01395    if ( alignRight ) {     // x orientation
01396       gamemap->ellipse->x1 = agmp->resolutionx - ( 640 - x1 );
01397       gamemap->ellipse->x2 = agmp->resolutionx - ( 640 - x2 );
01398    } else {
01399       gamemap->ellipse->x1 = x1;
01400       gamemap->ellipse->x2 = x2;
01401    }
01402 
01403    if ( alignBottom ) {     // y orientation
01404       gamemap->ellipse->y1 = agmp->resolutiony - ( 480 - y1 );
01405       gamemap->ellipse->y2 = agmp->resolutiony - ( 480 - y2 );
01406    } else {
01407       gamemap->ellipse->y1 = y1;
01408       gamemap->ellipse->y2 = y2;
01409    }
01410 
01411    gamemap->ellipse->color = white;
01412    gamemap->ellipse->precision = 0.15;
01413    gamemap->ellipse->active = 1;
01414 
01415    if ( md )
01416       md->updateDashboard();
01417 
01418    */
01419 }
01420 
01421 void DisplayEllipse::setup()
01422 {
01423    x1 = getid("x1",x1,0,639);
01424    y1 = getid("y1",y1,0,479);
01425    x2 = getid("x2",x2,0,639);
01426    y2 = getid("y2",y2,0,479);
01427    alignRight = choice_dlg("x orientation","~l~eft","~r~ight") - 1;
01428    alignBottom = choice_dlg("y orientation","~t~op","~b~ottom") - 1;
01429 }
01430 
01431 
01432 void RemoveEllipse::execute( MapDisplayInterface* md )
01433 {
01434    /*
01435    if ( gamemap->ellipse ) {
01436       gamemap->ellipse->active = 0;
01437       if ( md )
01438          md->repaintDisplay();
01439    }
01440    */
01441 }
01442 
01443 
01444 
01445 
01446 void ChangeBuildingOwner :: readData ( tnstream& stream )
01447 {
01448    versionTest(stream,1,1);
01449    pos.read( stream );
01450    newOwner = stream.readInt();
01451 }
01452 
01453 
01454 void ChangeBuildingOwner :: writeData ( tnstream& stream )
01455 {
01456    stream.writeInt( 1 );
01457    pos.write( stream );
01458    stream.writeInt ( newOwner );
01459 }
01460 
01461 
01462 void ChangeBuildingOwner :: setup ()
01463 {
01464    getxy_building( &pos.x, &pos.y );
01465    newOwner = getid("new owner",newOwner,0,8);
01466 }
01467 
01468 void ChangeBuildingOwner :: execute( MapDisplayInterface* md )
01469 {
01470    MapField* fld = gamemap->getField ( pos );
01471    if ( fld && fld->building ) {
01472       fld->building->convert ( newOwner );
01473       #ifdef sgmain
01474       evaluateviewcalculation ( gamemap );
01475       #endif
01476       if ( md ) 
01477          mapChanged( gamemap );
01478    }
01479 }
01480 
01481 
01482 void DisplayImmediateMessage::execute( MapDisplayInterface* md )
01483 {
01484    if ( gamemap->state == GameMap::Replay )
01485       return;
01486 
01487    if ( !message.empty() ) {
01488       if ( recipients == 0 )
01489          new Message ( message, gamemap, 1 << gamemap->actplayer, 0 );
01490       else
01491          new Message ( message, gamemap, recipients, 0 );
01492 
01493       #ifdef sgmain
01494       viewunreadmessages ( gamemap->player[ gamemap->actplayer ] );
01495       #endif
01496    }
01497 }
01498 
01499 void DisplayImmediateMessage::readData( tnstream& stream )
01500 {
01501    int version = versionTest(stream,1,2);
01502    message = stream.readString(true);
01503    if ( version >= 2 )
01504       recipients = stream.readInt();
01505    else
01506       recipients = 0;
01507 }
01508 
01509 void DisplayImmediateMessage::writeData( tnstream& stream )
01510 {
01511    stream.writeInt(2);
01512    stream.writeString( message );
01513    stream.writeInt( recipients );
01514 }
01515 
01516 void DisplayImmediateMessage::setup()
01517 {
01518 
01519    vector<ASCString> player;
01520    for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
01521       player.push_back( gamemap->getPlayer(p).getName() );
01522 
01523    BitMapEditor bme (recipients, "Select recieving players", player );
01524    bme.Show();
01525    bme.RunModal();
01526 
01527 
01528    while ( message.find ( "#CRT#" ) != ASCString::npos )
01529       message.replace ( message.find ( "#CRT#" ), 5, "\n" );
01530    while ( message.find ( "#crt#" ) != ASCString::npos )
01531       message.replace ( message.find ( "#crt#" ), 5, "\n" );
01532    MultiLineEditor( "Message", message );
01533 }
01534 
01535 
01536 ASCString DisplayImmediateMessage::getLocalizationString() const
01537 {
01538    return message;
01539 }
01540 
01541 void DisplayImmediateMessage::setLocalizationString( const ASCString& s ) 
01542 {
01543    message = s;
01544 }
01545 
01546 
01547 
01548 
01549 void AddProductionCapability :: readData ( tnstream& stream )
01550 {
01551    versionTest(stream,1,1);
01552    pos.read( stream );
01553    vehicleTypeID = stream.readInt();
01554 }
01555 
01556 
01557 void AddProductionCapability :: writeData ( tnstream& stream )
01558 {
01559    stream.writeInt( 1 );
01560    pos.write( stream );
01561    stream.writeInt ( vehicleTypeID );
01562 }
01563 
01564 
01565 void AddProductionCapability :: setup ()
01566 {
01567    getxy_building( &pos.x, &pos.y );
01568    chooseVehicleType( vehicleTypeID );
01569 }
01570 
01571 void AddProductionCapability :: execute( MapDisplayInterface* md )
01572 {
01573    MapField* fld = gamemap->getField ( pos );
01574    if ( fld && fld->building && vehicleTypeID >= 0 )
01575       fld->building->addProductionLine( gamemap->getvehicletype_byid(vehicleTypeID) );
01576    
01577 }
01578 
01579 
01580 
01581 void ChangeDiplomaticStatus :: readData ( tnstream& stream )
01582 {
01583    versionTest(stream,1,1);
01584    proposingPlayer = stream.readInt();
01585    targetPlayer = stream.readInt();
01586    proposal = Proposal(stream.readInt());
01587 }
01588 
01589 
01590 void ChangeDiplomaticStatus :: writeData ( tnstream& stream )
01591 {
01592    stream.writeInt( 1 );
01593    stream.writeInt ( proposingPlayer );
01594    stream.writeInt ( targetPlayer );
01595    stream.writeInt ( proposal );
01596 }
01597 
01598 
01599 void ChangeDiplomaticStatus :: setup ()
01600 {
01601    proposingPlayer = editInt("Announcing Player",proposingPlayer,0,7);
01602    targetPlayer = editInt("Receiving Player",targetPlayer,0,7);
01603 
01604    vector<ASCString> list;
01605    list.push_back ( "Propose Peace");
01606    list.push_back ( "Declare War");
01607    list.push_back ( "Sneak Attack");
01608 
01609    proposal = Proposal ( chooseString ( "Action", list, proposal ));
01610 }
01611 
01612 void ChangeDiplomaticStatus :: execute( MapDisplayInterface* md )
01613 {
01614 #ifdef sgmain
01615    auto_ptr<DiplomacyCommand> dc ( new DiplomacyCommand( gamemap->getPlayer(proposingPlayer) ));  
01616    if ( proposal == Peace ) {
01617       dc->newstate( PEACE, gamemap->getPlayer(targetPlayer) );
01618    } else
01619       if ( proposal == War ) {
01620          dc->newstate( WAR, gamemap->getPlayer(targetPlayer) );
01621       } else {
01622          dc->sneakAttack( gamemap->getPlayer(targetPlayer) );
01623       }
01624       
01625    ActionResult res = dc->execute( createContext(gamemap) );
01626    if ( res.successful() )
01627       dc.release();
01628 #endif   
01629 }
01630 
01631 
01632 
01633 
01634 
01635 
01636 class ChangePlayerState : public EventAction {
01637       int player;
01638       Player::PlayerStatus state;
01639     public:
01640        ChangePlayerState(): EventAction( EventAction_ChangePlayerState), player(0), state (Player::off){};
01641 
01642          void readData ( tnstream& stream )
01643          {
01644             versionTest(stream,1,1);
01645             player = stream.readInt();
01646             state = (Player::PlayerStatus) stream.readInt();
01647          }
01648 
01649 
01650          void writeData ( tnstream& stream )
01651          {
01652             stream.writeInt( 1 );
01653             stream.writeInt ( player );
01654             stream.writeInt ( state );
01655          }
01656 
01657       void execute( MapDisplayInterface* md )
01658       {
01659          gamemap->getPlayer(player).stat  = state;
01660       }
01661 
01662       void setup()
01663       {
01664          player = editInt("Player",player,0,7);
01665 
01666          vector<ASCString> list;
01667          list.push_back ( "human");
01668          list.push_back ( "computer");
01669          list.push_back ( "off");
01670          list.push_back ( "supervisor");
01671          list.push_back ( "suspended");
01672 
01673 #if 1
01674          state = Player::PlayerStatus( chooseString ( "State", list, state ));
01675 #else
01676          /* this is intended as security measure to prevent a player in a duell
01677             from switching himself to supervisor and seeing the whole map */
01678          do {
01679             state = Player::PlayerStatus( chooseString ( "State", list, state ));
01680             if ( state == Player::supervisor )
01681                warning("setting a player to supervisor is not allowed");
01682          } while ( state == Player::supervisor );
01683 #endif
01684       }
01685 
01686       ASCString getName() const { return "Change player state"; };
01687 };
01688 
01689 
01690 
01691 
01692 
01693 void SetViewSharing :: readData ( tnstream& stream )
01694 {
01695    versionTest(stream,1,1);
01696    viewingPlayer = stream.readInt();
01697    providingPlayer = stream.readInt();
01698    enable = stream.readInt();
01699 }
01700 
01701 
01702 void SetViewSharing :: writeData ( tnstream& stream )
01703 {
01704    stream.writeInt( 1 );
01705    stream.writeInt ( viewingPlayer );
01706    stream.writeInt ( providingPlayer );
01707    stream.writeInt ( enable );
01708 }
01709 
01710 
01711 void SetViewSharing :: setup ()
01712 {
01713    viewingPlayer = editInt("Viewing Player",viewingPlayer,0,7);
01714    providingPlayer = editInt("Providing Player",providingPlayer,0,7);
01715 
01716    vector<ASCString> list;
01717    list.push_back ( "Disable View Sharing");
01718    list.push_back ( "Enable View Sharing");
01719 
01720    enable = chooseString ( "Action", list, enable );
01721 }
01722 
01723 void SetViewSharing :: execute( MapDisplayInterface* md )
01724 {
01725    if ( enable )
01726       gamemap->player[providingPlayer].diplomacy.setState( viewingPlayer, PEACE_SV );
01727    else
01728       if ( gamemap->player[providingPlayer].diplomacy.getState( viewingPlayer ) >= PEACE_SV )
01729          gamemap->player[providingPlayer].diplomacy.setState( viewingPlayer, PEACE );
01730          
01731    #ifdef sgmain
01732    computeview( gamemap );
01733    #endif
01734    if ( md ) {
01735       md->displayMap();
01736       md->updateDashboard();
01737    }
01738 }
01739 
01740 
01741 
01742 
01743 void AddResources :: readData ( tnstream& stream )
01744 {
01745    versionTest(stream,1,1);
01746    res.read( stream );
01747    pos.read( stream );
01748 }
01749 
01750 
01751 void AddResources :: writeData ( tnstream& stream )
01752 {
01753    stream.writeInt( 1 );
01754    res.write( stream );
01755    pos.write( stream );
01756 }
01757 
01758 
01759 void AddResources :: setup ()
01760 {
01761    getxy_building( &pos.x, &pos.y );
01762 
01763    res.energy   = editInt("Energy",res.energy,minint);
01764    res.material = editInt("Material",res.material,minint);
01765    res.fuel     = editInt("Fuel",res.fuel ,minint);
01766 }
01767 
01768 void AddResources :: execute( MapDisplayInterface* md )
01769 {
01770    MapField* fld = gamemap->getField ( pos );
01771    if ( fld && fld->building )
01772       fld->building->putResource( res, 0 );
01773 }
01774 
01775 
01776 void Reinforcements :: readData ( tnstream& stream )
01777 {
01778    versionTest(stream,1,1);
01779    objectNum = stream.readInt();
01780    buf.readfromstream ( &stream );
01781 }
01782 
01783 
01784 void Reinforcements :: writeData ( tnstream& stream )
01785 {
01786    stream.writeInt( 1 );
01787    stream.writeInt( objectNum );
01788    buf.writetostream ( &stream );
01789 }
01790 
01791 
01792 void Reinforcements :: setup ()
01793 {
01794    vector<ASCString> list;
01795    list.push_back ( "Append units / buildings");
01796    list.push_back ( "Reposition and reselect units / buildings");
01797    list.push_back ( "Clear buffer and select other units / buildings");
01798 
01799    int i = chooseString ( "Choose Action", list, 0 );
01800    if ( i == 2 ){
01801       buf.clear();
01802       objectNum = 0;
01803    }
01804    if ( i == 1 ){
01805       execute( NULL );
01806       buf.clear();
01807       objectNum = 0;
01808    }
01809 
01810    ReinforcementSelector::CoordinateList fieldlist;
01811    ReinforcementSelector rs( fieldlist, gamemap, buf, objectNum );
01812    rs.Show();
01813    rs.RunModal();
01814 
01815 
01816 }
01817 
01818 class FindUnitPlacementPos : public SearchFields {
01819       Vehicle* vehicle;
01820    public:
01821       FindUnitPlacementPos ( GameMap* gamemap, Vehicle* veh )
01822         : SearchFields ( gamemap ), vehicle(veh)
01823         {
01824            initsearch(MapCoordinate(veh->xpos, veh->ypos),0,10);
01825            startsearch();
01826         };
01827 
01828       void testfield ( const MapCoordinate& pos )
01829       {
01830          MapField* fld = gamemap->getField( pos );
01831          if ( fld && !fld->vehicle ) {
01832             if ( fieldAccessible( fld, vehicle, -2, NULL, true ) == 2 ) {
01833                fld->vehicle = vehicle;
01834                fld->vehicle->setnewposition ( pos );
01835                fld->vehicle->addview();
01836                cancelSearch = true;
01837             }
01838          }
01839       };
01840 };
01841 
01842 
01843 void Reinforcements :: execute( MapDisplayInterface* md )
01844 {
01845    int cnt = 0;
01846    MemoryStream stream ( &buf, tnstream::reading );
01847    while ( cnt < objectNum ) {
01848       Type type = Type(stream.readInt());
01849       if ( type == ReinfVehicle ) {
01850          try {
01851             Vehicle* veh = Vehicle::newFromStream( gamemap, stream, gamemap->idManager.getNewNetworkID() );
01852             FindUnitPlacementPos fupp( gamemap, veh );
01853          } 
01854          catch ( InvalidID err ) {
01855             displaymessage( "Error executing event 'Reinforcements'\n" +  err.getMessage(), 1);
01856             throw ShutDownMap();
01857          }
01858       }
01859       if ( type == ReinfBuilding ) {
01860         Building* bld = Building::newFromStream ( gamemap, stream );
01861         #if 0
01862         MapCoordinate pos = bld->getPosition();
01863 
01864         for ( int x = 0; x < 4; x++ )
01865            for ( int y = 0; y < 6; y++ )
01866               if ( bld->typ->getpicture ( BuildingType::LocalCoordinate( x , y ) )) {
01867                  MapField* field = gamemap->getField( bld->typ->getFieldCoordinate( pos, BuildingType::LocalCoordinate( x, y) ));
01868                  if ( !field ) {
01869                     delete bld;
01870                     // displaymessage("building does not fit here", 1 );
01871                     return;
01872                  }
01873 
01874                  /*
01875                  if ( !bld->typ->terrainaccess.accessible ( field->bdt ) ) {
01876                     delete bld;
01877                     displaymessage("building does can not be build here", 1 );
01878                     return;
01879                  }
01880                  */
01881 
01882 
01883                  if ( field->vehicle ) {
01884                     delete field->vehicle;
01885                     field->vehicle = NULL;
01886                  }
01887                  if ( field->building ) {
01888                     delete field->building;
01889                     field->building = NULL;
01890                  }
01891               }
01892          bld->chainbuildingtofield( pos );
01893          #endif
01894          gamemap->calculateAllObjects();
01895          bld->addview();
01896       }
01897       ++cnt;
01898    }
01899    #ifdef sgmain
01900    evaluateviewcalculation ( gamemap );
01901    // computeview ( gamemap );
01902 
01903    #endif
01904 
01905    if ( md ) 
01906       mapChanged( gamemap );
01907 }
01908 
01909 template<class T>
01910 ASCString TriggerNameProvider() {
01911    // dynamic allocation is to prevent a compiler bug in gcc 4.2.1
01912    T* t = new T();
01913    ASCString name = t->getTypeName();
01914    delete t;
01915    return name;
01916 };
01917 
01918 template<class T>
01919 ASCString ActionNameProvider() {
01920    T* t = new T();
01921    ASCString name = t->getName();
01922    delete t;
01923    return name;
01924 };
01925 
01926 
01927 
01928 template <typename TriggerType > 
01929 bool registerTrigger( EventTrigger_ID id )
01930 {
01931    return eventTriggerFactory::Instance().registerClass( id, ObjectCreator<EventTrigger, TriggerType>,  TriggerNameProvider<TriggerType>() );
01932 }
01933 
01934 template <typename ActionType > 
01935 bool registerAction( EventAction_ID id )
01936 {
01937    return eventActionFactory::Instance().registerClass( id, ObjectCreator<EventAction, ActionType>,  ActionNameProvider<ActionType>() );
01938 }
01939 
01940 
01941 
01942 
01943 namespace {
01944    const bool r1 = registerTrigger<TurnPassed>                 ( Trigger_TurnPassed );
01945    const bool r2 = registerTrigger<UnitLost>                   ( Trigger_UnitLost );
01946    const bool r3 = registerTrigger<UnitConquered>              ( Trigger_UnitConquered );
01947    const bool r4 = registerTrigger<UnitDestroyed>              ( Trigger_UnitDestroyed );
01948    const bool r5 = registerTrigger<AllBuildingsLost>           ( Trigger_AllBuildingsLost );
01949    const bool r6 = registerTrigger<AllUnitsLost>               ( Trigger_AllUnitsLost );
01950    const bool r7 = registerTrigger<TriggerNothingFalse>        ( Trigger_NothingFalse );
01951    const bool r8 = registerTrigger<TriggerNothingTrue>         ( Trigger_NothingTrue );
01952    const bool r9 = registerTrigger<BuildingConquered>          ( Trigger_BuildingConquered );
01953    const bool r10 = registerTrigger<BuildingLost>              ( Trigger_BuildingLost );
01954    const bool r11 = registerTrigger<BuildingDestroyed>         ( Trigger_BuildingDestroyed );
01955    const bool r12 = registerTrigger<BuildingSeen>              ( Trigger_BuildingSeen );
01956    const bool r13 = registerTrigger<EventTriggered>            ( Trigger_EventTriggered );
01957    const bool r14 = registerTrigger<AllEnemyBuildingsDestroyed>( Trigger_AllEnemyBuildingsDestroyed );
01958    const bool r15 = registerTrigger<AllEnemyUnitsDestroyed>    ( Trigger_AllEnemyUnitsDestroyed );
01959    const bool r16 = registerTrigger<SpecificUnitEntersPolygon> ( Trigger_SpecificUnitEntersPolygon );
01960    const bool r17 = registerTrigger<AnyUnitEntersPolygon>      ( Trigger_AnyUnitEntersPolygon );
01961    const bool r18 = registerTrigger<ResourceTribute>           ( Trigger_ResourceTribute );
01962 
01963    const bool s0 = registerAction<Action_Nothing>( EventAction_Nothing );
01964    const bool s1 = registerAction<DisplayMessage>( EventAction_DisplayMessage );
01965    const bool s2 = registerAction<WindChange>( EventAction_WindChange );
01966    const bool s3 = registerAction<ChangeGameParameter>( EventAction_ChangeGameParameter );
01967    const bool s4 = registerAction<WeatherChange>( EventAction_WeatherChange );
01968    const bool s5 = registerAction<MapChange>( EventAction_MapChange );
01969    const bool s6 = registerAction<AddObject>( EventAction_AddObject );
01970    const bool s7 = registerAction<MapChangeCompleted>( EventAction_MapChangeCompleted );
01971    const bool s8 = registerAction<ChangeBuildingDamage>( EventAction_ChangeBuildingDamage );
01972    const bool s9 = registerAction<NextMap>( EventAction_NextMap );
01973    const bool s10 = registerAction<LoseMap>( EventAction_LoseMap );
01974    const bool s11 = registerAction<DisplayEllipse>( EventAction_DisplayEllipse );
01975    const bool s12 = registerAction<RemoveEllipse>( EventAction_RemoveEllipse );
01976    const bool s13 = registerAction<ChangeBuildingOwner>( EventAction_ChangeBuildingOwner );
01977    const bool s14 = registerAction<RemoveAllObjects>( EventAction_RemoveAllObjects );
01978    const bool s15 = registerAction<DisplayImmediateMessage>( EventAction_DisplayImmediateMessage );
01979    const bool s16 = registerAction<AddProductionCapability>( EventAction_AddProductionCapabiligy );
01980    const bool s17 = registerAction<ChangeDiplomaticStatus>( EventAction_ChangeDiplomaticStatus );
01981    const bool s18 = registerAction<AddResources>( EventAction_AddResources );
01982    const bool s19 = registerAction<Reinforcements>( EventAction_Reinforcements );
01983    const bool s20 = registerAction<SetViewSharing>( EventAction_SetViewSharing );
01984    const bool s21 = registerAction<ChangePlayerState>( EventAction_ChangePlayerState );
01985 };
01986 

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