123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- #include "Aufzeichnung.h"
- #include <MausEreignis.h>
- #include <TastaturEreignis.h>
- // Inhalt der Aufzeichnung Klasse auf Aufzeichnung.h
- // Konstruktor
- Aufzeichnung::Aufzeichnung()
- : ReferenceCounter()
- {
- nMsg = 0;
- nMsgVorwärts = 0;
- nachrichten = 0;
- bestenliste = 0;
- chat = 0;
- steuerung = 0;
- kam = 0;
- map = 0;
- ende = 0;
- spieler = new RCArray< VideoSpieler >();
- spielZeit = 0;
- rSpielZeit = new Array< double >();
- spielPause = 1;
- spielerAnzahl = 0;
- teamAnzahl = 0;
- kamSpielerNummer = -1;
- mx = -1;
- my = -1;
- geladen = 0;
- pauseZeit = -1;
- time = 0;
- }
- // Destruktor
- Aufzeichnung::~Aufzeichnung()
- {
- spieler->release();
- if( ende )
- ende->release();
- if( map )
- map->release();
- if( kam )
- kam->release();
- if( steuerung )
- steuerung->release();
- if( chat )
- chat->release();
- if( bestenliste )
- bestenliste->release();
- if( nachrichten )
- nachrichten->release();
- rSpielZeit->release();
- }
- // nicht constant
- void Aufzeichnung::setUIFactory( UIInit &factory )
- {
- uiFactory = factory;
- }
- bool Aufzeichnung::ladeSpiel( int id )
- {
- nachrichten = new SpielNachricht( id );
- bestenliste = new VideoBestenliste( uiFactory );
- chat = new VideoChat( uiFactory );
- steuerung = new VideoSteuerung( uiFactory );
- kam = new VideoKamera();
- map = new VideoKarte();
- ende = new VideoEnde( uiFactory );
- Text f;
- if( nachrichten->hatFehler( &f ) )
- {
- ende->setText( f );
- ende->setSichtbar( 1 );
- geladen = 1;
- return 1;
- }
- spielerAnzahl = nachrichten->getSVD()->spielerAnzahl;
- teamAnzahl = 0;
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- SpielerVideoDaten *dat = nachrichten->getSPVD( i );
- if( !i )
- kam->setSize( dat->kamBreite, dat->kamHöhe );
- VideoSpieler *tmp = new VideoSpieler( dat );
- bestenliste->addSpieler( tmp );
- spieler->set( tmp, i );
- teamAnzahl = teamAnzahl < dat->team ? dat->team : teamAnzahl;
- }
- teamAnzahl++;
- bestenliste->setTeamAnzahl( teamAnzahl );
- for( int i = 0; i < nachrichten->getTeamAnzahl(); i++ )
- {
- TeamVideoDaten *dat = nachrichten->getTVD( i );
- bestenliste->setTeamMaxPunkte( dat->teamNummer, dat->maxPunkte );
- bestenliste->setTeamPunkte( dat->teamNummer, dat->punkte );
- }
- RundeVideoDaten *rDat = nachrichten->getRVD();
- map->setSize( rDat->mapBreite, rDat->mapHöhe );
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- RundeSpielerVideoDaten *dat = nachrichten->getRSVD( i );
- spieler->z( i )->neuRunde( 1, dat, 1 );
- bestenliste->updateSpielerStatus( spieler->z( i ) );
- }
- pauseZeit = 3;
- ende->setText( "Die Aufzeichnung des Spiels wird geladen.\nRunde 1 beginnt in kürze." );
- ende->setSichtbar( 1 );
- geladen = 1;
- return 1;
- }
- void Aufzeichnung::doPublicMausEreignis( MausEreignis &me )
- {
- if( !geladen )
- return;
- if( kam->istMausIn( me.mx, me.my ) )
- {
- if( me.id == ME_PLinks )
- {
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->istMausIn( kam->getLinks() + me.mx - kam->getRX( kam->getLinks() ), kam->getOben() + me.my - kam->getRY( kam->getOben() ) ) )
- {
- kamSpielerNummer = spieler->z( i )->getSpielerNummer();
- me.verarbeitet = 1;
- break;
- }
- }
- }
- if( ( me.id == ME_RLinks || me.id == ME_RRechts ) && mx >= 0 )
- {
- mx = -1;
- my = -1;
- }
- if( me.id == ME_Bewegung && mx >= 0 )
- {
- kam->addPosition( mx - me.mx, my - me.my, map );
- mx = me.mx;
- my = me.my;
- }
- if( ( me.id == ME_PLinks || me.id == ME_PRechts ) && mx < 0 && !me.verarbeitet )
- {
- mx = me.mx;
- my = me.my;
- kamSpielerNummer = -1;
- }
- me.verarbeitet = 1;
- }
- else
- {
- mx = -1;
- my = -1;
- }
- bestenliste->doPublicMausEreignis( me );
- steuerung->doPublicMausEreignis( me );
- }
- void Aufzeichnung::doTastaturEreignis( TastaturEreignis &te )
- {
- if( !geladen )
- return;
- if( te.id == TE_Press )
- {
- switch( te.taste )
- {
- case T_Links:
- kam->addPosition( -2, 0, map );
- te.verarbeitet = 1;
- break;
- case T_Oben:
- kam->addPosition( 0, -2, map );
- te.verarbeitet = 1;
- break;
- case T_Rechts:
- kam->addPosition( 2, 0, map );
- te.verarbeitet = 1;
- break;
- case T_Unten:
- kam->addPosition( 0, 2, map );
- te.verarbeitet = 1;
- break;
- }
- if( te.verarbeitet )
- kamSpielerNummer = -1;
- }
- }
- bool Aufzeichnung::spielTick( double spielZeit )
- {
- this->spielZeit += spielZeit;
- bool setKam = kamSpielerNummer >= 0;
- int x = 0;
- int y = 0;
- bool rEnd = 0;
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- VideoSpieler *tmp = spieler->z( i );
- if( tmp )
- {
- if( tmp->getSpielerNummer() == kamSpielerNummer )
- {
- x = (int)( tmp->getX() + 0.5 );
- y = (int)( tmp->getY() + 0.5 );
- }
- bool amLeben = tmp->istAmLeben();
- tmp->tick( map->zMap(), spielZeit );
- if( amLeben != tmp->istAmLeben() )
- {
- bestenliste->updateSpielerStatus( tmp );
- for( int j = 0; j < spielerAnzahl; j++ )
- {
- VideoSpieler *s = spieler->z( j );
- if( s && s != tmp && s->istAmLeben() )
- bestenliste->addPunkt( s->getTeam(), s->getSpielerNummer(), spielZeit > 0 );
- }
- }
- if( amLeben && !tmp->istAmLeben() )
- { // gestorben
- int team = tmp->getTeam();
- bool teamLebt = 0;
- for( int k = 0; k < spielerAnzahl; k++ )
- {
- if( spieler->z( k ) && spieler->z( k )->getTeam() == team )
- teamLebt |= spieler->z( k )->istAmLeben();
- }
- if( !teamLebt )
- {
- int teamAmLebenAnzahl = 0;
- for( int k = 0; k < teamAnzahl; k++ )
- {
- if( !bestenliste->teamExistiert( k ) )
- continue;
- bool amLeben = 0;
- for( int l = 0; l < spielerAnzahl; l++ )
- {
- if( spieler->z( l ) && spieler->z( l )->getTeam() == k )
- amLeben |= spieler->z( l )->istAmLeben();
- }
- if( amLeben )
- {
- teamAmLebenAnzahl++;
- bestenliste->addPunkt( k, 1 );
- }
- else
- bestenliste->addPunkt( k, 0 );
- if( !bestenliste->getTeamPunkte( k ) )
- bestenliste->setTeamStatus( k, "tod", 0xFFFF0000 );
- }
- if( teamAmLebenAnzahl <= 1 )
- rEnd = 1;
- }
- }
- if( !amLeben && tmp->istAmLeben() )
- { // Wiederbelebt
- int team = tmp->getTeam();
- bool teamLebt = 0;
- for( int k = 0; k < spielerAnzahl; k++ )
- {
- if( k != i && spieler->z( k ) && spieler->z( k )->getTeam() == team )
- teamLebt |= spieler->z( k )->istAmLeben();
- }
- if( !teamLebt )
- {
- for( int k = 0; k < teamAnzahl; k++ )
- {
- if( !bestenliste->teamExistiert( k ) )
- continue;
- bool amLeben = 0;
- for( int l = 0; l < spielerAnzahl; l++ )
- {
- if( l != i && spieler->z( l ) && spieler->z( l )->getTeam() == k )
- amLeben |= spieler->z( l )->istAmLeben();
- }
- if( amLeben )
- bestenliste->addPunkt( k, 0 );
- else
- bestenliste->addPunkt( k, 1 );
- if( bestenliste->getTeamPunkte( k ) )
- bestenliste->setTeamStatus( k, "lebt", 0xFF00FF00 );
- }
- }
- }
- }
- }
- if( setKam )
- {
- double z = spielZeit < 0 ? -spielZeit : spielZeit;
- double px = ( ( x - kam->getX() ) / 100.0 ) * ( 50 * z );
- double py = ( ( y - kam->getY() ) / 100.0 ) * ( 50 * z );
- kam->addPosition( (int)px, (int)py, map );
- }
- chat->tick( spielZeit );
- steuerung->tick( spielZeit );
- if( rEnd && spielZeit > 0 )
- { // Runden Ende
- int nAnz = 0;
- int nAnz2 = 0;
- for( int i = 0; i < teamAnzahl; i++ )
- {
- if( bestenliste->teamExistiert( i ) )
- {
- nAnz += bestenliste->hatTeamGewonnen( i );
- nAnz2 += bestenliste->getTeamPunkte( i ) >= 0;
- }
- }
- if( nAnz || nAnz2 <= 1 || nachrichten->getRunde() >= 9 )
- { // Spiel Ende
- steuerung->pause( 1 );
- return 1;
- }
- spielPause = 1;
- pauseZeit = 2;
- ende->setText( "Die nächste Runde beginnt in kürze." );
- ende->setSichtbar( 1 );
- int r = nachrichten->setRundenEnde( 1 );
- rSpielZeit->set( spielZeit, r - 1 );
- this->spielZeit = 0;
- time = 0;
- bestenliste->updatePunkte();
- kam->nextRunde( 1 );
- map->nextRunde( 1 );
- RundeVideoDaten *dat = nachrichten->getRVD();
- map->setSize( dat->mapBreite, dat->mapHöhe );
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- spieler->z( i )->neuRunde( 1, nachrichten->getRSVD( i ), bestenliste->getTeamPunkte( spieler->z( i )->getTeam() ) != 0 );
- bestenliste->updateSpielerStatus( spieler->z( i ) );
- }
- return 1;
- }
- return 0;
- }
- bool Aufzeichnung::tick( double tickVal )
- {
- if( !geladen )
- return 0;
- if( spielPause )
- {
- if( pauseZeit >= 0 )
- {
- pauseZeit -= tickVal;
- if( pauseZeit < 0 )
- {
- pauseZeit = 0;
- spielPause = 0;
- ende->setSichtbar( 0 );
- }
- }
- chat->tick( 0 );
- steuerung->tick( 0 );
- return 1;
- }
- if( ( steuerung->istVorwärts() || nMsg && nMsgVorwärts ) && !( nMsg && !nMsgVorwärts ) )
- {
- if( steuerung->istZeitlupe() )
- time += tickVal / steuerung->getSpeed();
- else
- time += tickVal * steuerung->getSpeed();
- while( steuerung->getSpeed() != 0 )
- {
- while( !nMsg || nMsg->typ && steuerung->getSpeed() != 0 )
- {
- if( !nMsg )
- nMsg = nachrichten->GetNextNachricht();
- if( !nMsg )
- break;
- nMsgVorwärts = 1;
- if( !nMsg->typ )
- break;
- VideoAktionMSG *ak = (VideoAktionMSG *)nMsg;
- switch( ak->aktion )
- {
- case 0: // T_Links Press
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setLinksKurve( 1 );
- break;
- }
- }
- break;
- case 1: // T_Links Release
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setLinksKurve( 0 );
- break;
- }
- }
- break;
- case 2: // T_Rechts Press
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setRechtsKurve( 1 );
- break;
- }
- }
- break;
- case 3: // T_Rechts Release
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setRechtsKurve( 0 );
- break;
- }
- }
- break;
- case 4: // Chat Nachricht
- if( 1 )
- {
- VideoChatMSG *msg = (VideoChatMSG *)ak;
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- Text txt = spieler->z( i )->zName()->getText();
- txt += ": ";
- txt += msg->msg.getText();
- chat->addNachricht( txt );
- break;
- }
- }
- }
- break;
- case 5: // Linien Unterbrechung
- if( 1 )
- {
- VideoLinieMSG *lMsg = (VideoLinieMSG *)ak;
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setLinienUnterbrechung( lMsg->unterbrechung != 0 );
- break;
- }
- }
- }
- break;
- }
- nMsg = 0;
- }
- if( !nMsg )
- break;
- if( time > spielZeit + TICK )
- {
- bool end = spielTick( TICK );
- nMsg = 0;
- if( !steuerung->istVorwärts() || end )
- break;
- }
- else
- break;
- }
- }
- else
- {
- if( steuerung->istZeitlupe() )
- time -= tickVal / steuerung->getSpeed();
- else
- time -= tickVal * steuerung->getSpeed();
- while( 1 )
- {
- while( !nMsg || nMsg->typ )
- {
- if( !nMsg )
- {
- nMsg = nachrichten->GetLastNachricht();
- nMsgVorwärts = 0;
- if( !nMsg )
- {
- int r = nachrichten->setRundenEnde( 0 );
- if( r < 0 )
- { // Spiel Beginn
- steuerung->pause( 0 );
- return 1;
- }
- bestenliste->updatePunkte( 0 );
- kam->nextRunde( 0 );
- map->nextRunde( 0 );
- for( int i = 0; i < spielerAnzahl; i++ )
- spieler->z( i )->neuRunde( 0, 0, 1 );
- spielPause = 1;
- pauseZeit = 2;
- ende->setText( "Vorherige Runde beginnt in kürze." );
- ende->setSichtbar( 1 );
- spielZeit = rSpielZeit->get( r );
- time = spielZeit;
- return 1;
- }
- }
- if( !nMsg->typ )
- break;
- VideoAktionMSG *ak = (VideoAktionMSG *)nMsg;
- switch( ak->aktion )
- {
- case 0: // T_Links Press
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setLinksKurve( 0 );
- break;
- }
- }
- break;
- case 1: // T_Links Release
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setLinksKurve( 1 );
- break;
- }
- }
- break;
- case 2: // T_Rechts Press
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setRechtsKurve( 0 );
- break;
- }
- }
- break;
- case 3: // T_Rechts Release
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setRechtsKurve( 1 );
- break;
- }
- }
- break;
- case 4: // Chat Nachricht
- if( 1 )
- {
- VideoChatMSG *msg = (VideoChatMSG *)ak;
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- Text txt = spieler->z( i )->zName()->getText();
- txt += ": ";
- txt += msg->msg.getText();
- chat->removeNachricht( txt );
- break;
- }
- }
- }
- break;
- case 5: // Linien Unterbrechung
- if( 1 )
- {
- VideoLinieMSG *lMsg = (VideoLinieMSG *)ak;
- if( 1 )
- {
- for( int i = 0; i < spielerAnzahl; i++ )
- {
- if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
- {
- spieler->z( i )->setLinienUnterbrechung( lMsg->unterbrechung == 0 );
- break;
- }
- }
- }
- }
- break;
- }
- nMsg = 0;
- }
- if( time <= spielZeit - TICK )
- {
- spielTick( -TICK );
- nMsg = 0;
- if( steuerung->istVorwärts() )
- break;
- }
- else
- break;
- }
- }
- return 1;
- }
- void Aufzeichnung::render( Bild &zRObj )
- {
- if( !geladen )
- return;
- bestenliste->render( zRObj );
- chat->render( zRObj );
- steuerung->render( zRObj );
- kam->render( zRObj );
- int x = kam->getRX( kam->getLinks() ) + 1, y = kam->getRY( kam->getOben() ) + 1;
- if( zRObj.setDrawOptions( x, y, kam->getRechts() - kam->getLinks() - 2, kam->getUnten() - kam->getOben() - 2 ) )
- {
- zRObj.addScrollOffset( x, y );
- map->render( kam, zRObj );
- for( int i = 0; i < spielerAnzahl; i++ )
- spieler->z( i )->render( kam, zRObj );
- zRObj.releaseDrawOptions();
- }
- if( ende )
- ende->render( zRObj );
- }
- // constant
- bool Aufzeichnung::hatVerlassen( bool jetzt ) const
- {
- if( !geladen )
- return 0;
- return steuerung->istBeendet( jetzt );
- }
|