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

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-2005  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 "newfont.h"
00036 #include "typen.h"
00037 // #include "basegfx.h"
00038 
00039 #include "gameevent_dialogs.h"
00040 #include "spfst.h"
00041 #include "loaders.h"
00042 #include "gameevents.h"
00043 #include "dlg_box.h"
00044 #include "dialog.h"
00045 #include "errors.h"
00046 #include "itemrepository.h"
00047 #include "messagedlg.h"
00048 #include "mapdisplayinterface.h"
00049 
00050 #ifdef sgmain
00051 // # include "gamedlg.h"
00052 # include "viewcalculation.h"
00053 # include "resourcenet.h"
00054 # include "unitctrl.h"
00055 #endif
00056 
00057 
00058 void    viewtextmessage ( int id, int player )
00059 {
00060    ASCString txt = readtextmessage( id );
00061    if ( !txt.empty() ) {
00062 
00063       int to;
00064       if ( player < 8 )
00065          to = (1 << player);
00066       else
00067          to = 0xff;
00068 
00069       new Message ( txt, actmap, to );
00070       #ifdef sgmain
00071       if ( player == actmap->actplayer )
00072          viewunreadmessages ( actmap->player[ actmap->actplayer ] );
00073       #endif
00074    } else
00075       displaymessage( "Message %d not found", 1, id );
00076 }
00077 
00078 
00079 
00080 
00082 // Trigger
00083 
00084 
00085 int versionTest( tnstream& stream, int min, int max )
00086 {
00087    int version = stream.readInt();
00088    if ( version < min || version > max )
00089       throw tinvalidversion( stream.getLocation(), max, version );
00090    return version;
00091 }      
00092 
00093 void TriggerNothing::readData( tnstream& stream )
00094 {
00095    versionTest(stream,1,1);
00096 }
00097 
00098 void TriggerNothing::writeData( tnstream& stream )
00099 {
00100    stream.writeInt(1);
00101 }
00102 
00103 
00104 
00105 EventTrigger::State TurnPassed::getState( int player )
00106 {
00107    if ( gamemap->time.turn() > turn || (gamemap->time.turn() == turn && gamemap->time.move() >= move ))
00108       return finally_fulfilled;
00109    else
00110       return unfulfilled;
00111 }
00112 
00113 
00114 void TurnPassed::arm()
00115 {
00116    GameTime t;
00117    t.set ( turn, move );
00118    gamemap->eventTimes.push_back ( t );
00119    sort( gamemap->eventTimes.begin(), gamemap->eventTimes.end(), GameTime::comp );
00120 }
00121 
00122 void TurnPassed::readData( tnstream& stream )
00123 {
00124    versionTest(stream,1,1);
00125    turn = stream.readInt();
00126    move = stream.readInt();
00127 }
00128 
00129 void TurnPassed::writeData( tnstream& stream )
00130 {
00131    stream.writeInt(1);
00132    stream.writeInt( turn );
00133    stream.writeInt( move );
00134 }
00135 
00136 void TurnPassed::setup()
00137 {
00138    turn = editInt( "turn", turn );
00139    move = editInt( "move", move );
00140 }
00141 
00142 
00143 ASCString TurnPassed::getTypeName() const
00144 {
00145    return "turn passed";
00146 }
00147 
00148 ASCString TurnPassed::getDetailledName() const
00149 {
00150    if ( turn >= 0 ) {
00151       ASCString s;
00152       s.format( "turn %d , move %d passed ", turn, move );
00153       return s; 
00154    } else
00155       return getTypeName();
00156 }
00157 
00158 
00159 
00160 ASCString BuildingPositionTrigger::getName() const
00161 {
00162    ASCString s = "Building ";
00163    if ( gamemap->getField(pos) && gamemap->getField(pos)->building )
00164       s += gamemap->getField(pos)->building->getName();
00165    else
00166       if ( pos.valid() )
00167          s += " <not found> ";
00168 
00169    return s;
00170 }
00171 
00172 void BuildingPositionTrigger::setup()
00173 {
00174    getxy_building( &pos.x, &pos.y );
00175 }
00176 
00177 
00178 
00179 EventTrigger::State BuildingConquered::getState( int player )
00180 {
00181    tfield* fld = gamemap->getField ( pos );
00182    if( !fld ) {
00183       displaymessage ("invalid event - map field not found!", 1);
00184       return finally_failed;
00185    }
00186 
00187    if ( !fld->building )
00188       return finally_failed;
00189 
00190    if ( fld->building->getOwner() == player )
00191       return fulfilled;
00192    else
00193       return unfulfilled;
00194 }
00195 
00196 void BuildingConquered::arm()
00197 {
00198    if( !gamemap->getField ( pos ) ) {
00199       displaymessage ("invalid event - map field not found!", 1);
00200       return;
00201    }
00202 
00203    Building* bld = gamemap->getField ( pos )->building;
00204    if ( bld )
00205       bld->conquered.connect( SigC::slot( *this, &BuildingConquered::triggered ));
00206 }
00207 
00208 void BuildingConquered::triggered()
00209 {
00210    if ( isFulfilled() )
00211       eventReady();
00212 }
00213 
00214 
00215 EventTrigger::State BuildingLost::getState( int player )
00216 {
00217    State s = BuildingConquered::getState ( player );
00218    if ( s == fulfilled)
00219       return unfulfilled;
00220    if ( s == unfulfilled )
00221       return fulfilled;
00222    return s;
00223 }
00224 
00225 
00226 void BuildingLost::arm()
00227 {
00228    if( !gamemap->getField ( pos ) ) {
00229       displaymessage ("invalid event - map field not found!", 1);
00230       return;
00231    }
00232 
00233    Building* bld = gamemap->getField ( pos )->building;
00234    if ( bld ) {
00235       bld->conquered.connect( SigC::slot( *this, &BuildingConquered::triggered ));
00236       bld->destroyed.connect( SigC::slot( *this, &BuildingConquered::triggered ));
00237    }
00238 }
00239 
00240 
00241 
00242 void PositionTrigger::readData( tnstream& stream )
00243 {
00244    versionTest(stream,1,1);
00245    pos.read( stream );
00246 }
00247 
00248 
00249 void PositionTrigger::writeData( tnstream& stream )
00250 {
00251    stream.writeInt(1);
00252    pos.write( stream );
00253 }
00254 
00255 EventTrigger::State BuildingDestroyed::getState( int player )
00256 {
00257    if( !gamemap->getField ( pos ) ) {
00258       displaymessage ("invalid event - map field not found!", 1);
00259       return finally_fulfilled;
00260    }
00261 
00262    tfield* fld = gamemap->getField ( pos );
00263    if ( !fld->building )
00264       return finally_fulfilled;
00265    else
00266       return unfulfilled;
00267 }
00268 
00269 
00270 EventTrigger::State BuildingSeen::getState( int player )
00271 {
00272    if( !gamemap->getField ( pos ) ) {
00273       displaymessage ("invalid event - map field not found!", 1);
00274       return finally_fulfilled;
00275    }
00276 
00277    Building* bld = gamemap->getField ( pos )->building;
00278    if ( !bld )
00279       return finally_failed;
00280 
00281    int cnt = 0;
00282    for ( int x = 0; x < 4; x++ )
00283       for ( int y = 0; y < 6; y++ ) {
00284          if ( bld->typ->fieldExists ( BuildingType::LocalCoordinate(x, y) ) ) {
00285             tfield* fld = bld->getField ( BuildingType::LocalCoordinate( x, y) );
00286             if ( fld ) {
00287                int vis = (fld-> visible >> (player*2) ) & 3;
00288                if ( bld->typ->buildingheight >= chschwimmend && bld->typ->buildingheight <= chhochfliegend ) {
00289                   if ( vis >= visible_now )
00290                      cnt++;
00291                } else {
00292                   if ( vis == visible_all )
00293                      cnt++;
00294                }
00295             }
00296          }
00297       }
00298 
00299    if ( cnt )
00300       return finally_fulfilled;
00301    else
00302       return unfulfilled;
00303 }
00304 
00305 void BuildingSeen::arm()
00306 {
00307    if( !gamemap->getField ( pos ) ) {
00308       displaymessage ("invalid event - map field not found!", 1);
00309       return;
00310    }
00311 
00312    Building* bld = gamemap->getField ( pos )->building;
00313    if ( bld ) {
00314       bld->connection |= cconnection_seen;
00315       #ifdef sgmain
00316       buildingSeen.connect( SigC::slot( *this, &BuildingSeen::triggered ));
00317       #endif
00318    }
00319 }
00320 
00321 void BuildingSeen::triggered()
00322 {
00323    if ( isFulfilled() )
00324       eventReady();
00325 }
00326 
00327 
00328 EventTrigger::State AllBuildingsLost::getState( int player )
00329 {
00330    if ( gamemap->player[player].buildingList.empty() )
00331       return fulfilled;
00332    else
00333       return unfulfilled;
00334 }
00335 
00336 ASCString AllBuildingsLost::getTypeName() const
00337 {
00338    return "All Buildings Lost";
00339 }
00340 
00341 ASCString AllBuildingsLost::getDetailledName() const
00342 {
00343    return getTypeName();
00344 }
00345 
00346 
00347 EventTrigger::State AllUnitsLost::getState( int player )
00348 {
00349    if ( gamemap->player[player].vehicleList.empty() )
00350       return fulfilled;
00351    else
00352       return unfulfilled;
00353 }
00354 
00355 ASCString AllUnitsLost::getTypeName() const
00356 {
00357    return "All Units Lost";
00358 }
00359 
00360 ASCString AllUnitsLost::getDetailledName() const
00361 {
00362    return getTypeName();
00363 }
00364 
00365 void UnitTrigger::readData ( tnstream& stream )
00366 {
00367    versionTest(stream,1,1);
00368    unitID = stream.readInt();
00369 }
00370 
00371 
00372 void UnitTrigger::writeData ( tnstream& stream )
00373 {
00374    stream.writeInt(1);
00375    stream.writeInt( unitID );
00376 }
00377 
00378 ASCString UnitTrigger::getName() const
00379 {
00380    ASCString s = "unit ";
00381    if ( gamemap ) {
00382       if ( gamemap->getUnit( unitID ))
00383          s += gamemap->getUnit( unitID )->getName();
00384       else
00385          s += "<not found>";
00386    }
00387    return s;
00388 }
00389 
00390 void UnitTrigger::setup()
00391 {
00392    unitID = selectunit ( unitID );
00393 }
00394 
00395 void UnitTrigger::triggered()
00396 {
00397    state( -1 );
00398    eventReady();
00399 }
00400 
00401 
00402 void UnitLost::arm()
00403 {
00404    Vehicle* veh = gamemap->getUnit( unitID );
00405    if ( veh ) {
00406       veh->destroyed.connect( SigC::slot( *this, &UnitLost::triggered ));
00407       veh->conquered.connect( SigC::slot( *this, &UnitLost::triggered ));
00408    }
00409 }
00410 
00411 
00412 EventTrigger::State UnitLost::getState( int player )
00413 {
00414   Vehicle* veh = gamemap->getUnit( unitID );
00415   if ( !veh )
00416      return finally_fulfilled;
00417   if ( veh->getOwner() != player )
00418      return fulfilled;
00419   return unfulfilled;
00420 }
00421 
00422 
00423 ASCString UnitLost::getTypeName() const
00424 {
00425    return "unit lost";
00426 }
00427 
00428 
00429 ASCString UnitLost::getDetailledName() const
00430 {
00431    return UnitTrigger::getName() + " lost";
00432 }
00433 
00434 
00435 
00436 
00437 
00438 EventTrigger::State UnitConquered::getState( int player )
00439 {
00440   Vehicle* veh = gamemap->getUnit( unitID );
00441   if ( !veh )
00442      return finally_failed;
00443   if ( veh->getOwner() == player )
00444      return fulfilled;
00445   return unfulfilled;
00446 
00447 }
00448 
00449 ASCString UnitConquered::getTypeName() const
00450 {
00451    return "unit conquered";
00452 }
00453 
00454 
00455 ASCString UnitConquered::getDetailledName() const
00456 {
00457    return UnitTrigger::getName() + " conquered";
00458 }
00459 
00460 void UnitConquered::arm()
00461 {
00462    Vehicle* veh = gamemap->getUnit( unitID );
00463    if ( veh )
00464       veh->conquered.connect( SigC::slot( *this, &UnitConquered::triggered ));
00465 }
00466 
00467 
00468 
00469 
00470 EventTrigger::State UnitDestroyed::getState( int player )
00471 {
00472   Vehicle* veh = gamemap->getUnit( unitID );
00473   if ( !veh )
00474      return finally_fulfilled;
00475   return unfulfilled;
00476 }
00477 
00478 
00479 ASCString UnitDestroyed::getTypeName() const
00480 {
00481    return "unit destroyed";
00482 }
00483 
00484 ASCString UnitDestroyed::getDetailledName() const
00485 {
00486    return UnitTrigger::getName() + " destroyed";
00487 }
00488 
00489 void UnitDestroyed::arm()
00490 {
00491   Vehicle* veh = gamemap->getUnit( unitID );
00492   if ( veh )
00493      veh->destroyed.connect( SigC::slot( *this, &UnitDestroyed::triggered ));
00494 }
00495 
00496 
00497 
00498 
00499 EventTrigger::State EventTriggered::getState( int player )
00500 {
00501    for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i )
00502       if ( (*i)->id == eventID && (*i)->status == Event::Executed )
00503         return finally_fulfilled;
00504   return unfulfilled;
00505 }
00506 
00507 void EventTriggered::readData ( tnstream& stream )
00508 {
00509    versionTest(stream,1,1);
00510    eventID = stream.readInt();
00511 }
00512 
00513 void EventTriggered::writeData ( tnstream& stream )
00514 {
00515    stream.writeInt(1);
00516    stream.writeInt( eventID );
00517 }
00518 
00519 
00520 Event* EventTriggered::getTargetEventName() const
00521 {
00522    if ( gamemap )
00523       for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i )
00524          if ( (*i)->id == eventID )
00525             return *i;
00526    return NULL;
00527 }
00528 
00529 
00530 ASCString EventTriggered::getTypeName() const
00531 {
00532    return "Event triggered";
00533 }
00534 
00535 ASCString EventTriggered::getDetailledName() const
00536 {
00537    Event* e = getTargetEventName();
00538    if ( e ) {
00539       ASCString s = "Event ";
00540       if ( !e->description.empty() )
00541          s += e->description;
00542       else
00543          s += e->action->getName();
00544       s += " triggered";
00545       return s;
00546    } else
00547       return getTypeName();
00548 }
00549 
00550 void EventTriggered::setup()
00551 {
00552    vector<int> eventIDs;
00553    vector<ASCString> eventnames;
00554    int fnd = -1;
00555    int counter = 0;
00556    for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i ) {
00557       eventnames.push_back( (*i)->action->getName() + " : " + (*i)->description );
00558       eventIDs.push_back ( (*i)->id );
00559       if ( (*i)->id == eventID )
00560          fnd = counter;
00561       ++counter;
00562    }
00563 
00564    int res = chooseString ( "select event", eventnames, fnd );
00565    if ( res >= 0)
00566       eventID = eventIDs[res];
00567 }
00568 
00569 void EventTriggered::arm()
00570 {
00571    Event* e = getTargetEventName();
00572    if ( e )
00573       e->executed.connect( SigC::slot( *this, &EventTriggered::triggered));
00574 }
00575 
00576 void EventTriggered::triggered()
00577 {
00578    state( -1 );
00579    eventReady();
00580 }
00581 
00582 
00583 EventTrigger::State AllEnemyUnitsDestroyed::getState( int player )
00584 {
00585    for ( int i = 0; i < 8; i++ )
00586       if ( gamemap->player[player].diplomacy.isHostile(i))
00587          if ( !gamemap->player[i].vehicleList.empty() )
00588             return unfulfilled;
00589 
00590     return fulfilled;
00591 }
00592 
00593 
00594 ASCString AllEnemyUnitsDestroyed::getDetailledName() const
00595 {
00596    return getTypeName();
00597 }
00598 
00599 ASCString AllEnemyUnitsDestroyed::getTypeName() const
00600 {
00601    return "All enemy units destroyed";
00602 }
00603 
00604 void AllEnemyUnitsDestroyed::arm()
00605 {
00606    ContainerBase::anyContainerDestroyed.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyUnitsDestroyed::triggered)));
00607    ContainerBase::anyContainerConquered.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyUnitsDestroyed::triggered)));
00608 }
00609 
00610 void AllEnemyUnitsDestroyed::triggered()
00611 {
00612    if ( isFulfilled() )
00613       eventReady();
00614 }
00615 
00616 
00617 EventTrigger::State AllEnemyBuildingsDestroyed::getState( int player )
00618 {
00619    for ( int i = 0; i < 8; i++ )
00620       if ( actmap->getPlayer(player).diplomacy.isHostile(i))
00621          if ( !gamemap->player[i].buildingList.empty() )
00622             return unfulfilled;
00623 
00624     return fulfilled;
00625 }
00626 
00627 ASCString AllEnemyBuildingsDestroyed::getTypeName() const
00628 {
00629    return "All enemy buildings destroyed";
00630 }
00631 
00632 ASCString AllEnemyBuildingsDestroyed::getDetailledName() const
00633 {
00634    return getTypeName();
00635 }
00636 
00637 
00638 
00639 void AllEnemyBuildingsDestroyed::arm()
00640 {
00641    ContainerBase::anyContainerDestroyed.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyBuildingsDestroyed::triggered)));
00642    ContainerBase::anyContainerConquered.connect( SigC::hide<ContainerBase*>( SigC::slot( *this, &AllEnemyBuildingsDestroyed::triggered)));
00643 }
00644 
00645 void AllEnemyBuildingsDestroyed::triggered()
00646 {
00647    if ( isFulfilled() )
00648       eventReady();
00649 }
00650 
00651 
00652 EventTrigger::State SpecificUnitEntersPolygon::getState( int player )
00653 {
00654   found = false;
00655   operate();
00656   if ( found )
00657      return fulfilled;
00658   else
00659      return unfulfilled;
00660 }
00661 
00662 void SpecificUnitEntersPolygon::fieldOperator( const MapCoordinate& mc )
00663 {
00664    tfield* fld = gamemap->getField ( mc );
00665    if ( !arming ) {
00666       if ( fld && fld->vehicle )
00667          if ( fld->vehicle->networkid == unitID || unitID == -1 )
00668             found = true;
00669 
00670       Vehicle* veh = gamemap->getUnit( unitID );
00671       if ( veh )
00672          if ( mc.x == veh->getPosition().x && mc.y == veh->getPosition().y )
00673             found = true;
00674    } else
00675       fld->connection |= cconnection_areaentered_specificunit;
00676 }
00677 
00678 void SpecificUnitEntersPolygon::readData ( tnstream& stream )
00679 {
00680   versionTest(stream,1,1);
00681   readMapModificationData( stream );
00682   unitID = stream.readInt();
00683 }
00684 
00685 void SpecificUnitEntersPolygon::writeData ( tnstream& stream )
00686 {
00687   stream.writeInt(1);
00688   writeMapModificationData( stream );
00689   stream.writeInt( unitID );
00690 }
00691 
00692 ASCString SpecificUnitEntersPolygon::getTypeName() const
00693 {
00694    return "specific unit entered polygon";
00695 }
00696 
00697 
00698 ASCString SpecificUnitEntersPolygon::getDetailledName() const
00699 {
00700    ASCString s;
00701    if ( unitID > 0  && gamemap->getUnit( unitID )) {
00702       s = "unit ";
00703       s += gamemap->getUnit( unitID )->getName();
00704    } else
00705       s = "specific unit";
00706    s += " enters polygon";
00707    return s;
00708 }
00709 
00710 void SpecificUnitEntersPolygon::setup()
00711 {
00712    FieldAddressing::setup();
00713    unitID = selectunit ( unitID );
00714 }
00715 
00716 void SpecificUnitEntersPolygon::arm ()
00717 {
00718    #ifdef sgmain
00719    arming = true;
00720    operate();
00721    arming = false;
00722    fieldCrossed.connect( SigC::slot( *this, &SpecificUnitEntersPolygon::triggered));
00723    Vehicle* veh = gamemap->getUnit( unitID );
00724    if ( veh )
00725       veh->connection |= cconnection_areaentered_specificunit;
00726    #endif
00727 }
00728 
00729 void SpecificUnitEntersPolygon::triggered()
00730 {
00731    if ( isFulfilled() )
00732       eventReady();
00733 }
00734 
00735 EventTrigger::State AnyUnitEntersPolygon::getState( int player )
00736 {
00737   found = false;
00738   operate();
00739   if ( found )
00740      return finally_fulfilled;
00741   else
00742      return unfulfilled;
00743 }
00744 
00745 void AnyUnitEntersPolygon::fieldOperator( const MapCoordinate& mc )
00746 {
00747    tfield* fld = gamemap->getField ( mc );
00748    if ( !arming ) {
00749       if ( fld && fld->vehicle )
00750          if ( (1 << fld->vehicle->getOwner()) & player )
00751             found = true;
00752 
00753       if ( fld && fld->building )
00754          for ( ContainerBase::Cargo::const_iterator i = fld->building->getCargo().begin(); i != fld->building->getCargo().end(); ++i )
00755             if ( *i ) 
00756                if ( (1 << (*i)->getOwner()) & player )
00757                   found = true;
00758 
00759    } else {
00760      fld->connection |= cconnection_areaentered_anyunit;
00761    }
00762 }
00763 
00764 void AnyUnitEntersPolygon::readData ( tnstream& stream )
00765 {
00766   versionTest(stream,1,1);
00767   readMapModificationData( stream );
00768   player = stream.readInt();
00769 }
00770 
00771 void AnyUnitEntersPolygon::writeData ( tnstream& stream )
00772 {
00773   stream.writeInt(1);
00774   writeMapModificationData( stream );
00775   stream.writeInt( player );
00776 }
00777 
00778 ASCString AnyUnitEntersPolygon::getTypeName() const
00779 {
00780    return "Any unit entered polygon";
00781 }
00782 
00783 ASCString AnyUnitEntersPolygon::getDetailledName() const
00784 {
00785    ASCString s = "any unit ";
00786    if ( player ) {
00787       s += "from ";
00788       for ( int i = 0; i < 8; ++i )
00789          if ( player & ( 1 << i)) {
00790             s += gamemap->player[i].getName();
00791             s += " ";
00792          }
00793    }
00794    s += " enters polygon";
00795    return s;
00796 }
00797 
00798 void AnyUnitEntersPolygon::setup()
00799 {
00800    FieldAddressing::setup();
00801    playerselall( &player );
00802 }
00803 
00804 void AnyUnitEntersPolygon::arm()
00805 {
00806    #ifdef sgmain
00807    arming = true;
00808    operate();
00809    arming = false;
00810    fieldCrossed.connect( SigC::slot( *this, &AnyUnitEntersPolygon::triggered));
00811    #endif
00812 }
00813 
00814 void AnyUnitEntersPolygon::triggered()
00815 {
00816    if ( isFulfilled() )
00817       eventReady();
00818 }
00819 
00820 
00821 EventTrigger::State ResourceTribute::getState( int player )
00822 {
00823     if ( payingPlayer < 0 || gamemap->tribute.avail[payingPlayer][player] + gamemap->tribute.paid[player][payingPlayer] < demand )
00824        return unfulfilled;
00825     else
00826        return finally_fulfilled;
00827 }
00828 
00829 void ResourceTribute::readData ( tnstream& stream )
00830 {
00831    versionTest(stream,1,1);
00832    payingPlayer = stream.readInt();
00833    demand.read ( stream );
00834 }
00835 
00836 
00837 void ResourceTribute::writeData ( tnstream& stream )
00838 {
00839    stream.writeInt( 1 );
00840    stream.writeInt( payingPlayer );
00841    demand.write ( stream );
00842 }
00843 
00844 
00845 ASCString ResourceTribute::getTypeName() const
00846 {
00847    return "Resource tribute";
00848 }
00849 
00850 ASCString ResourceTribute::getDetailledName() const
00851 {
00852    if ( payingPlayer >= 0 ) {
00853       ASCString s;
00854       s.format ( "Resource tribute: %d E ; %d M ; %d F", demand.energy, demand.material, demand.fuel );
00855       return s;
00856    } else
00857       return getTypeName();
00858 }
00859 
00860 void ResourceTribute::setup()
00861 {
00862    payingPlayer = editInt( "Paying Player", payingPlayer );
00863    demand.energy = editInt( "energy", demand.energy );
00864    demand.material = editInt( "material", demand.material );
00865    demand.fuel = editInt( "fuel", demand.fuel );
00866 }
00867 
00868 void ResourceTribute::arm()
00869 {
00870   #ifdef sgmain
00871    tributeTransferred.connect( SigC::slot( *this, &ResourceTribute::triggered));
00872   #endif 
00873 }
00874 
00875 void ResourceTribute::triggered()
00876 {
00877    if ( isFulfilled() )
00878       eventReady();
00879 }
00880 
00882 // Actions
00883 
00884 
00885 void Action_Nothing::readData( tnstream& stream )
00886 {
00887    stream.readInt();
00888 }
00889 
00890 void Action_Nothing::writeData( tnstream& stream )
00891 {
00892    stream.writeInt(1);
00893 }
00894 
00895 
00896 void WindChange::execute( MapDisplayInterface* md )
00897 {
00898    if ( speed != -1 )
00899       gamemap->weather.windSpeed = speed;
00900 
00901    if ( direction != -1 )
00902       gamemap->weather.windDirection = direction;
00903 
00904    if ( md )
00905       md->updateDashboard();
00906 }
00907 
00908 void WindChange::readData( tnstream& stream )
00909 {
00910    versionTest(stream,1,1);
00911    speed = stream.readInt();
00912    direction = stream.readInt();
00913 }
00914 
00915 void WindChange::writeData( tnstream& stream )
00916 {
00917    stream.writeInt(1);
00918    stream.writeInt( speed );
00919    stream.writeInt( direction );
00920 }
00921 
00922 void WindChange::setup()
00923 {
00924    speed     = editInt("Wind Speed", speed, 0, 255);
00925    direction = editInt("Wind Direction", direction, 0, 5);
00926 }
00927 
00928 
00929 
00930 void ChangeGameParameter::execute( MapDisplayInterface* md )
00931 {
00932    if ( parameterNum >= 0 )
00933       if ( gameParameterSettings[parameterNum ].changeableByEvent )
00934          gamemap->setgameparameter( GameParameter(parameterNum) , parameterValue );
00935 }
00936 
00937 void ChangeGameParameter::readData( tnstream& stream )
00938 {
00939    versionTest(stream,1,1);
00940    parameterNum = stream.readInt();
00941    parameterValue = stream.readInt();
00942 }
00943 
00944 void ChangeGameParameter::writeData( tnstream& stream )
00945 {
00946    stream.writeInt(1);
00947    stream.writeInt( parameterNum );
00948    stream.writeInt( parameterValue );
00949 }
00950 
00951 int ChangeGameParameter::selectgameparameter( int para )
00952 {
00953    vector<ASCString> list;
00954    for ( int i = 0; i < gameparameternum; ++i )
00955       list.push_back ( gameParameterSettings[i].name );
00956    return chooseString("Select GameParameter", list, para );
00957 }
00958 
00959 void ChangeGameParameter::setup()
00960 {
00961     int nr = selectgameparameter( parameterNum );
00962     if ( (nr >= 0) && ( nr < gameparameternum) ) {
00963        if ( gameParameterSettings[nr].changeableByEvent ) {
00964           int org = parameterValue;
00965           if ( org < gameParameterSettings[nr].minValue && org > gameParameterSettings[nr].maxValue )
00966              org = gameParameterSettings[nr].defaultValue;
00967           parameterValue = getid("Parameter Val", org, gameParameterSettings[nr].minValue, gameParameterSettings[nr].maxValue);
00968           parameterNum = nr;
00969        } else
00970           displaymessage("This parameter cannot be changed by events",1);
00971     }
00972     
00973 }
00974 
00975 
00976 
00977 void DisplayMessage::execute( MapDisplayInterface* md )
00978 {
00979    if ( gamemap->state == GameMap::Replay )
00980       return;
00981 
00982    viewtextmessage ( messageNum , gamemap->actplayer );
00983 }
00984 
00985 void DisplayMessage::readData( tnstream& stream )
00986 {
00987    versionTest(stream,1,1);
00988    messageNum = stream.readInt();
00989 }
00990 
00991 void DisplayMessage::writeData( tnstream& stream )
00992 {
00993    stream.writeInt(1);
00994    stream.writeInt( messageNum );
00995 }
00996 
00997 void DisplayMessage::setup()
00998 {
00999   messageNum = editInt ( "Message ID", messageNum );
01000 }
01001 
01002 
01003 
01004 
01005 void FieldAddressing::setpointabs ( int x,  int y  )
01006 {
01007    fieldOperator ( MapCoordinate(x,y) );
01008 }
01009 
01010 void FieldAddressing::operate (  )
01011 {
01012    if ( addressingMode == singleField ) {
01013       for ( Fields::iterator i = fields.begin(); i != fields.end(); ++i )
01014          fieldOperator ( *i );
01015    }
01016    if ( addressingMode == poly ) {
01017       for ( Polygons::iterator i = polygons.begin(); i != polygons.end(); ++i )
01018          paintPolygon ( *i );
01019    }
01020    if ( addressingMode == global ) {
01021       for ( int y = 0; y < gameMap->ysize; ++y )
01022          for ( int x = 0; x < gameMap->xsize; ++x )
01023              fieldOperator ( MapCoordinate ( x, y ));
01024    }
01025 }
01026 
01027 void FieldAddressing::setField ( const MapCoordinate& pos )
01028 {
01029    addressingMode = singleField;
01030    fields.clear();
01031    fields.push_back ( pos );
01032 }
01033 
01034 void FieldAddressing::setPolygon ( const Poly_gon& poly_gon )
01035 {
01036    addressingMode = poly;
01037    polygons.clear();
01038    polygons.push_back ( poly_gon );
01039 }
01040 
01041 void FieldAddressing::setGlobal()
01042 {
01043    addressingMode = global;
01044 }
01045 
01046 
01047 
01048 void FieldAddressing::readMapModificationData ( tnstream& stream )
01049 {
01050    versionTest(stream,1000,1000);
01051    addressingMode = AddressingMode ( stream.readInt() );
01052    if ( addressingMode == singleField )
01053       readClassContainer( fields, stream );
01054 
01055    if ( addressingMode == poly )
01056       readClassContainer( polygons, stream );
01057 }
01058 
01059 
01060 void FieldAddressing::setup ()
01061 {
01062    vector<ASCString> entries;
01063    entries.push_back ( "none" );
01064    entries.push_back ( "Single Fields");
01065    entries.push_back ( "Polygons" );
01066    entries.push_back ( "global");
01067 
01068    int c = chooseString ( "choose operation target", entries, addressingMode );
01069    if ( c < 0 )
01070       return;
01071 
01072    addressingMode = AddressingMode( c );
01073 
01074    if (  addressingMode == singleField )
01075       selectFields( fields );
01076    else
01077       if ( addressingMode == poly ) {
01078          if ( !polygons.size() )
01079             polygons.push_back ( Poly_gon() );
01080          editpolygon ( polygons[0] );
01081       }
01082 }
01083 
01084 
01085 void FieldAddressing::writeMapModificationData ( tnstream& stream )
01086 {
01087    stream.writeInt( 1000 );
01088    stream.writeInt ( addressingMode );
01089 
01090    if ( addressingMode == singleField )
01091       writeClassContainer ( fields, stream );
01092 
01093    if ( addressingMode == poly )
01094       writeClassContainer ( polygons, stream );
01095 }
01096 
01097 void MapModificationEvent::execute( MapDisplayInterface* md )
01098 {
01099    operate();
01100    if ( md ) {
01101       md->displayMap();
01102       md->updateDashboard();
01103    }
01104 }
01105 
01106 
01107 void WeatherChange :: readData ( tnstream& stream )
01108 {
01109    versionTest(stream,1,1);
01110    weather = stream.readInt();
01111    readMapModificationData ( stream );
01112 }
01113 
01114 
01115 void WeatherChange :: writeData ( tnstream& stream )
01116 {
01117    stream.writeInt( 1 );
01118    stream.writeInt( weather );
01119    writeMapModificationData ( stream );
01120 }
01121 
01122 void WeatherChange :: fieldOperator( const MapCoordinate& mc )
01123 {
01124    tfield* field = gamemap->getField ( mc );
01125    if ( field ) 
01126       field->setweather( weather );
01127 }
01128 
01129 void WeatherChange :: setup ()
01130 {
01131   FieldAddressing::setup();
01132   chooseWeather( weather );
01133 }
01134 
01135 
01136 void MapChange :: readData ( tnstream& stream )
01137 {
01138    versionTest(stream,1,1);
01139    terrainID = stream.readInt();
01140    readMapModificationData ( stream );
01141 }
01142 
01143 
01144 void MapChange :: writeData ( tnstream& stream )
01145 {
01146    stream.writeInt( 1 );
01147    stream.writeInt( terrainID );
01148    writeMapModificationData ( stream );
01149 }
01150 
01151 void MapChange :: fieldOperator( const MapCoordinate& mc )
01152 {
01153    TerrainType* typ = terrainTypeRepository.getObject_byID ( terrainID );
01154    if ( !typ )
01155       return;
01156 
01157    tfield* field = gamemap->getField ( mc );
01158    if ( field ) {
01159       int w = field->getweather();
01160       if (typ->weather[w] == NULL)
01161          w = 0;
01162 
01163       field->typ = typ->weather[ w ];
01164       field->setparams();
01165    }
01166 }
01167 
01168 void MapChange :: setup ()
01169 {
01170   FieldAddressing::setup();
01171   chooseTerrain( terrainID );
01172 }
01173 
01174 
01175 
01176 void AddObject :: readData ( tnstream& stream )
01177 {
01178    versionTest(stream,1,1);
01179    objectID = stream.readInt();
01180    readMapModificationData ( stream );
01181 }
01182 
01183 
01184 void AddObject :: writeData ( tnstream& stream )
01185 {
01186    stream.writeInt( 1 );
01187    stream.writeInt( objectID );
01188    writeMapModificationData ( stream );
01189 }
01190 
01191 
01192 void AddObject :: fieldOperator( const MapCoordinate& mc )
01193 {
01194    ObjectType* obj = objectTypeRepository.getObject_byID ( objectID );
01195    if ( !obj )
01196       return;
01197 
01198    tfield* field = gamemap->getField ( mc );
01199    if ( field ) {
01200       field->addobject ( obj, -1, true );
01201       field->setparams();
01202     }
01203 }
01204 
01205 void AddObject :: setup ()
01206 {
01207   FieldAddressing::setup();
01208   chooseObject( objectID );
01209 }
01210 
01211 
01212 
01213 
01214 void RemoveAllObjects :: readData ( tnstream& stream )
01215 {
01216    versionTest(stream,1,1);
01217    readMapModificationData ( stream );
01218 }
01219 
01220 
01221 void RemoveAllObjects :: writeData ( tnstream& stream )
01222 {
01223    stream.writeInt( 1 );
01224    writeMapModificationData ( stream );
01225 }
01226 
01227 
01228 void RemoveAllObjects :: fieldOperator( const MapCoordinate& mc )
01229 {
01230    tfield* field = gamemap->getField ( mc );
01231    if ( field ) {
01232       field->objects.clear();
01233       field->setparams();
01234     }
01235 }
01236 
01237 void RemoveAllObjects :: setup ()
01238 {
01239   FieldAddressing::setup();
01240 }
01241 
01242 
01243 
01244 void MapChangeCompleted :: execute( MapDisplayInterface* md )
01245 {
01246    checkobjectsforremoval();
01247    checkunitsforremoval ();
01248 
01249    if ( md ) {
01250       md->displayMap();
01251       md->updateDashboard();
01252    }
01253 
01254 }
01255 
01256 
01257 void ChangeBuildingDamage::readData ( tnstream& stream )
01258 {
01259    versionTest(stream,1,1);
01260    damage = stream.readInt();
01261    position.read ( stream );
01262 }
01263 
01264 void ChangeBuildingDamage::writeData ( tnstream& stream )
01265 {
01266    stream.writeInt( 1);
01267    stream.writeInt( damage );
01268    position.write ( stream );
01269 }
01270 
01271 void ChangeBuildingDamage::execute( MapDisplayInterface* md )
01272 {
01273    tfield* fld = gamemap->getField ( position );
01274    if ( fld && fld->building ) {
01275       if ( damage >= 100 ) {
01276          delete fld->building;
01277          fld->building = NULL;
01278 
01279          if ( md ) {
01280            md->displayMap();
01281            md->updateDashboard();
01282          }
01283       } else {
01284          fld->building->damage  = damage;
01285          if ( md )
01286            md->updateDashboard();
01287       }
01288    }
01289 }
01290 
01291 void ChangeBuildingDamage::setup()
01292 {
01293    getxy_building ( &position.x, &position.y );
01294    damage = editInt("new building damage", damage, 0, 100);
01295 }
01296 
01297 
01298 void NextMap::readData ( tnstream& stream )
01299 {
01300    versionTest(stream,1,1);
01301    mapID = stream.readInt();
01302 }
01303 
01304 void NextMap::writeData ( tnstream& stream )
01305 {
01306    stream.writeInt( 1);
01307    stream.writeInt( mapID );
01308 }
01309 
01310 void NextMap::execute( MapDisplayInterface* md )
01311 {
01312    if ( gamemap->state == GameMap::Replay )
01313       return;
01314 
01315    ASCString name = gamemap->preferredFileNames.mapname[0];
01316    if ( name.find('.') != ASCString::npos )
01317       name.erase( name.find('.') );
01318 
01319    
01320    savegame( "map-" + name + "-completed" + (savegameextension + 1) );
01321    throw  LoadNextMap(mapID);
01322 }
01323 
01324 void NextMap::setup()
01325 {
01326    mapID = editInt("ID of next map", mapID, 0, maxint);
01327 }
01328 
01329 
01330 
01331 void LoseMap::execute( MapDisplayInterface* md )
01332 {
01333    if ( gamemap->state == GameMap::Replay )
01334       return;
01335 
01336    if ( !gamemap->continueplaying ) {
01337       displaymessage ( "You have been defeated !", 3 );
01338       delete gamemap;
01339       gamemap = NULL;
01340       throw NoMapLoaded();
01341    }
01342 }
01343 
01344 
01345 void DisplayEllipse::readData ( tnstream& stream )
01346 {
01347    versionTest(stream,1,1);
01348    x1 = stream.readInt();
01349    x2 = stream.readInt();
01350    y1 = stream.readInt();
01351    y2 = stream.readInt();
01352    alignRight = stream.readInt();
01353    alignBottom = stream.readInt();
01354 }
01355 
01356 void DisplayEllipse::writeData ( tnstream& stream )
01357 {
01358    stream.writeInt( 1 );
01359    stream.writeInt( x1 );
01360    stream.writeInt( x2 );
01361    stream.writeInt( y1 );
01362    stream.writeInt( y2 );
01363    stream.writeInt( alignRight );
01364    stream.writeInt( alignBottom );
01365 }
01366 
01367 void DisplayEllipse::execute( MapDisplayInterface* md )
01368 {
01369    warning("Ellipses are not supported any more!");
01370    /*
01371    if ( !gamemap->ellipse )
01372       gamemap->ellipse = new EllipseOnScreen;
01373 
01374    if ( alignRight ) {     // x orientation
01375       gamemap->ellipse->x1 = agmp->resolutionx - ( 640 - x1 );
01376       gamemap->ellipse->x2 = agmp->resolutionx - ( 640 - x2 );
01377    } else {
01378       gamemap->ellipse->x1 = x1;
01379       gamemap->ellipse->x2 = x2;
01380    }
01381 
01382    if ( alignBottom ) {     // y orientation
01383       gamemap->ellipse->y1 = agmp->resolutiony - ( 480 - y1 );
01384       gamemap->ellipse->y2 = agmp->resolutiony - ( 480 - y2 );
01385    } else {
01386       gamemap->ellipse->y1 = y1;
01387       gamemap->ellipse->y2 = y2;
01388    }
01389 
01390    gamemap->ellipse->color = white;
01391    gamemap->ellipse->precision = 0.15;
01392    gamemap->ellipse->active = 1;
01393 
01394    if ( md )
01395       md->updateDashboard();
01396 
01397    */
01398 }
01399 
01400 void DisplayEllipse::setup()
01401 {
01402    x1 = getid("x1",x1,0,639);
01403    y1 = getid("y1",y1,0,479);
01404    x2 = getid("x2",x2,0,639);
01405    y2 = getid("y2",y2,0,479);
01406    alignRight = choice_dlg("x orientation","~l~eft","~r~ight") - 1;
01407    alignBottom = choice_dlg("y orientation","~t~op","~b~ottom") - 1;
01408 }
01409 
01410 
01411 void RemoveEllipse::execute( MapDisplayInterface* md )
01412 {
01413    /*
01414    if ( gamemap->ellipse ) {
01415       gamemap->ellipse->active = 0;
01416       if ( md )
01417          md->repaintDisplay();
01418    }
01419    */
01420 }
01421 
01422 
01423 
01424 
01425 void ChangeBuildingOwner :: readData ( tnstream& stream )
01426 {
01427    versionTest(stream,1,1);
01428    pos.read( stream );
01429    newOwner = stream.readInt();
01430 }
01431 
01432 
01433 void ChangeBuildingOwner :: writeData ( tnstream& stream )
01434 {
01435    stream.writeInt( 1 );
01436    pos.write( stream );
01437    stream.writeInt ( newOwner );
01438 }
01439 
01440 
01441 void ChangeBuildingOwner :: setup ()
01442 {
01443    getxy_building( &pos.x, &pos.y );
01444    newOwner = getid("new owner",newOwner,0,8);
01445 }
01446 
01447 void ChangeBuildingOwner :: execute( MapDisplayInterface* md )
01448 {
01449    tfield* fld = gamemap->getField ( pos );
01450    if ( fld && fld->building ) {
01451       fld->building->convert ( newOwner );
01452       #ifdef sgmain
01453       evaluateviewcalculation ( gamemap );
01454       #endif
01455       if ( md ) {
01456          md->displayMap();
01457          md->updateDashboard();
01458       }
01459    }
01460 }
01461 
01462 
01463 void DisplayImmediateMessage::execute( MapDisplayInterface* md )
01464 {
01465    if ( gamemap->state == GameMap::Replay )
01466       return;
01467 
01468    if ( !message.empty() ) {
01469       if ( recipients == 0 )
01470          new Message ( message, gamemap, 1 << gamemap->actplayer, 0 );
01471       else
01472          new Message ( message, gamemap, recipients, 0 );
01473 
01474       #ifdef sgmain
01475       viewunreadmessages ( gamemap->player[ gamemap->actplayer ] );
01476       #endif
01477    }
01478 }
01479 
01480 void DisplayImmediateMessage::readData( tnstream& stream )
01481 {
01482    int version = versionTest(stream,1,2);
01483    message = stream.readString(true);
01484    if ( version >= 2 )
01485       recipients = stream.readInt();
01486    else
01487       recipients = 0;
01488 }
01489 
01490 void DisplayImmediateMessage::writeData( tnstream& stream )
01491 {
01492    stream.writeInt(2);
01493    stream.writeString( message );
01494    stream.writeInt( recipients );
01495 }
01496 
01497 void DisplayImmediateMessage::setup()
01498 {
01499 
01500    vector<ASCString> player;
01501    for ( int p = 0; p < gamemap->getPlayerCount(); ++p )
01502       player.push_back( gamemap->getPlayer(p).getName() );
01503 
01504    BitMapEditor bme (recipients, "Select recieving players", player );
01505    bme.Show();
01506    bme.RunModal();
01507 
01508 
01509    while ( message.find ( "#CRT#" ) != ASCString::npos )
01510       message.replace ( message.find ( "#CRT#" ), 5, "\n" );
01511    while ( message.find ( "#crt#" ) != ASCString::npos )
01512       message.replace ( message.find ( "#crt#" ), 5, "\n" );
01513    MultiLineEditor( "Message", message );
01514 }
01515 
01516 
01517 
01518 
01519 void AddProductionCapability :: readData ( tnstream& stream )
01520 {
01521    versionTest(stream,1,1);
01522    pos.read( stream );
01523    vehicleTypeID = stream.readInt();
01524 }
01525 
01526 
01527 void AddProductionCapability :: writeData ( tnstream& stream )
01528 {
01529    stream.writeInt( 1 );
01530    pos.write( stream );
01531    stream.writeInt ( vehicleTypeID );
01532 }
01533 
01534 
01535 void AddProductionCapability :: setup ()
01536 {
01537    getxy_building( &pos.x, &pos.y );
01538    chooseVehicleType( vehicleTypeID );
01539 }
01540