#include "Map.h" #include #include #include #include #include #include #include #include // Inhalt der Map Klasse aus Map.h // Konstruktor Map::Map( KSGClient::MinigameServerClient *klient ) { this->klient = klient; map = new RCArray< Array< int > >(); score = 0; scoreCheck = score * 11197; breite = 0; höhe = 0; geschwindigkeit = 0; bAnzahl = 0; next = 0; beendet = 1; rend = 0; rGen = 0; gameTime = 0; ref = 1; } // Destruktor Map::~Map() { speichern(); map->release(); if( rGen ) rGen->release(); if( klient ) klient->release(); } // private void Map::remove( int x, int y ) { if( !map->z( x ) || !map->z( x )->hat( y ) || !map->z( x )->get( y ) ) return; int f = map->z( x )->get( y ); map->z( x )->set( 0, y ); if( !f ) return; if( map->z( x - 1 ) && map->z( x - 1 )->hat( y ) && map->z( x - 1 )->get( y ) == f ) remove( x - 1, y ); if( map->z( x + 1 ) && map->z( x + 1 )->hat( y ) && map->z( x + 1 )->get( y ) == f ) remove( x + 1, y ); if( map->z( x ) && map->z( x )->hat( y - 1 ) && map->z( x )->get( y - 1 ) == f ) remove( x, y - 1 ); if( map->z( x ) && map->z( x )->hat( y + 1 ) && map->z( x )->get( y + 1 ) == f ) remove( x, y + 1 ); } // nicht constant void Map::reset( Text *zOptionen ) { gameTime = 0; next = 0; beendet = 0; score = 0; scoreCheck = score * 11197; map->leeren(); Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) ); breite = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) ); höhe = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) ); bAnzahl = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) ); geschwindigkeit = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) ); bool fortsetzen = (int)*tmp != 0; tmp->release(); if( rGen ) rGen = rGen->release(); if( fortsetzen && DateiExistiert( "data/Minigames/Blöcke/data/game.save" ) && klient ) { if( capture.istOffen() ) capture.close(); capture.setDatei( "data/Minigames/Blöcke/data/game.mgc" ); capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen ); Datei *save = new Datei(); save->setDatei( "data/Minigames/Blöcke/data/game.save" ); save->open( Datei::Style::lesen ); int br = 0; int hö = 0; __int64 seed; save->lese( (char*)&seed, 8 ); rGen = new RandomGenerator(); rGen->setSeed( seed ); save->lese( (char*)&gameTime, 8 ); save->lese( (char*)&br, 4 ); save->lese( (char*)&hö, 4 ); if( br == breite && hö == höhe ) { save->lese( (char*)&score, 4 ); scoreCheck = score * 11197; for( int x = 0; x < breite; x++ ) { map->set( new Array< int >(), x ); for( int y = 0; y < höhe; y++ ) { int f = 0; save->lese( (char*)&f, 4 ); map->z( x )->set( f, y ); } } next = geschwindigkeit / 1000.0; } save->close(); save->release(); int xOff = 0; for( int x = 0; x < breite; x++ ) { if( !map->z( x - xOff ) ) continue; Array< int > *row = map->z( x - xOff ); int yOff = 0; for( int y = 0; y < höhe; y++ ) { if( row->hat( y - yOff ) && !row->get( y - yOff ) ) { row->remove( y - yOff ); yOff++; } } bool del = 1; for( int y = 0; y < höhe; y++ ) del &= !row->hat( y - yOff ) || !row->get( y - yOff ); if( del ) { map->remove( x - xOff ); xOff++; } } } else { rGen = new RandomGenerator(); if( klient ) { if( capture.istOffen() ) capture.close(); DateiRemove( "data/Minigames/Blöcke/data/game.mgc" ); capture.setDatei( "data/Minigames/Blöcke/data/game.mgc" ); capture.erstellen(); capture.open( Datei::Style::schreiben ); __int64 seed = rGen->getSeed(); capture.schreibe( (char*)&seed, 8 ); } else { tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1 ); rGen->setSeed( (__int64)*tmp ); tmp->release(); } } } void Map::doPublicMausEreignis( MausEreignis &me ) { if( beendet ) return; cs.lock(); if( me.id == ME_RRechts ) { next = 0; if( klient ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( "\x1", 1 ); } } if( me.id != ME_RLinks ) { cs.unlock(); return; } if( klient ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( "\x0", 1 ); capture.schreibe( (char*)&me.mx, 4 ); capture.schreibe( (char*)&me.my, 4 ); } int x = (int)( me.mx / ( 800.0 / breite ) ); int y = (int)( höhe - ( me.my / ( 500.0 / höhe ) ) ); if( !map->z( x ) || !map->z( x )->hat( y ) || !map->z( x )->get( y ) ) { cs.unlock(); return; } bool remove = 0; int f = map->z( x )->get( y ); if( map->z( x - 1 ) && map->z( x - 1 )->hat( y ) && map->z( x - 1 )->get( y ) == f ) remove = 1; if( map->z( x + 1 ) && map->z( x + 1 )->hat( y ) && map->z( x + 1 )->get( y ) == f ) remove = 1; if( map->z( x ) && map->z( x )->hat( y - 1 ) && map->z( x )->get( y - 1 ) == f ) remove = 1; if( map->z( x ) && map->z( x )->hat( y + 1 ) && map->z( x )->get( y + 1 ) == f ) remove = 1; if( !remove ) { cs.unlock(); return; } rend = 1; this->remove( x, y ); int xOff = 0; for( int x = 0; x < breite; x++ ) { if( !map->z( x - xOff ) ) continue; Array< int > *row = map->z( x - xOff ); int yOff = 0; for( int y = 0; y < höhe; y++ ) { if( row->hat( y - yOff ) && !row->get( y - yOff ) ) { row->remove( y - yOff ); yOff++; } } bool del = 1; for( int y = 0; y < höhe; y++ ) del &= !row->hat( y - yOff ) || !row->get( y - yOff ); if( del ) { score++; scoreCheck = score * 11197; map->remove( x - xOff ); xOff++; } } cs.unlock(); } void Map::doTastaturEreignis( TastaturEreignis &te ) { cs.lock(); if( te.id == TE_Release ) { next = 0; if( klient ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( "\x1", 1 ); } } cs.unlock(); } bool Map::tick( double tickVal ) { bool ret = rend; rend = 0; if( beendet ) return ret; cs.lock(); gameTime += tickVal; next -= tickVal; if( next < 0 ) { next = geschwindigkeit / 1000.0; Array< int > *n = new Array< int >(); for( int i = 0; i < höhe; i++ ) { int val = (int)( rGen->rand() * bAnzahl ); switch( val ) { case 0: n->set( 0xFFFF0000, i ); break; case 1: n->set( 0xFF00FF00, i ); break; case 2: n->set( 0xFF0000FF, i ); break; case 3: n->set( 0xFFFFFF00, i ); break; case 4: n->set( 0xFF00FFFF, i ); break; case 5: n->set( 0xFFFF00FF, i ); break; case 6: n->set( 0xFFFFFFFF, i ); break; case 7: n->set( 0xFFFF5555, i ); break; case 8: n->set( 0xFF55FF55, i ); break; case 9: n->set( 0xFF5555FF, i ); break; default: n->set( 0xFF000000, i ); break; } } map->add( n, 0 ); if( map->z( breite ) ) { Array< int > *row = map->z( breite ); for( int i = 0; i < höhe; i++ ) { if( row->hat( i ) ) beendet |= row->get( i ) != 0; } beendet |= ( score * 11197 != scoreCheck ); if( score * 11197 != scoreCheck ) { score = 0; scoreCheck = 0; } if( beendet && klient ) { capture.close(); DateiRemove( "data/Minigames/Blöcke/data/upload.mgc" ); DateiUmbenennen( "data/Minigames/Blöcke/data/game.mgc", "data/Minigames/Blöcke/data/upload.mgc" ); int tmpScore = score; KSGClient::MinigameServerClient *tmpKlient = klient->getThis(); new AsynchronCall( [ tmpScore, tmpKlient ]() { InitDatei *opd = new InitDatei( "data/Minigames/Blöcke/data/optionen.ini" ); opd->laden(); if( !opd->wertExistiert( "Breite" ) ) opd->addWert( "Breite", "20" ); if( !opd->wertExistiert( "Height" ) ) opd->addWert( "Height", "12" ); if( !opd->wertExistiert( "Farben" ) ) opd->addWert( "Farben", "5" ); if( !opd->wertExistiert( "Geschwindigkeit" ) ) opd->addWert( "Geschwindigkeit", "4000" ); if( !opd->wertExistiert( "Fortsetzen" ) ) opd->addWert( "Fortsetzen", "0" ); Text optionen = "Width="; optionen += opd->zWert( "Breite" )->getText(); optionen += ",Height="; optionen += opd->zWert( "Height" )->getText(); optionen += ",Farben="; optionen += opd->zWert( "Farben" )->getText(); optionen += ",Speed="; optionen += opd->zWert( "Geschwindigkeit" )->getText(); opd->release(); Datei d; d.setDatei( "data/Minigames/Blöcke/data/upload.mgc" ); tmpKlient->reportEndOfGame( "Bloecke", optionen, tmpScore, &d ); DateiRemove( "data/Minigames/Blöcke/data/upload.mgc" ); tmpKlient->release(); } ); KSGTDatei *stb = new KSGTDatei( "data/Minigames/Blöcke/data/score.ksgt" ); if( !stb->laden() ) DateiPfadErstellen( "data/Minigames/Blöcke/data/score.ksgt" ); RCArray< Text > *zeile = new RCArray< Text >(); Zeit *zeit = getZeit(); zeile->add( zeit->getZeit( "y-m-d h:i:s" ) ); zeit->release(); Text *scoreT = new Text(); scoreT->append( score ); zeile->add( scoreT ); Text *breiteT = new Text(); breiteT->append( breite ); zeile->add( breiteT ); Text *höheT = new Text(); höheT->append( höhe ); zeile->add( höheT ); Text *geschwindigkeitT = new Text(); geschwindigkeitT->append( geschwindigkeit ); zeile->add( geschwindigkeitT ); Text *bAnzahlT = new Text(); bAnzahlT->append( bAnzahl ); zeile->add( bAnzahlT ); stb->addZeile( 6, zeile ); zeile->release(); stb->speichern(); stb->release(); DateiRemove( "data/Minigames/Blöcke/data/game.save" ); } } map->remove( breite ); ret = 1; } cs.unlock(); return ret; } void Map::render( Bild &zRObj ) { for( int x = 0; x < breite; x++ ) { if( !map->z( x ) ) continue; Array< int > *row = map->z( x ); for( int y = 0; y < höhe; y++ ) { if( !row->hat( y ) ) continue; int xs = (int)( x * ( 800.0 / breite ) ); int ys = (int)( ( höhe - y - 1 ) * ( 500.0 / höhe ) ); int xe = (int)( ( x + 1 ) * ( 800.0 / breite ) ); int ye = (int)( ( höhe - y ) * ( 500.0 / höhe ) ); zRObj.fillRegion( xs, ys, xe - xs, ye - ys, row->get( y ) ); } } } void Map::speichern() { if( !beendet && klient ) { if( capture.istOffen() ) capture.close(); Datei *d = new Datei(); d->setDatei( "data/Minigames/Blöcke/data/game.save" ); d->erstellen(); d->open( Datei::Style::schreiben ); __int64 seed = rGen->getSeed(); d->schreibe( (char*)&seed, 8 ); d->schreibe( (char*)&gameTime, 8 ); d->schreibe( (char*)&breite, 4 ); d->schreibe( (char*)&höhe, 4 ); d->schreibe( (char*)&score, 4 ); for( int x = 0; x < breite; x++ ) { for( int y = 0; y < höhe; y++ ) { int f = 0; if( map->z( x ) && map->z( x )->hat( y ) ) f = map->z( x )->get( y ); d->schreibe( (char*)&f, 4 ); } } d->close(); d->release(); } else if( klient ) DateiRemove( "data/Minigames/Blöcke/data/game.save" ); } // constant int Map::getScore() const { return score; } bool Map::istBeendet() const { return beendet; } // Reference Counting Map *Map::getThis() { ref++; return this; } Map *Map::release() { ref--; if( !ref ) delete this; return 0; }