00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
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
01415
01416
01417
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