#include "Spiel.h" #include "DrachenAuge.h" #include "Brand.h" #define TICK 0.03333333 // Konstruktor Spiel::Spiel() : ReferenceCounter() { zKlients = 0; psqldb = 0; nextId = 0; isRunning = 0; log = 0; spielerAnzahl = 0; zAccounts = 0; spielId = 0; karteId = 0; pause = 0; gameTicks = 0; ende = 1; stat = new Statistik(); zWinner = 0; lastRunnedTrigger = 0; zuletztEingeschalteteBariere = 0; zuletztAusgeschalteteBariere = 0; zuletztBewegteBariere = 0; lastTeamChangedBase = 0; lastDropedDrop = 0; zuletztAufgehobenerGegenstand = KEIN_GEGENSTAND; zuletztBenutzterGegenstand = KEIN_GEGENSTAND; zuletztGedropterGegenstand = KEIN_GEGENSTAND; zuletztAbgefeuertesGeschoss = 0; zuletztUmgelenktesGeschoss = 0; zuletztBariereGetroffenesGeschoss = 0; zuletztTunnelBenutztesGeschoss = 0; zuletztGeschossGetroffenesGeschoss = 0; zuletztAktivierterSchalter = 0; zuletztSchadenGemachterSpieler = 0; zuletztSchadenGenommenerSpieler = 0; zuletztGeheilterSpieler = 0; zuletztLevelUpSpieler = 0; zuletztErfahrungBekommenerSpieler = 0; zuletztGegenstandAktivierterSpieler = 0; zuletztGegenstandAufgehobenerSpieler = 0; zuletztSchalterAktivierterSpieler = 0; zuletztTunnelBenutzterSpieler = 0; zuletztGestorbenerSpieler = 0; zuletztWiederbelebterSpieler = 0; zuletztGeschossenerSpieler = 0; zuletztAbgelaufenerTimer = 0; zuletztGestarteterTimer = 0; zuletztPausierterTimer = 0; zuletztFortgesetzterTimer = 0; zuletztBenutzterTunnel = 0; zuletztBenutzteUmlenkung = 0; nextAutoVerschiebung = 10; nextAutoSchaltung = 10; } // Destruktor Spiel::~Spiel() { stat->release(); if( psqldb ) psqldb->release(); if( lastRunnedTrigger ) lastRunnedTrigger->release(); if( zuletztEingeschalteteBariere ) zuletztEingeschalteteBariere->release(); if( zuletztAusgeschalteteBariere ) zuletztAusgeschalteteBariere->release(); if( zuletztBewegteBariere ) zuletztBewegteBariere->release(); if( lastTeamChangedBase ) lastTeamChangedBase->release(); if( lastDropedDrop ) lastDropedDrop->release(); if( zuletztAbgefeuertesGeschoss ) zuletztAbgefeuertesGeschoss->release(); if( zuletztUmgelenktesGeschoss ) zuletztUmgelenktesGeschoss->release(); if( zuletztBariereGetroffenesGeschoss ) zuletztBariereGetroffenesGeschoss->release(); if( zuletztTunnelBenutztesGeschoss ) zuletztTunnelBenutztesGeschoss->release(); if( zuletztGeschossGetroffenesGeschoss ) zuletztGeschossGetroffenesGeschoss->release(); if( zuletztAktivierterSchalter ) zuletztAktivierterSchalter->release(); if( zuletztSchadenGemachterSpieler ) zuletztSchadenGemachterSpieler->release(); if( zuletztSchadenGenommenerSpieler ) zuletztSchadenGenommenerSpieler->release(); if( zuletztGeheilterSpieler ) zuletztGeheilterSpieler->release(); if( zuletztLevelUpSpieler ) zuletztLevelUpSpieler->release(); if( zuletztErfahrungBekommenerSpieler ) zuletztErfahrungBekommenerSpieler->release(); if( zuletztGegenstandAktivierterSpieler ) zuletztGegenstandAktivierterSpieler->release(); if( zuletztGegenstandAufgehobenerSpieler ) zuletztGegenstandAufgehobenerSpieler->release(); if( zuletztSchalterAktivierterSpieler ) zuletztSchalterAktivierterSpieler->release(); if( zuletztTunnelBenutzterSpieler ) zuletztTunnelBenutzterSpieler->release(); if( zuletztGestorbenerSpieler ) zuletztGestorbenerSpieler->release(); if( zuletztWiederbelebterSpieler ) zuletztWiederbelebterSpieler->release(); if( zuletztGeschossenerSpieler ) zuletztGeschossenerSpieler->release(); if( zuletztAbgelaufenerTimer ) zuletztAbgelaufenerTimer->release(); if( zuletztGestarteterTimer ) zuletztGestarteterTimer->release(); if( zuletztPausierterTimer ) zuletztPausierterTimer->release(); if( zuletztFortgesetzterTimer ) zuletztFortgesetzterTimer->release(); if( zuletztBenutzterTunnel ) zuletztBenutzterTunnel->release(); if( zuletztBenutzteUmlenkung ) zuletztBenutzteUmlenkung->release(); if( zKlients ) zKlients->release(); if( zAccounts ) zAccounts->release(); } // nicht constant void Spiel::setPSQLK( SSDatenbankV* psqldb ) { if( this->psqldb ) this->psqldb->release(); this->psqldb = psqldb; stat->setPSQLDB( dynamic_cast(psqldb->getThis()) ); } // call 1 void Spiel::setSpielId( int id ) { spielId = id; stat->setSpielId( id ); } // call 2 void Spiel::setKarteId( int karteId ) { this->karteId = karteId; stat->setKarteId( karteId ); } // call 3 void Spiel::setTempPfad( char* pfad ) { mapPfad = pfad; mapPfad += "/"; } // call 3.5 void Spiel::setAccounts( int anzahl, Array< int >* zAccounts ) { if( this->zAccounts ) this->zAccounts->release(); this->zAccounts = dynamic_cast *>(zAccounts->getThis()); spielerAnzahl = anzahl; } // call 4 void Spiel::setKlients( int anzahl, RCArray< SSKlientV >* zKlients ) { if( this->zKlients ) this->zKlients->release(); this->zKlients = dynamic_cast *>(zKlients->getThis()); } // call 5 void Spiel::setSpielerNummern( int anzahl, Array< int >* spielerNummern ) { MapReader* reader = new MapReader( karteId, dynamic_cast(psqldb->getThis()), mapPfad ); reader->ladeKarte( this ); reader->release(); for( int i = 0; i < anzahl; i++ ) { for( auto s : spieler ) { if( s->getId() == spielerNummern->get( i ) ) { s->setAccount( zAccounts->get( i ) ); s->setKlient( new Klient( zKlients->get( i ) ) ); break; } } } zAccounts = (Array*)zAccounts->release(); zKlients = (RCArray*)zKlients->release(); stat->setTeams( &teams ); stat->setSpieler( &spieler ); } // call 6 void Spiel::run() { log = new Datei(); Text* pfad = new Text( "../spiel log/" ); pfad->append( spielId ); pfad->append( "/verlauf.ksggl" ); log->setDatei( pfad ); log->remove(); log->erstellen(); log->open( Datei::Style::schreiben ); time_t t; time( &t ); srand( (unsigned int)t ); log->schreibe( (char*)&spielerAnzahl, 4 ); int anz = spieler.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { Spieler* tmp = spieler.z( i ); if( tmp && tmp->zKlient() ) { tmp->zKlient()->sendeInit( &spieler, randG.getSeed() ); log->schreibe( (char*)&i, 4 ); int sNum = tmp->getId(); log->schreibe( (char*)&sNum, 4 ); tmp->zKlient()->sendeSpielerNummer( sNum ); Text* name = psqldb->getAccountRufName( tmp->getAccountId() ); char len = (char)(name ? name->getLength() : 0); log->schreibe( &len, 1 ); if( len ) log->schreibe( name->getText(), len ); if( name ) { tmp->setName( name->getText() ); name->release(); } } } __int64 randSeed = randG.getSeed(); log->schreibe( (char*)&randSeed, 8 ); Array< char > spielerStatus; ZeitMesser* zeit = new ZeitMesser(); zeit->messungStart(); isRunning = 1; ende = 0; double ausgleich = 0; double sZ = 0; gameTicks = -1; for( int i = 0; i < anz; i++ ) { Spieler* tmp = spieler.z( i ); if( tmp && tmp->zKlient() ) tmp->zKlient()->sendeStart(); } throwEvent( new Ereignis( INITIALISIERUNG ) ); double rZeit = 0; while( !ende ) { zeit->messungEnde(); zeit->messungStart(); double z = zeit->getSekunden(); ausgleich += TICK - z; if( ausgleich > 0 ) Sleep( (int)(ausgleich * 1000) ); rZeit += z; while( sZ + TICK < rZeit && !ende ) { c.lock(); sZ += TICK; gameTicks++; char ch = 0; log->schreibe( &ch, 1 ); tick( TICK ); c.unlock(); } } zeit->messungEnde(); zeit->release(); for( int i = 0; i < anz; i++ ) { if( spieler.z( i ) && spieler.z( i )->zKlient() ) { if( !zWinner ) { spielerStatus.set( 5, i ); // Datenbank Unentschieden spieler.z( i )->zKlient()->sendeSpielEnde( 2 ); } else if( zWinner != spieler.z( i )->zTeam() ) { spielerStatus.set( 1, i ); // Datenbank Verloren spieler.z( i )->zKlient()->sendeSpielEnde( 0 ); } else { spielerStatus.set( 2, i ); // Datenbank Gewonnen spieler.z( i )->zKlient()->sendeSpielEnde( 1 ); } } if( spieler.z( i ) && (!spieler.z( i )->zKlient() || !spieler.z( i )->zKlient()->istOnline()) ) spielerStatus.set( 3, i ); } psqldb->setSpielStatusBeendet( spielId, 5 ); for( int i = 0; i < anz; i++ ) { Spieler* tmp = spieler.z( i ); if( tmp ) { psqldb->setSpielSpielerStatus( spielId, tmp->getAccountId(), tmp->getPunkte(), spielerStatus.get( i ) ); psqldb->addSpielerStatistik( tmp->getAccountId(), spielId ); } } log->close(); log = (Datei*)log->release(); isRunning = 0; } // call 7 void Spiel::klientOffline( int accountId ) { for( int i = 0; i < spieler.getEintragAnzahl(); i++ ) { if( spieler.z( i )->getAccountId() == accountId ) spieler.z( i )->zKlient()->offline(); } } void Spiel::klientOnline( int accountId, SSKlientV* zKlient ) { for( int i = 0; i < spieler.getEintragAnzahl(); i++ ) { if( spieler.z( i )->getAccountId() == accountId ) { c.lock(); Spieler* s = spieler.z( i ); Klient* tmp = s->zKlient(); tmp->online( zKlient ); tmp->sendeSpielerNummer( s->getId() ); //-------------------------- c.unlock(); } } } void Spiel::nachricht( int accountId, int len, char* bytes ) { if( !isRunning ) return; c.lock(); if( ende ) { c.unlock(); return; } char* msgBeg = bytes; int msgLen = len; int msgAccount = accountId; bool saveMSG = 1; len--; switch( *bytes ) { case 0: // key press bytes++; len--; for( int i = 0; i < spieler.getEintragAnzahl(); i++ ) { Spieler* tmp = spieler.z( i ); if( tmp && tmp->getAccountId() == accountId ) { if( !tmp->setTastenStand( *bytes, 1 ) ) { saveMSG = 0; break; } Ereignis* e = new Ereignis( SPIELER_KEY_PRESSED ); e->addParameter( "Betroffene Taste", new Integer( *bytes, 1 ) ); e->addParameter( "Ausführender Spieler", dynamic_cast(tmp->getThis()) ); throwEvent( e ); for( int j = 0; j < spieler.getEintragAnzahl(); j++ ) { Spieler* s = spieler.z( j ); if( s && s->zKlient() ) s->zKlient()->sendeTastaturStatus( tmp->getId(), *bytes, 1 ); } break; } } break; case 1: // key release bytes++; len--; for( int i = 0; i < spieler.getEintragAnzahl(); i++ ) { Spieler* tmp = spieler.z( i ); if( tmp && tmp->getAccountId() == accountId ) { if( !tmp->setTastenStand( (unsigned char)*bytes, 0 ) ) { saveMSG = 0; break; } Ereignis* e = new Ereignis( SPIELER_KEY_RELEASED ); e->addParameter( "Betroffene Taste", new Integer( *bytes, 1 ) ); e->addParameter( "Ausführender Spieler", dynamic_cast(tmp->getThis()) ); throwEvent( e ); for( int j = 0; j < spieler.getEintragAnzahl(); j++ ) { Spieler* s = spieler.z( j ); if( s && s->zKlient() ) s->zKlient()->sendeTastaturStatus( tmp->getId(), *bytes, 0 ); } break; } } break; case 3: // chat Nachricht if( 1 ) { bytes++; Text* txt = psqldb->getAccountRufName( accountId ); txt->append( ": " ); txt->append( bytes, len ); for( int i = 0; i < spieler.getEintragAnzahl(); i++ ) { Spieler* tmp = spieler.z( i ); if( tmp && tmp->zKlient() ) tmp->zKlient()->sendeChatNachricht( txt->getText() ); } txt->release(); len = 0; } break; default: saveMSG = 0; } if( len ) { // error } if( log && log->istOffen() && saveMSG ) { char c = 1; log->schreibe( &c, 1 ); int spielerNum = 0; for( int i = 0; i < spieler.getEintragAnzahl(); i++ ) { Spieler* tmp = spieler.z( i ); if( tmp && tmp->getAccountId() == msgAccount ) { spielerNum = tmp->getId(); break; } } log->schreibe( (char*)&spielerNum, 4 ); short l = (short)msgLen; log->schreibe( (char*)&l, 2 ); log->schreibe( msgBeg, l ); } c.unlock(); } void Spiel::setMapSize( int width, int height ) { mapSize = Punkt( width, height ); } void Spiel::setPausiert( bool pausiert ) { this->pause = pausiert; } void Spiel::tick( double zeit ) { if( pause ) zeit = 0; nextAutoVerschiebung -= zeit; nextAutoSchaltung -= zeit; if( nextAutoVerschiebung <= 0 ) { nextAutoVerschiebung += 30 + randG.rand() * 30; int anz = 0; for( auto b : barieren ) { if( b->hatStyle( Bariere::Style::AutoVerschiebung ) ) anz++; } if( anz ) { int rand = (int)(randG.rand() * anz); for( auto b : barieren ) { if( b->hatStyle( Bariere::Style::AutoVerschiebung ) ) { if( rand == 0 ) { b->startAutoVerschiebung( this ); break; } rand--; } } } } if( nextAutoSchaltung <= 0 ) { nextAutoSchaltung += 30 + randG.rand() * 30; int anz = 0; for( auto b : barieren ) { if( b->hatStyle( Bariere::Style::AutoSchaltung ) ) anz++; } if( anz ) { int rand = (int)(randG.rand() * anz); for( auto b : barieren ) { if( b->hatStyle( Bariere::Style::AutoSchaltung ) ) { if( rand == 0 ) { b->startAutoSchaltung( this ); break; } rand--; } } } } // gegenstand despawn for( int i = 0; i < items.getEintragAnzahl(); i++ ) { if( items.z( i )->tick( zeit ) ) { items.remove( i ); i--; } } Richtung rs[] = { OBEN, RECHTS, UNTEN, LINKS }; // spieler bewegungen for( auto s : spieler ) { if( s->zKlient() ) s->zKlient()->sendeTick(); for( Richtung r : rs ) { s->move( r, zeit ); if( s->getX() < 0 || s->getY() < 0 || s->getX() + s->getWidth() >= (float)mapSize.x || s->getY() + s->getHeight() >= (float)mapSize.y ) s->move( r, -zeit ); else { for( auto b : barieren ) { // spieler - bariere intersection if( b->hatStyle( Bariere::Style::Aktiv ) && (b->zTeam() != s->zTeam()) && b->intersectsWith( s ) ) s->move( r, -zeit ); } } } } for( auto s : spieler ) s->tick( zeit, this ); // barieren bewegung for( auto b : barieren ) b->tick( zeit, this ); // geschoss bewegung for( int i = 0; i < shots.getEintragAnzahl(); i++ ) { Geschoss* g = shots.z( i ); g->tick( zeit ); bool removed = 0; // geschoss - bariere intersection bool intersectsWithBariere = 0; for( auto b : barieren ) { if( b->hatStyle( Bariere::Style::Aktiv ) && b->intersectsWith( g ) ) { intersectsWithBariere = 1; break; } } if( intersectsWithBariere || g->getX() < 0 || g->getY() < 0 || g->getX() + g->getWidth() >= (float)mapSize.x || g->getY() + g->getHeight() >= (float)mapSize.y ) { if( zuletztBariereGetroffenesGeschoss ) zuletztBariereGetroffenesGeschoss->release(); zuletztBariereGetroffenesGeschoss = dynamic_cast(g->getThis()); g->tick( -zeit ); switch( g->getTyp() ) { case GESCHOSS_PFEIL: shots.remove( i ); i--; removed = 1; break; case GESCHOSS_KUGEL: case GESCHOSS_DRACHENAUGE: g->invertDirection(); break; case GESCHOSS_FEUERBALL: if( intersectsWithBariere ) { feuer.add( new FeuerballTreffer( ++nextId, (int)g->getX() - (int)g->getWidth() / 2, (int)g->getY() - (int)g->getHeight() / 2, g->getBesitzer(), 10 ) ); shots.remove( i ); i--; removed = 1; } else g->invertDirection(); break; case GESCHOSS_MINE: for( auto s : spieler ) { if( s->abstandZu( g ) < 50 ) { s->nimmSchaden( 100 - s->abstandZu( g ), g->zBesitzer(), MITTE, this ); if( g->zBesitzer() ) g->zBesitzer()->addTreffer( this ); s->addGetroffen(); } } shots.remove( i ); i--; removed = 1; break; } } if( !removed ) { // geschoss - tunnel intersection for( auto t : tunnel ) { if( t->istAktiv() && t->intersectsWith( g ) ) { g->setX( g->getX() + (float)t->getZielX() - t->getX() ); g->setY( g->getY() + (float)t->getZielY() - t->getY() ); g->addTunnel( this ); Ereignis* e = new Ereignis( TUNNEL_BENUTZT ); e->addParameter( "Betroffes Geschoss", dynamic_cast(g->getThis()) ); e->addParameter( "Betroffer Tunnel", dynamic_cast(t->getThis()) ); throwEvent( e ); } } // geschoss - schalter intersection if( g->getTyp() == GESCHOSS_PFEIL ) { for( auto s : schalter ) { if( s->isAktive() && s->intersectsWith( g ) ) { shots.remove( i ); i--; removed = 1; g->addSchalter(); activateShalter( s->getId() ); break; } } } if( !removed ) { // geschoss - umlenkung intersection if( g->getTyp() != GESCHOSS_PFEIL ) { for( auto u : umlenkungen ) { if( u->isAktive() && !u->hatAbklingzeit() && g->getTyp() != GESCHOSS_PFEIL && u->intersectsWith( g ) ) { g->setRichtung( u->getRichtung() ); g->addUmlenkung( this ); u->addBenutzt( this ); Ereignis* e = new Ereignis( UMLENKUNG_LENKT_UM ); e->addParameter( "Betroffes Geschoss", dynamic_cast(g->getThis()) ); e->addParameter( "Betroffe Umlenkung", dynamic_cast(u->getThis()) ); throwEvent( e ); } } } // geschoss - geschoss intersection if( g->getTyp() == GESCHOSS_PFEIL ) { for( int j = 0; j < shots.getEintragAnzahl(); j++ ) { if( i == j ) continue; Geschoss* g2 = shots.z( j ); if( g2->intersectsWith( g ) ) { if( g2->getTyp() == GESCHOSS_PFEIL ) removed = 1; g->addGeschossTreffer( this ); if( j < i ) i--; shots.remove( j ); } } if( removed ) { shots.remove( i ); i--; } } if( !removed ) { // geschoss - spieler intersection for( auto s : spieler ) { if( s->istAmLeben() && g->intersectsWith( s ) ) { switch( g->getTyp() ) { case GESCHOSS_PFEIL: { s->nimmSchaden( PFEIL_DAMAGE, g->zBesitzer(), invert( g->getRichtung() ), this ); break; } case GESCHOSS_KUGEL: { s->nimmSchaden( KUGEL_DAMAGE, g->zBesitzer(), invert( g->getRichtung() ), this ); break; } case GESCHOSS_DRACHENAUGE: s->addEffekt( new DrachenAugeEffect( g->zBesitzer(), s ) ); break; case GESCHOSS_FEUERBALL: feuer.add( new FeuerballTreffer( ++nextId, (int)g->getX() - (int)g->getWidth() / 2, (int)g->getY() - (int)g->getHeight() / 2, g->getBesitzer(), 10 ) ); break; case GESCHOSS_MINE: for( auto s2 : spieler ) { if( s2->abstandZu( g ) < 50 ) { s2->nimmSchaden( 100 - s->abstandZu( g ), g->zBesitzer(), MITTE, this ); if( g->zBesitzer() ) g->zBesitzer()->addTreffer( this ); s->addGetroffen(); } } break; } if( g->getTyp() != GESCHOSS_MINE ) { if( g->zBesitzer() ) g->zBesitzer()->addTreffer( this ); s->addGetroffen(); } shots.remove( i ); i--; removed = 1; break; } } } } } } // Feuer Ticks for( int i = 0; i < feuer.getEintragAnzahl(); i++ ) { FeuerballTreffer* f = feuer.z( i ); f->tick( zeit ); if( f->isOver() ) { feuer.remove( i ); i--; continue; } if( f->makeDamage() ) { for( auto s : spieler ) { if( s->abstandZu( f ) < f->getWidth() / 2 ) s->addEffekt( new BrandEffekt( f->zVerursacher(), s ) ); } } } // Drop Ticks for( auto d : drops ) d->tick( zeit, this ); // Timer Ticks for( auto t : timer ) t->tick( zeit, this ); // Umlenkung Ticks for( auto u : umlenkungen ) u->tick( zeit ); // Base Ticks for( auto b : basen ) b->tick( zeit, this ); // aktive trigger Ticks for( int i = 0; i < triggerRuns.getEintragAnzahl(); i++ ) { if( !triggerRuns.z( i )->runNext( zeit ) ) { Ereignis* e = new Ereignis( AUSLOESER_RUNNED ); e->addParameter( "Betroffener Auslöser", triggerRuns.z( i )->getTrigger() ); throwEvent( e ); triggerRuns.remove( i ); i--; } } } void Spiel::addVariable( const char* name, Variable* var ) { bool found = 0; for( auto v : variablen ) { if( v->getName().istGleich( name ) ) { found = 1; break; } } if( !found ) variablen.add( new VarPointer( name, var ) ); else var->release(); } void Spiel::setVariable( const char* name, Variable* var ) { bool found = 0; for( auto v : variablen ) { if( v->getName().istGleich( name ) ) { v->setVariable( var ); found = 1; break; } } if( !found ) var->release(); } void Spiel::addTeam( Team* team ) { teams.add( team ); } void Spiel::addSpieler( Spieler* spieler ) { this->spieler.add( spieler ); } void Spiel::addBariere( Bariere* bariere ) { nextId = nextId > bariere->getId() ? nextId : bariere->getId() + 1; barieren.add( bariere ); } void Spiel::addBase( Base* base ) { nextId = nextId > base->getId() ? nextId : base->getId() + 1; basen.add( base ); } void Spiel::addDrop( Drop* drop ) { nextId = nextId > drop->getId() ? nextId : drop->getId() + 1; drops.add( drop ); } void Spiel::addGegenstand( Gegenstand* gegenstand ) { nextId = nextId > gegenstand->getId() ? nextId : gegenstand->getId() + 1; items.add( gegenstand ); zuletztGedropterGegenstand = gegenstand->getTyp(); Ereignis* e = new Ereignis( GEGENSTAND_DROPED ); e->addParameter( "Betroffener Gegenstand", dynamic_cast(gegenstand->getThis()) ); throwEvent( e ); } void Spiel::addGeschoss( Geschoss* geschoss ) { nextId = nextId > geschoss->getId() ? nextId : geschoss->getId() + 1; if( zuletztAbgefeuertesGeschoss ) zuletztAbgefeuertesGeschoss->release(); zuletztAbgefeuertesGeschoss = dynamic_cast(geschoss->getThis()); shots.add( geschoss ); } void Spiel::addSchalter( Schalter* schalter ) { nextId = nextId > schalter->getId() ? nextId : schalter->getId() + 1; this->schalter.add( schalter ); } void Spiel::addSchiene( Schiene* schiene ) { nextId = nextId > schiene->getId() ? nextId : schiene->getId() + 1; schienen.add( schiene ); } void Spiel::addTimer( Timer* timer ) { nextId = nextId > timer->getId() ? nextId : timer->getId() + 1; this->timer.add( timer ); } void Spiel::addTunnel( Tunnel* tunnel ) { nextId = nextId > tunnel->getId() ? nextId : tunnel->getId() + 1; this->tunnel.add( tunnel ); } void Spiel::addUmlenkung( Umlenkung* umlenkung ) { nextId = nextId > umlenkung->getId() ? nextId : umlenkung->getId() + 1; umlenkungen.add( umlenkung ); } void Spiel::addTrigger( Trigger* trigger ) { nextId = nextId > trigger->getId() ? nextId : trigger->getId() + 1; this->trigger.add( trigger ); } void Spiel::addTriggerRun( TriggerRun* tRun ) { if( tRun ) { if( lastRunnedTrigger ) lastRunnedTrigger->release(); lastRunnedTrigger = tRun->getTrigger(); triggerRuns.add( tRun ); } } void Spiel::spielerActivate( Spieler* zSpieler ) { // spieler - item intersection for( int i = 0; i < items.getEintragAnzahl(); i++ ) { if( items.z( i )->intersectsWith( zSpieler ) ) { if( zSpieler->addItem( items.z( i )->getTyp(), 1, this ) ) { items.remove( i ); i--; } } } // Spieler - schalter intersection for( int i = 0; i < schalter.getEintragAnzahl(); i++ ) { if( schalter.z( i )->intersectsWith( zSpieler ) ) { zSpieler->addSchalterBenutzung( this ); schalter.z( i )->press( this ); } } // Spieler - tunnel intersection for( int i = 0; i < tunnel.getEintragAnzahl(); i++ ) { if( tunnel.z( i )->intersectsWith( zSpieler ) ) { zSpieler->addTunnelBenutzung( this ); zSpieler->setX( (float)tunnel.z( i )->getZielX() - zSpieler->getWidth() / 2.f ); zSpieler->setY( (float)tunnel.z( i )->getZielY() - zSpieler->getHeight() / 2.f ); tunnel.z( i )->addBenutzung( this ); } } } Team* Spiel::getTeam( int id ) const { for( auto t : teams ) { if( t->getTeamNummer() == id ) return dynamic_cast(t->getThis()); } return 0; } Spieler* Spiel::getSpieler( int id ) const { for( auto s : spieler ) { if( s->getId() == id ) return dynamic_cast(s->getThis()); } return 0; } Iterator Spiel::getSpieler() const { return spieler.begin(); } Iterator Spiel::getBarieren() const { return barieren.begin(); } Bariere* Spiel::getBariere( int id ) const { for( auto b : barieren ) { if( b->getId() == id ) return dynamic_cast(b->getThis()); } return 0; } Base* Spiel::getBase( int id ) const { for( auto b : basen ) { if( b->getId() == id ) return dynamic_cast(b->getThis()); } return 0; } Drop* Spiel::getDrop( int id ) const { for( auto d : drops ) { if( d->getId() == id ) return dynamic_cast(d->getThis()); } return 0; } Schalter* Spiel::getSchalter( int id ) const { for( auto s : schalter ) { if( s->getId() == id ) return dynamic_cast(s->getThis()); } return 0; } Schiene* Spiel::getSchiene( int id ) const { for( auto s : schienen ) { if( s->getId() == id ) return dynamic_cast(s->getThis()); } return 0; } Timer* Spiel::getTimer( int id ) const { for( auto t : timer ) { if( t->getId() == id ) return dynamic_cast(t->getThis()); } return 0; } Tunnel* Spiel::getTunnel( int id ) const { for( auto t : tunnel ) { if( t->getId() == id ) return dynamic_cast(t->getThis()); } return 0; } Umlenkung* Spiel::getUmlenkung( int id ) const { for( auto u : umlenkungen ) { if( u->getId() == id ) return dynamic_cast(u->getThis()); } return 0; } Trigger* Spiel::getTrigger( int id ) const { for( auto t : trigger ) { if( t->getId() == id ) return dynamic_cast(t->getThis()); } return 0; } Variable* Spiel::getVariable( const char* name ) const { for( auto v : variablen ) { if( v->getName().istGleich( name ) ) return v->getVariable(); } return 0; } Variable* Spiel::zVariable( const char* name ) const { for( auto v : variablen ) { if( v->getName().istGleich( name ) ) return v->zVariable(); } return 0; } bool Spiel::istPausiert() const { return pause; } void Spiel::activateShalter( int id ) { for( auto s : schalter ) { if( s->getId() == id ) s->press( this ); } } void Spiel::throwEvent( Ereignis* e ) { for( auto t : trigger ) { if( t->hatEreignis( e->getTyp() ) ) { TriggerRun* tr = t->runTrigger( dynamic_cast(e->getThis()), this ); if( tr ) triggerRuns.add( tr ); } } e->release(); } bool Spiel::needEvent( EreignisTyp typ ) const { for( auto t : trigger ) { if( t->hatEreignis( typ ) ) return 1; } return 0; } int Spiel::getNextId() { return ++nextId; } double Spiel::getRand() { return randG.rand(); } int Spiel::getTickCount() const { return gameTicks; } void Spiel::setEnde( Team* zGewinner ) { zWinner = zGewinner; ende = true; } Trigger* Spiel::getRandomTrigger() { if( !trigger.getEintragAnzahl() ) return 0; return trigger.get( (int)(randG.rand() * trigger.getEintragAnzahl()) ); } Trigger* Spiel::getLastRunnedTrigger() const { return lastRunnedTrigger ? dynamic_cast(lastRunnedTrigger->getThis()) : 0; } Bariere* Spiel::getRandomBariere() { return barieren.get( (int)(randG.rand() * barieren.getEintragAnzahl()) ); } void Spiel::setZuletztEingeschalteteBariere( Bariere* b ) { if( zuletztEingeschalteteBariere ) zuletztEingeschalteteBariere->release(); zuletztEingeschalteteBariere = b; } Bariere* Spiel::getZuletztEingeschalteteBariere() const { return zuletztEingeschalteteBariere ? dynamic_cast(zuletztEingeschalteteBariere->getThis()) : 0; } void Spiel::setZuletztAusgeschalteteBariere( Bariere* b ) { if( zuletztAusgeschalteteBariere ) zuletztAusgeschalteteBariere->release(); zuletztAusgeschalteteBariere = b; } Bariere* Spiel::getZuletztAusgeschalteteBariere() const { return zuletztAusgeschalteteBariere ? dynamic_cast(zuletztAusgeschalteteBariere->getThis()) : 0; } void Spiel::setZuletztBewegteBariere( Bariere* b ) { if( zuletztBewegteBariere ) zuletztBewegteBariere->release(); zuletztBewegteBariere = b; } Bariere* Spiel::getZuletztBewegteBariere() const { return zuletztBewegteBariere ? dynamic_cast(zuletztBewegteBariere->getThis()) : 0; } Base* Spiel::getRandomBase() { if( !basen.getEintragAnzahl() ) return 0; return basen.get( (int)(randG.rand() * basen.getEintragAnzahl()) ); } void Spiel::setLastTeamChangedBase( Base* b ) { if( lastTeamChangedBase ) lastTeamChangedBase->release(); lastTeamChangedBase = b; } Base* Spiel::getLastTeamChangedBase() const { return lastTeamChangedBase ? dynamic_cast(lastTeamChangedBase->getThis()) : 0; } Drop* Spiel::getRandomDrop() { if( !drops.getEintragAnzahl() ) return 0; return drops.get( (int)(randG.rand() * drops.getEintragAnzahl()) ); } void Spiel::setLastDrop( Drop* d ) { if( lastDropedDrop ) lastDropedDrop->release(); lastDropedDrop = d; } Drop* Spiel::getLastDrop() const { return lastDropedDrop ? dynamic_cast(lastDropedDrop->getThis()) : 0; } void Spiel::setItemZuletztAufgehoben( GegenstandTyp g ) { zuletztAufgehobenerGegenstand = g; } GegenstandTyp Spiel::getItemZuletztAufgehoben() const { return zuletztAufgehobenerGegenstand; } void Spiel::setItemZuletztAktiviert( GegenstandTyp g ) { zuletztBenutzterGegenstand = g; } GegenstandTyp Spiel::getItemZuletztAktiviert() const { return zuletztBenutzterGegenstand; } GegenstandTyp Spiel::getItemZuletztGedropt() const { return zuletztGedropterGegenstand; } Geschoss* Spiel::getRandomGeschoss() { if( !shots.getEintragAnzahl() ) return 0; return shots.get( (int)(randG.rand() * shots.getEintragAnzahl()) ); } Geschoss* Spiel::getGeschossZuletztAbgefeuert() const { return zuletztAbgefeuertesGeschoss ? dynamic_cast(zuletztAbgefeuertesGeschoss->getThis()) : 0; } void Spiel::setGeschossZuletztUmgelenkt( Geschoss* g ) { if( zuletztUmgelenktesGeschoss ) zuletztUmgelenktesGeschoss->release(); zuletztUmgelenktesGeschoss = g; } Geschoss* Spiel::getGeschossZuletztUmgelenkt() const { return zuletztUmgelenktesGeschoss ? dynamic_cast(zuletztUmgelenktesGeschoss->getThis()) : 0; } Geschoss* Spiel::getGeschossZuletztBariereGetroffen() const { return zuletztBariereGetroffenesGeschoss ? dynamic_cast(zuletztBariereGetroffenesGeschoss->getThis()) : 0; } void Spiel::setGeschossZuletztTunnelBenutzt( Geschoss* g ) { if( zuletztTunnelBenutztesGeschoss ) zuletztTunnelBenutztesGeschoss->release(); zuletztTunnelBenutztesGeschoss = g; } Geschoss* Spiel::getGeschossZuletztTunnelBenutzt() const { return zuletztTunnelBenutztesGeschoss ? dynamic_cast(zuletztTunnelBenutztesGeschoss->getThis()) : 0; } void Spiel::setGeschossZuletztGeschossGetroffen( Geschoss* g ) { if( zuletztGeschossGetroffenesGeschoss ) zuletztGeschossGetroffenesGeschoss->release(); zuletztGeschossGetroffenesGeschoss = g; } Geschoss* Spiel::getGeschossZuletztGeschossGetroffen() const { return zuletztGeschossGetroffenesGeschoss ? dynamic_cast(zuletztGeschossGetroffenesGeschoss->getThis()) : 0; } Schalter* Spiel::getRandomSchalter() { if( !schalter.getEintragAnzahl() ) return 0; return schalter.get( (int)(randG.rand() * schalter.getEintragAnzahl()) ); } void Spiel::setSchalterZuletztAktiviert( Schalter* s ) { if( zuletztAktivierterSchalter ) zuletztAktivierterSchalter->release(); zuletztAktivierterSchalter = s; } Schalter* Spiel::getSchalterZuletztAktiviert() const { return zuletztAktivierterSchalter ? dynamic_cast(zuletztAktivierterSchalter->getThis()) : 0; } Spieler* Spiel::getRandomSpieler() { if( !spieler.getEintragAnzahl() ) return 0; return spieler.get( (int)(randG.rand() * spieler.getEintragAnzahl()) ); } Spieler* Spiel::getRandomSpieler( Team* zTeam ) { if( !zTeam || !zTeam->getSpielerAnzahl() ) return 0; int index = (int)(randG.rand() * zTeam->getSpielerAnzahl()); for( auto s : spieler ) { if( s->zTeam() == zTeam ) { if( index-- <= 0 ) return dynamic_cast(s->getThis()); } } return 0; } void Spiel::setSpielerZuletztSchadenGemacht( Spieler* s ) { if( zuletztSchadenGemachterSpieler ) zuletztSchadenGemachterSpieler->release(); zuletztSchadenGemachterSpieler = s; } Spieler* Spiel::getSpielerZuletztSchadenGemacht() const { return zuletztSchadenGemachterSpieler ? dynamic_cast(zuletztSchadenGemachterSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztSchadenGenommen( Spieler* s ) { if( zuletztSchadenGenommenerSpieler ) zuletztSchadenGenommenerSpieler->release(); zuletztSchadenGenommenerSpieler = s; } Spieler* Spiel::getSpielerZuletztSchadenGenommen() const { return zuletztSchadenGenommenerSpieler ? dynamic_cast(zuletztSchadenGenommenerSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztGeheilt( Spieler* s ) { if( zuletztGeheilterSpieler ) zuletztGeheilterSpieler->release(); zuletztGeheilterSpieler = s; } Spieler* Spiel::getSpielerZuletztGeheilt() const { return zuletztGeheilterSpieler ? dynamic_cast(zuletztGeheilterSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztLevelUp( Spieler* s ) { if( zuletztLevelUpSpieler ) zuletztLevelUpSpieler->release(); zuletztLevelUpSpieler = s; } Spieler* Spiel::getSpielerZuletztLevelUp() const { return zuletztLevelUpSpieler ? dynamic_cast(zuletztLevelUpSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztErfahrungBekommen( Spieler* s ) { if( zuletztErfahrungBekommenerSpieler ) zuletztErfahrungBekommenerSpieler->release(); zuletztErfahrungBekommenerSpieler = s; } Spieler* Spiel::getSpielerZuletztErfahrungBekommen() const { return zuletztErfahrungBekommenerSpieler ? dynamic_cast(zuletztErfahrungBekommenerSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztGegenstandAktiviert( Spieler* s ) { if( zuletztGegenstandAktivierterSpieler ) zuletztGegenstandAktivierterSpieler->release(); zuletztGegenstandAktivierterSpieler = s; } Spieler* Spiel::getSpielerZuletztGegenstandAktiviert() const { return zuletztGegenstandAktivierterSpieler ? dynamic_cast(zuletztGegenstandAktivierterSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztGegenstandAufgehoben( Spieler* s ) { if( zuletztGegenstandAufgehobenerSpieler ) zuletztGegenstandAufgehobenerSpieler->release(); zuletztGegenstandAufgehobenerSpieler = s; } Spieler* Spiel::getSpielerZuletztGegenstandAufgehoben() const { return zuletztGegenstandAufgehobenerSpieler ? dynamic_cast(zuletztGegenstandAufgehobenerSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztSchalterAktiviert( Spieler* s ) { if( zuletztSchalterAktivierterSpieler ) zuletztSchalterAktivierterSpieler->release(); zuletztSchalterAktivierterSpieler = s; } Spieler* Spiel::getSpielerZuletztSchalterAktiviert() const { return zuletztSchalterAktivierterSpieler ? dynamic_cast(zuletztSchalterAktivierterSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztTunnelBenutzt( Spieler* s ) { if( zuletztTunnelBenutzterSpieler ) zuletztTunnelBenutzterSpieler->release(); zuletztTunnelBenutzterSpieler = s; } Spieler* Spiel::getSpielerZuletztTunnelBenutzt() const { return zuletztTunnelBenutzterSpieler ? dynamic_cast(zuletztTunnelBenutzterSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztGestorben( Spieler* s ) { if( zuletztGestorbenerSpieler ) zuletztGestorbenerSpieler->release(); zuletztGestorbenerSpieler = s; } Spieler* Spiel::getSpielerZuletztGestorben() const { return zuletztGestorbenerSpieler ? dynamic_cast(zuletztGestorbenerSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztWiederbelebt( Spieler* s ) { if( zuletztWiederbelebterSpieler ) zuletztWiederbelebterSpieler->release(); zuletztWiederbelebterSpieler = s; } Spieler* Spiel::getSpielerZuletztWiederbelebt() const { return zuletztWiederbelebterSpieler ? dynamic_cast(zuletztWiederbelebterSpieler->getThis()) : 0; } void Spiel::setSpielerZuletztGeschossen( Spieler* s ) { if( zuletztGeschossenerSpieler ) zuletztGeschossenerSpieler->release(); zuletztGeschossenerSpieler = s; } Spieler* Spiel::getSpielerZuletztGeschossen() const { return zuletztGeschossenerSpieler ? dynamic_cast(zuletztGeschossenerSpieler->getThis()) : 0; } Team* Spiel::getRandomTeam() { if( !teams.getEintragAnzahl() ) return 0; return teams.get( (int)(randG.rand() * teams.getEintragAnzahl()) ); } Timer* Spiel::getRandomTimer() { if( !timer.getEintragAnzahl() ) return 0; return timer.get( (int)(randG.rand() * timer.getEintragAnzahl()) ); } void Spiel::setTimerZuletztAbgelaufen( Timer* t ) { if( zuletztAbgelaufenerTimer ) zuletztAbgelaufenerTimer->release(); zuletztAbgelaufenerTimer = t; } Timer* Spiel::getTimerZuletztAbgelaufen() const { return zuletztAbgelaufenerTimer ? dynamic_cast(zuletztAbgelaufenerTimer->getThis()) : 0; } void Spiel::setTimerZuletztGestartet( Timer* t ) { if( zuletztGestarteterTimer ) zuletztGestarteterTimer->release(); zuletztGestarteterTimer = t; } Timer* Spiel::getTimerZuletztGestartet() const { return zuletztGestarteterTimer ? dynamic_cast(zuletztGestarteterTimer->getThis()) : 0; } void Spiel::setTimerZuletztPausiert( Timer* t ) { if( zuletztPausierterTimer ) zuletztPausierterTimer->release(); zuletztPausierterTimer = t; } Timer* Spiel::getTimerZuletztPausiert() const { return zuletztPausierterTimer ? dynamic_cast(zuletztPausierterTimer->getThis()) : 0; } void Spiel::setTimerZuletztFortgesetzt( Timer* t ) { if( zuletztFortgesetzterTimer ) zuletztFortgesetzterTimer->release(); zuletztFortgesetzterTimer = t; } Timer* Spiel::getTimerZuletztFortgesetzt() const { return zuletztFortgesetzterTimer ? dynamic_cast(zuletztFortgesetzterTimer->getThis()) : 0; } Tunnel* Spiel::getRandomTunnel() { if( !tunnel.getEintragAnzahl() ) return 0; return tunnel.get( (int)(randG.rand() * tunnel.getEintragAnzahl()) ); } void Spiel::setTunnelZuletztBenutzt( Tunnel* t ) { if( zuletztBenutzterTunnel ) zuletztBenutzterTunnel->release(); zuletztBenutzterTunnel = t; } Tunnel* Spiel::getTunnelZuletztBenutzt() const { return zuletztBenutzterTunnel ? dynamic_cast(zuletztBenutzterTunnel->getThis()) : 0; } Umlenkung* Spiel::getRandomUmlenkung() { if( !umlenkungen.getEintragAnzahl() ) return 0; return umlenkungen.get( (int)(randG.rand() * umlenkungen.getEintragAnzahl()) ); } void Spiel::setUmlenkungZuletztBenutzt( Umlenkung* t ) { if( zuletztBenutzteUmlenkung ) zuletztBenutzteUmlenkung->release(); zuletztBenutzteUmlenkung = t; } Umlenkung* Spiel::getUmlenkungZuletztBenutzt() const { return zuletztBenutzteUmlenkung ? dynamic_cast(zuletztBenutzteUmlenkung->getThis()) : 0; } StatistikV* Spiel::getStatistik() const { return dynamic_cast(stat->getThis()); }