#include "Spiel.h" #include "DrachenAuge.h" #include "Brand.h" #define TICK 0.03333333 // Konstruktor Spiel::Spiel() { 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; ref = 1; } // 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( 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 = zAccounts->getThis(); spielerAnzahl = anzahl; } // call 4 void Spiel::setKlients( int anzahl, RCArray< SSKlientV > *zKlients ) { if( this->zKlients ) this->zKlients->release(); this->zKlients = zKlients->getThis(); } // call 5 void Spiel::setSpielerNummern( int anzahl, Array< int > *spielerNummern ) { MapReader *reader = new MapReader( karteId, psqldb->getThis(), mapPfad ); reader->ladeKarte( this ); reader->release(); for( int i = 0; i < anzahl; i++ ) { for( auto s = spieler.getIterator(); s; s++ ) { if( s->getId() == spielerNummern->get( i ) ) { s->setAccount( zAccounts->get( i ) ); s->setKlient( new Klient( zKlients->get( i ) ) ); break; } } } zAccounts = zAccounts->release(); zKlients = 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 = 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", 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", 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.getIterator(); b; b++ ) { if( b->hatStyle( Bariere::Style::AutoVerschiebung ) ) anz++; } if( anz ) { int rand = (int)( randG.rand() * anz ); for( auto b = barieren.getIterator(); b; b++ ) { 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.getIterator(); b; b++ ) { if( b->hatStyle( Bariere::Style::AutoSchaltung ) ) anz++; } if( anz ) { int rand = (int)( randG.rand() * anz ); for( auto b = barieren.getIterator(); b; b++ ) { 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.getIterator(); s; s++ ) { 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.getIterator(); b; b++ ) { // spieler - bariere intersection if( b->hatStyle( Bariere::Style::Aktiv ) && ( b->zTeam() != s->zTeam() ) && b->intersectsWith( s ) ) s->move( r, -zeit ); } } } } for( auto s = spieler.getIterator(); s; s++ ) s->tick( zeit, this ); // barieren bewegung for( auto b = barieren.getIterator(); b; b++ ) 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.getIterator(); b; b++ ) { 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 = (Geschoss *)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.getIterator(); s; s++ ) { 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.getIterator(); t; t++ ) { 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", g->getThis() ); e->addParameter( "Betroffer Tunnel", t->getThis() ); throwEvent( e ); } } // geschoss - schalter intersection if( g->getTyp() == GESCHOSS_PFEIL ) { for( auto s = schalter.getIterator(); s; s++ ) { 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.getIterator(); u; u++ ) { 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", g->getThis() ); e->addParameter( "Betroffe Umlenkung", 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.getIterator(); s; s++ ) { 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.getIterator(); s2; s2++ ) { 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.getIterator(); s; s++ ) { if( s->abstandZu( f ) < f->getWidth() / 2 ) s->addEffekt( new BrandEffekt( f->zVerursacher(), s ) ); } } } // Drop Ticks for( auto d = drops.getIterator(); d; d++ ) d->tick( zeit, this ); // Timer Ticks for( auto t = timer.getIterator(); t; t++ ) t->tick( zeit, this ); // Umlenkung Ticks for( auto u = umlenkungen.getIterator(); u; u++ ) u->tick( zeit ); // Base Ticks for( auto b = basen.getIterator(); b; b++ ) 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.getIterator(); v; v++ ) { 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.getIterator(); v; v++ ) { 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", gegenstand->getThis() ); throwEvent( e ); } void Spiel::addGeschoss( Geschoss *geschoss ) { nextId = nextId > geschoss->getId() ? nextId : geschoss->getId() + 1; if( zuletztAbgefeuertesGeschoss ) zuletztAbgefeuertesGeschoss->release(); zuletztAbgefeuertesGeschoss = (Geschoss *)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.getIterator(); t; t++ ) { if( t->getTeamNummer() == id ) return (Team *)t->getThis(); } return 0; } Spieler *Spiel::getSpieler( int id ) const { for( auto s = spieler.getIterator(); s; s++ ) { if( s->getId() == id ) return (Spieler *)s->getThis(); } return 0; } Iterator Spiel::getSpieler() const { return spieler.getIterator(); } Iterator Spiel::getBarieren() const { return barieren.getIterator(); } Bariere *Spiel::getBariere( int id ) const { for( auto b = barieren.getIterator(); b; b++ ) { if( b->getId() == id ) return (Bariere *)b->getThis(); } return 0; } Base *Spiel::getBase( int id ) const { for( auto b = basen.getIterator(); b; b++ ) { if( b->getId() == id ) return (Base *)b->getThis(); } return 0; } Drop *Spiel::getDrop( int id ) const { for( auto d = drops.getIterator(); d; d++ ) { if( d->getId() == id ) return (Drop *)d->getThis(); } return 0; } Schalter *Spiel::getSchalter( int id ) const { for( auto s = schalter.getIterator(); s; s++ ) { if( s->getId() == id ) return (Schalter *)s->getThis(); } return 0; } Schiene *Spiel::getSchiene( int id ) const { for( auto s = schienen.getIterator(); s; s++ ) { if( s->getId() == id ) return (Schiene *)s->getThis(); } return 0; } Timer *Spiel::getTimer( int id ) const { for( auto t = timer.getIterator(); t; t++ ) { if( t->getId() == id ) return (Timer *)t->getThis(); } return 0; } Tunnel *Spiel::getTunnel( int id ) const { for( auto t = tunnel.getIterator(); t; t++ ) { if( t->getId() == id ) return (Tunnel *)t->getThis(); } return 0; } Umlenkung *Spiel::getUmlenkung( int id ) const { for( auto u = umlenkungen.getIterator(); u; u++ ) { if( u->getId() == id ) return (Umlenkung *)u->getThis(); } return 0; } Trigger *Spiel::getTrigger( int id ) const { for( auto t = trigger.getIterator(); t; t++ ) { if( t->getId() == id ) return (Trigger *)t->getThis(); } return 0; } Variable *Spiel::getVariable( const char *name ) const { for( auto v = variablen.getIterator(); v; v++ ) { if( v->getName().istGleich( name ) ) return v->getVariable(); } return 0; } Variable *Spiel::zVariable( const char *name ) const { for( auto v = variablen.getIterator(); v; v++ ) { 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.getIterator(); s; s++ ) { if( s->getId() == id ) s->press( this ); } } void Spiel::throwEvent( Ereignis *e ) { for( auto t = trigger.getIterator(); t; t++ ) { if( t->hatEreignis( e->getTyp() ) ) { TriggerRun *tr = t->runTrigger( e->getThis(), this ); if( tr ) triggerRuns.add( tr ); } } e->release(); } bool Spiel::needEvent( EreignisTyp typ ) const { for( auto t = trigger.getIterator(); t; t++ ) { 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 ? (Trigger *)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 ? (Bariere *)zuletztEingeschalteteBariere->getThis() : 0; } void Spiel::setZuletztAusgeschalteteBariere( Bariere *b ) { if( zuletztAusgeschalteteBariere ) zuletztAusgeschalteteBariere->release(); zuletztAusgeschalteteBariere = b; } Bariere *Spiel::getZuletztAusgeschalteteBariere() const { return zuletztAusgeschalteteBariere ? (Bariere *)zuletztAusgeschalteteBariere->getThis() : 0; } void Spiel::setZuletztBewegteBariere( Bariere *b ) { if( zuletztBewegteBariere ) zuletztBewegteBariere->release(); zuletztBewegteBariere = b; } Bariere *Spiel::getZuletztBewegteBariere() const { return zuletztBewegteBariere ? (Bariere *)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 ? (Base *)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 ? (Drop *)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 ? (Geschoss *)zuletztAbgefeuertesGeschoss->getThis() : 0; } void Spiel::setGeschossZuletztUmgelenkt( Geschoss *g ) { if( zuletztUmgelenktesGeschoss ) zuletztUmgelenktesGeschoss->release(); zuletztUmgelenktesGeschoss = g; } Geschoss *Spiel::getGeschossZuletztUmgelenkt() const { return zuletztUmgelenktesGeschoss ? (Geschoss *)zuletztUmgelenktesGeschoss->getThis() : 0; } Geschoss *Spiel::getGeschossZuletztBariereGetroffen() const { return zuletztBariereGetroffenesGeschoss ? (Geschoss *)zuletztBariereGetroffenesGeschoss->getThis() : 0; } void Spiel::setGeschossZuletztTunnelBenutzt( Geschoss *g ) { if( zuletztTunnelBenutztesGeschoss ) zuletztTunnelBenutztesGeschoss->release(); zuletztTunnelBenutztesGeschoss = g; } Geschoss *Spiel::getGeschossZuletztTunnelBenutzt() const { return zuletztTunnelBenutztesGeschoss ? (Geschoss *)zuletztTunnelBenutztesGeschoss->getThis() : 0; } void Spiel::setGeschossZuletztGeschossGetroffen( Geschoss *g ) { if( zuletztGeschossGetroffenesGeschoss ) zuletztGeschossGetroffenesGeschoss->release(); zuletztGeschossGetroffenesGeschoss = g; } Geschoss *Spiel::getGeschossZuletztGeschossGetroffen() const { return zuletztGeschossGetroffenesGeschoss ? (Geschoss *)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 ? (Schalter *)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.getIterator(); s; s++ ) { if( s->zTeam() == zTeam ) { if( index-- <= 0 ) return (Spieler *)s->getThis(); } } return 0; } void Spiel::setSpielerZuletztSchadenGemacht( Spieler *s ) { if( zuletztSchadenGemachterSpieler ) zuletztSchadenGemachterSpieler->release(); zuletztSchadenGemachterSpieler = s; } Spieler *Spiel::getSpielerZuletztSchadenGemacht() const { return zuletztSchadenGemachterSpieler ? (Spieler *)zuletztSchadenGemachterSpieler->getThis() : 0; } void Spiel::setSpielerZuletztSchadenGenommen( Spieler *s ) { if( zuletztSchadenGenommenerSpieler ) zuletztSchadenGenommenerSpieler->release(); zuletztSchadenGenommenerSpieler = s; } Spieler *Spiel::getSpielerZuletztSchadenGenommen() const { return zuletztSchadenGenommenerSpieler ? (Spieler *)zuletztSchadenGenommenerSpieler->getThis() : 0; } void Spiel::setSpielerZuletztGeheilt( Spieler *s ) { if( zuletztGeheilterSpieler ) zuletztGeheilterSpieler->release(); zuletztGeheilterSpieler = s; } Spieler *Spiel::getSpielerZuletztGeheilt() const { return zuletztGeheilterSpieler ? (Spieler *)zuletztGeheilterSpieler->getThis() : 0; } void Spiel::setSpielerZuletztLevelUp( Spieler *s ) { if( zuletztLevelUpSpieler ) zuletztLevelUpSpieler->release(); zuletztLevelUpSpieler = s; } Spieler *Spiel::getSpielerZuletztLevelUp() const { return zuletztLevelUpSpieler ? (Spieler *)zuletztLevelUpSpieler->getThis() : 0; } void Spiel::setSpielerZuletztErfahrungBekommen( Spieler *s ) { if( zuletztErfahrungBekommenerSpieler ) zuletztErfahrungBekommenerSpieler->release(); zuletztErfahrungBekommenerSpieler = s; } Spieler *Spiel::getSpielerZuletztErfahrungBekommen() const { return zuletztErfahrungBekommenerSpieler ? (Spieler *)zuletztErfahrungBekommenerSpieler->getThis() : 0; } void Spiel::setSpielerZuletztGegenstandAktiviert( Spieler *s ) { if( zuletztGegenstandAktivierterSpieler ) zuletztGegenstandAktivierterSpieler->release(); zuletztGegenstandAktivierterSpieler = s; } Spieler *Spiel::getSpielerZuletztGegenstandAktiviert() const { return zuletztGegenstandAktivierterSpieler ? (Spieler *)zuletztGegenstandAktivierterSpieler->getThis() : 0; } void Spiel::setSpielerZuletztGegenstandAufgehoben( Spieler *s ) { if( zuletztGegenstandAufgehobenerSpieler ) zuletztGegenstandAufgehobenerSpieler->release(); zuletztGegenstandAufgehobenerSpieler = s; } Spieler *Spiel::getSpielerZuletztGegenstandAufgehoben() const { return zuletztGegenstandAufgehobenerSpieler ? (Spieler *)zuletztGegenstandAufgehobenerSpieler->getThis() : 0; } void Spiel::setSpielerZuletztSchalterAktiviert( Spieler *s ) { if( zuletztSchalterAktivierterSpieler ) zuletztSchalterAktivierterSpieler->release(); zuletztSchalterAktivierterSpieler = s; } Spieler *Spiel::getSpielerZuletztSchalterAktiviert() const { return zuletztSchalterAktivierterSpieler ? (Spieler *)zuletztSchalterAktivierterSpieler->getThis() : 0; } void Spiel::setSpielerZuletztTunnelBenutzt( Spieler *s ) { if( zuletztTunnelBenutzterSpieler ) zuletztTunnelBenutzterSpieler->release(); zuletztTunnelBenutzterSpieler = s; } Spieler *Spiel::getSpielerZuletztTunnelBenutzt() const { return zuletztTunnelBenutzterSpieler ? (Spieler *)zuletztTunnelBenutzterSpieler->getThis() : 0; } void Spiel::setSpielerZuletztGestorben( Spieler *s ) { if( zuletztGestorbenerSpieler ) zuletztGestorbenerSpieler->release(); zuletztGestorbenerSpieler = s; } Spieler *Spiel::getSpielerZuletztGestorben() const { return zuletztGestorbenerSpieler ? (Spieler *)zuletztGestorbenerSpieler->getThis() : 0; } void Spiel::setSpielerZuletztWiederbelebt( Spieler *s ) { if( zuletztWiederbelebterSpieler ) zuletztWiederbelebterSpieler->release(); zuletztWiederbelebterSpieler = s; } Spieler *Spiel::getSpielerZuletztWiederbelebt() const { return zuletztWiederbelebterSpieler ? (Spieler *)zuletztWiederbelebterSpieler->getThis() : 0; } void Spiel::setSpielerZuletztGeschossen( Spieler *s ) { if( zuletztGeschossenerSpieler ) zuletztGeschossenerSpieler->release(); zuletztGeschossenerSpieler = s; } Spieler *Spiel::getSpielerZuletztGeschossen() const { return zuletztGeschossenerSpieler ? (Spieler *)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 ? (Timer *)zuletztAbgelaufenerTimer->getThis() : 0; } void Spiel::setTimerZuletztGestartet( Timer *t ) { if( zuletztGestarteterTimer ) zuletztGestarteterTimer->release(); zuletztGestarteterTimer = t; } Timer *Spiel::getTimerZuletztGestartet() const { return zuletztGestarteterTimer ? (Timer *)zuletztGestarteterTimer->getThis() : 0; } void Spiel::setTimerZuletztPausiert( Timer *t ) { if( zuletztPausierterTimer ) zuletztPausierterTimer->release(); zuletztPausierterTimer = t; } Timer *Spiel::getTimerZuletztPausiert() const { return zuletztPausierterTimer ? (Timer *)zuletztPausierterTimer->getThis() : 0; } void Spiel::setTimerZuletztFortgesetzt( Timer *t ) { if( zuletztFortgesetzterTimer ) zuletztFortgesetzterTimer->release(); zuletztFortgesetzterTimer = t; } Timer *Spiel::getTimerZuletztFortgesetzt() const { return zuletztFortgesetzterTimer ? (Timer *)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 ? (Tunnel *)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 ? (Umlenkung *)zuletztBenutzteUmlenkung->getThis() : 0; } StatistikV *Spiel::getStatistik() const { return stat->getThis(); } // Reference Counting SpielKlasse *Spiel::getThis() { ref++; return this; } SpielKlasse *Spiel::release() { if( !--ref ) delete this; return 0; }