#include "Editor.h" #include #include "Interface\Dialogs\Frage.h" #include "Interface\Dialogs\Nachricht.h" #include #include #include using namespace Editor; // Inhalt der Editor Klasse aus Editor.h // Konstruktor AsteroidsEditor::AsteroidsEditor() { kamera = new Kamera2D(); minimap = new Kamera2D(); minimap->setSize( 200, 200 ); minimap->setStyle( ZeichnungHintergrund::Style::Sichtbar | ZeichnungHintergrund::Style::Rahmen ); minimap->setRahmenFarbe( 0xFFFFFFFF ); minimap->setName( "minimap" ); schrift = 0; klient = 0; laden = 0; i = 0; alpha = 0; status = START; dialogs = new Array< Dialog * >(); sts = 0; rend = 1; daten = 0; moveObj = 0; rotObj = 0; ref = 1; } // Destruktor AsteroidsEditor::~AsteroidsEditor() { if( sts ) sts->release(); if( schrift ) schrift->release(); if( klient ) klient->release(); if( laden ) laden->release(); if( i ) i->release(); if( daten ) daten->release(); dialogs->release(); kamera->release(); minimap->release(); } void AsteroidsEditor::ladeKarte() { if( sts ) sts = (SpielerTeamStruktur *)sts->release(); sts = new SpielerTeamStruktur(); klient->getSpielerTeamStruktur( sts ); if( daten ) daten->release(); daten = new KarteDaten( (EditorKlient *)klient->getThis(), sts ); i->setDaten( (KarteDaten *)daten->getThis() ); minimap->setWelt( daten->getWelt(), 0 ); minimap->lookAtWorldPos( daten->zWelt()->getWorldInfo().size / 2 ); minimap->lookAtWorldArea( daten->zWelt()->getWorldInfo().size.x, daten->zWelt()->getWorldInfo().size.y ); kamera->setWelt( daten->getWelt(), 1 ); } // nicht constant void AsteroidsEditor::addDialog( Dialog * d ) { c.lock(); dialogs->add( d ); c.unlock(); } // nicht constant void AsteroidsEditor::setSchrift( Schrift * schrift ) { if( this->schrift ) this->schrift->release(); this->schrift = schrift; if( !i && windowSize != Punkt() ) i = new Interface( schrift, windowSize ); } void AsteroidsEditor::setKlient( KSGClient::EditorServerClient * ekv ) { if( klient ) klient->release(); klient = new EditorKlient( ekv ); } void AsteroidsEditor::setLadeAnimation( Animation2D * la ) { if( laden ) laden->release(); laden = la; } void AsteroidsEditor::setSichtbar() { status = START; Punkt mS = windowSize; if( windowSize != Punkt() ) { EditorKlient *k = klient->getThis(); TextRenderer *zS = new TextRenderer( schrift->getThis() ); new AsynchronCall( [ this, k, zS, mS ]( void ) -> void { int ret = k->init(); if( ret == 2 ) { std::function< void() > wiederherstellen = [ this, k ] { status = START; ladeKarte(); this->status = INITIALIZED; }; std::function< void() > verwerfen = [ this, k, zS, mS ] { status = START; if( !k->sitzungVerwerfen() ) { Text t = "Fehler beim verwerfen der Sitzung: "; t += k->getLastError(); this->addDialog( new Nachricht( zS->getThis(), t, mS, 0 ) ); } ladeKarte(); this->status = INITIALIZED; }; this->addDialog( new Frage( zS->getThis(), "Es wurde eine alte ungespeicherte Sitzung gefunden. möchtest du sie Wiederherstellen?", "Ja", "Nein", wiederherstellen, verwerfen, verwerfen, mS ) ); this->status = INITIALIZED; } else if( ret == 1 ) { ladeKarte(); this->status = INITIALIZED; } else { Status *st = &status; this->status = INITIALIZED; this->addDialog( new Nachricht( zS->getThis(), Text( "Fehler beim Initialisieren: " ) += k->getLastError(), mS, [ st ]() { *st = EXIT; } ) ); } zS->release(); k->release(); } ); } rend = 1; } void AsteroidsEditor::doMausEreignis( MausEreignis & me ) { c.lock(); for( auto i = dialogs->getIterator(); i && i._; i++ ) i->doMausEreignis( me ); bool dialogActive = dialogs->hat( 0 ); int anz = dialogs->getEintragAnzahl(); c.unlock(); if( anz == 0 ) { i->doMausEreignis( me ); if( i->hatVerlassen() && status == INITIALIZED && !dialogActive && me.id == ME_RLinks ) { status = WARTEND; EditorKlient *k = klient->getThis(); TextRenderer *zS = new TextRenderer( schrift->getThis() ); Punkt mS = windowSize; new AsynchronCall( [ this, k, zS, mS ]( void ) -> void { if( !k->sitzungBeenden() ) { this->addDialog( new Nachricht( zS->getThis(), Text( "Fehler beim Speichern: " ) += k->getLastError(), mS, 0 ) ); status = INITIALIZED; } else status = EXIT; zS->release(); k->release(); } ); } } if( !me.verarbeitet ) { if( me.id == ME_PLinks ) { Vertex pos = kamera->getWorldCoordinates( Punkt( me.mx, me.my ) ); moveObj = (EditorObject *)daten->zWelt()->getObjectAt( (int)pos.x, (int)pos.y ); if( moveObj ) me.verarbeitet = 1; } if( me.id == ME_PMitte ) { Vertex pos = kamera->getWorldCoordinates( Punkt( me.mx, me.my ) ); rotObj = (EditorObject *)daten->zWelt()->getObjectAt( (int)pos.x, (int)pos.y ); if( rotObj ) me.verarbeitet = 1; } if( me.id == ME_Bewegung ) { if( moveObj ) { moveObj->setPosition( moveObj->getPosition() + Punkt( me.mx, me.my ) - maus ); rend = 1; me.verarbeitet = 1; } if( rotObj ) { rotObj->addDrehung( ( me.mx - maus.x ) / 100.f ); rend = 1; me.verarbeitet = 1; } } if( me.id == ME_RLinks ) { if( moveObj ) { moveObj->update(); me.verarbeitet = 1; moveObj = 0; } } if( me.id == ME_RMitte ) { if( rotObj ) { rotObj->update(); me.verarbeitet = 1; rotObj = 0; } } } if( !me.verarbeitet ) { if( getMausStand( M_Links ) ) { if( me.mx >= minimap->getX() && me.mx < minimap->getX() + minimap->getBreite() && me.my >= minimap->getY() && me.my <= minimap->getY() + minimap->getHeight() ) { kamera->lookAtWorldPos( minimap->getWorldCoordinates( Punkt( me.mx - minimap->getX(), me.my - minimap->getY() ) ) ); } else { if( me.id == ME_Bewegung ) kamera->lookAtWorldPos( kamera->getWorldPosition() + maus - Punkt( me.mx, me.my ) ); } } if( me.id == ME_UScroll ) kamera->setZoom( kamera->getZoom() / 0.9f ); if( me.id == ME_DScroll ) kamera->setZoom( kamera->getZoom() / 1.1f ); } maus.x = me.mx; maus.y = me.my; } void AsteroidsEditor::doTastaturEreignis( TastaturEreignis & te ) { c.lock(); for( auto i = dialogs->getIterator(); i && i._; i++ ) i->doTastaturEreignis( te ); int anz = dialogs->getEintragAnzahl(); c.unlock(); if( anz == 0 ) i->doTastaturEreignis( te ); } bool AsteroidsEditor::tick( double z ) { if( ( status == WARTEND || status == START || ( daten && daten->hasAktions() ) ) && alpha != 100 ) { if( laden && !laden->istSichtbar() ) laden->setSichtbar( 1 ); if( alpha < 100 ) { alpha += (unsigned char)( 100 * z ); if( alpha > 100 ) alpha = 100; } else { alpha -= (unsigned char)( 100 * z ); if( alpha < 100 ) alpha = 100; } rend = 1; } else if( alpha != 255 ) { if( laden &&laden->istSichtbar() ) laden->setSichtbar( 0 ); if( alpha + 100 * z > 255 ) alpha = 255; else alpha += (unsigned char)( 100 * z ); rend = 1; } if( laden ) rend |= laden->tick( z ); rend |= i->tick( z ); rend |= minimap->tick( z ); rend |= kamera->tick( z ); c.lock(); for( auto i = dialogs->getIterator(); i && i._; i++ ) rend |= i->tick( z ); c.unlock(); bool tmp = rend; rend = 0; return tmp; } void AsteroidsEditor::render( Bild & zRObj ) { if( windowSize == Punkt() ) { if( status != EXIT ) windowSize = zRObj.getSize(); setSichtbar(); if( !i && schrift ) i = new Interface( schrift, windowSize ); } zRObj.setAlpha( alpha ); kamera->setSize( zRObj.getSize() ); kamera->render( zRObj ); minimap->setPosition( 10, zRObj.getHeight() - 210 ); minimap->render( zRObj ); i->render( zRObj ); c.lock(); for( int i = dialogs->getEintragAnzahl() - 1; i >= 0; i-- ) { dialogs->get( i )->render( zRObj ); if( dialogs->get( i )->hatVerlassen() ) { delete dialogs->get( i ); dialogs->remove( i ); } } c.unlock(); zRObj.releaseAlpha(); if( laden ) laden->render( zRObj ); } // constant bool AsteroidsEditor::hatVerlassen( bool jetzt ) const { return status == EXIT; } // Reference Counting EditorV *AsteroidsEditor::getThis() { ref++; return this; } EditorV *AsteroidsEditor::release() { ref--; if( !ref ) delete this; return 0; }