#include "SpielKlasse.h" #include #include #include #include #include #include #include "Ship/Ship.h" #include "Define.h" // Inhalt der SpielKlasse Klasse aus SpielKlasse.h // Konstruktor SpielKlasse::SpielKlasse() { spielZeit = 0; rZeit = 0; rendern = 0; stkn = new RCArray< STKNachricht >(); stkna = 0; schrift = 0; time_t t; time( &t ); srand( (unsigned int)t ); infoKlient = 0; spielKlient = 0; spieler = new RCArray< Spieler >(); teams = new RCArray< Team >(); objekte = new RCArray< SpielObjekt >(); screen = 0; kam = 0; spielerAnzahl = 0; karteId = 0; ladenProzent = 0; spielerNummer = 0; map = 0; end = 0; chat = new SpielChat(); tasten = new char[ 256 ]; for( int i = 0; i < 256; i++ ) tasten[ i ] = 0; mx = -1; my = -1; bestenliste = 0; schüsse = new RCArray< Laser >(); ship = 0; spielPause = 1; ref = 1; } // Destruktor SpielKlasse::~SpielKlasse() { if( map ) { for( int i = 0; i < map->getMaxTeamAnzahl(); i++ ) { if( teams->z( i ) ) teams->z( i )->reset(); } } stkn->release(); if( schrift ) schrift->release(); if( infoKlient ) infoKlient->release(); if( spielKlient ) spielKlient->release(); if( kam ) kam->release(); if( map ) map->release(); if( end ) end->release(); if( bestenliste ) bestenliste->release(); if( ship ) ship->release(); chat->relese(); spieler->release(); teams->release(); objekte->release(); if( screen ) screen->release(); schüsse->release(); delete[] tasten; } // privat bool SpielKlasse::istAmLeben() const { for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) return spieler->z( i )->istAmLeben(); } return 0; } // nicht constant void SpielKlasse::lock() { if( screen ) screen->lock(); } void SpielKlasse::unlock() { if( screen ) screen->unlock(); } void SpielKlasse::setSchrift( Schrift *schrift ) { if( this->schrift ) this->schrift->release(); this->schrift = schrift; chat->setSchrift( schrift ); if( !bestenliste ) bestenliste = new Bestenliste( schrift->getThis() ); if( !ship ) ship = new Ship( schrift ); } void SpielKlasse::setBildschirm( Bildschirm *screen ) { this->screen = screen; } void SpielKlasse::nachricht( int län, char *bytes ) { if( !län ) return; lock(); stkn->add( new STKNachricht( län, bytes ), stkna ); stkna++; unlock(); } void SpielKlasse::setKlients( InformationKlientV *infoKlient, SpielKlientV *spielKlient ) { if( this->infoKlient ) this->infoKlient->release(); this->infoKlient = infoKlient; if( this->spielKlient ) this->spielKlient->release(); this->spielKlient = spielKlient; } void SpielKlasse::setKarteId( int karteId ) { this->karteId = karteId; } void SpielKlasse::ladeDaten() { kam = new Kamera(); map = new Karte(); Text *mapPf = new Text( "data/tmp/Karten/" ); mapPf->append( karteId ); mapPf->append( "/spiel/data/data.sts" ); Datei *stsD = new Datei(); stsD->setDatei( mapPf->getText() ); stsD->open( Datei::Style::lesen ); map->ladeSts( stsD ); stsD->close(); stsD->release(); spielKlient->setLadenProzent( 5 ); mapPf->ersetzen( mapPf->getLength() - 3, mapPf->getLength(), "map" ); Datei *mapD = new Datei(); mapD->setDatei( mapPf->getText() ); mapD->open( Datei::Style::lesen ); map->ladeMap( mapD, infoKlient, karteId, spielKlient ); mapD->close(); mapD->release(); mapPf->release(); for( int i = 0; i < map->getMaxSpielerAnzahl(); i++ ) spieler->set( map->createSpieler( i, schrift, infoKlient ), i ); spielKlient->setLadenProzent( 95 ); for( int i = 0; i < map->getZeichnungAnzahl(); i++ ) objekte->set( map->createZeichnung( i, schrift ), i ); bestenliste->setTeamAnzahl( map->getMaxTeamAnzahl() ); spielKlient->setLadenProzent( 100 ); } void SpielKlasse::doMausEreignis( MausEreignis &me ) { if( end ) { end->doMausEreignis( me ); return; } if( !istAmLeben() ) { 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 ) { mx = me.mx; my = me.my; } me.verarbeitet = 1; } else { mx = -1; my = -1; } int skill = ship->doMausEreignis( me ); if( skill >= 0 ) { char *bytes = new char[ 2 ]; bytes[ 0 ] = 9; bytes[ 1 ] = (char)skill; spielKlient->spielNachricht( 2, bytes ); } chat->doMausEreignis( me ); if( bestenliste ) bestenliste->doMausEreignis( me ); } void SpielKlasse::doTastaturEreignis( TastaturEreignis &te ) { bestenliste->doTastaturEreignis( te ); if( end ) return; if( !chat->istAktiv() ) { if( istAmLeben() ) { if( te.id == TE_Press ) { switch( te.taste ) { case 'w': case 'W': case T_Oben: if( !tasten[ T_Oben ] ) { tasten[ T_Oben ] = 1; char byte = 0; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; case 'a': case 'A': case T_Links: if( !tasten[ T_Links ] ) { tasten[ T_Links ] = 1; char byte = 2; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; case 'd': case 'D': case T_Rechts: if( !tasten[ T_Rechts ] ) { tasten[ T_Rechts ] = 1; char byte = 4; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; case T_Space: if( !tasten[ T_Space ] ) { tasten[ T_Space ] = 1; char byte = 6; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; } } if( te.id == TE_Release ) { switch( te.taste ) { case 'w': case 'W': case T_Oben: if( tasten[ T_Oben ] ) { tasten[ T_Oben ] = 0; char byte = 1; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; case 'a': case 'A': case T_Links: if( tasten[ T_Links ] ) { tasten[ T_Links ] = 0; char byte = 3; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; case 'd': case 'D': case T_Rechts: if( tasten[ T_Rechts ] ) { tasten[ T_Rechts ] = 0; char byte = 5; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; case T_Space: if( tasten[ T_Space ] ) { tasten[ T_Space ] = 0; char byte = 7; spielKlient->spielNachricht( 1, &byte ); te.verarbeitet = 1; } break; } } } else { 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 ) chat->doTastaturEreignis( te, spielKlient ); } void SpielKlasse::stknVerarbeitung() { lock(); for( int i = 0; i < stkna; i++ ) { STKNachricht *n = stkn->z( i ); int zeit = n->getSpielZeit(); if( zeit > spielZeit ) break; int län = n->getLength(); char *bytes = n->getNachricht(); län--; int sNum = 0; switch( bytes[ 0 ] ) { case 0: // spieler drückt gas bytes++; sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) spieler->z( i )->setTastataturStatus( T_GAS, 1, zeit, map ); } break; case 1: // spieler lässt gas los bytes++; sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) spieler->z( i )->setTastataturStatus( T_GAS, 0, zeit, map ); } break; case 2: // spieler drückt rotl bytes++; sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) spieler->z( i )->setTastataturStatus( T_ROT_L, 1, zeit, map ); } break; case 3: // spieler lässt rotl los bytes++; sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) spieler->z( i )->setTastataturStatus( T_ROT_L, 0, zeit, map ); } break; case 4: // spieler drückt rotr bytes++; sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) spieler->z( i )->setTastataturStatus( T_ROT_R, 1, zeit, map ); } break; case 5: // spieler lässt rotr los bytes++; sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) spieler->z( i )->setTastataturStatus( T_ROT_R, 0, zeit, map ); } break; case 6: // Init Spieler if( 1 ) { bytes++; spielerAnzahl = (int)*bytes; bytes++; län--; for( int i = 0; i < spielerAnzahl; i++ ) { int sNum = *(int*)bytes; Spieler *tmp = spieler->z( sNum - 1 ); bytes += 4; län -= 4; tmp->setAccountId( *(int*)bytes ); bytes += 4; län -= 4; if( !teams->z( map->getTeamNummer( sNum ) ) ) teams->set( map->createTeam( map->getTeamNummer( sNum ) ), map->getTeamNummer( sNum ) ); tmp->setTeam( teams->get( map->getTeamNummer( sNum ) ) ); tmp->zTeam()->spieler->add( tmp->getThis() ); spieler->add( tmp ); bestenliste->addSpieler( tmp ); bestenliste->updateSpieler( tmp ); bestenliste->updateTeam( tmp->zTeam() ); } int max = map->getMaxSpielerAnzahl(); for( int i = 0; i < max; i++ ) { if( !spieler->z( i )->zTeam() ) { spieler->remove( i ); i--; max--; } } } break; case 0x8: // Chat Nachricht if( 1 ) { bytes++; Text *txt = new Text( "" ); txt->append( bytes, län ); chat->addNachricht( txt->getText() ); txt->release(); län = 0; } break; case 0x9: // Spieler Nummer bytes++; spielerNummer = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) { ship->update( spieler->z( i ) ); break; } } break; case 0xA: // Start spielPause = 0; rendern = 1; break; case 0xB: // Ende end = new Ende( schrift ); bytes++; län--; end->setGewonnen( *bytes ); break; case 0xC: // Skill if( 1 ) { bytes++; sNum = *(int*)bytes; bytes += 4; län -= 4; char art = *bytes; län--; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) { Team *tmp = spieler->z( i )->zTeam(); if( art == 6 || art == 7 || art == 8 ) { for( auto *j = &tmp->spieler->getArray(); j && j->set && j->var; j = j->next ) j->var->setMoveZeit( zeit - spielZeit, map ); } spieler->z( i )->setSkill( art ); tmp->akkuLeistung = tmp->getAkkuLeistungBonus(); tmp->beschleunigung = tmp->getBeschleunigungBonus(); tmp->laserEffizienz = tmp->getLaserEffizienzBonus(); tmp->laserIntensität = tmp->getLaserIntensitätBonus(); tmp->laserTempo = tmp->getLaserTempoBonus(); tmp->maxEnergie = tmp->getMaxEnergieBonus(); tmp->maxStabilität = tmp->getMaxStabilitätBonus(); tmp->reparatur = tmp->getReperaturBonus(); tmp->wendigkeit = tmp->getWendigkeitBonus(); if( art == 6 || art == 7 || art == 8 ) { for( auto *j = &tmp->spieler->getArray(); j && j->set && j->var; j = j->next ) j->var->setMoveZeit( spielZeit - zeit, map ); } break; } } for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) { ship->update( spieler->z( i ) ); break; } } } break; case 0xD: // Schuss if( 1 ) { bytes++; int id = *(int*)bytes; bytes += 4; län -= 4; sNum = *(int*)bytes; bytes += 4; län -= 4; double xPos = *(double*)bytes; bytes += 8; län -= 8; double yPos = *(double*)bytes; bytes += 8; län -= 8; double xSpeed = *(double*)bytes; bytes += 8; län -= 8; double ySpeed = *(double*)bytes; bytes += 8; län -= 8; double intensität = *(double*)bytes; län -= 8; int farbe = 0; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) { spieler->z( i )->setMoveZeit( zeit - spielZeit, map ); spieler->z( i )->setPosition( Vec2< double >( xPos, yPos ) ); spieler->z( i )->hatGeschossen(); farbe = spieler->z( i )->zTeam()->farbe; spieler->z( i )->setMoveZeit( spielZeit - zeit, map ); break; } } if( sNum == spielerNummer ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) { ship->update( spieler->z( i ) ); bestenliste->updateSpieler( spieler->z( i ) ); break; } } } Laser *l = new Laser( id, Vec2< double >( xPos, yPos ), Vec2< double >( xSpeed, ySpeed ), sNum, intensität, farbe ); l->tick( spielZeit - zeit, map ); schüsse->add( l ); } break; case 0xE: // Treffer if( 1 ) { bytes++; int schuss = *(int*)bytes; bytes += 4; län -= 4; int sNum = *(int*)bytes; län -= 4; int anz = schüsse->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( schüsse->z( i )->getId() == schuss ) { Laser *tmp = schüsse->z( i ); tmp->tick( zeit - spielZeit, map ); if( sNum >= 0 ) { for( int j = 0; j < spielerAnzahl; j++ ) { if( spieler->z( j )->getSpielerNummer() == sNum ) { spieler->z( j )->nimmSchaden( tmp->getIntensität() ); bestenliste->updateSpieler( spieler->z( j ) ); } if( spieler->z( j )->getSpielerNummer() == tmp->getSpieler() ) { spieler->z( j )->machSchaden( tmp->getIntensität() ); bestenliste->updateSpieler( spieler->z( j ) ); } } } schüsse->remove( i ); break; } } if( sNum == spielerNummer ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) { ship->update( spieler->z( i ) ); break; } } } } break; case 0xF: // Wiederbelebung if( 1 ) { bytes++; int sNum = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) { spieler->z( i )->wiederbelebung(); break; } } if( sNum == spielerNummer ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) { ship->update( spieler->z( i ) ); break; } } } } break; case 0x10: // Tod if( 1 ) { bytes++; sNum = *(int*)bytes; bytes += 4; län -= 4; int killer = *(int*)bytes; län -= 4; for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == sNum ) { spieler->z( i )->sterben(); bestenliste->updateSpieler( spieler->z( i ) ); } if( spieler->z( i )->getSpielerNummer() == killer ) { spieler->z( i )->addKill(); spieler->z( i )->zTeam()->punkte++; bestenliste->updateTeam( spieler->z( i )->zTeam() ); bestenliste->updateSpieler( spieler->z( i ) ); } } if( sNum == spielerNummer ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getSpielerNummer() == spielerNummer ) { ship->update( spieler->z( i ) ); break; } } } } break; default: // Fehler beim verarbeiten break; } if( län != 0 ) { // Fehler beim verarbeiten chat->addNachricht( "Es ist ein Fehler beim verarbeiten einer Nachricht aufgetreten.", 0xFFFF0000 ); } n->setVerarbeitet(); } for( int i = stkna; i > 0; i-- ) { if( !stkn->z( 0 ) || !stkn->z( 0 )->istVerarbeitet() ) break; stkna--; stkn->remove( 0 ); } unlock(); } bool SpielKlasse::tick( double zeit ) { if( spielPause ) { zeit = 0; stknVerarbeitung(); return 1; } rZeit += zeit; double sZ = 0; while( sZ + TICK < rZeit ) { sZ += TICK; rZeit -= TICK; spielZeit++; stknVerarbeitung(); if( end ) return 1; int x = 0; int y = 0; bool setKam = 0; lock(); int objektAnzahl = objekte->getEintragAnzahl(); for( int i = 0; i < objektAnzahl; i++ ) objekte->z( i )->tick(); for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->tick( map ) && spieler->z( i )->getSpielerNummer() == spielerNummer ) ship->update( spieler->z( i ) ); if( spielerNummer == spieler->z( i )->getSpielerNummer() ) { x = (int)spieler->z( i )->getPos().x; y = (int)spieler->z( i )->getPos().y; setKam = spieler->z( i )->istAmLeben(); } } int schussAnzahl = schüsse->getEintragAnzahl(); for( int i = 0; i < schussAnzahl; i++ ) schüsse->z( i )->tick( 1, map ); unlock(); if( setKam ) { double px = ( ( x - kam->getPos().x ) / 100.0 ) * ( abs( ( x - kam->getPos().x ) / 2 ) * TICK ); double py = ( ( y - kam->getPos().y ) / 100.0 ) * ( abs( ( y - kam->getPos().y ) / 2 ) * TICK ); if( abs( x - kam->getPos().x ) > abs( x - ( kam->getPos().x - map->getSize().x ) ) ) px = ( ( x - ( kam->getPos().x - map->getSize().x ) ) / 100.0 ) * ( abs( ( x - kam->getPos().x ) / 2 ) * TICK ); else if( abs( x - kam->getPos().x ) > abs( x - ( kam->getPos().x + map->getSize().x ) ) ) px = ( ( x - ( kam->getPos().x + map->getSize().x ) ) / 100.0 ) * ( abs( ( x - kam->getPos().x ) / 2 ) * TICK ); if( abs( y - kam->getPos().y ) > abs( y - ( kam->getPos().y - map->getSize().y ) ) ) py = ( ( y - ( kam->getPos().y - map->getSize().y ) ) / 100.0 ) * ( abs( ( y - kam->getPos().y ) / 2 ) * TICK ); else if( abs( y - kam->getPos().y ) > abs( y - ( kam->getPos().y + map->getSize().y ) ) ) py = ( ( y - ( kam->getPos().y + map->getSize().y ) ) / 100.0 ) * ( abs( ( y - kam->getPos().y ) / 2 ) * TICK ); kam->addPosition( (int)px, (int)py, map ); } chat->tick( !zeit ? 0.05 : zeit ); if( ship ) ship->tick( !zeit ? 0.05 : zeit ); } return 1; } void SpielKlasse::render( Bild &zRObj ) { if( !rendern ) return; lock(); for( int i = 0; kam->beginnRender( zRObj, map, i ); i++ ) { int objektAnzahl = objekte->getEintragAnzahl(); for( int i = 0; i < objektAnzahl; i++ ) objekte->z( i )->render( zRObj ); for( int j = 0; j < spielerAnzahl; j++ ) spieler->z( j )->render( zRObj ); int schussAnzahl = schüsse->getEintragAnzahl(); for( int j = 0; j < schussAnzahl; j++ ) schüsse->z( j )->render( zRObj ); for( int j = 0; j < spielerAnzahl; j++ ) spieler->z( j )->renderLeben( zRObj ); kam->endRender( zRObj ); } kam->beginnMinimap( zRObj, map ); for( int j = 0; j < spielerAnzahl; j++ ) spieler->z( j )->renderMinimap( zRObj, map ); int schussAnzahl = schüsse->getEintragAnzahl(); for( int j = 0; j < schussAnzahl; j++ ) schüsse->z( j )->renderMinimap( zRObj, map ); kam->endMinimap( zRObj ); chat->render( zRObj ); if( bestenliste ) bestenliste->render( zRObj ); if( ship ) ship->render( zRObj ); if( end ) end->render( zRObj ); unlock(); } // constant int SpielKlasse::läuft() const { if( !rendern ) return 3; if( !end ) return 2; if( end && !end->getWeiter() ) return 1; if( end && end->getWeiter() ) return 0; return 0; } // Reference Counting SpielV *SpielKlasse::getThis() { ref++; return this; } SpielV *SpielKlasse::release() { ref--; if( !ref ) delete this; return 0; }