Prechádzať zdrojové kódy

use framework uiInit and referenceCounter

Kolja Strohm 3 rokov pred
rodič
commit
b9f4e8511d
67 zmenil súbory, kde vykonal 3716 pridanie a 1884 odobranie
  1. 82 8
      StickmanWorldOnline/Aktionen.cpp
  2. 16 0
      StickmanWorldOnline/Aktionen.h
  3. 9 9
      StickmanWorldOnline/Bariere.cpp
  4. 8 8
      StickmanWorldOnline/Base.cpp
  5. 6 8
      StickmanWorldOnline/Bestenliste.cpp
  6. 3 2
      StickmanWorldOnline/Bestenliste.h
  7. 22 22
      StickmanWorldOnline/DLLStart.cpp
  8. 2 2
      StickmanWorldOnline/Drop.cpp
  9. 344 0
      StickmanWorldOnline/Editor.cpp
  10. 3 9
      StickmanWorldOnline/Editor.h
  11. 1 0
      StickmanWorldOnline/EditorKarte.cpp
  12. 310 86
      StickmanWorldOnline/EditorKarte.h
  13. 1421 0
      StickmanWorldOnline/EditorKlient.cpp
  14. 44 19
      StickmanWorldOnline/EditorKlient.h
  15. 4 17
      StickmanWorldOnline/Effect.cpp
  16. 1 4
      StickmanWorldOnline/Effect.h
  17. 50 0
      StickmanWorldOnline/EncryptedNetworkReader.cpp
  18. 33 0
      StickmanWorldOnline/EncryptedNetworkReader.h
  19. 57 77
      StickmanWorldOnline/Ende.cpp
  20. 17 20
      StickmanWorldOnline/Ende.h
  21. 1 1
      StickmanWorldOnline/Enterhaken.cpp
  22. 2 15
      StickmanWorldOnline/Ereignis.cpp
  23. 1 4
      StickmanWorldOnline/Ereignis.h
  24. 21 0
      StickmanWorldOnline/Frage.h
  25. 18 18
      StickmanWorldOnline/Gegenstand.cpp
  26. 11 11
      StickmanWorldOnline/Geschoss.cpp
  27. 28 32
      StickmanWorldOnline/HistorieStatistik.h
  28. 80 193
      StickmanWorldOnline/Initialisierung.cpp
  29. 11 11
      StickmanWorldOnline/Initialisierung.h
  30. 3 10
      StickmanWorldOnline/Interface.h
  31. 24 0
      StickmanWorldOnline/Model.cpp
  32. 17 0
      StickmanWorldOnline/Model.h
  33. 18 0
      StickmanWorldOnline/Nachricht.h
  34. 137 137
      StickmanWorldOnline/Reader.cpp
  35. 6 8
      StickmanWorldOnline/Reader.h
  36. 15 65
      StickmanWorldOnline/Resource.cpp
  37. 13 24
      StickmanWorldOnline/Resource.h
  38. 0 7
      StickmanWorldOnline/RightTools.h
  39. 1 1
      StickmanWorldOnline/Rolle.cpp
  40. 9 24
      StickmanWorldOnline/STKNachricht.cpp
  41. 16 18
      StickmanWorldOnline/STKNachricht.h
  42. 3 3
      StickmanWorldOnline/Schalter.cpp
  43. 1 1
      StickmanWorldOnline/Schiene.cpp
  44. 86 107
      StickmanWorldOnline/Spiel.cpp
  45. 3 9
      StickmanWorldOnline/Spiel.h
  46. 89 114
      StickmanWorldOnline/SpielChat.cpp
  47. 18 22
      StickmanWorldOnline/SpielChat.h
  48. 5 31
      StickmanWorldOnline/SpielStatistik.cpp
  49. 2 8
      StickmanWorldOnline/SpielStatistik.h
  50. 37 37
      StickmanWorldOnline/Spieler.cpp
  51. 8 15
      StickmanWorldOnline/SpielerGUI.cpp
  52. 312 360
      StickmanWorldOnline/StatistikChat.cpp
  53. 86 99
      StickmanWorldOnline/StatistikChat.h
  54. 29 45
      StickmanWorldOnline/StatistikTabelle.cpp
  55. 25 28
      StickmanWorldOnline/StatistikTabelle.h
  56. 9 0
      StickmanWorldOnline/StickmanWorldOnline.vcxproj
  57. 48 9
      StickmanWorldOnline/StickmanWorldOnline.vcxproj.filters
  58. 1 1
      StickmanWorldOnline/Sturm.cpp
  59. 7 7
      StickmanWorldOnline/Timer.cpp
  60. 11 72
      StickmanWorldOnline/Trigger.cpp
  61. 6 20
      StickmanWorldOnline/Trigger.h
  62. 2 2
      StickmanWorldOnline/Tunnel.cpp
  63. 3 3
      StickmanWorldOnline/Umlenkung.cpp
  64. 4 17
      StickmanWorldOnline/Variablen.cpp
  65. 12 4
      StickmanWorldOnline/Variablen.h
  66. 20 0
      StickmanWorldOnline/View.cpp
  67. 24 0
      StickmanWorldOnline/View.h

+ 82 - 8
StickmanWorldOnline/Aktionen.cpp

@@ -54,7 +54,7 @@ bool Aktion::runNext( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory,
             return 1;
         }
         if( result )
-            zMemory->setVar( zPC->getUniqueString() + "R" + i + "__", result->getThis() );
+            zMemory->setVar( zPC->getUniqueString() + "R" + i + "__", dynamic_cast<Variable *>( result->getThis() ) );
         zPC->count();
         if( waitCount > 0 )
         {
@@ -76,6 +76,19 @@ bool Aktion::runNext( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory,
 void Aktion::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount )
 {}
 
+void Aktion::writeOptions( StreamWriter &dat )
+{}
+
+AktionTyp Aktion::getTyp() const
+{
+    return typ;
+}
+
+RCArray< Aktion > *Aktion::zSubActions() const
+{
+    return subActions;
+}
+
 
 KonstantNichts::KonstantNichts()
     : Aktion( KONSTANT_NICHTS, new RCArray< Aktion >() )
@@ -98,6 +111,11 @@ void KonstantInteger::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMem
     setReturn( new Integer( value ) );
 }
 
+void KonstantInteger::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&value, 4 );
+}
+
 
 KonstantGegenstandTyp::KonstantGegenstandTyp( GegenstandTyp val )
     : Aktion( KONSTANT_GEGENSTAND_TYP, new RCArray< Aktion >() )
@@ -110,6 +128,11 @@ void KonstantGegenstandTyp::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory
     setReturn( new GegenstandTypVar( value ) );
 }
 
+void KonstantGegenstandTyp::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&value, 4 );
+}
+
 
 KonstantTaste::KonstantTaste( unsigned char val )
     : Aktion( KONSTANT_TASTE, new RCArray< Aktion >() )
@@ -122,6 +145,11 @@ void KonstantTaste::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemor
     setReturn( new Integer( (int)value, 1 ) );
 }
 
+void KonstantTaste::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&value, 1 );
+}
+
 
 KonstantBoolean::KonstantBoolean( bool val )
     : Aktion( KONSTANT_BOOLEAN, new RCArray< Aktion >() )
@@ -134,6 +162,11 @@ void KonstantBoolean::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMem
     setReturn( new Boolean( value ) );
 }
 
+void KonstantBoolean::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&value, 1 );
+}
+
 
 KonstantString::KonstantString( Text val )
     : Aktion( KONSTANT_STRING, new RCArray< Aktion >() )
@@ -146,6 +179,13 @@ void KonstantString::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemo
     setReturn( new String( value ) );
 }
 
+void KonstantString::writeOptions( StreamWriter &dat )
+{
+    char len = (char)value.getLength();
+    dat.schreibe( (char *)&len, 1 );
+    dat.schreibe( value, len );
+}
+
 
 KonstantFloat::KonstantFloat( float val )
     : Aktion( KONSTANT_FLOAT, new RCArray< Aktion >() )
@@ -158,6 +198,11 @@ void KonstantFloat::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemor
     setReturn( new Float( value ) );
 }
 
+void KonstantFloat::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&value, 4 );
+}
+
 
 KonstantVariable::KonstantVariable( Text name )
     : Aktion( KONSTANT_VARIABLE, new RCArray< Aktion >() )
@@ -177,6 +222,13 @@ void KonstantVariable::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMe
         setReturn( new Variable( NICHTS ) );
 }
 
+void KonstantVariable::writeOptions( StreamWriter &dat )
+{
+    char len = (char)name.getLength();
+    dat.schreibe( (char *)&len, 1 );
+    dat.schreibe( name, len );
+}
+
 
 Warten::Warten( RCArray< Aktion > *subActions )
     : Aktion( WARTEN, subActions )
@@ -260,6 +312,13 @@ void SetVariable::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory,
         zSpiel->setVariable( name, getParam( 0 ) );
 }
 
+void SetVariable::writeOptions( StreamWriter &dat )
+{
+    char len = (char)name.getLength();
+    dat.schreibe( (char *)&len, 1 );
+    dat.schreibe( name, len );
+}
+
 
 TriggerAktion::TriggerAktion( RCArray< Aktion > *subActions )
     : Aktion( TRIGGER_AKTION, subActions )
@@ -278,7 +337,7 @@ bool TriggerAktion::runNext( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zM
                 zPC->stepOut();
                 return 1;
             }
-            zMemory->setVar( zPC->getUniqueString() + "R0__", t->getThis() );
+            zMemory->setVar( zPC->getUniqueString() + "R0__", dynamic_cast<Variable *>( t->getThis() ) );
             zPC->count();
         }
     }
@@ -393,7 +452,7 @@ SpielerGiveItem::SpielerGiveItem( RCArray< Aktion > *subActions )
 void SpielerGiveItem::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount )
 {
     ( (Spieler *)zParam( 2 ) )->addItem( ( (GegenstandTypVar *)zParam( 0 ) )->getValue(),
-        ( (Integer *)zParam( 1 ) )->getValue(), zSpiel );
+                                         ( (Integer *)zParam( 1 ) )->getValue(), zSpiel );
 }
 
 
@@ -408,7 +467,7 @@ SpielerRemoveItem::SpielerRemoveItem( RCArray< Aktion > *subActions )
 void SpielerRemoveItem::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount )
 {
     ( (Spieler *)zParam( 2 ) )->removeItem( ( (GegenstandTypVar *)zParam( 0 ) )->getValue(),
-        ( (Integer *)zParam( 1 ) )->getValue() );
+                                            ( (Integer *)zParam( 1 ) )->getValue() );
 }
 
 
@@ -806,7 +865,7 @@ TriggerRunStart::TriggerRunStart( RCArray< Aktion > *subActions )
 
 void TriggerRunStart::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount )
 {
-    zSpiel->addTriggerRun( ( (Trigger *)zParam( 0 ) )->runTrigger( zEreignis->getThis(), zSpiel ) );
+    zSpiel->addTriggerRun( ( (Trigger *)zParam( 0 ) )->runTrigger( dynamic_cast<Ereignis *>( zEreignis->getThis() ), zSpiel ) );
 }
 
 
@@ -903,7 +962,7 @@ void GeschossNeu::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory,
                                 getRichtungFromString( ( (String *)zParam( 3 ) )->getValue() ),
                                 ( (Integer *)zParam( 0 ) )->getValue(),
                                 ( (Integer *)zParam( 1 ) )->getValue(), 0 );
-    zSpiel->addGeschoss( (Geschoss *)g->getThis() );
+    zSpiel->addGeschoss( dynamic_cast<Geschoss *>( g->getThis() ) );
     setReturn( g );
 }
 
@@ -1146,6 +1205,11 @@ void IntegerRechnen::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemo
     }
 }
 
+void IntegerRechnen::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&this->op, 1 );
+}
+
 
 IntegerZufall::IntegerZufall( RCArray< Aktion > *subActions )
     : Aktion( INTEGER_ZUFALL, subActions )
@@ -2688,6 +2752,11 @@ void BooleanRechnung::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMem
     }
 }
 
+void BooleanRechnung::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&this->op, 1 );
+}
+
 
 Sequenz::Sequenz( RCArray< Aktion > *subActions )
     : Aktion( SEQUENZ, subActions )
@@ -2765,6 +2834,11 @@ void FloatRechnung::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemor
     }
 }
 
+void FloatRechnung::writeOptions( StreamWriter &dat )
+{
+    dat.schreibe( (char *)&op, 1 );
+}
+
 
 FloatAusInteger::FloatAusInteger( RCArray< Aktion > *subActions )
     : Aktion( FLOAT_AUS_INTEGER, subActions )
@@ -2835,9 +2909,9 @@ BestenlisteNeu::BestenlisteNeu( RCArray<Aktion> *subActions )
 
 void BestenlisteNeu::run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount )
 {
-    Bestenliste *b = new Bestenliste( zSpiel->getNextId(), zSpiel->zResources()->getSchrift() );
+    Bestenliste *b = new Bestenliste( zSpiel->getNextId(), zSpiel->zResources()->getUIFactory() );
     zSpiel->addBestenliste( b );
-    setReturn( b->getThis() );
+    setReturn( dynamic_cast<Bestenliste *>( b->getThis() ) );
 }
 
 

+ 16 - 0
StickmanWorldOnline/Aktionen.h

@@ -2,6 +2,7 @@
 
 #include "Variablen.h"
 #include <Array.h>
+#include <Writer.h>
 
 class Spiel;
 class Ereignis;
@@ -270,6 +271,10 @@ public:
     // gibt 1 zurück, wenn die aktion vollständig ausgeführt wurde
     virtual bool runNext( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount );
     virtual void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount );
+
+    virtual void writeOptions( StreamWriter &dat );
+    AktionTyp getTyp() const;
+    RCArray< Aktion > *zSubActions() const;
 };
 
 class KonstantNichts : public Aktion
@@ -287,6 +292,7 @@ private:
 public:
     KonstantInteger( int val );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class KonstantGegenstandTyp : public Aktion
@@ -297,6 +303,7 @@ private:
 public:
     KonstantGegenstandTyp( GegenstandTyp val );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class KonstantTaste : public Aktion
@@ -307,6 +314,7 @@ private:
 public:
     KonstantTaste( unsigned char taste );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class KonstantBoolean : public Aktion
@@ -317,6 +325,7 @@ private:
 public:
     KonstantBoolean( bool val );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class KonstantString : public Aktion
@@ -327,6 +336,7 @@ private:
 public:
     KonstantString( Text val );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class KonstantFloat : public Aktion
@@ -337,6 +347,7 @@ private:
 public:
     KonstantFloat( float val );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class KonstantVariable : public Aktion
@@ -347,6 +358,7 @@ private:
 public:
     KonstantVariable( Text name );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class Warten : public Aktion
@@ -374,6 +386,7 @@ public:
     // value
     SetVariable( Text name, RCArray< Aktion > *subActions );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class TriggerAktion : public Aktion
@@ -847,6 +860,7 @@ public:
     // left, right
     IntegerRechnen( RCArray< Aktion > *subActions, Operator op );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class IntegerZufall : public Aktion
@@ -1787,6 +1801,7 @@ public:
     // v1, v2
     BooleanRechnung( RCArray< Aktion > *subActions, Operator op );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class Sequenz : public Aktion
@@ -1805,6 +1820,7 @@ public:
     // left, right
     FloatRechnung( RCArray< Aktion > *subActions, Operator op );
     void run( Spiel *zSpiel, Ereignis *zEreignis, LocalMemory *zMemory, ProgramCounter *zPC, double &waitCount ) override;
+    void writeOptions( StreamWriter &dat ) override;
 };
 
 class FloatAusInteger : public Aktion

+ 9 - 9
StickmanWorldOnline/Bariere.cpp

@@ -15,9 +15,9 @@ Bariere::Bariere( ResourceRegistry *zResources, int id, int x, int y, int breite
     verschiebungAnzahl = 0;
     schaltungAnzahl = 0;
     this->team = team;
-    this->resources = zResources->getThis();
+    this->resources = dynamic_cast<ResourceRegistry *>( zResources->getThis() );
     if( breite > height )
-        this->textur = resources->zResource( R_BARIERE, team ? team->getFarbe() : 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( resources->zResource( R_BARIERE, team ? team->getFarbe() : 0 )->getImages()->getThis() );
     else
     {
         Bild *r = resources->zResource( R_BARIERE, team ? team->getFarbe() : 0 )->getImages();
@@ -39,13 +39,13 @@ void Bariere::setStyle( int style, bool add, Spiel *zSpiel )
     if( add )
     {
         if( ( style | Style::Aktiv ) == style && ( this->style | Style::Aktiv ) != this->style )
-            zSpiel->setZuletztEingeschalteteBariere( (Bariere *)getThis() );
+            zSpiel->setZuletztEingeschalteteBariere( dynamic_cast<Bariere *>( getThis() ) );
         this->style |= style;
     }
     else
     {
         if( ( style | Style::Aktiv ) == style && ( this->style | Style::Aktiv ) == this->style )
-            zSpiel->setZuletztAusgeschalteteBariere( (Bariere *)getThis() );
+            zSpiel->setZuletztAusgeschalteteBariere( dynamic_cast<Bariere *>( getThis() ) );
         this->style &= ~style;
     }
 }
@@ -59,11 +59,11 @@ void Bariere::startAutoVerschiebung( Spiel *zSpiel )
 {
     if( !hatStyle( Style::AutoVerschiebung ) || hatStyle( Style::InVerschiebung ) )
         return;
-    zSpiel->setZuletztBewegteBariere( (Bariere *)getThis() );
+    zSpiel->setZuletztBewegteBariere( dynamic_cast<Bariere *>( getThis() ) );
     currentWeite = 0;
     setStyle( Style::InVerschiebung, 1, zSpiel );
     Ereignis *e = new Ereignis( BARIERE_WIRD_VERSCHOBEN );
-    e->addParameter( "Betroffene Bariere", getThis() );
+    e->addParameter( "Betroffene Bariere", dynamic_cast<Bariere *>( getThis() ) );
     e->addParameter( "Status", new String( "Start" ) );
     zSpiel->throwEvent( e );
 }
@@ -110,7 +110,7 @@ void Bariere::tick( double time, Spiel *zSpiel )
             setStyle( Style::Aktiv, !hatStyle( Style::Aktiv ), zSpiel );
             schaltungAnzahl++;
             Ereignis *e = new Ereignis( BARIERE_SWITCHED );
-            e->addParameter( "Betroffene Bariere", getThis() );
+            e->addParameter( "Betroffene Bariere", dynamic_cast<Bariere *>( getThis() ) );
             zSpiel->throwEvent( e );
         }
     }
@@ -125,7 +125,7 @@ void Bariere::tick( double time, Spiel *zSpiel )
             setStyle( Style::NextVerschiebungLinksOben, !hatStyle( Style::NextVerschiebungLinksOben ), zSpiel );
             verschiebungAnzahl++;
             Ereignis *e = new Ereignis( BARIERE_WIRD_VERSCHOBEN );
-            e->addParameter( "Betroffene Bariere", getThis() );
+            e->addParameter( "Betroffene Bariere", dynamic_cast<Bariere *>( getThis() ) );
             e->addParameter( "Status", new String( "Feritg" ) );
             zSpiel->throwEvent( e );
         }
@@ -179,7 +179,7 @@ Team *Bariere::getTeam() const
 {
     if( !team )
         return 0;
-    return (Team *)team->getThis();
+    return  dynamic_cast<Team *>( team->getThis() );
 }
 
 Team *Bariere::zTeam() const

+ 8 - 8
StickmanWorldOnline/Base.cpp

@@ -17,8 +17,8 @@ Base::Base( ResourceRegistry *zResources, int id, int x, int y, int width, int h
     inChange = 0;
     nextTeam = 0;
     leftTime = (float)maxTime;
-    resources = zResources->getThis();
-    this->textur = resources->zResource( R_BASE, team ? team->getFarbe() : 0 )->getImages()->getThis();
+    resources = dynamic_cast<ResourceRegistry *>( zResources->getThis() );
+    this->textur = dynamic_cast<Bild *>( resources->zResource( R_BASE, team ? team->getFarbe() : 0 )->getImages()->getThis() );
     texturScale = 1;
 }
 
@@ -35,16 +35,16 @@ Base::~Base()
 void Base::setTeam( Team *team, Spiel *zSpiel )
 {
     Ereignis *e = new Ereignis( BASIS_BESITZERWECHSEL );
-    e->addParameter( "Betroffene Basis", getThis() );
-    e->addParameter( "Vorheriges Team", this->team ? this->team->getThis() : new Variable( NICHTS ) );
-    e->addParameter( "Nächstes Team", team ? team->getThis() : new Variable( NICHTS ) );
+    e->addParameter( "Betroffene Basis", dynamic_cast<Base *>( getThis() ) );
+    e->addParameter( "Vorheriges Team", this->team ? dynamic_cast<Base *>( this->team->getThis() ) : new Variable( NICHTS ) );
+    e->addParameter( "Nächstes Team", team ? dynamic_cast<Team *>( team->getThis() ) : new Variable( NICHTS ) );
     if( this->team )
         this->team->release();
     this->team = team;
     if( textur )
         textur->release();
-    textur = resources->zResource( R_BASE, team ? team->getFarbe() : 0 )->getImages()->getThis();
-    zSpiel->setLastTeamChangedBase( (Base *)getThis() );
+    textur = dynamic_cast<Bild *>( resources->zResource( R_BASE, team ? team->getFarbe() : 0 )->getImages()->getThis() );
+    zSpiel->setLastTeamChangedBase( dynamic_cast<Base *>( getThis() ) );
     zSpiel->throwEvent( e );
 }
 
@@ -104,7 +104,7 @@ int Base::getId() const
 
 Team *Base::getTeam() const
 {
-    return team ? (Team *)team->getThis() : 0;
+    return team ? dynamic_cast<Team *>( team->getThis() ) : 0;
 }
 
 Team *Base::zTeam() const

+ 6 - 8
StickmanWorldOnline/Bestenliste.cpp

@@ -2,10 +2,10 @@
 #include "Initialisierung.h"
 
 
-Bestenliste::Bestenliste( int id, Schrift *schrift )
+Bestenliste::Bestenliste( int id, UIInit &uiFactory )
     : Variable( BESTENLISTE )
 {
-    this->schrift = schrift;
+    this->uiFactory = uiFactory;
     this->id = id;
     ram.setFarbe( 0xFFFFFFFF );
     ram.setRamenBreite( 1 );
@@ -13,9 +13,7 @@ Bestenliste::Bestenliste( int id, Schrift *schrift )
 }
 
 Bestenliste::~Bestenliste()
-{
-    schrift->release();
-}
+{}
 
 int Bestenliste::getSpaltenBreite( int j ) const
 {
@@ -48,12 +46,12 @@ void Bestenliste::setSichtbar( bool sichtbar )
 
 void Bestenliste::addSpalte( const char *name )
 {
-    spalten.add( initTextFeld( 0, 0, -1, -1, schrift, TextFeld::Style::Text | TextFeld::Style::Center, name ) );
+    spalten.add( initTextFeld( 0, 0, -1, -1, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, name ) );
 }
 
 void Bestenliste::addZeile( const char *name )
 {
-    zeilen.add( initTextFeld( 0, 0, -1, -1, schrift, TextFeld::Style::Text | TextFeld::Style::Center, name ) );
+    zeilen.add( initTextFeld( 0, 0, -1, -1, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, name ) );
 }
 
 void Bestenliste::setWert( const char *spalte, const char *zeile, const char *wert )
@@ -72,7 +70,7 @@ void Bestenliste::setWert( const char *spalte, const char *zeile, const char *we
     }
     if( !werte.z( zeileI ) )
         werte.set( new RCArray< TextFeld >(), zeileI );
-    werte.z( zeileI )->set( initTextFeld( 0, 0, -1, 20, schrift, TextFeld::Style::Text | TextFeld::Style::Center, wert ), spalteI );
+    werte.z( zeileI )->set( initTextFeld( 0, 0, -1, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, wert ), spalteI );
 }
 
 const char *Bestenliste::getWert( const char *spalte, const char *zeile )

+ 3 - 2
StickmanWorldOnline/Bestenliste.h

@@ -5,6 +5,7 @@
 #include "Array.h"
 #include <TextFeld.h>
 #include <Rahmen.h>
+#include <UIInitialization.h>
 
 
 class Bestenliste : public Variable
@@ -13,7 +14,7 @@ private:
     RCArray< TextFeld > spalten;
     RCArray< TextFeld > zeilen;
     RCArray< RCArray< TextFeld > > werte;
-    Schrift *schrift;
+    UIInit uiFactory;
     LRahmen ram;
     int id;
     bool sichtbar;
@@ -21,7 +22,7 @@ private:
     int getSpaltenBreite( int i ) const;
 
 public:
-    Bestenliste( int id, Schrift *schrift );
+    Bestenliste( int id, UIInit &uiFactory );
     ~Bestenliste();
     void setSichtbar( bool sichtbar );
     void addSpalte( const char *name );

+ 22 - 22
StickmanWorldOnline/DLLStart.cpp

@@ -7,31 +7,31 @@
 
 extern "C"
 { // Dll Einstiegs Funktionen
-	__declspec( dllexport ) SpielV *getSpielKlasse()
-	{
-		return new Spiel();
-	}
+    __declspec( dllexport ) SpielV *getSpielKlasse()
+    {
+        return new Spiel();
+    }
 
-	__declspec( dllexport ) SpielStatistikV *GetStatistikKlasse()
-	{
-		return new SpielStatistik();
-	}
+    __declspec( dllexport ) SpielStatistikV *GetStatistikKlasse()
+    {
+        return new SpielStatistik();
+    }
 
-	__declspec( dllexport ) AccountHistorieStatistikV *GetAccountHistorieStatistik()
-	{
-		return 0;
-		//return new HistorieStatistik();
-	}
+    __declspec( dllexport ) AccountHistorieStatistikV *GetAccountHistorieStatistik()
+    {
+        return 0;
+        //return new HistorieStatistik();
+    }
 
-	__declspec( dllexport ) AufzeichnungV *GetAufzeichnung()
-	{
-		return 0;
-		//return new Aufzeichnung();
-	}
+    __declspec( dllexport ) AufzeichnungV *GetAufzeichnung()
+    {
+        return 0;
+        //return new Aufzeichnung();
+    }
 
-	__declspec( dllexport ) EditorV *getEditor()
-	{
+    __declspec( dllexport ) EditorV *getEditor()
+    {
+        //return new Editor::SMWEditor();
         return 0;
-		//return new Editor::SMWEditor();
-	}
+    }
 }

+ 2 - 2
StickmanWorldOnline/Drop.cpp

@@ -52,7 +52,7 @@ void Drop::setTime( float time )
 
 void Drop::doDrop( Spiel *zSpiel )
 {
-    zSpiel->setLastDrop( (Drop *)getThis() );
+    zSpiel->setLastDrop( dynamic_cast<Drop *>( getThis() ) );
     nextDrop = (float)maxTime;
     for( int i = 0; i < numDrops; i++ )
     {
@@ -70,7 +70,7 @@ void Drop::doDrop( Spiel *zSpiel )
             zSpiel->addGegenstand( new Gegenstand( zSpiel->zResources(), zSpiel->getNextId(), (GegenstandTyp)typ, x, y ) );
     }
     Ereignis *e = new Ereignis( DROP_AKTION );
-    e->addParameter( "Betroffener Drop", getThis() );
+    e->addParameter( "Betroffener Drop", dynamic_cast<Drop *>( getThis() ) );
     zSpiel->throwEvent( e );
 }
 

+ 344 - 0
StickmanWorldOnline/Editor.cpp

@@ -0,0 +1,344 @@
+#include "Editor.h"
+#include <AsynchronCall.h>
+#include "Nachricht.h"
+#include "Frage.h"
+#include <Globals.h>
+#include <Bild.h>
+
+using namespace Editor;
+/*
+// Konstruktor
+SMWEditor::SMWEditor()
+    : ReferenceCounter()
+{
+    status = START;
+    klient = 0;
+    laden = 0;
+    i = 0;
+    dialogs = new Array< Dialog * >();
+    sts = 0;
+    daten = 0;
+    moveObj = 0;
+    rotObj = 0;
+    alpha = 0;
+    rend = 0;
+    uiFactory.initParam.schrift = 0;
+}
+
+// Destruktor
+SMWEditor::~SMWEditor()
+{
+    if( klient )
+        klient->release();
+    if( laden )
+        laden->release();
+    if( i )
+        i->release();
+    if( sts )
+        sts->release();
+    if( daten )
+        daten->release();
+    if( moveObj )
+        moveObj->release();
+    if( rotObj )
+        rotObj->release();
+    dialogs->release();
+}
+
+// private
+void SMWEditor::ladeKarte()
+{
+    if( sts )
+        sts = (SpielerTeamStruktur *)sts->release();
+    sts = new SpielerTeamStruktur();
+    klient->getSpielerTeamStruktur( sts );
+    if( daten )
+        daten->release();
+    daten = new KarteDaten( dynamic_cast<EditorKlient *>( klient->getThis() ), sts );
+    i->setDaten( dynamic_cast<KarteDaten *>( daten->getThis() ) );
+}
+
+// nicht constant
+void SMWEditor::addDialog( Dialog *d )
+{
+    c.lock();
+    dialogs->add( d );
+    c.unlock();
+}
+
+void SMWEditor::setUIFactory( UIInit &uiFactory )
+{
+    this->uiFactory = uiFactory;
+    if( !i && windowSize != Punkt() )
+        i = new Interface( uiFactory, windowSize );
+}
+
+void SMWEditor::setKlient( KSGClient::EditorServerClient *ekv )
+{
+    if( klient )
+        klient->release();
+    klient = new EditorKlient( ekv );
+}
+
+void SMWEditor::setLadeAnimation( Animation2D *la )
+{
+    if( laden )
+        laden->release();
+    laden = la;
+}
+
+void SMWEditor::setSichtbar()
+{
+    status = START;
+    Punkt mS = windowSize;
+    if( windowSize != Punkt() )
+    {
+        EditorKlient *k = dynamic_cast<EditorKlient *>( klient->getThis() );
+        TextRenderer *zS = new TextRenderer( dynamic_cast<Schrift *>( uiFactory.initParam.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( dynamic_cast<TextRenderer *>( zS->getThis() ), t, mS, 0 ) );
+                    }
+                    ladeKarte();
+                    this->status = INITIALIZED;
+                };
+                this->addDialog( new Frage( dynamic_cast<TextRenderer *>( 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( dynamic_cast<TextRenderer *>( zS->getThis() ), Text( "Fehler beim Initialisieren: " ) += k->getLastError(), mS, [st]() { *st = EXIT; } ) );
+            }
+            zS->release();
+            k->release();
+        } );
+    }
+    rend = 1;
+}
+
+void SMWEditor::doPublicMausEreignis( MausEreignis &me )
+{
+    //TODO
+    c.lock();
+    for( auto i = dialogs->getIterator(); i && i._; i++ )
+        i->doPublicMausEreignis( me );
+    bool dialogActive = dialogs->hat( 0 );
+    int anz = dialogs->getEintragAnzahl();
+    c.unlock();
+    if( anz == 0 )
+    {
+        i->doPublicMausEreignis( me );
+        if( i->hatVerlassen() && status == INITIALIZED && !dialogActive && me.id == ME_RLinks )
+        {
+            status = WARTEND;
+            EditorKlient *k = dynamic_cast<EditorKlient *>( klient->getThis() );
+            TextRenderer *zS = new TextRenderer( dynamic_cast<Schrift *>( uiFactory.initParam.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()->zObjectAt( (int)pos.x, (int)pos.y, 1 );
+            if( moveObj )
+                me.verarbeitet = 1;
+        }
+        if( me.id == ME_PMitte )
+        {
+            Vertex pos = kamera->getWorldCoordinates( Punkt( me.mx, me.my ) );
+            rotObj = (EditorObject *)daten->zWelt()->zObjectAt( (int)pos.x, (int)pos.y, 1 );
+            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 SMWEditor::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 SMWEditor::tick( double z )
+{
+    if( ( status == WARTEND || status == START || ( daten && daten->hasAktions() ) ) )
+    {
+        if( 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;
+    return 0;
+}
+
+void SMWEditor::render( Bild &zRObj )
+{
+    if( windowSize == Punkt() )
+    {
+        if( status != EXIT )
+            windowSize = zRObj.getSize();
+        setSichtbar();
+        if( !i && uiFactory.initParam.schrift )
+            i = new Interface( uiFactory, 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 SMWEditor::hatVerlassen( bool jetzt ) const
+{
+    return status == EXIT;
+}
+*/

+ 3 - 9
StickmanWorldOnline/Editor.h

@@ -22,23 +22,20 @@ namespace Editor
             EXIT
         };
         Status status;
-        Schrift *schrift;
+        UIInit uiFactory;
         EditorKlient *klient;
         Animation2D *laden;
         Interface *i;
-        Array< Dialog* > *dialogs;
+        Array< Dialog * > *dialogs;
         Critical c;
         Punkt windowSize;
         SpielerTeamStruktur *sts;
         KarteDaten *daten;
-        Kamera2D *kamera;
-        Kamera2D *minimap;
         Punkt maus;
         EditorObject *moveObj;
         EditorObject *rotObj;
         unsigned char alpha;
         bool rend;
-        int ref;
 
         void ladeKarte();
 
@@ -49,7 +46,7 @@ namespace Editor
         ~SMWEditor();
         // nicht constant
         void addDialog( Dialog *d );
-        void setSchrift( Schrift *schrift ) override;
+        void setUIFactory( UIInit &uiFactory ) override;
         void setKlient( KSGClient::EditorServerClient *ekv ) override;
         void setLadeAnimation( Animation2D *la ) override;
         void setSichtbar() override;
@@ -59,9 +56,6 @@ namespace Editor
         void render( Bild &zRObj ) override;
         // constant
         bool hatVerlassen( bool jetzt ) const override;
-        // Reference Counting
-        EditorV *getThis() override;
-        EditorV *release() override;
     };
 }
 

+ 1 - 0
StickmanWorldOnline/EditorKarte.cpp

@@ -0,0 +1 @@
+#include "EditorKarte.h"

+ 310 - 86
StickmanWorldOnline/EditorKarte.h

@@ -7,90 +7,175 @@
 #include <Welt2D.h>
 #include <Model2D.h>
 #include <GSLDateiV.h>
+#include "Model.h"
+#include "Variablen.h"
+#include "Trigger.h"
 
 namespace Editor
 {
-    struct ResourceDaten
+    struct TeamDaten : public Model
     {
         int id;
-        Text path;
+        int maxWbzeit;
+        int punkte;
+
+        TeamDaten();
+        TeamDaten( const TeamDaten &daten );
     };
 
-    struct SpielerDaten //: public Model
+    struct SpielerDaten : public Model
     {
         int id;
-        Punkt pos;
-        double rot;
-        double beschleunigung;
-        int maxStabilität;
-        int maxEnergie;
-        double reparatur;
-        double akkuLeistung;
-        int laserIntensität;
-        int laserEffizienz;
-        int laserTempo;
-        double wendigkeit;
-        double antriebEffizienz;
-        double energieSchild;
-        double energieSchildEffizienz;
-        int netzwerk;
-        int skillPunkte;
-        int m2d;
-        int bild;
+        Punkt spawn;
 
         SpielerDaten();
         SpielerDaten( const SpielerDaten &daten );
     };
 
-    struct TeamDaten// : public Model
+    struct BariereDaten : public Model
     {
         int id;
-        int maxPunkte;
-        double beschleunigung;
-        int maxStabilität;
-        int maxEnergie;
-        double reparatur;
-        double akkuLeistung;
-        int laserIntensität;
-        int laserEffizienz;
-        int laserTempo;
-        double wendigkeit;
-        double antriebEffizienz;
-        double energieSchild;
-        double energieSchildEffizienz;
-        int punkte;
+        Punkt pos;
+        Punkt size;
+        int style;
+        int verschiebungWeite;
+        int autoSchaltungMaxTime;
+        int team;
 
-        TeamDaten();
-        TeamDaten( const TeamDaten &daten );
+        BariereDaten();
+        BariereDaten( const BariereDaten &daten );
+    };
+
+    struct BaseDaten : public Model
+    {
+        int id;
+        Punkt pos;
+        Punkt size;
+        int maxTime;
+        int team;
+        bool showTimer;
+        Punkt timer;
+        int timerFarbe;
+
+        BaseDaten();
+        BaseDaten( const BariereDaten &daten );
+    };
+
+    struct DropDaten : public Model
+    {
+        int id;
+        Punkt minPos;
+        Punkt maxPos;
+        int maxTime;
+        int numDrops;
+        float wahrscheinlichkeit[ ITEMANZAHL ];
+        Text name;
+
+        DropDaten();
+        DropDaten( const BariereDaten &daten );
     };
 
-    struct ObjektDaten //: public Model
+    struct SchalterDaten : public Model
     {
+        int id;
         Punkt pos;
-        float rot;
-        float scale;
+        Punkt size;
+        bool aktiv;
+
+        SchalterDaten();
+        SchalterDaten( const BariereDaten &daten );
+    };
+
+    struct SchieneDaten : public Model
+    {
         int id;
-        int m2d;
-        int bild;
-        int style;
-        int maxStabilität;
-        int maxEnergie;
-        int energieRadius;
-        double reparatur;
-        double akkuLeistung;
-        char team;
+        Punkt pos;
+        Punkt size;
 
-        ObjektDaten();
-        ObjektDaten( const ObjektDaten &daten );
+        SchieneDaten();
+        SchieneDaten( const BariereDaten &daten );
     };
 
-    class EditorObject : public Model2DObject
+    struct TimerDaten : public Model
+    {
+        int id;
+        Punkt pos;
+        int maxZeit;
+        bool sichtbar;
+        bool autoWiederhohlung;
+        bool runns;
+        int farbe;
+        Text name;
+
+        TimerDaten();
+        TimerDaten( const BariereDaten &daten );
+    };
+
+    struct TunnelDaten : public Model
+    {
+        int id;
+        Punkt pos;
+        Punkt size;
+        Punkt ziel;
+        bool aktiv;
+
+        TunnelDaten();
+        TunnelDaten( const BariereDaten &daten );
+    };
+
+    struct UmlenkungDaten : public Model
+    {
+        int id;
+        Punkt pos;
+        Punkt size;
+        char richtung;
+        int maxAbklingzeit;
+        bool drehend;
+        bool aktiv;
+
+        UmlenkungDaten();
+        UmlenkungDaten( const BariereDaten &daten );
+    };
+
+    struct TriggerDaten : public Model
+    {
+        int id;
+        Text name;
+        Array< EreignisTyp > *ereignisse;
+        RCArray< Bedingung > *bedingungen;
+        RCArray< Aktion > *aktionen;
+
+        TriggerDaten();
+        TriggerDaten( const BariereDaten &daten );
+        ~TriggerDaten();
+    };
+
+    struct VariableDaten : public Model
+    {
+        Text oldName;
+        Text name;
+        Variable *var;
+
+        VariableDaten();
+        VariableDaten( const BariereDaten &daten );
+        ~VariableDaten();
+    };
+
+    class EditorObject : public ZeichnungHintergrund
     {
     public:
         enum ObjektTyp
         {
             SPIELER,
-            OBJEKT
+            BARIERE,
+            BASE,
+            BASE_TIMER,
+            SCHALTER,
+            SCHIENE,
+            TIMER,
+            TUNNEL,
+            TUNNEL_ZIEL,
+            UMLENKUNG
         };
 
     private:
@@ -115,45 +200,149 @@ namespace Editor
         void update();
     };
 
-    class EdObjekt : public EditorObject
+    class EdBariere : public EditorObject
     {
     private:
-        ObjektDaten *mdl;
+        BariereDaten *mdl;
 
     public:
-        EdObjekt( ObjektDaten *model );
-        ~EdObjekt();
+        EdBariere( BariereDaten *model );
+        ~EdBariere();
         void update();
     };
 
-    class UpdateObserver //: public View
+    class EdBase : public EditorObject
+    {
+    private:
+        BaseDaten *mdl;
+
+    public:
+        EdBase( BaseDaten *model );
+        ~EdBase();
+        void update();
+    };
+
+    class EdBaseTimer : public EditorObject
+    {
+    private:
+        BaseDaten *mdl;
+
+    public:
+        EdBaseTimer( BaseDaten *model );
+        ~EdBaseTimer();
+        void update();
+    };
+
+    class EdDrop : public EditorObject
+    {
+    private:
+        DropDaten *mdl;
+
+    public:
+        EdDrop( DropDaten *model );
+        ~EdDrop();
+        void update();
+    };
+
+    class EdSchalter : public EditorObject
+    {
+    private:
+        SchalterDaten *mdl;
+
+    public:
+        EdSchalter( SchalterDaten *model );
+        ~EdSchalter();
+        void update();
+    };
+
+    class EdSchiene : public EditorObject
+    {
+    private:
+        SchieneDaten *mdl;
+
+    public:
+        EdSchiene( SchieneDaten *model );
+        ~EdSchiene();
+        void update();
+    };
+
+    class EdTimer : public EditorObject
+    {
+    private:
+        TimerDaten *mdl;
+
+    public:
+        EdTimer( TimerDaten *model );
+        ~EdTimer();
+        void update();
+    };
+
+    class EdTunnel : public EditorObject
+    {
+    private:
+        TunnelDaten *mdl;
+
+    public:
+        EdTunnel( TunnelDaten *model );
+        ~EdTunnel();
+        void update();
+    };
+
+    class EdTunnelZiel : public EditorObject
+    {
+    private:
+        TunnelDaten *mdl;
+
+    public:
+        EdTunnelZiel( TunnelDaten *model );
+        ~EdTunnelZiel();
+        void update();
+    };
+
+    class EdUmlenkung : public EditorObject
+    {
+    private:
+        UmlenkungDaten *mdl;
+
+    public:
+        EdUmlenkung( UmlenkungDaten *model );
+        ~EdUmlenkung();
+        void update();
+    };
+
+    class UpdateObserver : public View
     {
     private:
         std::function< void() > f;
 
     public:
         UpdateObserver( std::function< void() > f );
-        //void update( Model *m ) override;
+        void update( Model *m ) override;
     };
 
-    typedef GSL::GSLDateiV *( *GetGSLDatei )( );
-
     class KarteDaten : public Thread
     {
     private:
+        Punkt renderPos;
         EditorKlient *client;
         SpielerTeamStruktur *sts;
         Array< SpielerDaten * > spieler;
         Array< TeamDaten * > teams;
-        Array< ObjektDaten * > objekte;
-        Array< ResourceDaten * > resources;
+        Array< BariereDaten * > barieren;
+        Array< BaseDaten * > basen;
+        Array< DropDaten * > drops;
+        Array< SchalterDaten * > schalter;
+        Array< SchieneDaten * > schienen;
+        Array< TimerDaten * > timer;
+        Array< TunnelDaten * > tunnel;
+        Array< UmlenkungDaten * > umlenkungen;
+        Array< TriggerDaten * > trigger;
+        Array< VariableDaten * > variablen;
+        RCArray< EditorObject > *objects;
         Text error;
         Array< std::function< void() > > aktionen;
         Critical cs;
-        Welt2D *welt;
-       // RCArray< View > views;
         Punkt size;
-        GetGSLDatei getGSLDatei;
         bool exit;
 
         void loadSpielResourcePathsFromFolder( const char *folderPath, RCArray< Text > *zPaths );
@@ -161,11 +350,41 @@ namespace Editor
     public:
         KarteDaten( EditorKlient *client, SpielerTeamStruktur *sts );
         ~KarteDaten();
-        void addObjekt( ObjektDaten &daten, std::function< void( int ) > callBack );
-        void removeObjekt( int index );
+        void addBariere( BariereDaten &daten, std::function< void( int ) > callBack );
+        void removeBariere( int index );
+        void addBase( BaseDaten &daten, std::function< void( int ) > callBack );
+        void removeBase( int index );
+        void addDrop( DropDaten &daten, std::function< void( int ) > callBack );
+        void removeDrop( int index );
+        void addSchalter( SchalterDaten &daten, std::function< void( int ) > callBack );
+        void removeSchalter( int index );
+        void addSchiene( SchieneDaten &daten, std::function< void( int ) > callBack );
+        void removeSchiene( int index );
+        void addTimer( TimerDaten &daten, std::function< void( int ) > callBack );
+        void removeTimer( int index );
+        void addTunnel( TunnelDaten &daten, std::function< void( int ) > callBack );
+        void removeTunnel( int index );
+        void addUmlenkung( UmlenkungDaten &daten, std::function< void( int ) > callBack );
+        void removeUmlenkung( int index );
+        void addTrigger( TriggerDaten &daten, std::function< void( int ) > callBack );
+        void removeTrigger( int index );
+        void addVariable( VariableDaten &daten, std::function< void( int ) > callBack );
+        void removeVariable( int index );
         void thread() override;
-        ResourceDaten *getResource( int index );
-        ObjektDaten *getObjekt( int index );
+        void doPublicMausEreignis( MausEreignis &me );
+        void doTastaturEreignis( TastaturEreignis &te );
+        bool tick( double tickVal );
+        void render( Bild &rObj );
+        BariereDaten *getBariere( int index );
+        BaseDaten *getBase( int index );
+        DropDaten *getDrop( int index );
+        SchalterDaten *getSchalter( int index );
+        SchieneDaten *getSchiene( int index );
+        TimerDaten *getTimer( int index );
+        TunnelDaten *getTunnel( int index );
+        UmlenkungDaten *getUmlenkung( int index );
+        TriggerDaten *getTrigger( int index );
+        VariableDaten *getVariable( int index );
         SpielerDaten *getSpieler( int index );
         TeamDaten *getTeam( int index );
         const char *getTeamName( int index );
@@ -173,23 +392,28 @@ namespace Editor
         int getSpielerAnzahl() const;
         int getTeamIndexById( int id );
         int getTeamAnzahl() const;
-        int getObjektIndexById( int id );
-        int getObjektAnzahl() const;
-        int getResourceIndexById( int id );
-        int getResourceAnzahl();
+        int getBariereIndexById( int id );
+        int getBariereAnzahl() const;
+        int getBaseIndexById( int id );
+        int getBaseAnzahl() const;
+        int getDropIndexById( int id );
+        int getDropAnzahl() const;
+        int getSchalterIndexById( int id );
+        int getSchalterAnzahl() const;
+        int getSchieneIndexById( int id );
+        int getSchieneAnzahl() const;
+        int getTimerIndexById( int id );
+        int getTimerAnzahl() const;
+        int getTunnelIndexById( int id );
+        int getTunnelAnzahl() const;
+        int getUmlenkungIndexById( int id );
+        int getUmlenkungAnzahl() const;
+        int getTriggerIndexById( int id );
+        int getTriggerAnzahl() const;
+        int getVariableIndexByName( Text name );
+        int getVariableAnzahl() const;
         bool hasError() const;
         char *getError() const;
         bool hasAktions() const;
-        Welt2D *getWelt() const;
-        Welt2D *zWelt() const;
-        void getResourceIdFromPath( const char *path, std::function< void( int ) > callBack );
-        bool doesResourceExist( const char *path );
-        Model2DData *loadModelFromRessource( int id );
-        Bild *loadBildFromRessource( int id );
-        Model2DData *loadModelFromPath( const char *path );
-        Bild *loadBildFromPath( const char *path );
-        void loadUnusedResourcePaths( std::function< void( RCArray< Text > * ) > callBack );
-        // löscht das objekt wenn es nicht mehr gebraucht wird und beendet den Thread
-        Thread *release() override;
     };
 }

+ 1421 - 0
StickmanWorldOnline/EditorKlient.cpp

@@ -0,0 +1,1421 @@
+#include "EditorKlient.h"
+#include "EditorKarte.h"
+#include "Reader.h"
+#include <Network.h>
+#include <Klient.h>
+
+using namespace Editor;
+/*
+SpielerTeamStruktur::SpielerTeamStruktur()
+{
+    spielerAnzahl = 0;
+    teamAnzahl = 0;
+    spielerFarbe = new Array< int >();
+    teamFarbe = new Array< int >();
+    teamName = new RCArray< Text >();
+    teamSize = new Array< int >();
+    ref = 1;
+}
+
+SpielerTeamStruktur::~SpielerTeamStruktur()
+{
+    spielerFarbe->release();
+    teamFarbe->release();
+    teamName->release();
+    teamSize->release();
+}
+
+SpielerTeamStrukturV *SpielerTeamStruktur::getThis()
+{
+    ref++;
+    return this;
+}
+
+SpielerTeamStrukturV *SpielerTeamStruktur::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Konstruktor
+//  k: Der zu verwendende Klient
+EditorKlient::EditorKlient( KSGClient::EditorServerClient *k )
+    : ReferenceCounter()
+{
+    klient = k;
+}
+
+// Destruktor
+EditorKlient::~EditorKlient()
+{
+    klient->release();
+}
+
+// Initialisiert den Server
+//  return: 1, falls erfolgreich
+//          2, falls bereits eine Sitzung existiert
+//          0, sonnst
+int EditorKlient::init()
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    k->sendeEncrypted( "\x0", 1 );
+    char ret;
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+        k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret;
+}
+
+// Verwirft die vorhandene Sitzung und erstellt eine neue
+bool EditorKlient::sitzungVerwerfen()
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x1", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+// Speichert Sitzung und beendet Editor
+bool EditorKlient::sitzungBeenden()
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x2", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+// Lädt die Spieler Team Struktur
+bool EditorKlient::getSpielerTeamStruktur( SpielerTeamStrukturV *zSts )
+{
+    return klient->ladeTeamDaten( zSts );
+}
+
+bool EditorKlient::loadMapSize( Punkt &size )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x3", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->getNachrichtEncrypted( (char *)&size.x, 4 );
+        k->getNachrichtEncrypted( (char *)&size.y, 4 );
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadSpieler( Array< SpielerDaten * > &spieler )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x5", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            SpielerDaten *s = new SpielerDaten();
+            k->getNachrichtEncrypted( (char *)&s->id, 4 );
+            k->getNachrichtEncrypted( (char *)&s->spawn.x, 4 );
+            k->getNachrichtEncrypted( (char *)&s->spawn.y, 4 );
+            spieler.add( s );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadTeams( Array< TeamDaten * > &teams )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x4", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            TeamDaten *t = new TeamDaten();
+            k->getNachrichtEncrypted( (char *)&t->id, 4 );
+            k->getNachrichtEncrypted( (char *)&t->maxWbzeit, 4 );
+            k->getNachrichtEncrypted( (char *)&t->punkte, 4 );
+            teams.add( t );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadBarieren( Array< BariereDaten * > &barieren )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x6", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            BariereDaten *b = new BariereDaten();
+            k->getNachrichtEncrypted( (char *)&b->id, 4 );
+            k->getNachrichtEncrypted( (char *)&b->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&b->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&b->size.x, 4 );
+            k->getNachrichtEncrypted( (char *)&b->size.y, 4 );
+            k->getNachrichtEncrypted( (char *)&b->style, 4 );
+            k->getNachrichtEncrypted( (char *)&b->verschiebungWeite, 4 );
+            k->getNachrichtEncrypted( (char *)&b->autoSchaltungMaxTime, 4 );
+            k->getNachrichtEncrypted( (char *)&b->team, 4 );
+            barieren.add( b );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadBasen( Array< BaseDaten * > &basen )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x7", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            BaseDaten *b = new BaseDaten();
+            k->getNachrichtEncrypted( (char *)&b->id, 4 );
+            k->getNachrichtEncrypted( (char *)&b->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&b->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&b->size.x, 4 );
+            k->getNachrichtEncrypted( (char *)&b->size.y, 4 );
+            k->getNachrichtEncrypted( (char *)&b->maxTime, 4 );
+            k->getNachrichtEncrypted( (char *)&b->team, 4 );
+            k->getNachrichtEncrypted( (char *)&b->showTimer, 1 );
+            k->getNachrichtEncrypted( (char *)&b->timer.x, 4 );
+            k->getNachrichtEncrypted( (char *)&b->timer.y, 4 );
+            k->getNachrichtEncrypted( (char *)&b->timerFarbe, 4 );
+            basen.add( b );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadDrops( Array< DropDaten * > &drops )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x8", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            DropDaten *d = new DropDaten();
+            k->getNachrichtEncrypted( (char *)&d->id, 4 );
+            k->getNachrichtEncrypted( (char *)&d->minPos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&d->minPos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&d->maxPos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&d->maxPos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&d->maxTime, 4 );
+            k->getNachrichtEncrypted( (char *)&d->numDrops, 4 );
+            for( int j = 0; j < ITEMANZAHL; j++ )
+                k->getNachrichtEncrypted( (char *)&d->wahrscheinlichkeit[ j ], 4 );
+            unsigned char len;
+            k->getNachrichtEncrypted( (char *)&len, 1 );
+            char *name = new char[ (__int64)len + 1 ];
+            k->getNachrichtEncrypted( name, len );
+            name[ len ] = 0;
+            d->name = name;
+            delete[] name;
+            drops.add( d );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadSchalter( Array< SchalterDaten * > &schalter )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x9", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            SchalterDaten *s = new SchalterDaten();
+            k->getNachrichtEncrypted( (char *)&s->id, 4 );
+            k->getNachrichtEncrypted( (char *)&s->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&s->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&s->size.x, 4 );
+            k->getNachrichtEncrypted( (char *)&s->size.y, 4 );
+            k->getNachrichtEncrypted( (char *)&s->aktiv, 1 );
+            schalter.add( s );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadSchienen( Array< SchieneDaten * > &schienen )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\xA", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            SchieneDaten *s = new SchieneDaten();
+            k->getNachrichtEncrypted( (char *)&s->id, 4 );
+            k->getNachrichtEncrypted( (char *)&s->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&s->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&s->size.x, 4 );
+            k->getNachrichtEncrypted( (char *)&s->size.y, 4 );
+            schienen.add( s );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadTimer( Array< TimerDaten * > &timer )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\xB", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            TimerDaten *t = new TimerDaten();
+            k->getNachrichtEncrypted( (char *)&t->id, 4 );
+            k->getNachrichtEncrypted( (char *)&t->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&t->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&t->maxZeit, 4 );
+            k->getNachrichtEncrypted( (char *)&t->sichtbar, 1 );
+            k->getNachrichtEncrypted( (char *)&t->autoWiederhohlung, 1 );
+            k->getNachrichtEncrypted( (char *)&t->runns, 1 );
+            k->getNachrichtEncrypted( (char *)&t->farbe, 4 );
+            unsigned char len;
+            k->getNachrichtEncrypted( (char *)&len, 1 );
+            char *name = new char[ (__int64)len + 1 ];
+            name[ len ] = 0;
+            k->getNachrichtEncrypted( name, len );
+            t->name = name;
+            delete[]name;
+            timer.add( t );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadTunnel( Array< TunnelDaten * > &tunnel )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\xC", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            TunnelDaten *t = new TunnelDaten();
+            k->getNachrichtEncrypted( (char *)&t->id, 4 );
+            k->getNachrichtEncrypted( (char *)&t->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&t->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&t->size.x, 4 );
+            k->getNachrichtEncrypted( (char *)&t->size.y, 4 );
+            k->getNachrichtEncrypted( (char *)&t->ziel.x, 4 );
+            k->getNachrichtEncrypted( (char *)&t->ziel.y, 4 );
+            k->getNachrichtEncrypted( (char *)&t->aktiv, 1 );
+            tunnel.add( t );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadUmlenkung( Array< UmlenkungDaten * > &umlenkung )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\xD", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            UmlenkungDaten *u = new UmlenkungDaten();
+            k->getNachrichtEncrypted( (char *)&u->id, 4 );
+            k->getNachrichtEncrypted( (char *)&u->pos.x, 4 );
+            k->getNachrichtEncrypted( (char *)&u->pos.y, 4 );
+            k->getNachrichtEncrypted( (char *)&u->size.x, 4 );
+            k->getNachrichtEncrypted( (char *)&u->size.y, 4 );
+            k->getNachrichtEncrypted( (char *)&u->richtung, 1 );
+            k->getNachrichtEncrypted( (char *)&u->maxAbklingzeit, 4 );
+            k->getNachrichtEncrypted( (char *)&u->drehend, 1 );
+            k->getNachrichtEncrypted( (char *)&u->aktiv, 1 );
+            umlenkung.add( u );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadTrigger( Array< TriggerDaten * > &trigger )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\xE", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            TriggerDaten *t = new TriggerDaten();
+            k->getNachrichtEncrypted( (char *)&t->id, 4 );
+            unsigned char len;
+            k->getNachrichtEncrypted( (char *)&len, 1 );
+            char *name = new char[ (__int64)len + 1 ];
+            name[ len ] = 0;
+            k->getNachrichtEncrypted( name, len );
+            t->name = name;
+            delete[]name;
+            int ereignisAnzahl;
+            int bedingungAnzahl;
+            int aktionAnzahl;
+            k->getNachrichtEncrypted( (char *)&ereignisAnzahl, 4 );
+            k->getNachrichtEncrypted( (char *)&bedingungAnzahl, 4 );
+            k->getNachrichtEncrypted( (char *)&aktionAnzahl, 4 );
+            for( int j = 0; j < ereignisAnzahl; j++ )
+            {
+                int typ;
+                k->getNachrichtEncrypted( (char *)&typ, 4 );
+                t->ereignisse->add( (EreignisTyp)typ );
+            }
+            Network::EncryptedNetworkReader reader( k );
+            for( int j = 0; j < bedingungAnzahl; j++ )
+                t->bedingungen->add( new Bedingung( MapReader::readAktion( reader ) ) );
+            for( int j = 0; j < aktionAnzahl; j++ )
+                t->aktionen->add( MapReader::readAktion( reader ) );
+            trigger.add( t );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::loadVariable( Array< VariableDaten * > &variable )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\xF", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz;
+        k->getNachrichtEncrypted( (char *)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            VariableDaten *v = new VariableDaten();
+            unsigned char len;
+            k->getNachrichtEncrypted( (char *)&len, 1 );
+            char *name = new char[ (__int64)len + 1 ];
+            k->getNachrichtEncrypted( name, len );
+            name[ len ] = 0;
+            v->oldName = name;
+            v->name = name;
+            delete[]name;
+            char typ;
+            k->getNachrichtEncrypted( &typ, 1 );
+            char def;
+            k->getNachrichtEncrypted( &def, 1 );
+            if( !def )
+                v->var = new Variable( NICHTS );
+            else
+            {
+                switch( typ )
+                {
+                case NICHTS:
+                    v->var = new Variable( NICHTS );
+                    break;
+                case INTEGER:
+                {
+                    int val;
+                    k->getNachrichtEncrypted( (char *)&val, 4 );
+                    v->var = new Integer( val );
+                    break;
+                }
+                case BOOLEAN:
+                {
+                    bool val;
+                    k->getNachrichtEncrypted( (char *)&val, 1 );
+                    v->var = new Boolean( val );
+                    break;
+                }
+                case STRING:
+                {
+                    char len;
+                    k->getNachrichtEncrypted( (char *)&len, 1 );
+                    char *value = new char[ (__int64)len + 1 ];
+                    k->getNachrichtEncrypted( value, len );
+                    value[ (int)len ] = 0;
+                    v->var = new String( value );
+                    delete[] value;
+                    break;
+                }
+                case RICHTUNG:
+                {
+                    char len;
+                    k->getNachrichtEncrypted( (char *)&len, 1 );
+                    char *value = new char[ (__int64)len + 1 ];
+                    k->getNachrichtEncrypted( value, len );
+                    value[ (int)len ] = 0;
+                    v->var = new String( getRichtungFromString( Text( value ) ) );
+                    delete[] value;
+                    break;
+                }
+                case FLOAT:
+                {
+                    float val;
+                    k->getNachrichtEncrypted( (char *)&val, 4 );
+                    v->var = new Float( val );
+                    break;
+                }
+                case TASTE:
+                {
+                    char val;
+                    k->getNachrichtEncrypted( &val, 1 );
+                    v->var = new Integer( val, 1 );
+                    break;
+                }
+                case SPIELER:
+                case TIMER:
+                case TEAM:
+                case BARIERE:
+                case SCHALTER:
+                case SCHIENE:
+                case TUNNEL:
+                case UMLENKUNG:
+                case TRIGGER:
+                case BASE:
+                {
+                    int id;
+                    k->getNachrichtEncrypted( (char *)&id, 4 );
+                    v->var = new Template( (VariableTyp)typ, id );
+                    break;
+                }
+                case GEGENSTAND:
+                {
+                    int id;
+                    k->getNachrichtEncrypted( (char *)&id, 4 );
+                    v->var = new GegenstandTypVar( (GegenstandTyp)id );
+                    break;
+                }
+                default:
+                    v->var = new Variable( NICHTS );
+                }
+            }
+            variable.add( v );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveMapSize( Punkt size )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x10", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&size.x, 4 );
+        k->sendeEncrypted( (char *)&size.y, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveTeam( const TeamDaten *team )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x11", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&team->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&team->maxWbzeit, 4 );
+            k->sendeEncrypted( (char *)&team->punkte, 4 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveSpieler( const SpielerDaten *spieler )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x12", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&spieler->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&spieler->spawn.x, 4 );
+            k->sendeEncrypted( (char *)&spieler->spawn.y, 4 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveBariere( const BariereDaten *bariere )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x13", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&bariere->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&bariere->pos.x, 4 );
+            k->sendeEncrypted( (char *)&bariere->pos.y, 4 );
+            k->sendeEncrypted( (char *)&bariere->size.x, 4 );
+            k->sendeEncrypted( (char *)&bariere->size.y, 4 );
+            k->sendeEncrypted( (char *)&bariere->style, 4 );
+            k->sendeEncrypted( (char *)&bariere->verschiebungWeite, 4 );
+            k->sendeEncrypted( (char *)&bariere->autoSchaltungMaxTime, 4 );
+            k->sendeEncrypted( (char *)&bariere->team, 4 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveBase( const BaseDaten *base )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x14", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&base->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&base->pos.x, 4 );
+            k->sendeEncrypted( (char *)&base->pos.y, 4 );
+            k->sendeEncrypted( (char *)&base->size.x, 4 );
+            k->sendeEncrypted( (char *)&base->size.y, 4 );
+            k->sendeEncrypted( (char *)&base->maxTime, 4 );
+            k->sendeEncrypted( (char *)&base->team, 4 );
+            k->sendeEncrypted( (char *)&base->showTimer, 1 );
+            k->sendeEncrypted( (char *)&base->timer.x, 4 );
+            k->sendeEncrypted( (char *)&base->timer.y, 4 );
+            k->sendeEncrypted( (char *)&base->timerFarbe, 4 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveDrop( const DropDaten *drop )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x15", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&drop->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&drop->minPos.x, 4 );
+            k->sendeEncrypted( (char *)&drop->minPos.y, 4 );
+            k->sendeEncrypted( (char *)&drop->maxPos.x, 4 );
+            k->sendeEncrypted( (char *)&drop->maxPos.y, 4 );
+            k->sendeEncrypted( (char *)&drop->maxTime, 4 );
+            k->sendeEncrypted( (char *)&drop->numDrops, 4 );
+            for( int j = 0; j < ITEMANZAHL; j++ )
+                k->sendeEncrypted( (char *)&drop->wahrscheinlichkeit[ j ], 4 );
+            unsigned char len = (unsigned char)drop->name.getLength();
+            k->sendeEncrypted( (char *)&len, 1 );
+            k->sendeEncrypted( drop->name, len );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveSchalter( const SchalterDaten *schalter )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x16", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&schalter->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&schalter->pos.x, 4 );
+            k->sendeEncrypted( (char *)&schalter->pos.y, 4 );
+            k->sendeEncrypted( (char *)&schalter->size.x, 4 );
+            k->sendeEncrypted( (char *)&schalter->size.y, 4 );
+            k->sendeEncrypted( (char *)&schalter->aktiv, 1 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveSchiene( const SchieneDaten *schiene )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x17", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&schiene->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&schiene->pos.x, 4 );
+            k->sendeEncrypted( (char *)&schiene->pos.y, 4 );
+            k->sendeEncrypted( (char *)&schiene->size.x, 4 );
+            k->sendeEncrypted( (char *)&schiene->size.y, 4 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveTimer( const TimerDaten *timer )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x18", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&timer->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&timer->pos.x, 4 );
+            k->sendeEncrypted( (char *)&timer->pos.y, 4 );
+            k->sendeEncrypted( (char *)&timer->maxZeit, 4 );
+            k->sendeEncrypted( (char *)&timer->sichtbar, 1 );
+            k->sendeEncrypted( (char *)&timer->autoWiederhohlung, 1 );
+            k->sendeEncrypted( (char *)&timer->runns, 1 );
+            k->sendeEncrypted( (char *)&timer->farbe, 4 );
+            unsigned char len = (unsigned char)timer->name.getLength();
+            k->sendeEncrypted( (char *)&len, 1 );
+            k->sendeEncrypted( timer->name, len );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveTunnel( const TunnelDaten *tunnel )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x19", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&tunnel->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&tunnel->pos.x, 4 );
+            k->sendeEncrypted( (char *)&tunnel->pos.y, 4 );
+            k->sendeEncrypted( (char *)&tunnel->size.x, 4 );
+            k->sendeEncrypted( (char *)&tunnel->size.y, 4 );
+            k->sendeEncrypted( (char *)&tunnel->ziel.x, 4 );
+            k->sendeEncrypted( (char *)&tunnel->ziel.y, 4 );
+            k->sendeEncrypted( (char *)&tunnel->aktiv, 1 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveUmlenkung( const UmlenkungDaten *umlenkung )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x1A", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&umlenkung->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            k->sendeEncrypted( (char *)&umlenkung->pos.x, 4 );
+            k->sendeEncrypted( (char *)&umlenkung->pos.y, 4 );
+            k->sendeEncrypted( (char *)&umlenkung->size.x, 4 );
+            k->sendeEncrypted( (char *)&umlenkung->size.y, 4 );
+            k->sendeEncrypted( (char *)&umlenkung->richtung, 1 );
+            k->sendeEncrypted( (char *)&umlenkung->maxAbklingzeit, 4 );
+            k->sendeEncrypted( (char *)&umlenkung->drehend, 1 );
+            k->sendeEncrypted( (char *)&umlenkung->aktiv, 1 );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveTrigger( const TriggerDaten *trigger )
+{
+    Network::Klient *k = klient->beginEditorMessage();
+    if( !k )
+    {
+        error = klient->getLetzterFehler();
+        return 0;
+    }
+    error = "";
+    char ret;
+    k->sendeEncrypted( "\x1B", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char *)&trigger->id, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            unsigned char len = (unsigned char)trigger->name.getLength();
+            k->sendeEncrypted( (char *)&len, 1 );
+            k->sendeEncrypted( trigger->name, len );
+            int ereignisAnzahl = trigger->ereignisse->getEintragAnzahl();
+            int bedingungAnzahl = trigger->bedingungen->getEintragAnzahl();
+            int aktionAnzahl = trigger->aktionen->getEintragAnzahl();
+            k->sendeEncrypted( (char *)&ereignisAnzahl, 4 );
+            k->sendeEncrypted( (char *)&bedingungAnzahl, 4 );
+            k->sendeEncrypted( (char *)&aktionAnzahl, 4 );
+            for( int j = 0; j < ereignisAnzahl; j++ )
+            {
+                int typ = (int)trigger->ereignisse->get( j );
+                k->sendeEncrypted( (char *)&typ, 4 );
+            }
+            Network::EncryptedNetworkWriter writer( k );
+            for( int j = 0; j < bedingungAnzahl; j++ )
+                MapReader::writeAktion( trigger->bedingungen->z( j )->zExpression(), writer );
+            for( int j = 0; j < aktionAnzahl; j++ )
+                MapReader::writeAktion( trigger->aktionen->z( j ), writer );
+            k->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        unsigned char l = 0;
+        k->getNachrichtEncrypted( (char *)&l, 1 );
+        char *err = new char[ (__int64)l + 1 ];
+        err[ l ] = 0;
+        k->getNachrichtEncrypted( err, l );
+        error = err;
+        delete[] err;
+        ret = 0;
+    }
+    klient->endEditorMessage();
+    return ret == 1;
+}
+
+bool EditorKlient::saveVariable( const VariableDaten *variable )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteBariere( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteBase( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteDrop( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteSchalter( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteSchiene( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteTimer( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteTunnel( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteUmlenkung( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteTrigger( int id )
+{
+
+    return 0;
+}
+
+bool EditorKlient::deleteVariable( int id )
+{
+
+    return 0;
+}
+
+// Gibt den Letzten Fehler zurück
+char *EditorKlient::getLastError() const
+{
+    return error;
+}*/

+ 44 - 19
StickmanWorldOnline/EditorKlient.h

@@ -6,10 +6,18 @@
 
 namespace Editor
 {
-    struct ResourceDaten;
     struct TeamDaten;
     struct SpielerDaten;
-    struct ObjektDaten;
+    struct BariereDaten;
+    struct BaseDaten;
+    struct DropDaten;
+    struct SchalterDaten;
+    struct SchieneDaten;
+    struct TimerDaten;
+    struct TunnelDaten;
+    struct UmlenkungDaten;
+    struct TriggerDaten;
+    struct VariableDaten;
 
     class SpielerTeamStruktur : public SpielerTeamStrukturV
     {
@@ -20,16 +28,13 @@ namespace Editor
         SpielerTeamStrukturV *release() override;
     };
 
-    class EditorKlient
+    class EditorKlient : public virtual ReferenceCounter
     {
     private:
         KSGClient::EditorServerClient *klient;
         Text error;
-        int ref;
         Critical cs;
 
-        void loadMapResourcePathsFromFolder( const char *folderPath, RCArray< Text > *zPaths );
-
     public:
         // Konstruktor
         //  k: Der zu verwendende Klient
@@ -48,22 +53,42 @@ namespace Editor
         // Lädt die Spieler Team Struktur
         bool getSpielerTeamStruktur( SpielerTeamStrukturV *zSts );
         bool loadMapSize( Punkt &size );
+        bool loadSpieler( Array< SpielerDaten * > &spieler );
+        bool loadTeams( Array< TeamDaten * > &teams );
+        bool loadBarieren( Array< BariereDaten * > &barieren );
+        bool loadBasen( Array< BaseDaten * > &basen );
+        bool loadDrops( Array< DropDaten * > &drops );
+        bool loadSchalter( Array< SchalterDaten * > &schalter );
+        bool loadSchienen( Array< SchieneDaten * > &schienen );
+        bool loadTimer( Array< TimerDaten * > &timer );
+        bool loadTunnel( Array< TunnelDaten * > &tunnel );
+        bool loadUmlenkung( Array< UmlenkungDaten * > &umlenkung );
+        bool loadTrigger( Array< TriggerDaten * > &trigger );
+        bool loadVariable( Array< VariableDaten * > &variable );
+        bool saveMapSize( Punkt size );
         bool saveTeam( const TeamDaten *team );
         bool saveSpieler( const SpielerDaten *spieler );
-        bool saveObjekt( const ObjektDaten *objekt );
-        bool deleteObjekt( int id );
-        bool loadResources( Array< ResourceDaten * > &resources );
-        int addResource( const char *path );
-        bool loadSpieler( Array< SpielerDaten* > &spieler );
-        bool loadTeams( Array< TeamDaten* > &teams );
-        bool loadObjekte( Array< ObjektDaten* > &Objekte );
-        Bild *loadBild( const char *templatePath );
-        Model2DData *loadModel( const char *templatePath );
-        RCArray< Text > *getAllMapResourcePaths();
+        bool saveBariere( const BariereDaten *bariere );
+        bool saveBase( const BaseDaten *base );
+        bool saveDrop( const DropDaten *drop );
+        bool saveSchalter( const SchalterDaten *schalter );
+        bool saveSchiene( const SchieneDaten *schiene );
+        bool saveTimer( const TimerDaten *timer );
+        bool saveTunnel( const TunnelDaten *tunnel );
+        bool saveUmlenkung( const UmlenkungDaten *umlenkung );
+        bool saveTrigger( const TriggerDaten *trigger );
+        bool saveVariable( const VariableDaten *variable );
+        bool deleteBariere( int id );
+        bool deleteBase( int id );
+        bool deleteDrop( int id );
+        bool deleteSchalter( int id );
+        bool deleteSchiene( int id );
+        bool deleteTimer( int id );
+        bool deleteTunnel( int id );
+        bool deleteUmlenkung( int id );
+        bool deleteTrigger( int id );
+        bool deleteVariable( int id );
         // Gibt den Letzten Fehler zurück
         char *getLastError() const;
-        // Reference Counting
-        EditorKlient *getThis();
-        EditorKlient *release();
     };
 }

+ 4 - 17
StickmanWorldOnline/Effect.cpp

@@ -2,11 +2,11 @@
 
 
 Effect::Effect( Spieler *zSpieler, float maxTime )
+    : ReferenceCounter()
 {
     this->zSpieler = zSpieler;
     timeLeft = maxTime;
     effectImage = 0;
-    ref = 1;
 }
 
 Effect::~Effect()
@@ -52,32 +52,19 @@ bool Effect::istGegenstandErlaubt( GegenstandTyp typ ) const
 void Effect::renderSpieler( Bild &rObj )
 {}
 
-bool Effect::renderEffect( int x, int y, int width, int height, Bild & rObj, Schrift * zSchrift )
+bool Effect::renderEffect( int x, int y, int width, int height, Bild &rObj, Schrift *zSchrift )
 {
     if( !effectImage )
         return 0;
     rObj.alphaBildSkall( x, y, width, height, *effectImage );
     TextRenderer tr;
-    tr.setSchriftZ( zSchrift->getThis() );
+    tr.setSchriftZ( dynamic_cast<Schrift *>( zSchrift->getThis() ) );
     tr.setSchriftSize( 12 );
-    tr.renderText( x + 5, y + 5, Text( (int)(timeLeft * 100) / 100.0 ), rObj, 0xFFFFFFFF );
+    tr.renderText( x + 5, y + 5, Text( (int)( timeLeft * 100 ) / 100.0 ), rObj, 0xFFFFFFFF );
     return 1;
 }
 
 Resource *Effect::getCurrentResource()
 {
     return 0;
-}
-
-Effect *Effect::getThis()
-{
-    ref++;
-    return this;
-}
-
-Effect *Effect::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
 }

+ 1 - 4
StickmanWorldOnline/Effect.h

@@ -6,13 +6,12 @@ class Spieler;
 class Spiel;
 class Team;
 
-class Effect
+class Effect : public virtual ReferenceCounter
 {
 protected:
     Spieler *zSpieler;
     Bild *effectImage;
     float timeLeft;
-    int ref;
 
 public:
     Effect( Spieler *zSpieler, float maxTime );
@@ -27,6 +26,4 @@ public:
     virtual void renderSpieler( Bild &rObj );
     virtual bool renderEffect( int x, int y, int width, int height, Bild &rObj, Schrift *zSchrift );
     virtual Resource *getCurrentResource();
-    Effect *getThis();
-    Effect *release();
 };

+ 50 - 0
StickmanWorldOnline/EncryptedNetworkReader.cpp

@@ -0,0 +1,50 @@
+#include "EncryptedNetworkReader.h"
+#include <stdexcept>
+
+using namespace Editor;

class NotImplementedException : public std::logic_error
+{
+public:
+    NotImplementedException() : std::logic_error{ "Function not implemented." } {}
+};
+
+EncryptedNetworkReader::EncryptedNetworkReader( Network::Klient *k )
+{
+    this->k = k;
+}

+EncryptedNetworkReader::~EncryptedNetworkReader()
+{
+    if( k )
+        k->release();
+}

+//! Setzt die Position des Bytes, das als nächstes gelesen werden soll
+//! \param pos Der Index des Bytes
+//! \param ende 1, wenn der Index vom ende der Resource zählt. 0, wenn der Index vom Beginn der Resource zählt
+void EncryptedNetworkReader::setLPosition( __int64 pos, bool ende )
+{
+    throw NotImplementedException();
+}

+//! Ließt aus der Datei
+//! \param bytes Ein Array, der mit Bytes aus der Resource gefüllt werden soll
+//! \param len Wie viele Bytes aus der Resource gelesen werden sollen
+void EncryptedNetworkReader::lese( char *bytes, int len )
+{
+    k->getNachrichtEncrypted( bytes, len );
+}

+//! Ließt die nächste zeile der Resource ein
+//! \return Die gelesene Zeile als Text mit zeilenumbruch
+Text *EncryptedNetworkReader::leseZeile()
+{
+    throw NotImplementedException();
+}

+//! Prüft, ob die Resource vollständig gelesen wurde
+//!  return 1, wenn die Resource vollständig gelesen wurde. 0, sonst
+bool EncryptedNetworkReader::istEnde() const
+{
+    return false;
+}

+//! Gibt den Index des Bytes aus der Resource zurück, welches als nächstes gelesen werden würde
+//! return -1, falls ein Fehler aufgetreten ist. Sonst die Position des Lesezeigers
+__int64 EncryptedNetworkReader::getLPosition() const
+{
+    throw NotImplementedException();
+}

+ 33 - 0
StickmanWorldOnline/EncryptedNetworkReader.h

@@ -0,0 +1,33 @@
+#pragma once
+#include <Klient.h>
+#include <Reader.h>
+
+namespace Editor
+{
+    class EncryptedNetworkReader : public Reader
+    {
+    private:
+        Network::Klient *k;
+
+    public:
+        EncryptedNetworkReader( Network::Klient *k );
+        ~EncryptedNetworkReader();
+        //! Setzt die Position des Bytes, das als nächstes gelesen werden soll
+        //! \param pos Der Index des Bytes
+        //! \param ende 1, wenn der Index vom ende der Resource zählt. 0, wenn der Index vom Beginn der Resource zählt
+        void setLPosition( __int64 pos, bool ende ) override;
+        //! Ließt aus der Datei
+        //! \param bytes Ein Array, der mit Bytes aus der Resource gefüllt werden soll
+        //! \param len Wie viele Bytes aus der Resource gelesen werden sollen
+        void lese( char *bytes, int len ) override;
+        //! Ließt die nächste zeile der Resource ein
+        //! \return Die gelesene Zeile als Text mit zeilenumbruch
+        Text *leseZeile() override;
+        //! Prüft, ob die Resource vollständig gelesen wurde
+        //!  return 1, wenn die Resource vollständig gelesen wurde. 0, sonst
+        bool istEnde() const override;
+        //! Gibt den Index des Bytes aus der Resource zurück, welches als nächstes gelesen werden würde
+        //! return -1, falls ein Fehler aufgetreten ist. Sonst die Position des Lesezeigers
+        __int64 getLPosition() const override;
+    };
+}

+ 57 - 77
StickmanWorldOnline/Ende.cpp

@@ -7,60 +7,55 @@
 
 // Inhalt der Ende Klasse aus Ende.h
 // Konstruktor
-Ende::Ende( Schrift *zSchrift )
+Ende::Ende( UIInit &uiFactory )
+    : ReferenceCounter()
 {
-	rahmen = new LRahmen();
-	rahmen->setSize( 200, 100 );
-	rahmen->setRamenBreite( 2 );
-	rahmen->setFarbe( 0xFFFFFFFF );
-	text = new TextFeld();
-	text->setStyle( TextFeld::Style::Text | TextFeld::Style::Center );
-	text->setSchriftZ( zSchrift->getThis() );
-	text->setText( "" );
-	text->setSchriftFarbe( 0xFFFFFFFF );
-	text->setSize( 200, 50 );
-	warten = new TextFeld();
-	warten->setStyle( ( TextFeld::Style::Text | TextFeld::Style::Center ) & ~TextFeld::Style::Sichtbar );
-	warten->setSchriftZ( zSchrift->getThis() );
-	warten->setText( "Bitte warten..." );
-	warten->setSchriftFarbe( 0xFFFFFFFF );
-	warten->setSize( 200, 50 );
-	ok = new Knopf();
-	ok->setStyle( Knopf::Style::Normal );
-	ok->setSize( 100, 20 );
-	ok->setText( "Weiter" );
-	ok->setSchriftZ( zSchrift->getThis() );
-	weiter = 0;
-	ref = 1;
+    rahmen = new LRahmen();
+    rahmen->setSize( 200, 100 );
+    rahmen->setRamenBreite( 2 );
+    rahmen->setFarbe( 0xFFFFFFFF );
+    text = uiFactory.createTextFeld( uiFactory.initParam );
+    text->setStyle( TextFeld::Style::Text | TextFeld::Style::Center );
+    text->setText( "" );
+    text->setSize( 200, 50 );
+    warten = uiFactory.createTextFeld( uiFactory.initParam );
+    warten->setStyle( ( TextFeld::Style::Text | TextFeld::Style::Center ) & ~TextFeld::Style::Sichtbar );
+    warten->setText( "Bitte warten..." );
+    warten->setSize( 200, 50 );
+    ok = uiFactory.createKnopf( uiFactory.initParam );
+    ok->setStyle( Knopf::Style::Normal );
+    ok->setSize( 100, 20 );
+    ok->setText( "Weiter" );
+    weiter = 0;
 }
 
 // Destruktor
 Ende::~Ende()
 {
-	rahmen->release();
-	text->release();
-	warten->release();
-	ok->release();
+    rahmen->release();
+    text->release();
+    warten->release();
+    ok->release();
 }
 
 // nicht constant
 void Ende::setGewonnen( char gewonnen )
 {
-	if( gewonnen == 1 )
-	{
-		text->setText( "Du hast gewonnen." );
-		text->setSchriftFarbe( 0xFF00FF00 );
-	}
-	else if( !gewonnen )
-	{
-		text->setText( "Du hast verloren." );
-		text->setSchriftFarbe( 0xFFFF0000 );
-	}
-	else
-	{
-		text->setText( "Unentschieden." );
-		text->setSchriftFarbe( 0xFFFFFFFF );
-	}
+    if( gewonnen == 1 )
+    {
+        text->setText( "Du hast gewonnen." );
+        text->setSchriftFarbe( 0xFF00FF00 );
+    }
+    else if( !gewonnen )
+    {
+        text->setText( "Du hast verloren." );
+        text->setSchriftFarbe( 0xFFFF0000 );
+    }
+    else
+    {
+        text->setText( "Unentschieden." );
+        text->setSchriftFarbe( 0xFFFFFFFF );
+    }
 }
 
 void Ende::doTastaturEreignis( TastaturEreignis &te )
@@ -75,47 +70,32 @@ void Ende::doTastaturEreignis( TastaturEreignis &te )
 
 void Ende::doPublicMausEreignis( MausEreignis &me )
 {
-	bool vera = me.verarbeitet;
-	ok->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-	{
-		ok->removeStyle( Knopf::Style::Sichtbar );
-		warten->addStyle( TextFeld::Style::Sichtbar );
-		weiter = 1;
-	}
-	me.verarbeitet = 1;
+    bool vera = me.verarbeitet;
+    ok->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        ok->removeStyle( Knopf::Style::Sichtbar );
+        warten->addStyle( TextFeld::Style::Sichtbar );
+        weiter = 1;
+    }
+    me.verarbeitet = 1;
 }
 
 void Ende::render( Bild &zRObj )
 {
-	rahmen->setPosition( zRObj.getBreite() / 2 - rahmen->getBreite() / 2, zRObj.getHeight() / 2 - rahmen->getHeight() / 2 );
-	zRObj.alphaRegion( rahmen->getX(), rahmen->getY(), rahmen->getBreite(), rahmen->getHeight(), 0xA0000000 );
-	rahmen->render( zRObj );
-	text->setPosition( rahmen->getX(), rahmen->getY() );
-	text->render( zRObj );
-	warten->setPosition( rahmen->getX(), rahmen->getY() + 50 );
-	warten->render( zRObj );
-	ok->setPosition( rahmen->getX() + rahmen->getBreite() / 2 - ok->getBreite() / 2, rahmen->getY() + 65 );
-	ok->render( zRObj );
+    rahmen->setPosition( zRObj.getBreite() / 2 - rahmen->getBreite() / 2, zRObj.getHeight() / 2 - rahmen->getHeight() / 2 );
+    zRObj.alphaRegion( rahmen->getX(), rahmen->getY(), rahmen->getBreite(), rahmen->getHeight(), 0xA0000000 );
+    rahmen->render( zRObj );
+    text->setPosition( rahmen->getX(), rahmen->getY() );
+    text->render( zRObj );
+    warten->setPosition( rahmen->getX(), rahmen->getY() + 50 );
+    warten->render( zRObj );
+    ok->setPosition( rahmen->getX() + rahmen->getBreite() / 2 - ok->getBreite() / 2, rahmen->getY() + 65 );
+    ok->render( zRObj );
 }
 
 // constant
 bool Ende::getWeiter() const
 {
-	return weiter;
-}
-
-// Reference Counting
-Ende *Ende::getThis()
-{
-	ref++;
-	return this;
-}
-
-Ende *Ende::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return weiter;
 }

+ 17 - 20
StickmanWorldOnline/Ende.h

@@ -3,34 +3,31 @@
 
 #include <Knopf.h>
 #include <Rahmen.h>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
-class Ende
+class Ende : public virtual ReferenceCounter
 {
 private:
-	LRahmen *rahmen;
-	TextFeld *text;
-	TextFeld *warten;
-	Knopf *ok;
-	bool weiter;
-	int ref;
+    LRahmen *rahmen;
+    TextFeld *text;
+    TextFeld *warten;
+    Knopf *ok;
+    bool weiter;
 
 public:
-	// Konstruktor
-	Ende( Schrift *zSchrift );
-	// Destruktor
-	~Ende();
-	// nicht constant
-	void setGewonnen( char gewonnen );
+    // Konstruktor
+    Ende( UIInit &uiFactory );
+    // Destruktor
+    ~Ende();
+    // nicht constant
+    void setGewonnen( char gewonnen );
     void doTastaturEreignis( TastaturEreignis &te );
-	void doPublicMausEreignis( MausEreignis &me );
-	void render( Bild &zRObj );
-	// constant
-	bool getWeiter() const;
-	// Reference Counting
-	Ende *getThis();
-	Ende *release();
+    void doPublicMausEreignis( MausEreignis &me );
+    void render( Bild &zRObj );
+    // constant
+    bool getWeiter() const;
 };
 
 #endif

+ 1 - 1
StickmanWorldOnline/Enterhaken.cpp

@@ -203,5 +203,5 @@ void EnterhakenEffect::renderSpieler( Bild &rObj )
 
 Resource *EnterhakenEffect::getCurrentResource()
 {
-    return spieler->getThis();
+    return  dynamic_cast<Resource *>( spieler->getThis() );
 }

+ 2 - 15
StickmanWorldOnline/Ereignis.cpp

@@ -2,9 +2,9 @@
 #include "Trigger.h"
 
 Ereignis::Ereignis( EreignisTyp typ )
+    : ReferenceCounter()
 {
     this->typ = typ;
-    ref = 1;
 }
 
 Ereignis::~Ereignis()
@@ -38,17 +38,4 @@ Variable *Ereignis::zParameter( const char *name ) const
             return v->zVariable();
     }
     return 0;
-}
-
-Ereignis *Ereignis::getThis()
-{
-    ref++;
-    return this;
-}
-
-Ereignis *Ereignis::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
+}

+ 1 - 4
StickmanWorldOnline/Ereignis.h

@@ -32,12 +32,11 @@ enum EreignisTyp
     UMLENKUNG_LENKT_UM // "Betroffes Geschoss", "Betroffe Umlenkung"
 };
 
-class Ereignis
+class Ereignis : public virtual ReferenceCounter
 {
 private:
     EreignisTyp typ;
     RCArray< VarPointer > params;
-    int ref;
 
 public:
     Ereignis( EreignisTyp typ );
@@ -46,6 +45,4 @@ public:
     void addParameter( const char *name, Variable *var );
     Variable *getParameter( const char *name ) const;
     Variable *zParameter( const char *name ) const;
-    Ereignis *getThis();
-    Ereignis *release();
 };

+ 21 - 0
StickmanWorldOnline/Frage.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "Dialog.h"
+#include <Knopf.h>
+
+class Frage : public Dialog
+{
+public:
+    // Konstructor
+    //  tr: Ein Zeiger auf die zu verwendende Schrift
+    //  frage: Die Frage die an den Benutzer gestellt werden soll
+    //  left: Die linke Antwort
+    //  right: Die rechte Antwort
+    //  leftAk: Ein Zeiger auf eine Funktion die beim wählen der Linken Antwort aufgerufen wird
+    //  rightAk: Ein Zeiger auf eine Funktion die beim wählen der Rechten Antwort aufgerufen wird
+    //  abbruchAk: Ein Zeiger auf eine Funktion die beim Schließen des Fensters aufgerufen wird
+    //  maxSize: Die Bildschirmgröße in Pixeln
+    Frage( TextRenderer *tr, const char *frage, const char *left, const char *right, std::function< void() > leftAk, std::function< void() > rightAk, std::function< void() > abbruchAk, Punkt maxSize );
+    // Destruktor
+    ~Frage();
+};

+ 18 - 18
StickmanWorldOnline/Gegenstand.cpp

@@ -124,7 +124,7 @@ float abklingzeit( GegenstandTyp typ )
 
 bool storable( GegenstandTyp typ )
 {
-    return !(typ == RWEISHEIT || typ == RSTRENGTH || typ == RBOSHEIT || typ == RLEBEN || typ == RTEMPO);
+    return !( typ == RWEISHEIT || typ == RSTRENGTH || typ == RBOSHEIT || typ == RLEBEN || typ == RTEMPO );
 }
 
 bool brauchtRichtung( GegenstandTyp typ )
@@ -160,55 +160,55 @@ Gegenstand::Gegenstand( ResourceRegistry *zResources, int id, GegenstandTyp typ,
     switch( typ )
     {
     case PFEIL:
-        this->textur = zResources->zResource( R_PFEIL, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_PFEIL, 0 )->getImages()->getThis() );
         break;
     case LEBEN:
-        this->textur = zResources->zResource( R_LEBEN, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_LEBEN, 0 )->getImages()->getThis() );
         break;
     case SCHILD:
-        this->textur = zResources->zResource( R_SCHILD, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_SCHILD, 0 )->getImages()->getThis() );
         break;
     case SCHUH:
-        this->textur = zResources->zResource( R_SCHUH, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_SCHUH, 0 )->getImages()->getThis() );
         break;
     case GEIST:
-        this->textur = zResources->zResource( R_GEIST, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_GEIST, 0 )->getImages()->getThis() );
         break;
     case KUGEL:
-        this->textur = zResources->zResource( R_KUGEL, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_KUGEL, 0 )->getImages()->getThis() );
         break;
     case ROLLE:
-        this->textur = zResources->zResource( R_ROLLE, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_ROLLE, 0 )->getImages()->getThis() );
         break;
     case STURM:
-        this->textur = zResources->zResource( R_STURM, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_STURM, 0 )->getImages()->getThis() );
         break;
     case DRACHENAUGE:
-        this->textur = zResources->zResource( R_DRACHENAUGE, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_DRACHENAUGE, 0 )->getImages()->getThis() );
         break;
     case FEUERBALL:
-        this->textur = zResources->zResource( R_FEUERBALL, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_FEUERBALL, 0 )->getImages()->getThis() );
         break;
     case ENTERHAKEN:
-        this->textur = zResources->zResource( R_ENTERHAKEN_ITEM, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_ENTERHAKEN_ITEM, 0 )->getImages()->getThis() );
         break;
     case MINE:
-        this->textur = zResources->zResource( R_MINE, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_MINE, 0 )->getImages()->getThis() );
         break;
     case RWEISHEIT:
-        this->textur = zResources->zResource( R_RWEISHEIT, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_RWEISHEIT, 0 )->getImages()->getThis() );
         break;
     case RSTRENGTH:
-        this->textur = zResources->zResource( R_RSTRENGTH, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_RSTRENGTH, 0 )->getImages()->getThis() );
         break;
     case RBOSHEIT:
-        this->textur = zResources->zResource( R_RBOSHEIT, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_RBOSHEIT, 0 )->getImages()->getThis() );
         break;
     case RLEBEN:
-        this->textur = zResources->zResource( R_RLEBEN, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_RLEBEN, 0 )->getImages()->getThis() );
         break;
     case RTEMPO:
-        this->textur = zResources->zResource( R_RTEMPO, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_RTEMPO, 0 )->getImages()->getThis() );
         break;
     default:
         break;

+ 11 - 11
StickmanWorldOnline/Geschoss.cpp

@@ -10,7 +10,7 @@ Geschoss::Geschoss( ResourceRegistry *zResources, int id, float speed, GeschossT
     this->speed = speed;
     this->richtung = r;
     this->besitzer = besitzer;
-    resources = zResources->getThis();
+    resources = dynamic_cast<ResourceRegistry *>( zResources->getThis() );
     tunnelBenutzt = 0;
     umgelenkt = 0;
     geschosseGetroffen = 0;
@@ -35,19 +35,19 @@ void Geschoss::invertDirection()
 
 void Geschoss::addUmlenkung( Spiel *zSpiel )
 {
-    zSpiel->setGeschossZuletztUmgelenkt( (Geschoss *)getThis() );
+    zSpiel->setGeschossZuletztUmgelenkt( dynamic_cast<Geschoss *>( getThis() ) );
     umgelenkt++;
 }
 
 void Geschoss::addGeschossTreffer( Spiel *zSpiel )
 {
-    zSpiel->setGeschossZuletztGeschossGetroffen( (Geschoss *)getThis() );
+    zSpiel->setGeschossZuletztGeschossGetroffen( dynamic_cast<Geschoss *>( getThis() ) );
     geschosseGetroffen++;
 }
 
 void Geschoss::addTunnel( Spiel *zSpiel )
 {
-    zSpiel->setGeschossZuletztTunnelBenutzt( (Geschoss *)getThis() );
+    zSpiel->setGeschossZuletztTunnelBenutzt( dynamic_cast<Geschoss *>( getThis() ) );
     schalter++;
 }
 
@@ -76,7 +76,7 @@ void Geschoss::setTyp( GeschossTyp typ )
     if( typ == GESCHOSS_PFEIL )
     {
         if( richtung == RECHTS )
-            textur = resources->zResource( R_PFEIL_GESCHOSS, 0 )->getImages()->getThis();
+            textur = dynamic_cast<Bild *>( resources->zResource( R_PFEIL_GESCHOSS, 0 )->getImages()->getThis() );
         else if( richtung == LINKS )
         {
             Bild *r = resources->zResource( R_PFEIL_GESCHOSS, 0 )->getImages();
@@ -117,11 +117,11 @@ void Geschoss::setTyp( GeschossTyp typ )
         setHeight( 20 );
         currentImage = 0;
         nextImage = 0.075;
-        textur = resources->zResource( R_FEUERBALL_GESCHOSS, 0 )->getImages()->getThis();
+        textur = dynamic_cast<Bild *>( resources->zResource( R_FEUERBALL_GESCHOSS, 0 )->getImages()->getThis() );
     }
     else
     {
-        setX( getX() + getWidth() / 2 - 15.f /2 );
+        setX( getX() + getWidth() / 2 - 15.f / 2 );
         setY( getY() + getHeight() / 2 - 15.f / 2 );
         setWidth( 15 );
         setHeight( 15 );
@@ -129,12 +129,12 @@ void Geschoss::setTyp( GeschossTyp typ )
         {
             currentImage = 0;
             nextImage = 0.075;
-            textur = resources->zResource( R_DRACHENAUGE_GESCHOSS, 0 )->getImages()->getThis();
+            textur = dynamic_cast<Bild *>( resources->zResource( R_DRACHENAUGE_GESCHOSS, 0 )->getImages()->getThis() );
         }
         if( typ == GESCHOSS_KUGEL )
-            textur = resources->zResource( R_KUGEL_GESCHOSS, 0 )->getImages()->getThis();
+            textur = dynamic_cast<Bild *>( resources->zResource( R_KUGEL_GESCHOSS, 0 )->getImages()->getThis() );
         if( typ == GESCHOSS_MINE )
-            textur = resources->zResource( R_MINE_GESCHOSS, 0 )->getImages()->getThis();
+            textur = dynamic_cast<Bild *>( resources->zResource( R_MINE_GESCHOSS, 0 )->getImages()->getThis() );
     }
 }
 
@@ -217,7 +217,7 @@ Spieler *Geschoss::zBesitzer() const
 
 Spieler *Geschoss::getBesitzer() const
 {
-    return besitzer ? (Spieler *)besitzer->getThis() : 0;
+    return besitzer ? dynamic_cast<Spieler *>( besitzer->getThis() ) : 0;
 }
 
 Richtung Geschoss::getRichtung() const

+ 28 - 32
StickmanWorldOnline/HistorieStatistik.h

@@ -8,40 +8,36 @@
 class HistorieStatistik : public AccountHistorieStatistikV
 {
 private:
-	Schrift *schrift;
-	Bildschirm *screen;
-	Array< SSDSpieler* > *gss;
-	Array< SSDTeam* > *gts;
-	StatistikTabelle *tabelle;
-	Knopf *fertig;
-	bool geladen;
-	bool geschlossen;
-	unsigned char alpha;
-	bool sichtbar;
-	double tickVal;
-	bool rend;
-	int ref;
+    Schrift *schrift;
+    Bildschirm *screen;
+    Array< SSDSpieler * > *gss;
+    Array< SSDTeam * > *gts;
+    StatistikTabelle *tabelle;
+    Knopf *fertig;
+    bool geladen;
+    bool geschlossen;
+    unsigned char alpha;
+    bool sichtbar;
+    double tickVal;
+    bool rend;
 
 public:
-	// Konstruktor
-	HistorieStatistik();
-	// Destruktor
-	~HistorieStatistik();
-	// nicht constant
-	virtual void setSchrift( Schrift *schrift );
-	virtual void setBildschirm( Bildschirm *zScreen );
-	virtual void ladeDaten( int spielId );
-	virtual void setSichtbar( bool sichtbar );
-	virtual void doPublicMausEreignis( MausEreignis &me );
-	virtual void doTastaturEreignis( TastaturEreignis &te );
-	virtual bool tick( double tickVal );
-	virtual void render( Bild &zRObj );
-	// constant
-	virtual bool istNochSichtbar() const;
-	virtual bool wurdeGeschlossen() const;
-	// Reference Counting
-	virtual AccountHistorieStatistikV *getThis();
-	virtual AccountHistorieStatistikV *release();
+    // Konstruktor
+    HistorieStatistik();
+    // Destruktor
+    ~HistorieStatistik();
+    // nicht constant
+    virtual void setUIFactory( UIInit &factory );
+    virtual void setBildschirm( Bildschirm *zScreen );
+    virtual void ladeDaten( int spielId );
+    virtual void setSichtbar( bool sichtbar );
+    virtual void doPublicMausEreignis( MausEreignis &me );
+    virtual void doTastaturEreignis( TastaturEreignis &te );
+    virtual bool tick( double tickVal );
+    virtual void render( Bild &zRObj );
+    // constant
+    virtual bool istNochSichtbar() const;
+    virtual bool wurdeGeschlossen() const;
 };
 
 #endif

+ 80 - 193
StickmanWorldOnline/Initialisierung.cpp

@@ -3,216 +3,103 @@
 #include <Bildschirm.h>
 #include <MausEreignis.h>
 
-Knopf *initKnopf( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *titel )
+Knopf *initKnopf( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *titel )
 {
-	Knopf *ret = new Knopf();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( zSchrift )
-		ret->setSchriftZ( zSchrift->getThis() );
-	if( titel )
-		ret->setText( titel );
-	return ret;
+    Knopf *ret = uiFactory.createKnopf( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    if( titel )
+        ret->setText( titel );
+    return ret;
 }
 
-KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *txt )
+KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *txt )
 {
-	KontrollKnopf *ret = new KontrollKnopf();
-	ret->addStyle( style );
-	if( zSchrift )
-		ret->setSchriftZ( zSchrift->getThis() );
-	if( txt )
-	{
-		ret->setText( txt );
-		ret->setSText( txt );
-	}
-	ret->setSFarbe( 0xFFFFFFFF );
-	ret->setSSize( 12 );
-	if( ret->hatStyle( TextFeld::Style::Buffered ) )
-	{
-		ret->setAlphaFeldFarbe( 0x5500FF00 );
-		ret->setAlphaFeldStrength( -5 );
-	}
-	if( ret->hatStyle( TextFeld::Style::Rahmen ) )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFF00FF00 );
-	}
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	ret->loadData( "data/bilder/system.ltdb" );
-    ret->setMausEreignis( _ret1ME );
-	return ret;
+    KontrollKnopf *ret = uiFactory.createKontrollKnopf( uiFactory.initParam );
+    ret->addStyle( style );
+    if( txt )
+    {
+        ret->setText( txt );
+        ret->setSText( txt );
+    }
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    return ret;
 }
 
-Fenster *initFenster( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *titel )
+Fenster *initFenster( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *titel )
 {
-	Fenster *ret = new Fenster();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( ret->hatStyle( Fenster::Style::Rahmen ) )
-	{
-		ret->setRBreite( 1 );
-		ret->setRFarbe( 0xFFFFFFFF );
-	}
-	if( ret->hatStyle( Fenster::Style::Titel ) )
-	{
-		if( titel )
-			ret->setTitel( titel );
-		if( zSchrift )
-			ret->setTSchriftZ( zSchrift->getThis() );
-		ret->setTSFarbe( 0xFFFFFFFF );
-		ret->zTTextFeld()->setSize( 0, 20 );
-		ret->zTTextFeld()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Rahmen );
-		ret->setTRFarbe( 0xFF00FF00 );
-		ret->setTRBreite( 1 );
-		if( ret->hatStyle( Fenster::Style::TitelBuffered ) )
-		{
-			ret->setTAfFarbe( 0x1000FF00 );
-			ret->setTAfStrength( -15 );
-		}
-	}
-	return ret;
+    Fenster *ret = uiFactory.createFenster( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    if( ret->hatStyle( Fenster::Style::Titel ) )
+    {
+        if( titel )
+            ret->setTitel( titel );
+    }
+    return ret;
 }
 
-TextFeld *initTextFeld( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *txt )
+TextFeld *initTextFeld( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *txt )
 {
-	TextFeld *ret = new TextFeld();
-	ret->setStyle( style );
-	if( zSchrift )
-		ret->setSchriftZ( zSchrift->getThis() );
-	if( txt )
-		ret->setText( txt );
-	ret->setSchriftFarbe( 0xFFFFFFFF );
-	ret->setSchriftSize( 12 );
-	if( ret->hatStyle( TextFeld::Style::Buffered ) )
-	{
-		ret->setAlphaFeldFarbe( 0x5500FF00 );
-		ret->setAlphaFeldStrength( -5 );
-	}
-	if( ret->hatStyle( TextFeld::Style::Rahmen ) )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFF00FF00 );
-	}
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-    if( br < 0 )
-        ret->setSize( ret->getNeededWidth(), hö );
-	return ret;
+    TextFeld *ret = uiFactory.createTextFeld( uiFactory.initParam );
+    ret->setStyle( style );
+    if( txt )
+        ret->setText( txt );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    return ret;
 }
 
-BildZ *initBildZ( int x, int y, int br, int hö, int style, Bild *b )
+BildZ *initBildZ( int x, int y, int br, int hö, UIInit &uiFactory, int style, Bild *b )
 {
-	BildZ *ret = new BildZ();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( b )
-		ret->setBildZ( b );
-	if( ( style | BildZ::Style::Rahmen ) == style )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFFFFFFFF );
-	}
-	return ret;
+    BildZ *ret = uiFactory.createBildZ( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    if( b )
+        ret->setBildZ( b );
+    return ret;
 }
 
-AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< const char * > values )
+AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, std::initializer_list< const char * > values )
 {
-	AuswahlBox *ret = new AuswahlBox();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( ( style | AuswahlBox::Style::Hintergrund ) == style )
-		ret->setHintergrundFarbe( 0xFF000000 );
-	if( ( style | AuswahlBox::Style::Erlaubt ) == style )
-		ret->setMausEreignis( _ret1ME );
-	if( zSchrift )
-		ret->setSchriftZ( zSchrift->getThis() );
-	if( ( style | AuswahlBox::Style::Rahmen ) == style )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFFFFFFFF );
-	}
-	if( ( style | AuswahlBox::Style::MaxHeight ) == style )
-		ret->setMaxAuskappHeight( 100 );
-	if( ( style | AuswahlBox::Style::MausRahmen ) == style )
-	{
-		ret->setMausRahmenBreite( 1 );
-		ret->setMausRahmenFarbe( 0xFF005500 );
-	}
-	if( ( style | AuswahlBox::Style::MausBuffer ) == style )
-	{
-		ret->setMausAlphaFeldFarbe( 0x00008700 );
-		ret->setMausAlphaFeldStrength( -8 );
-	}
-	if( ( style | AuswahlBox::Style::AuswahlRahmen ) == style )
-	{
-		ret->setAuswRahmenBreite( 1 );
-		ret->setAuswRahmenFarbe( 0xFF00FF00 );
-	}
-	if( ( style | AuswahlBox::Style::AuswahlBuffer ) == style )
-	{
-		ret->setAuswAlphaFeldFarbe( 0x0000FF00 );
-		ret->setAuswAlphaFeldStrength( -8 );
-	}
-	for( auto i = values.begin(); i != values.end(); i++ )
-	{
-		ret->addEintrag( *i );
-	}
-	return ret;
+    AuswahlBox *ret = uiFactory.createAuswahlBox( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    for( auto i = values.begin(); i != values.end(); i++ )
+    {
+        ret->addEintrag( *i );
+    }
+    return ret;
 }
 
-ObjTabelle *initObjTabelle( int x, int y, int br, int hö, Schrift *zSchrift, int style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe )
+ObjTabelle *initObjTabelle( int x, int y, int br, int hö, UIInit &uiFactory, int style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe )
 {
-	ObjTabelle *ret = new ObjTabelle();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( ( style | ObjTabelle::Style::Erlaubt ) == style )
-		ret->setMausEreignis( _ret1ME );
-	if( ( style | ObjTabelle::Style::Rahmen ) == style )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFFFFFFFF );
-	}
-	if( ( style | ObjTabelle::Style::Raster ) == style )
-	{
-		ret->setRasterBreite( 1 );
-		ret->setRasterFarbe( 0xFFFFFFFF );
-	}
-	if( ( style | ObjTabelle::Style::VScroll ) == style )
-		ret->setVertikalKlickScroll( 5 );
-	if( ( style | ObjTabelle::Style::HScroll ) == style )
-		ret->setHorizontalKlickScroll( 5 );
-	for( auto i = spalten.begin(); i != spalten.end(); i++ )
-	{
-		ret->addSpalte( i->name );
-		ret->setSpaltenBreite( i->name, i->breite );
-		if( ( style | ObjTabelle::Style::SpaltenBreiteMin ) == style )
-			ret->setMinSpaltenBreite( i->name, i->minBreite );
-		if( ( style | ObjTabelle::Style::SpaltenBreiteMax ) == style )
-			ret->setMaxSpaltenBreite( i->name, i->maxBreite );
-		if( überschriftHöhe )
-		{
-			if( ret->getZeilenNummer( "Überschrift" ) < 0 )
-			{
-				ret->addZeile( 0, "Überschrift" );
-				ret->setZeilenHeight( 0, 20 );
-			}
-			ret->setZeichnungZ( i->name, "Überschrift", initTextFeld( 0, 0, i->breite, 20, zSchrift, TextFeld::Style::Text, i->name ) );
-		}
-	}
-	return ret;
-}
-
-void initToolTip( Zeichnung *obj, const char *txt, Schrift *zSchrift, Bildschirm *zBs )
-{
-	obj->setToolTipText( txt, zBs, zSchrift );
-	obj->zToolTip()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::Hintergrund | TextFeld::Style::HAlpha | TextFeld::Style::Mehrzeilig );
-	obj->zToolTip()->setHintergrundFarbe( 0xA0000000 );
-	obj->zToolTip()->setRahmenFarbe( 0xFFFFFFFF );
+    ObjTabelle *ret = uiFactory.createObjTabelle( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    for( auto i = spalten.begin(); i != spalten.end(); i++ )
+    {
+        ret->addSpalte( i->name );
+        ret->setSpaltenBreite( i->name, i->breite );
+        if( ( style | ObjTabelle::Style::SpaltenBreiteMin ) == style )
+            ret->setMinSpaltenBreite( i->name, i->minBreite );
+        if( ( style | ObjTabelle::Style::SpaltenBreiteMax ) == style )
+            ret->setMaxSpaltenBreite( i->name, i->maxBreite );
+        if( überschriftHöhe )
+        {
+            if( ret->getZeilenNummer( "Überschrift" ) < 0 )
+            {
+                ret->addZeile( 0, "Überschrift" );
+                ret->setZeilenHeight( 0, 20 );
+            }
+            ret->setZeichnungZ( i->name, "Überschrift", initTextFeld( 0, 0, i->breite, 20, uiFactory, TextFeld::Style::Text, i->name ) );
+        }
+    }
+    return ret;
 }

+ 11 - 11
StickmanWorldOnline/Initialisierung.h

@@ -9,24 +9,24 @@
 #include <AuswahlBox.h>
 #include <Tabelle.h>
 #include <initializer_list>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
 struct OBJTabelleSpalteIni
 {
     const char *name;
-	int breite;
-	int minBreite;
-	int maxBreite;
+    int breite;
+    int minBreite;
+    int maxBreite;
 };
 
-Knopf *initKnopf( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *titel );
-KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *txt );
-Fenster *initFenster( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *titel );
-TextFeld *initTextFeld( int x, int y, int br, int hö, Schrift *zSchrift, int style, const char *txt );
-BildZ *initBildZ( int x, int y, int br, int hö, int style, Bild *b );
-AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< const char * > values );
-ObjTabelle *initObjTabelle( int x, int y, int br, int hö, Schrift *zSchrift, int style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe );
-void initToolTip( Zeichnung *obj, const char *txt, Schrift *zSchrift, Bildschirm *zBs );
+Knopf *initKnopf( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *titel );
+KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *txt );
+Fenster *initFenster( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *titel );
+TextFeld *initTextFeld( int x, int y, int br, int hö, UIInit &uiFactory, int style, const char *txt );
+BildZ *initBildZ( int x, int y, int br, int hö, UIInit &uiFactory, int style, Bild *b );
+AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, std::initializer_list< const char * > values );
+ObjTabelle *initObjTabelle( int x, int y, int br, int hö, UIInit &uiFactory, int style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe );
 
 #endif

+ 3 - 10
StickmanWorldOnline/Interface.h

@@ -12,17 +12,16 @@ namespace Editor
     class Interface : public ZeichnungHintergrund
     {
     private:
-        Knopf * beenden;
+        Knopf *beenden;
         RightTools *right;
         KarteDaten *daten;
-        Schrift *schrift;
+        UIInit uiFactory;
         bool verlassen;
-        int ref;
 
     public:
         // Konstruktor
         //  zS: Ein Zeiger auf die zu verwendende Schrift
-        Interface( Schrift *zS, Punkt maxSize );
+        Interface( UIInit uiFactory, Punkt maxSize );
         // Destruktor
         ~Interface();
         void setDaten( KarteDaten *daten );
@@ -40,11 +39,5 @@ namespace Editor
         void reset();
         // Gibt zurück, ob der Benutzer den Editor verlassen möchte
         bool hatVerlassen() const;
-        // erhöht den Reference Counter
-        //  return: this
-        Interface *getThis();
-        // verringert den Reference Counter und löscht das Objekt wenn es nicht mehr gebraucht wird.
-        //  return: 0
-        Interface *release();
     };
 }

+ 24 - 0
StickmanWorldOnline/Model.cpp

@@ -0,0 +1,24 @@
+#include "Model.h"
+
+using namespace Framework;
+
+Model::Model()
+{
+    views = new RCArray< View >();
+}
+
+Model::~Model()
+{
+    views->release();
+}
+
+void Model::addView( View *view )
+{
+    views->add( view );
+}
+
+void Model::update()
+{
+    for( auto v = views->getIterator(); v; v++ )
+        v->update( this );
+}

+ 17 - 0
StickmanWorldOnline/Model.h

@@ -0,0 +1,17 @@
+#pragma once
+#include "View.h"
+#include <Array.h>
+
+class View;
+
+class Model
+{
+protected:
+    Framework::RCArray< View > *views;
+
+public:
+    Model();
+    ~Model();
+    void addView( View *view );
+    void update();
+};

+ 18 - 0
StickmanWorldOnline/Nachricht.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#include "Dialog.h"
+#include <Knopf.h>
+
+using namespace Framework;
+
+class Nachricht : public Dialog
+{
+public:
+    // Konstruktor
+    //  tr: Die zu verwendende Schrift
+    //  nachricht: Der Fehler, der angezeigt werden soll
+    //  maxSize: Die Bildschirmgröße in Pixeln
+    Nachricht( TextRenderer *tr, char *nachricht, Punkt maxSize, std::function< void() > onClose );
+    // Destruktor
+    ~Nachricht();
+};

+ 137 - 137
StickmanWorldOnline/Reader.cpp

@@ -1,5 +1,6 @@
 #include "Reader.h"
 #include "Spiel.h"
+#include <Datei.h>
 
 struct SpielerTeamStruktur
 {
@@ -14,10 +15,10 @@ struct SpielerTeamStruktur
 
 // Konstruktor
 MapReader::MapReader( int karteId, char *tmpPfad )
+    : ReferenceCounter()
 {
     this->karteId = karteId;
     pfad = new Text( tmpPfad );
-    ref = 1;
 }
 
 // Destruktor
@@ -41,13 +42,13 @@ Array<int> *MapReader::getSpielerFarben()
     int spielerAnzahl;
     int teamAnzahl;
     datei->open( Datei::Style::lesen );
-    datei->lese( (char *)& spielerAnzahl, 4 );
-    datei->lese( (char *)& teamAnzahl, 4 );
+    datei->lese( (char *)&spielerAnzahl, 4 );
+    datei->lese( (char *)&teamAnzahl, 4 );
     Array< int > *result = new Array< int >();
     for( int i = 0; i < spielerAnzahl; i++ )
     {
         int f = 0;
-        datei->lese( (char *)& f, 4 );
+        datei->lese( (char *)&f, 4 );
         result->add( f );
     }
     datei->close();
@@ -69,18 +70,18 @@ Array<int> *MapReader::getTeamFarben()
     int spielerAnzahl;
     int teamAnzahl;
     datei->open( Datei::Style::lesen );
-    datei->lese( (char *)& spielerAnzahl, 4 );
-    datei->lese( (char *)& teamAnzahl, 4 );
+    datei->lese( (char *)&spielerAnzahl, 4 );
+    datei->lese( (char *)&teamAnzahl, 4 );
     for( int i = 0; i < spielerAnzahl; i++ )
     {
         int f = 0;
-        datei->lese( (char *)& f, 4 );
+        datei->lese( (char *)&f, 4 );
     }
     Array< int > *result = new Array< int >();
     for( int i = 0; i < teamAnzahl; i++ )
     {
         int f = 0;
-        datei->lese( (char *)& f, 4 );
+        datei->lese( (char *)&f, 4 );
         result->add( f );
     }
     datei->close();
@@ -88,10 +89,10 @@ Array<int> *MapReader::getTeamFarben()
     return result;
 }
 
-Aktion *MapReader::readAktion( Datei &dat )
+Aktion *MapReader::readAktion( StreamReader &dat )
 {
     int id;
-    dat.lese( (char *)& id, 4 );
+    dat.lese( (char *)&id, 4 );
     char pAnz = 0;
     dat.lese( &pAnz, 1 );
     RCArray< Aktion > *params = new RCArray< Aktion >();
@@ -349,35 +350,35 @@ Aktion *MapReader::readAktion( Datei &dat )
     {
         params->release();
         bool b;
-        dat.lese( (char *)& b, 1 );
+        dat.lese( (char *)&b, 1 );
         return new KonstantBoolean( b );
     }
     case KONSTANT_FLOAT:
     {
         params->release();
         float f;
-        dat.lese( (char *)& f, 4 );
+        dat.lese( (char *)&f, 4 );
         return new KonstantFloat( f );
     }
     case KONSTANT_INTEGER:
     {
         params->release();
         int i;
-        dat.lese( (char *)& i, 4 );
+        dat.lese( (char *)&i, 4 );
         return new KonstantInteger( i );
     }
     case KONSTANT_GEGENSTAND_TYP:
     {
         params->release();
         int i;
-        dat.lese( (char *)& i, 4 );
+        dat.lese( (char *)&i, 4 );
         return new KonstantGegenstandTyp( (GegenstandTyp)i );
     }
     case KONSTANT_TASTE:
     {
         params->release();
         unsigned char i;
-        dat.lese( (char *)& i, 1 );
+        dat.lese( (char *)&i, 1 );
         return new KonstantTaste( i );
     }
     case KONSTANT_NICHTS:
@@ -636,6 +637,19 @@ Aktion *MapReader::readAktion( Datei &dat )
     return new KonstantNichts();
 }
 
+void MapReader::writeAktion( Aktion *zAk, StreamWriter &dat )
+{
+    int id = zAk->getTyp();
+    dat.schreibe( (char *)&id, 4 );
+    unsigned char pAnz = (unsigned char)zAk->zSubActions()->getEintragAnzahl();
+    dat.schreibe( (char *)&pAnz, 1 );
+    for( auto e = zAk->zSubActions()->getIterator(); e; e++ )
+    {
+        writeAktion( e, dat );
+        e->writeOptions( dat );
+    }
+}
+
 // nicht constant
 void MapReader::ladeKarte( Spiel *zSpiel )
 {
@@ -652,18 +666,18 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         return;
     }
     datei->open( Datei::Style::lesen );
-    datei->lese( (char *)& sts.spielerAnzahl, 4 );
-    datei->lese( (char *)& sts.teamAnzahl, 4 );
+    datei->lese( (char *)&sts.spielerAnzahl, 4 );
+    datei->lese( (char *)&sts.teamAnzahl, 4 );
     for( int i = 0; i < sts.spielerAnzahl; i++ )
     {
         int farbe = 0;
-        datei->lese( (char *)& farbe, 4 );
+        datei->lese( (char *)&farbe, 4 );
         sts.spielerFarbe.set( farbe, i );
     }
     for( int i = 0; i < sts.teamAnzahl; i++ )
     {
         int farbe = 0;
-        datei->lese( (char *)& farbe, 4 );
+        datei->lese( (char *)&farbe, 4 );
         sts.teamFarbe.set( farbe, i );
     }
     for( int i = 0; i < sts.teamAnzahl; i++ )
@@ -680,7 +694,7 @@ void MapReader::ladeKarte( Spiel *zSpiel )
     for( int i = 0; i < sts.teamAnzahl; i++ )
     {
         int size = 0;
-        datei->lese( (char *)& size, 4 );
+        datei->lese( (char *)&size, 4 );
         sts.teamSize.set( size, i );
     }
     datei->close();
@@ -695,16 +709,16 @@ void MapReader::ladeKarte( Spiel *zSpiel )
     // map Size
     int width;
     int height;
-    mapFile.lese( (char *)& width, 4 );
-    mapFile.lese( (char *)& height, 4 );
+    mapFile.lese( (char *)&width, 4 );
+    mapFile.lese( (char *)&height, 4 );
     zSpiel->setMapSize( width, height );
     // teams
     for( int i = 0; i < sts.teamAnzahl; i++ )
     {
         int maxWbZeit;
         int punkte;
-        mapFile.lese( (char *)& maxWbZeit, 4 );
-        mapFile.lese( (char *)& punkte, 4 );
+        mapFile.lese( (char *)&maxWbZeit, 4 );
+        mapFile.lese( (char *)&punkte, 4 );
         zSpiel->addTeam( new Team( i, sts.teamSize.get( i ), punkte, maxWbZeit, sts.teamFarbe.get( i ), sts.teamName.z( i )->getText() ) );
     }
     // spieler
@@ -714,8 +728,8 @@ void MapReader::ladeKarte( Spiel *zSpiel )
     {
         int spawnX;
         int spawnY;
-        mapFile.lese( (char *)& spawnX, 4 );
-        mapFile.lese( (char *)& spawnY, 4 );
+        mapFile.lese( (char *)&spawnX, 4 );
+        mapFile.lese( (char *)&spawnY, 4 );
         if( i >= maxT )
         {
             team++;
@@ -726,7 +740,7 @@ void MapReader::ladeKarte( Spiel *zSpiel )
     }
     // Barieren
     int anz = 0;
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -738,19 +752,19 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         int autoSchaltungMaxTime;
         int team;
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& breite, 4 );
-        mapFile.lese( (char *)& height, 4 );
-        mapFile.lese( (char *)& style, 4 );
-        mapFile.lese( (char *)& verschiebungWeite, 4 );
-        mapFile.lese( (char *)& autoSchaltungMaxTime, 4 );
-        mapFile.lese( (char *)& team, 4 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&breite, 4 );
+        mapFile.lese( (char *)&height, 4 );
+        mapFile.lese( (char *)&style, 4 );
+        mapFile.lese( (char *)&verschiebungWeite, 4 );
+        mapFile.lese( (char *)&autoSchaltungMaxTime, 4 );
+        mapFile.lese( (char *)&team, 4 );
         zSpiel->addBariere( new Bariere( zSpiel->zResources(), id, x, y, breite, height, style, verschiebungWeite, autoSchaltungMaxTime, zSpiel->getTeam( team ) ) );
     }
     // Basen
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -764,21 +778,21 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         int timerX;
         int timerY;
         int timerFarbe;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& breite, 4 );
-        mapFile.lese( (char *)& height, 4 );
-        mapFile.lese( (char *)& maxTime, 4 );
-        mapFile.lese( (char *)& team, 4 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&breite, 4 );
+        mapFile.lese( (char *)&height, 4 );
+        mapFile.lese( (char *)&maxTime, 4 );
+        mapFile.lese( (char *)&team, 4 );
         mapFile.lese( (char *)&showTimer, 1 );
         mapFile.lese( (char *)&timerX, 4 );
         mapFile.lese( (char *)&timerY, 4 );
         mapFile.lese( (char *)&timerFarbe, 4 );
-        zSpiel->addBase( new Base( zSpiel->zResources(), id, x, y, breite, height, showTimer, Punkt( timerX, timerY ), timerFarbe, new TextRenderer( zSpiel->zResources()->getSchrift() ), maxTime, zSpiel->getTeam( team ) ) );
+        zSpiel->addBase( new Base( zSpiel->zResources(), id, x, y, breite, height, showTimer, Punkt( timerX, timerY ), timerFarbe, new TextRenderer( dynamic_cast<Schrift *>( zSpiel->zResources()->getUIFactory().initParam.schrift->getThis() ) ), maxTime, zSpiel->getTeam( team ) ) );
     }
     // Drops
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int minX;
@@ -789,17 +803,17 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         int numDrops;
         float wahrscheinlichkeit[ ITEMANZAHL ];
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& minX, 4 );
-        mapFile.lese( (char *)& minY, 4 );
-        mapFile.lese( (char *)& maxX, 4 );
-        mapFile.lese( (char *)& maxY, 4 );
-        mapFile.lese( (char *)& maxTime, 4 );
-        mapFile.lese( (char *)& numDrops, 4 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&minX, 4 );
+        mapFile.lese( (char *)&minY, 4 );
+        mapFile.lese( (char *)&maxX, 4 );
+        mapFile.lese( (char *)&maxY, 4 );
+        mapFile.lese( (char *)&maxTime, 4 );
+        mapFile.lese( (char *)&numDrops, 4 );
         for( int j = KEIN_GEGENSTAND; j < ITEMANZAHL; j++ )
-            mapFile.lese( (char *)& wahrscheinlichkeit[ j ], 4 );
+            mapFile.lese( (char *)&wahrscheinlichkeit[ j ], 4 );
         char len;
-        mapFile.lese( (char *)& len, 1 );
+        mapFile.lese( (char *)&len, 1 );
         char *name = new char[ (__int64)len + 1 ];
         mapFile.lese( name, len );
         name[ (int)len ] = 0;
@@ -807,7 +821,7 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         delete[] name;
     }
     // Schalter
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -816,16 +830,16 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         int height;
         bool aktive;
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& breite, 4 );
-        mapFile.lese( (char *)& height, 4 );
-        mapFile.lese( (char *)& aktive, 1 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&breite, 4 );
+        mapFile.lese( (char *)&height, 4 );
+        mapFile.lese( (char *)&aktive, 1 );
         zSpiel->addSchalter( new Schalter( zSpiel->zResources(), id, x, y, breite, height, aktive ) );
     }
     // Schiene
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -833,15 +847,15 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         int breite;
         int height;
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& breite, 4 );
-        mapFile.lese( (char *)& height, 4 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&breite, 4 );
+        mapFile.lese( (char *)&height, 4 );
         zSpiel->addSchiene( new Schiene( zSpiel->zResources(), id, x, y, breite, height ) );
     }
     // Timer
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -852,24 +866,24 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         bool runns;
         int farbe;
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& maxZeit, 4 );
-        mapFile.lese( (char *)& sichtbar, 1 );
-        mapFile.lese( (char *)& autoWiederhohlung, 1 );
-        mapFile.lese( (char *)& runns, 1 );
-        mapFile.lese( (char *)& farbe, 4 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&maxZeit, 4 );
+        mapFile.lese( (char *)&sichtbar, 1 );
+        mapFile.lese( (char *)&autoWiederhohlung, 1 );
+        mapFile.lese( (char *)&runns, 1 );
+        mapFile.lese( (char *)&farbe, 4 );
         char len;
-        mapFile.lese( (char *)& len, 1 );
+        mapFile.lese( (char *)&len, 1 );
         char *name = new char[ (__int64)len + 1 ];
         mapFile.lese( name, len );
         name[ (int)len ] = 0;
-        zSpiel->addTimer( new Timer( zSpiel->zResources()->zSchrift(), id, name, maxZeit, x, y, sichtbar, autoWiederhohlung, runns, farbe ) );
+        zSpiel->addTimer( new Timer( zSpiel->zResources()->getUIFactory().initParam.schrift, id, name, maxZeit, x, y, sichtbar, autoWiederhohlung, runns, farbe ) );
         delete[] name;
     }
     // Tunnel
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -880,18 +894,18 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         int zielY;
         bool aktiv;
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& breite, 4 );
-        mapFile.lese( (char *)& height, 4 );
-        mapFile.lese( (char *)& zielX, 4 );
-        mapFile.lese( (char *)& zielY, 4 );
-        mapFile.lese( (char *)& aktiv, 1 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&breite, 4 );
+        mapFile.lese( (char *)&height, 4 );
+        mapFile.lese( (char *)&zielX, 4 );
+        mapFile.lese( (char *)&zielY, 4 );
+        mapFile.lese( (char *)&aktiv, 1 );
         zSpiel->addTunnel( new Tunnel( zSpiel->zResources(), id, x, y, breite, height, zielX, zielY, aktiv ) );
     }
     // Umlenkungen
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int x;
@@ -903,37 +917,37 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         bool drehend;
         bool aktiv;
         int id;
-        mapFile.lese( (char *)& id, 4 );
-        mapFile.lese( (char *)& x, 4 );
-        mapFile.lese( (char *)& y, 4 );
-        mapFile.lese( (char *)& breite, 4 );
-        mapFile.lese( (char *)& height, 4 );
-        mapFile.lese( (char *)& richtung, 1 );
-        mapFile.lese( (char *)& maxAbklingzeit, 4 );
-        mapFile.lese( (char *)& drehend, 1 );
-        mapFile.lese( (char *)& aktiv, 1 );
+        mapFile.lese( (char *)&id, 4 );
+        mapFile.lese( (char *)&x, 4 );
+        mapFile.lese( (char *)&y, 4 );
+        mapFile.lese( (char *)&breite, 4 );
+        mapFile.lese( (char *)&height, 4 );
+        mapFile.lese( (char *)&richtung, 1 );
+        mapFile.lese( (char *)&maxAbklingzeit, 4 );
+        mapFile.lese( (char *)&drehend, 1 );
+        mapFile.lese( (char *)&aktiv, 1 );
         zSpiel->addUmlenkung( new Umlenkung( zSpiel->zResources(), id, x, y, breite, height, (Richtung)richtung, maxAbklingzeit, drehend, aktiv ) );
     }
     // Trigger
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         int id;
-        mapFile.lese( (char *)& id, 4 );
+        mapFile.lese( (char *)&id, 4 );
         char len;
-        mapFile.lese( (char *)& len, 1 );
+        mapFile.lese( (char *)&len, 1 );
         char *name = new char[ (__int64)len + 1 ];
         mapFile.lese( name, len );
         name[ (int)len ] = 0;
         int ereignisAnzahl;
         int bedingungAnzahl;
         int aktionAnzahl;
-        mapFile.lese( (char *)& ereignisAnzahl, 4 );
-        mapFile.lese( (char *)& bedingungAnzahl, 4 );
-        mapFile.lese( (char *)& aktionAnzahl, 4 );
+        mapFile.lese( (char *)&ereignisAnzahl, 4 );
+        mapFile.lese( (char *)&bedingungAnzahl, 4 );
+        mapFile.lese( (char *)&aktionAnzahl, 4 );
         EreignisTyp *ereignisse = new EreignisTyp[ ereignisAnzahl ];
         for( int j = 0; j < ereignisAnzahl; j++ )
-            mapFile.lese( (char *)& ereignisse[ j ], 4 );
+            mapFile.lese( (char *)&ereignisse[ j ], 4 );
         RCArray< Bedingung > *bedingungen = new RCArray< Bedingung >();
         for( int j = 0; j < bedingungAnzahl; j++ )
             bedingungen->add( new Bedingung( readAktion( mapFile ) ) );
@@ -944,11 +958,11 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         delete[] name;
     }
     // Variablen
-    mapFile.lese( (char *)& anz, 4 );
+    mapFile.lese( (char *)&anz, 4 );
     for( int i = 0; i < anz; i++ )
     {
         char len;
-        mapFile.lese( (char *)& len, 1 );
+        mapFile.lese( (char *)&len, 1 );
         char *name = new char[ (__int64)len + 1 ];
         mapFile.lese( name, len );
         name[ (int)len ] = 0;
@@ -969,21 +983,21 @@ void MapReader::ladeKarte( Spiel *zSpiel )
             case INTEGER:
             {
                 int val;
-                mapFile.lese( (char *)& val, 4 );
+                mapFile.lese( (char *)&val, 4 );
                 var = new Integer( val );
                 break;
             }
             case BOOLEAN:
             {
                 bool val;
-                mapFile.lese( (char *)& val, 1 );
+                mapFile.lese( (char *)&val, 1 );
                 var = new Boolean( val );
                 break;
             }
             case STRING:
             {
                 char len;
-                mapFile.lese( (char *)& len, 1 );
+                mapFile.lese( (char *)&len, 1 );
                 char *value = new char[ (__int64)len + 1 ];
                 mapFile.lese( value, len );
                 value[ (int)len ] = 0;
@@ -994,7 +1008,7 @@ void MapReader::ladeKarte( Spiel *zSpiel )
             case RICHTUNG:
             {
                 char len;
-                mapFile.lese( (char *)& len, 1 );
+                mapFile.lese( (char *)&len, 1 );
                 char *value = new char[ (__int64)len + 1 ];
                 mapFile.lese( value, len );
                 value[ (int)len ] = 0;
@@ -1005,7 +1019,7 @@ void MapReader::ladeKarte( Spiel *zSpiel )
             case FLOAT:
             {
                 float val;
-                mapFile.lese( (char *)& val, 4 );
+                mapFile.lese( (char *)&val, 4 );
                 var = new Float( val );
                 break;
             }
@@ -1019,77 +1033,77 @@ void MapReader::ladeKarte( Spiel *zSpiel )
             case SPIELER:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getSpieler( id );
                 break;
             }
             case TIMER:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getTimer( id );
                 break;
             }
             case TEAM:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getTeam( id );
                 break;
             }
             case BARIERE:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getBariere( id );
                 break;
             }
             case SCHALTER:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getSchalter( id );
                 break;
             }
             case BASE:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getBase( id );
                 break;
             }
             case GEGENSTAND:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = new GegenstandTypVar( (GegenstandTyp)id );
                 break;
             }
             case SCHIENE:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getSchiene( id );
                 break;
             }
             case TUNNEL:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getTunnel( id );
                 break;
             }
             case UMLENKUNG:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getUmlenkung( id );
                 break;
             }
             case TRIGGER:
             {
                 int id;
-                mapFile.lese( (char *)& id, 4 );
+                mapFile.lese( (char *)&id, 4 );
                 var = zSpiel->getTrigger( id );
                 break;
             }
@@ -1101,18 +1115,4 @@ void MapReader::ladeKarte( Spiel *zSpiel )
         delete[] name;
     }
     mapFile.close();
-}
-
-// Reference Counting
-MapReader *MapReader::getThis()
-{
-    ref++;
-    return this;
-}
-
-MapReader *MapReader::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
 }

+ 6 - 8
StickmanWorldOnline/Reader.h

@@ -1,6 +1,7 @@
 #pragma once
 
-#include <Datei.h>
+#include <Reader.h>
+#include <Writer.h>
 #include <Vec2.h>
 #include "Team.h"
 #include "Spiel.h"
@@ -8,14 +9,11 @@
 class Spiel;
 class Aktion;
 
-class MapReader
+class MapReader : public virtual ReferenceCounter
 {
 private:
     Text *pfad;
     int karteId;
-    int ref;
-
-    Aktion *readAktion( Datei &dat );
 
 public:
     // Konstruktor
@@ -26,7 +24,7 @@ public:
     Array< int > *getTeamFarben();
     // nicht constant
     void ladeKarte( Spiel *zSpiel );
-    // Reference Counting
-    MapReader *getThis();
-    MapReader *release();
+
+    static Aktion *readAktion( StreamReader &dat );
+    static void writeAktion( Aktion *zAk, StreamWriter &dat );
 };

+ 15 - 65
StickmanWorldOnline/Resource.cpp

@@ -3,9 +3,8 @@
 
 
 ColorMode::ColorMode()
-{
-    ref = 1;
-}
+    : ReferenceCounter()
+{}
 
 Bild *ColorMode::colorImage( Bild *zImg, int color )
 {
@@ -15,19 +14,6 @@ Bild *ColorMode::colorImage( Bild *zImg, int color )
     return result;
 }
 
-ColorMode *ColorMode::getThis()
-{
-    ref++;
-    return this;
-}
-
-ColorMode *ColorMode::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 
 AlphaColorMode::AlphaColorMode( unsigned char alpha )
 {
@@ -61,11 +47,11 @@ Bild *MaskColorMode::colorImage( Bild *zImg, int color )
 }
 
 
-Resource::Resource( ResourceIds id, int color )
+Resource::Resource( ResourceId id, int color )
+    : ReferenceCounter()
 {
     this->id = id;
     this->color = color;
-    ref = 1;
 }
 
 Resource *Resource::createColoredResource( int color, ColorMode *mode ) const
@@ -82,7 +68,7 @@ Iterator< Bild * > Resource::getImages() const
     return images.getIterator();
 }
 
-ResourceIds Resource::getId() const
+ResourceId Resource::getId() const
 {
     return id;
 }
@@ -107,57 +93,34 @@ int Resource::getImageCount() const
     return images.getEintragAnzahl();
 }
 
-Resource *Resource::getThis()
-{
-    ref++;
-    return this;
-}
-
-Resource *Resource::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 
 ResourceRegistry::ResourceRegistry( Text spielPfad, Text mapPfad )
+    : ReferenceCounter()
 {
     this->spielPfad = spielPfad;
     this->mapPfad = mapPfad;
-    ref = 1;
 }
 
 ResourceRegistry::~ResourceRegistry()
-{
-    if( schrift )
-        schrift->release();
-}
-
-void ResourceRegistry::setSchrift( Schrift *schrift )
-{
-    if( this->schrift )
-        this->schrift->release();
-    this->schrift = schrift;
-}
+{}
 
-Schrift *ResourceRegistry::zSchrift() const
+void ResourceRegistry::setUIFactory( UIInit &uiFactory )
 {
-    return schrift;
+    this->uiFactory = uiFactory;
 }
 
-Schrift *ResourceRegistry::getSchrift() const
+UIInit &ResourceRegistry::getUIFactory()
 {
-    return schrift ? schrift->getThis() : 0;
+    return uiFactory;
 }
 
-Resource *ResourceRegistry::getResource( ResourceIds id, int color, ColorMode *mode, Text path )
+Resource *ResourceRegistry::getResource( ResourceId id, int color, ColorMode *mode, Text path )
 {
     Resource *r = zResource( id, color, mode, path );
-    return r ? r->getThis() : 0;
+    return r ? dynamic_cast<Resource *>( r->getThis() ) : 0;
 }
 
-Resource *ResourceRegistry::zResource( ResourceIds id, int color, ColorMode *mode, Text path )
+Resource *ResourceRegistry::zResource( ResourceId id, int color, ColorMode *mode, Text path )
 {
     path.ersetzen( "map:", mapPfad );
     path.ersetzen( "spiel:", spielPfad );
@@ -199,7 +162,7 @@ Resource *ResourceRegistry::zResource( ResourceIds id, int color, ColorMode *mod
         return 0;
     }
     LTDBDatei dat;
-    dat.setDatei( path.getThis() );
+    dat.setDatei( dynamic_cast<Text *>( path.getThis() ) );
     dat.leseDaten( 0 );
     if( !dat.getBildAnzahl() )
     {
@@ -216,17 +179,4 @@ Resource *ResourceRegistry::zResource( ResourceIds id, int color, ColorMode *mod
     }
     mode->release();
     return r;
-}
-
-ResourceRegistry *ResourceRegistry::getThis()
-{
-    ref++;
-    return this;
-}
-
-ResourceRegistry *ResourceRegistry::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
 }

+ 13 - 24
StickmanWorldOnline/Resource.h

@@ -2,19 +2,15 @@
 
 #include <Bild.h>
 #include <Schrift.h>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
-class ColorMode
+class ColorMode : public virtual ReferenceCounter
 {
-private:
-    int ref;
-
 public:
     ColorMode();
     virtual Bild *colorImage( Bild *zImg, int color );
-    ColorMode *getThis();
-    ColorMode *release();
 };
 
 class AlphaColorMode : public ColorMode
@@ -37,7 +33,7 @@ public:
     Bild *colorImage( Bild *zImg, int color ) override;
 };
 
-enum ResourceIds
+enum ResourceId
 {
     R_BARIERE,
     R_BASE,
@@ -103,45 +99,38 @@ enum ResourceIds
 
 class ResourceRegistry;
 
-class Resource
+class Resource : public virtual ReferenceCounter
 {
 private:
-    ResourceIds id;
+    ResourceId id;
     int color;
-    int ref;
     RCArray< Bild > images;
 
 public:
-    Resource( ResourceIds id, int color );
+    Resource( ResourceId id, int color );
     virtual Resource *createColoredResource( int color, ColorMode *mode ) const;
     Iterator< Bild * > getImages() const;
-    ResourceIds getId() const;
+    ResourceId getId() const;
     int getColor() const;
     Bild *zImage( int id ) const;
     Bild *getImage( int id ) const;
     int getImageCount() const;
-    Resource *getThis();
-    Resource *release();
     friend ResourceRegistry;
 };
 
-class ResourceRegistry
+class ResourceRegistry : public virtual ReferenceCounter
 {
 private:
     RCArray< Resource > resources;
     Text spielPfad;
     Text mapPfad;
-    Schrift *schrift;
-    int ref;
+    UIInit uiFactory;
 
 public:
     ResourceRegistry( Text spielPfad, Text mapPfad );
     ~ResourceRegistry();
-    void setSchrift( Schrift *schrift );
-    Schrift *zSchrift() const;
-    Schrift *getSchrift() const;
-    Resource *getResource( ResourceIds id, int color, ColorMode *mode = 0, Text path = "" );
-    Resource *zResource( ResourceIds id, int color, ColorMode *mode = 0, Text path = "" );
-    ResourceRegistry *getThis();
-    ResourceRegistry *release();
+    void setUIFactory( UIInit &uiFactory );
+    UIInit &getUIFactory();
+    Resource *getResource( ResourceId id, int color, ColorMode *mode = 0, Text path = "" );
+    Resource *zResource( ResourceId id, int color, ColorMode *mode = 0, Text path = "" );
 };

+ 0 - 7
StickmanWorldOnline/RightTools.h

@@ -7,15 +7,11 @@ using namespace Framework;
 
 class RightTool : public Zeichnung
 {
-private:
-    int ref;
 
 public:
     RightTool();
     virtual ~RightTool();
     virtual void renderDialogs( Bild &rObj );
-    RightTool *getThis();
-    RightTool *release();
 };
 
 class RightTools : public ZeichnungHintergrund
@@ -24,7 +20,6 @@ private:
     AuswahlBox *toolAuswahl;
     RCArray< RightTool > *tools;
     Punkt maxSize;
-    int ref;
 
 public:
     RightTools( Schrift *zSchrift, Punkt maxSize );
@@ -35,6 +30,4 @@ public:
     bool tick( double tickVal ) override;
     void render( Bild &rObj ) override;
     void selectTool( int index );
-    RightTools *getThis();
-    RightTools *release();
 };

+ 1 - 1
StickmanWorldOnline/Rolle.cpp

@@ -63,5 +63,5 @@ bool RolleEffect::istGegenstandErlaubt( GegenstandTyp typ ) const
 
 Resource *RolleEffect::getCurrentResource()
 {
-    return annimation ? annimation->getThis() : 0;
+    return annimation ? dynamic_cast<Resource *>( annimation->getThis() ) : 0;
 }

+ 9 - 24
StickmanWorldOnline/STKNachricht.cpp

@@ -4,53 +4,38 @@
 // Inhalt der STKNachricht Klasse aus STKNachricht.h
 // Konstruktor
 STKNachricht::STKNachricht( int län, char *nachricht )
+    : ReferenceCounter()
 {
-	verarbeitet = 0;
-	this->län = län;
-	this->nachricht = new char[ this->län ];
+    verarbeitet = 0;
+    this->län = län;
+    this->nachricht = new char[ this->län ];
     memcpy( this->nachricht, nachricht, län );
-	ref = 1;
 }
 
 // Destruktor
 STKNachricht::~STKNachricht()
 {
-	delete[] nachricht;
+    delete[] nachricht;
 }
 
 // nicht constant
 void STKNachricht::setVerarbeitet()
 {
-	verarbeitet = 1;
+    verarbeitet = 1;
 }
 
 // constant
 bool STKNachricht::istVerarbeitet() const
 {
-	return verarbeitet;
+    return verarbeitet;
 }
 
 int STKNachricht::getLength() const
 {
-	return län;
+    return län;
 }
 
 char *STKNachricht::getNachricht() const
 {
-	return nachricht;
-}
-
-// Reference Counting
-STKNachricht *STKNachricht::getThis()
-{
-	ref++;
-	return this;
-}
-
-STKNachricht *STKNachricht::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return nachricht;
 }

+ 16 - 18
StickmanWorldOnline/STKNachricht.h

@@ -1,28 +1,26 @@
 #ifndef STKNachricht_H
 #define STKNachricht_H
 
-class STKNachricht
+#include <ReferenceCounter.h> 
+
+class STKNachricht : public virtual Framework::ReferenceCounter
 {
 private:
-	int län;
-	char *nachricht;
-	bool verarbeitet;
-	int ref;
+    int län;
+    char *nachricht;
+    bool verarbeitet;
 
 public:
-	// Konstruktor
-	STKNachricht( int län, char *nachricht );
-	// Destruktor
-	~STKNachricht();
-	// nicht constant
-	void setVerarbeitet();
-	// constant
-	bool istVerarbeitet() const;
-	int getLength() const;
-	char *getNachricht() const;
-	// Reference Counting
-	STKNachricht *getThis();
-	STKNachricht *release();
+    // Konstruktor
+    STKNachricht( int län, char *nachricht );
+    // Destruktor
+    ~STKNachricht();
+    // nicht constant
+    void setVerarbeitet();
+    // constant
+    bool istVerarbeitet() const;
+    int getLength() const;
+    char *getNachricht() const;
 };
 
 #endif

+ 3 - 3
StickmanWorldOnline/Schalter.cpp

@@ -9,7 +9,7 @@ Schalter::Schalter( ResourceRegistry *zResources, int id, int x, int y, int widt
     this->aktiv = aktive;
     aktivierungen = 0;
     texturScale = 1;
-    textur = zResources->zResource( R_SCHALTER, 0 )->getImages()->getThis();
+    textur = dynamic_cast<Bild *>( zResources->zResource( R_SCHALTER, 0 )->getImages()->getThis() );
 }
 
 void Schalter::setAktive( bool aktiv )
@@ -19,10 +19,10 @@ void Schalter::setAktive( bool aktiv )
 
 void Schalter::press( Spiel *zSpiel )
 {
-    zSpiel->setSchalterZuletztAktiviert( (Schalter *)getThis() );
+    zSpiel->setSchalterZuletztAktiviert( dynamic_cast<Schalter *>( getThis() ) );
     aktivierungen++;
     Ereignis *e = new Ereignis( SCHALTER_AKTIVIERT );
-    e->addParameter( "Betroffener Schalter", getThis() );
+    e->addParameter( "Betroffener Schalter", dynamic_cast<Schalter *>( getThis() ) );
     zSpiel->throwEvent( e );
 }
 

+ 1 - 1
StickmanWorldOnline/Schiene.cpp

@@ -5,7 +5,7 @@ Schiene::Schiene( ResourceRegistry *zResources, int id, int x, int y, int width,
 {
     this->id = id;
     if( width > height )
-        this->textur = zResources->zResource( R_SCHIENE, 0 )->getImages()->getThis();
+        this->textur = dynamic_cast<Bild *>( zResources->zResource( R_SCHIENE, 0 )->getImages()->getThis() );
     else
     {
         Bild *r = zResources->zResource( R_SCHIENE, 0 )->getImages();

+ 86 - 107
StickmanWorldOnline/Spiel.cpp

@@ -5,13 +5,12 @@
 
 // Konstruktor
 Spiel::Spiel()
+    : ReferenceCounter()
 {
     stkn = new RCArray< STKNachricht >();
-    schrift = 0;
     infoKlient = 0;
     spielKlient = 0;
-    zScreen = 0;
-    chat = new SpielChat();
+    chat = 0;
     end = 0;
     spielerGUI = 0;
     deads = new RCArray< DeadPlayer >();
@@ -64,20 +63,18 @@ Spiel::Spiel()
     resources = 0;
     nextAutoVerschiebung = 10;
     nextAutoSchaltung = 10;
-    ref = 1;
 }
 
 // Destruktor
 Spiel::~Spiel()
 {
     stkn->release();
-    if( schrift )
-        schrift->release();
     if( infoKlient )
         infoKlient->release();
     if( spielKlient )
         spielKlient->release();
-    chat->relese();
+    if( chat )
+        chat->release();
     if( end )
         end->release();
     if( spielerGUI )
@@ -275,7 +272,7 @@ void Spiel::tick()
         {
             if( zuletztBariereGetroffenesGeschoss )
                 zuletztBariereGetroffenesGeschoss->release();
-            zuletztBariereGetroffenesGeschoss = (Geschoss *)g->getThis();
+            zuletztBariereGetroffenesGeschoss = dynamic_cast<Geschoss *>( g->getThis() );
             g->tick( -zeit );
             switch( g->getTyp() )
             {
@@ -327,8 +324,8 @@ void Spiel::tick()
                     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() );
+                    e->addParameter( "Betroffes Geschoss", dynamic_cast<Geschoss *>( g->getThis() ) );
+                    e->addParameter( "Betroffer Tunnel", dynamic_cast<Tunnel *>( t->getThis() ) );
                     throwEvent( e );
                 }
             }
@@ -361,8 +358,8 @@ void Spiel::tick()
                             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() );
+                            e->addParameter( "Betroffes Geschoss", dynamic_cast<Geschoss *>( g->getThis() ) );
+                            e->addParameter( "Betroffe Umlenkung", dynamic_cast<Umlenkung *>( u->getThis() ) );
                             throwEvent( e );
                         }
                     }
@@ -523,19 +520,11 @@ void Spiel::unlock()
     c.unlock();
 }
 
-// call 4
-void Spiel::setSchrift( Schrift *schrift )
-{
-    if( this->schrift )
-        this->schrift->release();
-    this->schrift = schrift;
-    chat->setSchrift( schrift );
-}
-
 // call 3
-void Spiel::setBildschirm( Bildschirm *zScreen )
+void Spiel::setUIFactory( UIInit &uiFactory )
 {
-    this->zScreen = zScreen;
+    this->uiFactory = uiFactory;
+    chat = new SpielChat( uiFactory );
 }
 
 void Spiel::nachricht( int län, char *bytes )
@@ -572,7 +561,7 @@ void Spiel::ladeDaten()
     if( resources )
         resources->release();
     resources = new ResourceRegistry( gamePath->getText(), mapPf );
-    resources->setSchrift( schrift->getThis() );
+    resources->setUIFactory( uiFactory );
     resources->zResource( R_BARIERE, 0, new ColorMode(), "spiel:/bilder/textures.ltdb/bariere.png" );
     resources->zResource( R_BASE, 0, new ColorMode(), "spiel:/bilder/textures.ltdb/base.png" );
     resources->zResource( R_PFEIL_GESCHOSS, 0, new ColorMode(), "spiel:/bilder/textures.ltdb/pfeilg.png" );
@@ -641,8 +630,8 @@ void Spiel::ladeDaten()
     AlphaColorMode *alphaMode = new AlphaColorMode( 0x77 );
     for( auto c = colors->getIterator(); c; c++ )
     {
-        resources->zResource( R_BARIERE, c._, alphaMode->getThis() );
-        resources->zResource( R_BASE, c._, alphaMode->getThis() );
+        resources->zResource( R_BARIERE, c._, dynamic_cast<AlphaColorMode *>( alphaMode->getThis() ) );
+        resources->zResource( R_BASE, c._, dynamic_cast<AlphaColorMode *>( alphaMode->getThis() ) );
     }
     colors->release();
     alphaMode->release();
@@ -652,18 +641,18 @@ void Spiel::ladeDaten()
     MaskColorMode *maskMode = new MaskColorMode( 0xFFFFFF );
     for( auto c = colors->getIterator(); c; c++ )
     {
-        resources->zResource( R_ROLLE_OBEN, c._, maskMode->getThis() );
-        resources->zResource( R_ROLLE_LINKS, c._, maskMode->getThis() );
-        resources->zResource( R_ROLLE_RECHTS, c._, maskMode->getThis() );
-        resources->zResource( R_ROLLE_UNTEN, c._, maskMode->getThis() );
-        resources->zResource( R_STURM_OBEN, c._, maskMode->getThis() );
-        resources->zResource( R_STURM_LINKS, c._, maskMode->getThis() );
-        resources->zResource( R_STURM_RECHTS, c._, maskMode->getThis() );
-        resources->zResource( R_STURM_UNTEN, c._, maskMode->getThis() );
-        resources->zResource( R_SPIELER_STIRBT, c._, maskMode->getThis() );
-        resources->zResource( R_SPIELER, c._, maskMode->getThis() );
-        resources->zResource( R_SPIELER_RECHTS, c._, maskMode->getThis() );
-        resources->zResource( R_SPIELER_LINKS, c._, maskMode->getThis() );
+        resources->zResource( R_ROLLE_OBEN, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_ROLLE_LINKS, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_ROLLE_RECHTS, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_ROLLE_UNTEN, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_STURM_OBEN, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_STURM_LINKS, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_STURM_RECHTS, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_STURM_UNTEN, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_SPIELER_STIRBT, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_SPIELER, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_SPIELER_RECHTS, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
+        resources->zResource( R_SPIELER_LINKS, c._, dynamic_cast<MaskColorMode *>( maskMode->getThis() ) );
     }
     colors->release();
     spielKlient->setLadenProzent( 50 );
@@ -687,7 +676,8 @@ void Spiel::doPublicMausEreignis( MausEreignis &me )
         end->doPublicMausEreignis( me );
         return;
     }
-    chat->doPublicMausEreignis( me );
+    if( chat )
+        chat->doPublicMausEreignis( me );
 }
 
 void Spiel::doTastaturEreignis( TastaturEreignis &te )
@@ -699,7 +689,7 @@ void Spiel::doTastaturEreignis( TastaturEreignis &te )
         end->doTastaturEreignis( te );
         return;
     }
-    if( !chat->istAktiv() )
+    if( chat && !chat->istAktiv() )
     {
         if( te.id == TE_Press && !tasten[ te.taste ] )
         {
@@ -716,7 +706,7 @@ void Spiel::doTastaturEreignis( TastaturEreignis &te )
             te.verarbeitet = 1;
         }
     }
-    if( !te.verarbeitet )
+    if( chat && !te.verarbeitet )
         chat->doTastaturEreignis( te, spielKlient );
 }
 
@@ -731,7 +721,7 @@ void Spiel::stknVerarbeitung()
         {
         case 1: // initialisation
         {
-            spielerAnzahl = ( int ) * ( msg + 1 );
+            spielerAnzahl = (int)*( msg + 1 );
             for( int i = 0; i < spielerAnzahl; i++ )
             {
                 int sId = *(int *)( msg + 2 + (__int64)i * 8 );
@@ -761,7 +751,7 @@ void Spiel::stknVerarbeitung()
             for( auto s = spieler.getIterator(); s; s++ )
             {
                 if( s->getId() == spielerNummer )
-                    spielerGUI->setSpieler( (Spieler *)s->getThis() );
+                    spielerGUI->setSpieler( dynamic_cast<Spieler *>( s->getThis() ) );
             }
             n->setVerarbeitet();
             break;
@@ -784,7 +774,7 @@ void Spiel::stknVerarbeitung()
                     {
                         Ereignis *e = new Ereignis( aktiv ? SPIELER_KEY_PRESSED : SPIELER_KEY_RELEASED );
                         e->addParameter( "Betroffene Taste", new Integer( taste, 1 ) );
-                        e->addParameter( "Ausführender Spieler", s->getThis() );
+                        e->addParameter( "Ausführender Spieler", dynamic_cast<Spieler *>( s->getThis() ) );
                         throwEvent( e );
                     }
                     break;
@@ -808,7 +798,8 @@ void Spiel::stknVerarbeitung()
             char *buf = new char[ (__int64)n->getLength() ];
             memcpy( buf, msg + 1, n->getLength() - 1 );
             buf[ n->getLength() - 1 ] = 0;
-            chat->addNachricht( buf );
+            if( chat )
+                chat->addNachricht( buf );
             delete[] buf;
             n->setVerarbeitet();
             break;
@@ -836,7 +827,8 @@ bool Spiel::tick( double zeit )
             deadsCount--;
         }
     }
-    chat->tick( zeit );
+    if( chat )
+        chat->tick( zeit );
     return 1;
 }
 
@@ -894,7 +886,8 @@ void Spiel::render( Bild &zRObj )
     }
     if( begonnen )
     {
-        chat->render( zRObj );
+        if( chat )
+            chat->render( zRObj );
         if( end )
             end->render( zRObj );
     }
@@ -977,7 +970,7 @@ void Spiel::addGegenstand( Gegenstand *gegenstand )
     items.add( gegenstand );
     zuletztGedropterGegenstand = gegenstand->getTyp();
     Ereignis *e = new Ereignis( GEGENSTAND_DROPED );
-    e->addParameter( "Betroffener Gegenstand", gegenstand->getThis() );
+    e->addParameter( "Betroffener Gegenstand", dynamic_cast<Gegenstand *>( gegenstand->getThis() ) );
     throwEvent( e );
 }
 
@@ -986,7 +979,7 @@ void Spiel::addGeschoss( Geschoss *geschoss )
     nextId = nextId > geschoss->getId() ? nextId : geschoss->getId() + 1;
     if( zuletztAbgefeuertesGeschoss )
         zuletztAbgefeuertesGeschoss->release();
-    zuletztAbgefeuertesGeschoss = (Geschoss *)geschoss->getThis();
+    zuletztAbgefeuertesGeschoss = dynamic_cast<Geschoss *>( geschoss->getThis() );
     shots.add( geschoss );
 }
 
@@ -1078,7 +1071,7 @@ Team *Spiel::getTeam( int id ) const
     for( auto t = teams.getIterator(); t; t++ )
     {
         if( t->getTeamNummer() == id )
-            return (Team *)t->getThis();
+            return dynamic_cast<Team *>( t->getThis() );
     }
     return 0;
 }
@@ -1088,7 +1081,7 @@ Spieler *Spiel::getSpieler( int id ) const
     for( auto s = spieler.getIterator(); s; s++ )
     {
         if( s->getId() == id )
-            return (Spieler *)s->getThis();
+            return dynamic_cast<Spieler *>( s->getThis() );
     }
     return 0;
 }
@@ -1108,7 +1101,7 @@ Bariere *Spiel::getBariere( int id ) const
     for( auto b = barieren.getIterator(); b; b++ )
     {
         if( b->getId() == id )
-            return (Bariere *)b->getThis();
+            return dynamic_cast<Bariere *>( b->getThis() );
     }
     return 0;
 }
@@ -1118,7 +1111,7 @@ Base *Spiel::getBase( int id ) const
     for( auto b = basen.getIterator(); b; b++ )
     {
         if( b->getId() == id )
-            return (Base *)b->getThis();
+            return dynamic_cast<Base *>( b->getThis() );
     }
     return 0;
 }
@@ -1128,7 +1121,7 @@ Drop *Spiel::getDrop( int id ) const
     for( auto d = drops.getIterator(); d; d++ )
     {
         if( d->getId() == id )
-            return (Drop *)d->getThis();
+            return dynamic_cast<Drop *>( d->getThis() );
     }
     return 0;
 }
@@ -1138,7 +1131,7 @@ Schalter *Spiel::getSchalter( int id ) const
     for( auto s = schalter.getIterator(); s; s++ )
     {
         if( s->getId() == id )
-            return (Schalter *)s->getThis();
+            return dynamic_cast<Schalter *>( s->getThis() );
     }
     return 0;
 }
@@ -1148,7 +1141,7 @@ Schiene *Spiel::getSchiene( int id ) const
     for( auto s = schienen.getIterator(); s; s++ )
     {
         if( s->getId() == id )
-            return (Schiene *)s->getThis();
+            return dynamic_cast<Schiene *>( s->getThis() );
     }
     return 0;
 }
@@ -1158,7 +1151,7 @@ Timer *Spiel::getTimer( int id ) const
     for( auto t = timer.getIterator(); t; t++ )
     {
         if( t->getId() == id )
-            return (Timer *)t->getThis();
+            return dynamic_cast<Timer *>( t->getThis() );
     }
     return 0;
 }
@@ -1168,7 +1161,7 @@ Tunnel *Spiel::getTunnel( int id ) const
     for( auto t = tunnel.getIterator(); t; t++ )
     {
         if( t->getId() == id )
-            return (Tunnel *)t->getThis();
+            return dynamic_cast<Tunnel *>( t->getThis() );
     }
     return 0;
 }
@@ -1178,7 +1171,7 @@ Umlenkung *Spiel::getUmlenkung( int id ) const
     for( auto u = umlenkungen.getIterator(); u; u++ )
     {
         if( u->getId() == id )
-            return (Umlenkung *)u->getThis();
+            return dynamic_cast<Umlenkung *>( u->getThis() );
     }
     return 0;
 }
@@ -1188,7 +1181,7 @@ Trigger *Spiel::getTrigger( int id ) const
     for( auto t = trigger.getIterator(); t; t++ )
     {
         if( t->getId() == id )
-            return (Trigger *)t->getThis();
+            return dynamic_cast<Trigger *>( t->getThis() );
     }
     return 0;
 }
@@ -1233,7 +1226,7 @@ void Spiel::throwEvent( Ereignis *e )
     {
         if( t->hatEreignis( e->getTyp() ) )
         {
-            TriggerRun *tr = t->runTrigger( e->getThis(), this );
+            TriggerRun *tr = t->runTrigger( dynamic_cast<Ereignis *>( e->getThis() ), this );
             if( tr )
                 triggerRuns.add( tr );
         }
@@ -1275,7 +1268,7 @@ void Spiel::setEnde( Team *zGewinner )
         if( s->getId() == spielerNummer )
             i = s;
     }
-    end = new Ende( schrift );
+    end = new Ende( uiFactory );
     end->setGewonnen( ( zGewinner && i ) ? ( i->zTeam() == zGewinner ) : -1 );
 }
 
@@ -1288,7 +1281,7 @@ Trigger *Spiel::getRandomTrigger()
 
 Trigger *Spiel::getLastRunnedTrigger() const
 {
-    return lastRunnedTrigger ? (Trigger *)lastRunnedTrigger->getThis() : 0;
+    return lastRunnedTrigger ? dynamic_cast<Trigger *>( lastRunnedTrigger->getThis() ) : 0;
 }
 
 Bariere *Spiel::getRandomBariere()
@@ -1305,7 +1298,7 @@ void Spiel::setZuletztEingeschalteteBariere( Bariere *b )
 
 Bariere *Spiel::getZuletztEingeschalteteBariere() const
 {
-    return zuletztEingeschalteteBariere ? (Bariere *)zuletztEingeschalteteBariere->getThis() : 0;
+    return zuletztEingeschalteteBariere ? dynamic_cast<Bariere *>( zuletztEingeschalteteBariere->getThis() ) : 0;
 }
 
 void Spiel::setZuletztAusgeschalteteBariere( Bariere *b )
@@ -1317,7 +1310,7 @@ void Spiel::setZuletztAusgeschalteteBariere( Bariere *b )
 
 Bariere *Spiel::getZuletztAusgeschalteteBariere() const
 {
-    return zuletztAusgeschalteteBariere ? (Bariere *)zuletztAusgeschalteteBariere->getThis() : 0;
+    return zuletztAusgeschalteteBariere ? dynamic_cast<Bariere *>( zuletztAusgeschalteteBariere->getThis() ) : 0;
 }
 
 void Spiel::setZuletztBewegteBariere( Bariere *b )
@@ -1329,7 +1322,7 @@ void Spiel::setZuletztBewegteBariere( Bariere *b )
 
 Bariere *Spiel::getZuletztBewegteBariere() const
 {
-    return zuletztBewegteBariere ? (Bariere *)zuletztBewegteBariere->getThis() : 0;
+    return zuletztBewegteBariere ? dynamic_cast<Bariere *>( zuletztBewegteBariere->getThis() ) : 0;
 }
 
 Base *Spiel::getRandomBase()
@@ -1348,7 +1341,7 @@ void Spiel::setLastTeamChangedBase( Base *b )
 
 Base *Spiel::getLastTeamChangedBase() const
 {
-    return lastTeamChangedBase ? (Base *)lastTeamChangedBase->getThis() : 0;
+    return lastTeamChangedBase ? dynamic_cast<Base *>( lastTeamChangedBase->getThis() ) : 0;
 }
 
 Drop *Spiel::getRandomDrop()
@@ -1367,7 +1360,7 @@ void Spiel::setLastDrop( Drop *d )
 
 Drop *Spiel::getLastDrop() const
 {
-    return lastDropedDrop ? (Drop *)lastDropedDrop->getThis() : 0;
+    return lastDropedDrop ? dynamic_cast<Drop *>( lastDropedDrop->getThis() ) : 0;
 }
 
 void Spiel::setItemZuletztAufgehoben( GegenstandTyp g )
@@ -1404,7 +1397,7 @@ Geschoss *Spiel::getRandomGeschoss()
 
 Geschoss *Spiel::getGeschossZuletztAbgefeuert() const
 {
-    return zuletztAbgefeuertesGeschoss ? (Geschoss *)zuletztAbgefeuertesGeschoss->getThis() : 0;
+    return zuletztAbgefeuertesGeschoss ? dynamic_cast<Geschoss *>( zuletztAbgefeuertesGeschoss->getThis() ) : 0;
 }
 
 void Spiel::setGeschossZuletztUmgelenkt( Geschoss *g )
@@ -1416,12 +1409,12 @@ void Spiel::setGeschossZuletztUmgelenkt( Geschoss *g )
 
 Geschoss *Spiel::getGeschossZuletztUmgelenkt() const
 {
-    return zuletztUmgelenktesGeschoss ? (Geschoss *)zuletztUmgelenktesGeschoss->getThis() : 0;
+    return zuletztUmgelenktesGeschoss ? dynamic_cast<Geschoss *>( zuletztUmgelenktesGeschoss->getThis() ) : 0;
 }
 
 Geschoss *Spiel::getGeschossZuletztBariereGetroffen() const
 {
-    return zuletztBariereGetroffenesGeschoss ? (Geschoss *)zuletztBariereGetroffenesGeschoss->getThis() : 0;
+    return zuletztBariereGetroffenesGeschoss ? dynamic_cast<Geschoss *>( zuletztBariereGetroffenesGeschoss->getThis() ) : 0;
 }
 
 void Spiel::setGeschossZuletztTunnelBenutzt( Geschoss *g )
@@ -1433,7 +1426,7 @@ void Spiel::setGeschossZuletztTunnelBenutzt( Geschoss *g )
 
 Geschoss *Spiel::getGeschossZuletztTunnelBenutzt() const
 {
-    return zuletztTunnelBenutztesGeschoss ? (Geschoss *)zuletztTunnelBenutztesGeschoss->getThis() : 0;
+    return zuletztTunnelBenutztesGeschoss ? dynamic_cast<Geschoss *>( zuletztTunnelBenutztesGeschoss->getThis() ) : 0;
 }
 
 void Spiel::setGeschossZuletztGeschossGetroffen( Geschoss *g )
@@ -1445,7 +1438,7 @@ void Spiel::setGeschossZuletztGeschossGetroffen( Geschoss *g )
 
 Geschoss *Spiel::getGeschossZuletztGeschossGetroffen() const
 {
-    return zuletztGeschossGetroffenesGeschoss ? (Geschoss *)zuletztGeschossGetroffenesGeschoss->getThis() : 0;
+    return zuletztGeschossGetroffenesGeschoss ? dynamic_cast<Geschoss *>( zuletztGeschossGetroffenesGeschoss->getThis() ) : 0;
 }
 
 Schalter *Spiel::getRandomSchalter()
@@ -1464,7 +1457,7 @@ void Spiel::setSchalterZuletztAktiviert( Schalter *s )
 
 Schalter *Spiel::getSchalterZuletztAktiviert() const
 {
-    return zuletztAktivierterSchalter ? (Schalter *)zuletztAktivierterSchalter->getThis() : 0;
+    return zuletztAktivierterSchalter ? dynamic_cast<Schalter *>( zuletztAktivierterSchalter->getThis() ) : 0;
 }
 
 Spieler *Spiel::getRandomSpieler()
@@ -1484,7 +1477,7 @@ Spieler *Spiel::getRandomSpieler( Team *zTeam )
         if( s->zTeam() == zTeam )
         {
             if( index-- <= 0 )
-                return (Spieler *)s->getThis();
+                return dynamic_cast<Spieler *>( s->getThis() );
         }
     }
     return 0;
@@ -1499,7 +1492,7 @@ void Spiel::setSpielerZuletztSchadenGemacht( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztSchadenGemacht() const
 {
-    return zuletztSchadenGemachterSpieler ? (Spieler *)zuletztSchadenGemachterSpieler->getThis() : 0;
+    return zuletztSchadenGemachterSpieler ? dynamic_cast<Spieler *>( zuletztSchadenGemachterSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztSchadenGenommen( Spieler *s )
@@ -1511,7 +1504,7 @@ void Spiel::setSpielerZuletztSchadenGenommen( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztSchadenGenommen() const
 {
-    return zuletztSchadenGenommenerSpieler ? (Spieler *)zuletztSchadenGenommenerSpieler->getThis() : 0;
+    return zuletztSchadenGenommenerSpieler ? dynamic_cast<Spieler *>( zuletztSchadenGenommenerSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztGeheilt( Spieler *s )
@@ -1523,7 +1516,7 @@ void Spiel::setSpielerZuletztGeheilt( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztGeheilt() const
 {
-    return zuletztGeheilterSpieler ? (Spieler *)zuletztGeheilterSpieler->getThis() : 0;
+    return zuletztGeheilterSpieler ? dynamic_cast<Spieler *>( zuletztGeheilterSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztLevelUp( Spieler *s )
@@ -1535,7 +1528,7 @@ void Spiel::setSpielerZuletztLevelUp( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztLevelUp() const
 {
-    return zuletztLevelUpSpieler ? (Spieler *)zuletztLevelUpSpieler->getThis() : 0;
+    return zuletztLevelUpSpieler ? dynamic_cast<Spieler *>( zuletztLevelUpSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztErfahrungBekommen( Spieler *s )
@@ -1547,7 +1540,7 @@ void Spiel::setSpielerZuletztErfahrungBekommen( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztErfahrungBekommen() const
 {
-    return zuletztErfahrungBekommenerSpieler ? (Spieler *)zuletztErfahrungBekommenerSpieler->getThis() : 0;
+    return zuletztErfahrungBekommenerSpieler ? dynamic_cast<Spieler *>( zuletztErfahrungBekommenerSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztGegenstandAktiviert( Spieler *s )
@@ -1559,7 +1552,7 @@ void Spiel::setSpielerZuletztGegenstandAktiviert( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztGegenstandAktiviert() const
 {
-    return zuletztGegenstandAktivierterSpieler ? (Spieler *)zuletztGegenstandAktivierterSpieler->getThis() : 0;
+    return zuletztGegenstandAktivierterSpieler ? dynamic_cast<Spieler *>( zuletztGegenstandAktivierterSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztGegenstandAufgehoben( Spieler *s )
@@ -1571,7 +1564,7 @@ void Spiel::setSpielerZuletztGegenstandAufgehoben( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztGegenstandAufgehoben() const
 {
-    return zuletztGegenstandAufgehobenerSpieler ? (Spieler *)zuletztGegenstandAufgehobenerSpieler->getThis() : 0;
+    return zuletztGegenstandAufgehobenerSpieler ? dynamic_cast<Spieler *>( zuletztGegenstandAufgehobenerSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztSchalterAktiviert( Spieler *s )
@@ -1583,7 +1576,7 @@ void Spiel::setSpielerZuletztSchalterAktiviert( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztSchalterAktiviert() const
 {
-    return zuletztSchalterAktivierterSpieler ? (Spieler *)zuletztSchalterAktivierterSpieler->getThis() : 0;
+    return zuletztSchalterAktivierterSpieler ? dynamic_cast<Spieler *>( zuletztSchalterAktivierterSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztTunnelBenutzt( Spieler *s )
@@ -1595,7 +1588,7 @@ void Spiel::setSpielerZuletztTunnelBenutzt( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztTunnelBenutzt() const
 {
-    return zuletztTunnelBenutzterSpieler ? (Spieler *)zuletztTunnelBenutzterSpieler->getThis() : 0;
+    return zuletztTunnelBenutzterSpieler ? dynamic_cast<Spieler *>( zuletztTunnelBenutzterSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztGestorben( Spieler *s )
@@ -1607,7 +1600,7 @@ void Spiel::setSpielerZuletztGestorben( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztGestorben() const
 {
-    return zuletztGestorbenerSpieler ? (Spieler *)zuletztGestorbenerSpieler->getThis() : 0;
+    return zuletztGestorbenerSpieler ? dynamic_cast<Spieler *>( zuletztGestorbenerSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztWiederbelebt( Spieler *s )
@@ -1619,7 +1612,7 @@ void Spiel::setSpielerZuletztWiederbelebt( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztWiederbelebt() const
 {
-    return zuletztWiederbelebterSpieler ? (Spieler *)zuletztWiederbelebterSpieler->getThis() : 0;
+    return zuletztWiederbelebterSpieler ? dynamic_cast<Spieler *>( zuletztWiederbelebterSpieler->getThis() ) : 0;
 }
 
 void Spiel::setSpielerZuletztGeschossen( Spieler *s )
@@ -1631,7 +1624,7 @@ void Spiel::setSpielerZuletztGeschossen( Spieler *s )
 
 Spieler *Spiel::getSpielerZuletztGeschossen() const
 {
-    return zuletztGeschossenerSpieler ? (Spieler *)zuletztGeschossenerSpieler->getThis() : 0;
+    return zuletztGeschossenerSpieler ? dynamic_cast<Spieler *>( zuletztGeschossenerSpieler->getThis() ) : 0;
 }
 
 Team *Spiel::getRandomTeam()
@@ -1657,7 +1650,7 @@ void Spiel::setTimerZuletztAbgelaufen( Timer *t )
 
 Timer *Spiel::getTimerZuletztAbgelaufen() const
 {
-    return zuletztAbgelaufenerTimer ? (Timer *)zuletztAbgelaufenerTimer->getThis() : 0;
+    return zuletztAbgelaufenerTimer ? dynamic_cast<Timer *>( zuletztAbgelaufenerTimer->getThis() ) : 0;
 }
 
 void Spiel::setTimerZuletztGestartet( Timer *t )
@@ -1669,7 +1662,7 @@ void Spiel::setTimerZuletztGestartet( Timer *t )
 
 Timer *Spiel::getTimerZuletztGestartet() const
 {
-    return zuletztGestarteterTimer ? (Timer *)zuletztGestarteterTimer->getThis() : 0;
+    return zuletztGestarteterTimer ? dynamic_cast<Timer *>( zuletztGestarteterTimer->getThis() ) : 0;
 }
 
 void Spiel::setTimerZuletztPausiert( Timer *t )
@@ -1681,7 +1674,7 @@ void Spiel::setTimerZuletztPausiert( Timer *t )
 
 Timer *Spiel::getTimerZuletztPausiert() const
 {
-    return zuletztPausierterTimer ? (Timer *)zuletztPausierterTimer->getThis() : 0;
+    return zuletztPausierterTimer ? dynamic_cast<Timer *>( zuletztPausierterTimer->getThis() ) : 0;
 }
 
 void Spiel::setTimerZuletztFortgesetzt( Timer *t )
@@ -1693,7 +1686,7 @@ void Spiel::setTimerZuletztFortgesetzt( Timer *t )
 
 Timer *Spiel::getTimerZuletztFortgesetzt() const
 {
-    return zuletztFortgesetzterTimer ? (Timer *)zuletztFortgesetzterTimer->getThis() : 0;
+    return zuletztFortgesetzterTimer ? dynamic_cast<Timer *>( zuletztFortgesetzterTimer->getThis() ) : 0;
 }
 
 Tunnel *Spiel::getRandomTunnel()
@@ -1712,7 +1705,7 @@ void Spiel::setTunnelZuletztBenutzt( Tunnel *t )
 
 Tunnel *Spiel::getTunnelZuletztBenutzt() const
 {
-    return zuletztBenutzterTunnel ? (Tunnel *)zuletztBenutzterTunnel->getThis() : 0;
+    return zuletztBenutzterTunnel ? dynamic_cast<Tunnel *>( zuletztBenutzterTunnel->getThis() ) : 0;
 }
 
 Umlenkung *Spiel::getRandomUmlenkung()
@@ -1731,7 +1724,7 @@ void Spiel::setUmlenkungZuletztBenutzt( Umlenkung *t )
 
 Umlenkung *Spiel::getUmlenkungZuletztBenutzt() const
 {
-    return zuletztBenutzteUmlenkung ? (Umlenkung *)zuletztBenutzteUmlenkung->getThis() : 0;
+    return zuletztBenutzteUmlenkung ? dynamic_cast<Umlenkung *>( zuletztBenutzteUmlenkung->getThis() ) : 0;
 }
 
 ResourceRegistry *Spiel::zResources() const
@@ -1760,18 +1753,4 @@ int Spiel::l
     if( end && end->getWeiter() )
         return 0;
     return 0;
-}
-
-// Reference Counting 
-SpielV *Spiel::getThis()
-{
-    ref++;
-    return this;
-}
-
-SpielV *Spiel::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
 }

+ 3 - 9
StickmanWorldOnline/Spiel.h

@@ -29,10 +29,9 @@ class Spiel : public SpielV
 {
 private:
     RCArray< STKNachricht > *stkn;
-    Schrift *schrift;
+    UIInit uiFactory;
     KSGClient::InformationServerClient *infoKlient;
     KSGClient::SpielServerClient *spielKlient;
-    Bildschirm *zScreen;
     SpielChat *chat;
     Ende *end;
     SpielerGUI *spielerGUI;
@@ -105,7 +104,6 @@ private:
     bool pause;
     double nextAutoVerschiebung;
     double nextAutoSchaltung;
-    int ref;
 
     bool istAmLeben() const;
     void tick();
@@ -120,12 +118,11 @@ public:
     // nicht constant
     void lock();
     void unlock();
-    void setSchrift( Schrift *schrift ) override; // call 4
-    void setBildschirm( Bildschirm *zScreen ) override; // call 3
+    void setUIFactory( UIInit &factory ) override; // call 3
     void nachricht( int län, char *bytes ) override;
     void setKlients( KSGClient::InformationServerClient *infoKlient, KSGClient::SpielServerClient *spielKlient ) override; // call 2
     void setKarteId( int karteId ) override; // call 1
-    void ladeDaten() override; // call 5
+    void ladeDaten() override; // call 4
     void doPublicMausEreignis( MausEreignis &me ) override;
     void doTastaturEreignis( TastaturEreignis &te ) override;
     void stknVerarbeitung();
@@ -252,9 +249,6 @@ public:
     void addBestenliste( Bestenliste *b );
     // constant
     int läuft() const override;
-    // Reference Counting
-    SpielV *getThis() override;
-    SpielV *release() override;
 };
 
 #endif

+ 89 - 114
StickmanWorldOnline/SpielChat.cpp

@@ -9,128 +9,118 @@
 
 // Inhalt der SpielChat Klasse aus Chat.h
 // Konstruktor
-SpielChat::SpielChat()
+SpielChat::SpielChat( UIInit &uiFactory )
+    : ReferenceCounter()
 {
-	rahmen = new LRahmen();
-	rahmen->setFarbe( 0xFF909090 );
-	rahmen->setRamenBreite( 1 );
-	rahmen->setSize( 450, 200 );
-	verlauf = new TextFeld();
-	verlauf->setStyle( TextFeld::Style::TextGebiet & ~( TextFeld::Style::Erlaubt | TextFeld::Style::Rahmen | TextFeld::Style::Hintergrund ) );
-	verlauf->setText( "" );
-	verlauf->setSchriftFarbe( 0xFFFFFFFF );
-	verlauf->setSchriftSize( 12 );
-	verlauf->setSize( 446, 174 );
-	nachricht = new TextFeld();
-	nachricht->setStyle( TextFeld::Style::TextFeld & ~TextFeld::Style::Buffered );
-	nachricht->setText( "" );
-	nachricht->setSchriftFarbe( 0xFF909090 );
-	nachricht->setSchriftSize( 12 );
-	nachricht->setRahmenBreite( 1 );
-	nachricht->setRahmenFarbe( 0xFF909090 );
-	nachricht->setSize( 446, 20 );
-	ref = 1;
+    rahmen = new LRahmen();
+    rahmen->setFarbe( 0xFF909090 );
+    rahmen->setRamenBreite( 1 );
+    rahmen->setSize( 450, 200 );
+    verlauf = uiFactory.createTextFeld( uiFactory.initParam );
+    verlauf->setStyle( TextFeld::Style::TextGebiet & ~( TextFeld::Style::Erlaubt | TextFeld::Style::Rahmen | TextFeld::Style::Hintergrund ) );
+    verlauf->setText( "" );
+    verlauf->setSize( 446, 174 );
+    nachricht = uiFactory.createTextFeld( uiFactory.initParam );
+    nachricht->setStyle( TextFeld::Style::TextFeld & ~TextFeld::Style::Buffered );
+    nachricht->setText( "" );
+    nachricht->setSchriftFarbe( 0xFF909090 );
+    nachricht->setRahmenFarbe( 0xFF909090 );
+    nachricht->setSize( 446, 20 );
 }
 
 // Destruktor
 SpielChat::~SpielChat()
 {
-	rahmen->release();
-	verlauf->release();
-	nachricht->release();
+    rahmen->release();
+    verlauf->release();
+    nachricht->release();
 }
 
 // nicht constant
-void SpielChat::setSchrift( Schrift *zSchrift )
-{
-	verlauf->setSchriftZ( zSchrift->getThis() );
-	nachricht->setSchriftZ( zSchrift->getThis() );
-}
-
 void SpielChat::addNachricht( char *nachricht )
 {
-	verlauf->addZeile( nachricht, 0xFFFFFFFF );
-	verlauf->updateVScroll();
+    verlauf->addZeile( nachricht, 0xFFFFFFFF );
+    verlauf->updateVScroll();
 }
 
 void SpielChat::addNachricht( char *nachricht, int farbe )
 {
-	verlauf->addZeile( nachricht, farbe );
-	verlauf->updateVScroll();
+    verlauf->addZeile( nachricht, farbe );
+    verlauf->updateVScroll();
 }
 
 void SpielChat::doPublicMausEreignis( MausEreignis &me )
 {
-	bool vera = me.verarbeitet;
-	verlauf->doPublicMausEreignis( me );
-	nachricht->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet )
-	{
-		nachricht->setRahmenFarbe( 0xFFFFFFFF );
-		nachricht->setSchriftFarbe( 0xFFFFFFFF );
-		verlauf->setVertikalScrollFarbe( 0xFF808080, 0 );
-		rahmen->setFarbe( 0xFFFFFFFF );
-	}
-	else
-	{
-		nachricht->setRahmenFarbe( 0xFF909090 );
-		nachricht->setSchriftFarbe( 0xFF909090 );
-		verlauf->setVertikalScrollFarbe( 0xFF404040, 0 );
-		rahmen->setFarbe( 0xFF909090 );
-	}
+    bool vera = me.verarbeitet;
+    verlauf->doPublicMausEreignis( me );
+    nachricht->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet )
+    {
+        nachricht->setRahmenFarbe( 0xFFFFFFFF );
+        nachricht->setSchriftFarbe( 0xFFFFFFFF );
+        verlauf->setVertikalScrollFarbe( 0xFF808080, 0 );
+        rahmen->setFarbe( 0xFFFFFFFF );
+    }
+    else
+    {
+        nachricht->setRahmenFarbe( 0xFF909090 );
+        nachricht->setSchriftFarbe( 0xFF909090 );
+        verlauf->setVertikalScrollFarbe( 0xFF404040, 0 );
+        rahmen->setFarbe( 0xFF909090 );
+    }
 }
 
 void SpielChat::doTastaturEreignis( TastaturEreignis &te, KSGClient::SpielServerClient *zKlient )
 {
-	if( te.taste == T_Esc )
-		nachricht->removeStyle( TextFeld::Style::Fokus );
-	if( te.id == TE_Release && te.taste == T_Enter && !te.verarbeitet )
-	{
-		if( nachricht->hatStyle( TextFeld::Style::Fokus ) )
-		{
-			if( nachricht->zText()->getLength() )
-			{
-				short län = 1 + nachricht->zText()->getLength();
-				char *bytes = new char[ (__int64)län + 1 ];
-				*bytes = 3;
-				for( int i = 1; i <= län; i++ )
-					bytes[ i ] = nachricht->zText()->getText()[ i - 1 ];
-				nachricht->setText( "" );
-				nachricht->setAuswahl( 0, 0 );
-				nachricht->removeStyle( TextFeld::Style::Fokus );
-				zKlient->spielNachricht( län, bytes );
-				delete[] bytes;
-				te.verarbeitet = 1;
-			}
-		}
-		else
-		{
-			nachricht->addStyle( TextFeld::Style::Fokus );
-			nachricht->setAuswahl( 0, nachricht->zText()->getLength() );
-			te.verarbeitet = 1;
-		}
-	}
-	if( !te.verarbeitet )
-		nachricht->doTastaturEreignis( te );
-	if( nachricht->hatStyle( TextFeld::Style::Fokus ) )
-	{
-		nachricht->setRahmenFarbe( 0xFFFFFFFF );
-		nachricht->setSchriftFarbe( 0xFFFFFFFF );
-		verlauf->setVertikalScrollFarbe( 0xFF808080, 0 );
-		rahmen->setFarbe( 0xFFFFFFFF );
-	}
-	else
-	{
-		nachricht->setRahmenFarbe( 0xFF909090 );
-		nachricht->setSchriftFarbe( 0xFF909090 );
-		verlauf->setVertikalScrollFarbe( 0xFF404040, 0 );
-		rahmen->setFarbe( 0xFF909090 );
-	}
+    if( te.taste == T_Esc )
+        nachricht->removeStyle( TextFeld::Style::Fokus );
+    if( te.id == TE_Release && te.taste == T_Enter && !te.verarbeitet )
+    {
+        if( nachricht->hatStyle( TextFeld::Style::Fokus ) )
+        {
+            if( nachricht->zText()->getLength() )
+            {
+                short län = 1 + nachricht->zText()->getLength();
+                char *bytes = new char[ (__int64)län + 1 ];
+                *bytes = 3;
+                for( int i = 1; i <= län; i++ )
+                    bytes[ i ] = nachricht->zText()->getText()[ i - 1 ];
+                nachricht->setText( "" );
+                nachricht->setAuswahl( 0, 0 );
+                nachricht->removeStyle( TextFeld::Style::Fokus );
+                zKlient->spielNachricht( län, bytes );
+                delete[] bytes;
+                te.verarbeitet = 1;
+            }
+        }
+        else
+        {
+            nachricht->addStyle( TextFeld::Style::Fokus );
+            nachricht->setAuswahl( 0, nachricht->zText()->getLength() );
+            te.verarbeitet = 1;
+        }
+    }
+    if( !te.verarbeitet )
+        nachricht->doTastaturEreignis( te );
+    if( nachricht->hatStyle( TextFeld::Style::Fokus ) )
+    {
+        nachricht->setRahmenFarbe( 0xFFFFFFFF );
+        nachricht->setSchriftFarbe( 0xFFFFFFFF );
+        verlauf->setVertikalScrollFarbe( 0xFF808080, 0 );
+        rahmen->setFarbe( 0xFFFFFFFF );
+    }
+    else
+    {
+        nachricht->setRahmenFarbe( 0xFF909090 );
+        nachricht->setSchriftFarbe( 0xFF909090 );
+        verlauf->setVertikalScrollFarbe( 0xFF404040, 0 );
+        rahmen->setFarbe( 0xFF909090 );
+    }
 }
 
 void SpielChat::tick( double z )
 {
-	nachricht->tick( z );
+    nachricht->tick( z );
 }
 
 void SpielChat::render( Bild &zRObj )
@@ -138,28 +128,13 @@ void SpielChat::render( Bild &zRObj )
     rahmen->setPosition( Punkt( 10, zRObj.getHeight() - 210 ) );
     verlauf->setPosition( rahmen->getX() + 2, rahmen->getY() + 2 );
     nachricht->setPosition( rahmen->getX() + 2, rahmen->getY() + 178 );
-	rahmen->render( zRObj );
-	verlauf->render( zRObj );
-	nachricht->render( zRObj );
+    rahmen->render( zRObj );
+    verlauf->render( zRObj );
+    nachricht->render( zRObj );
 }
 
 // constant
 bool SpielChat::istAktiv() const
 {
-	return nachricht->hatStyle( TextFeld::Style::Fokus );
-}
-
-// Reference Counting
-SpielChat *SpielChat::getThis()
-{
-	ref++;
-	return this;
-}
-
-SpielChat *SpielChat::relese()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return nachricht->hatStyle( TextFeld::Style::Fokus );
 }

+ 18 - 22
StickmanWorldOnline/SpielChat.h

@@ -4,35 +4,31 @@
 #include <KSGNetwork.h>
 #include <TextFeld.h>
 #include <Rahmen.h>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
-class SpielChat
+class SpielChat : public virtual ReferenceCounter
 {
 private:
-	LRahmen *rahmen = 0;
-	TextFeld *verlauf;
-	TextFeld *nachricht;
-	int ref;
+    LRahmen *rahmen = 0;
+    TextFeld *verlauf;
+    TextFeld *nachricht;
 
 public:
-	// Konstruktor
-	SpielChat();
-	// Destruktor
-	~SpielChat();
-	// nicht constant
-	void setSchrift( Schrift *zSchrift );
-	void addNachricht( char *nachricht );
-	void addNachricht( char *nachricht, int farbe );
-	void doPublicMausEreignis( MausEreignis &me );
-	void doTastaturEreignis( TastaturEreignis &te, KSGClient::SpielServerClient *zKlient );
-	void tick( double z );
-	void render( Bild &zRObj );
-	// constant
-	bool istAktiv() const;
-	// Reference Counting
-	SpielChat *getThis();
-	SpielChat *relese();
+    // Konstruktor
+    SpielChat( UIInit &uiFactory );
+    // Destruktor
+    ~SpielChat();
+    // nicht constant
+    void addNachricht( char *nachricht );
+    void addNachricht( char *nachricht, int farbe );
+    void doPublicMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te, KSGClient::SpielServerClient *zKlient );
+    void tick( double z );
+    void render( Bild &zRObj );
+    // constant
+    bool istAktiv() const;
 };
 
 #endif

+ 5 - 31
StickmanWorldOnline/SpielStatistik.cpp

@@ -1,6 +1,7 @@
 #include "SpielStatistik.h"
 
 SpielStatistik::SpielStatistik()
+    : ReferenceCounter()
 {
     InitializeCriticalSection( &cs );
     addNachrichtF = 0;
@@ -10,8 +11,6 @@ SpielStatistik::SpielStatistik()
     istFreundF = 0;
     nachrichtParam = 0;
     bilder = 0;
-    schrift = 0;
-    screen = 0;
     infoc = 0;
     spielc = 0;
     status = 0;
@@ -21,7 +20,6 @@ SpielStatistik::SpielStatistik()
     tabelle = 0;
     accountId = 0;
     rend = 0;
-    ref = 1;
 }
 
 SpielStatistik::~SpielStatistik()
@@ -30,8 +28,6 @@ SpielStatistik::~SpielStatistik()
         chat->release();
     if( tabelle )
         tabelle->release();
-    if( schrift )
-        schrift->release();
     if( infoc )
         infoc->release();
     if( spielc )
@@ -91,16 +87,9 @@ void SpielStatistik::setR
     this->nachrichtParam = nachrichtParam;
 }
 
-void SpielStatistik::setSchrift( Schrift *schrift )
+void SpielStatistik::setUIFactory( UIInit &uiFactory )
 {
-    if( this->schrift )
-        this->schrift->release();
-    this->schrift = schrift;
-}
-
-void SpielStatistik::setBildschirm( Bildschirm *zScreen )
-{
-    screen = zScreen;
+    this->uiFactory = uiFactory;
 }
 
 void SpielStatistik::setKlients( KSGClient::InformationServerClient *infoc, KSGClient::SpielServerClient *spielc )
@@ -225,7 +214,7 @@ void SpielStatistik::nachricht( int l
     case 2: // Ladevorgang abgeschlossen
         if( 1 )
         {
-            chat = new StatistikChat( accountId, spielc->getThis(), infoc->getThis(), schrift->getThis(), bilder, addNachrichtF, addChatF, addFreundF, accountAnsehenF, nachrichtParam );
+            chat = new StatistikChat( accountId, spielc->getThis(), infoc->getThis(), uiFactory, bilder, addNachrichtF, addChatF, addFreundF, accountAnsehenF, nachrichtParam );
             int anz = gss->getEintragAnzahl();
             for( int i = 0; i < anz; i++ )
             {
@@ -236,7 +225,7 @@ void SpielStatistik::nachricht( int l
                         chat->addSpieler( acc, istFreundF( nachrichtParam, acc ) || acc == accountId );
                 }
             }
-            tabelle = new StatistikTabelle( gss->getThis(), gts->getThis(), schrift, screen );
+            tabelle = new StatistikTabelle( dynamic_cast<Array<SSDSpieler *>*>( gss->getThis() ), dynamic_cast<Array<SSDTeam *>*>( gts->getThis() ), uiFactory );
             status = 1;
         }
         break;
@@ -341,19 +330,4 @@ void SpielStatistik::verlassen()
 int SpielStatistik::getStatus() const // 0 = laden, 1 = läuft, 2 = fortsetzen
 {
     return status;
-}
-
-// Reference Counting
-SpielStatistikV *SpielStatistik::getThis()
-{
-    ref++;
-    return this;
-}
-
-SpielStatistikV *SpielStatistik::release()
-{
-    ref--;
-    if( !ref )
-        delete this;
-    return 0;
 }

+ 2 - 8
StickmanWorldOnline/SpielStatistik.h

@@ -16,8 +16,7 @@ private:
     bool( *istFreundF )( void *, int );
     void *nachrichtParam;
     BilderV *bilder;
-    Schrift *schrift;
-    Bildschirm *screen;
+    UIInit uiFactory;
     KSGClient::InformationServerClient *infoc;
     KSGClient::SpielServerClient *spielc;
     CRITICAL_SECTION cs;
@@ -28,7 +27,6 @@ private:
     int accountId;
     bool rend;
     int status;
-    int ref;
 
 public:
     // Konstruktor
@@ -44,8 +42,7 @@ public:
     void setRückrufFunktionen( void( *addNachrichtF )( void *, Text *, Text *, Text *, Text * ),
                                void( *addChatF )( void *, int ), void( *addFreundF )( void *, int ),
                                void( *accountAnsehenF )( void *, int ), bool( *istFreundF )( void *, int ), void *nachrichtParam ) override;
-    void setSchrift( Schrift *schrift ) override;
-    void setBildschirm( Bildschirm *zScreen ) override;
+    void setUIFactory( UIInit &factory ) override;
     void setKlients( KSGClient::InformationServerClient *infoc, KSGClient::SpielServerClient *spielc ) override;
     void nachricht( int län, char *bytes ) override;
     void doPublicMausEreignis( MausEreignis &me ) override;
@@ -55,9 +52,6 @@ public:
     void verlassen() override;
     // constant
     int getStatus() const override; // 0 = laden, 1 = läuft, 2 = fortsetzen
-    // Reference Counting
-    SpielStatistikV *getThis() override;
-    SpielStatistikV *release() override;
 };
 
 #endif

+ 37 - 37
StickmanWorldOnline/Spieler.cpp

@@ -222,9 +222,9 @@ Spieler::Spieler( ResourceRegistry *zResources, int id, Team *team, int spawnX,
     schadenNext = 0.075;
     showSchaden = 0;
     texturScale = 1;
-    resources = zResources->getThis();
+    resources = dynamic_cast<ResourceRegistry *>( zResources->getThis() );
     current = zResources->getResource( R_SPIELER, farbe );
-    textur = current->getImages()->getThis();
+    textur = dynamic_cast<Bild *>( current->getImages()->getThis() );
     heilungR = zResources->getResource( R_HEILUNG, 0 );
     schadenR = zResources->getResource( R_SCHADEN, 0 );
 }
@@ -362,9 +362,9 @@ void Spieler::setLaufTempo( float pps )
 void Spieler::addErfahrung( float anz, Spiel *zSpiel )
 {
     erfahrung += anz;
-    zSpiel->setSpielerZuletztErfahrungBekommen( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztErfahrungBekommen( dynamic_cast<Spieler *>( getThis() ) );
     Ereignis *e = new Ereignis( SPIELER_BEKOMMT_ERFAHRUNG );
-    e->addParameter( "Betroffener Spieler", getThis() );
+    e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
     e->addParameter( "Wert", new Float( anz ) );
     zSpiel->throwEvent( e );
     while( erfahrung > maxErfahrung )
@@ -397,9 +397,9 @@ void Spieler::levelUp( Spiel *zSpiel )
     }
     if( level <= 100 )
         lebensRegeneration += 0.25f;
-    zSpiel->setSpielerZuletztLevelUp( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztLevelUp( dynamic_cast<Spieler *>( getThis() ) );
     Ereignis *e = new Ereignis( SPIELER_LEVEL_UP );
-    e->addParameter( "Betroffener Spieler", getThis() );
+    e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
     zSpiel->throwEvent( e );
 }
 
@@ -431,13 +431,13 @@ void Spieler::levelDown( Spiel *zSpiel )
 void Spieler::addTunnelBenutzung( Spiel *zSpiel )
 {
     tunnelBenutzt++;
-    zSpiel->setSpielerZuletztTunnelBenutzt( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztTunnelBenutzt( dynamic_cast<Spieler *>( getThis() ) );
 }
 
 void Spieler::addSchalterBenutzung( Spiel *zSpiel )
 {
     schalterAktiviert++;
-    zSpiel->setSpielerZuletztSchalterAktiviert( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztSchalterAktiviert( dynamic_cast<Spieler *>( getThis() ) );
 }
 
 // aktualisiert auch die team statistik
@@ -482,9 +482,9 @@ void Spieler::wiederbelebung( Spiel *zSpiel )
 {
     amLeben = 1;
     leben = (float)maxLeben;
-    zSpiel->setSpielerZuletztWiederbelebt( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztWiederbelebt( dynamic_cast<Spieler *>( getThis() ) );
     Ereignis *e = new Ereignis( SPIELER_WIEDERBELEBT );
-    e->addParameter( "Betroffener Spieler", getThis() );
+    e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
     zSpiel->throwEvent( e );
 }
 
@@ -509,7 +509,7 @@ void Spieler::tick( double zeit, Spiel *zSpiel )
         if( tastenStand[ 'e' ] )
             zSpiel->spielerActivate( this );
         heilung( lebensRegeneration * (float)zeit, zSpiel, 0 );
-        Resource *r = current->getThis();
+        Resource *r = dynamic_cast<Resource *>( current->getThis() );
         for( auto e = effekte.getIterator(); e; e++ )
         {
             Resource *t = e->getCurrentResource();
@@ -594,7 +594,7 @@ void Spieler::useItem( Spiel *zSpiel )
 {
     if( istAmLeben() && inv.selectedItem() != KEIN_GEGENSTAND && istGegenstandErlaubt( inv.selectedItem() ) )
     {
-        zSpiel->setSpielerZuletztGegenstandAktiviert( (Spieler *)getThis() );
+        zSpiel->setSpielerZuletztGegenstandAktiviert( dynamic_cast<Spieler *>( getThis() ) );
         itemsVerwendet++;
         GegenstandTyp typ = inv.useItem();
         zSpiel->setItemZuletztAktiviert( typ );
@@ -602,8 +602,8 @@ void Spieler::useItem( Spiel *zSpiel )
         {
         case PFEIL:
             geschosseGeschossen++;
-            zSpiel->setSpielerZuletztGeschossen( (Spieler *)getThis() );
-            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_PFEIL, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, (Spieler *)getThis() ) );
+            zSpiel->setSpielerZuletztGeschossen( dynamic_cast<Spieler *>( getThis() ) );
+            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_PFEIL, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, dynamic_cast<Spieler *>( getThis() ) ) );
             break;
         case LEBEN:
             addEffekt( new LebenEffect( zSpiel->zResources(), this ) );
@@ -619,8 +619,8 @@ void Spieler::useItem( Spiel *zSpiel )
             break;
         case KUGEL:
             geschosseGeschossen++;
-            zSpiel->setSpielerZuletztGeschossen( (Spieler *)getThis() );
-            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_KUGEL, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, (Spieler *)getThis() ) );
+            zSpiel->setSpielerZuletztGeschossen( dynamic_cast<Spieler *>( getThis() ) );
+            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_KUGEL, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, dynamic_cast<Spieler *>( getThis() ) ) );
             break;
         case ROLLE:
             addEffekt( new RolleEffect( zSpiel->zResources(), this, getAusrichtung() ) );
@@ -630,27 +630,27 @@ void Spieler::useItem( Spiel *zSpiel )
             break;
         case DRACHENAUGE:
             geschosseGeschossen++;
-            zSpiel->setSpielerZuletztGeschossen( (Spieler *)getThis() );
-            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_DRACHENAUGE, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, (Spieler *)getThis() ) );
+            zSpiel->setSpielerZuletztGeschossen( dynamic_cast<Spieler *>( getThis() ) );
+            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_DRACHENAUGE, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, dynamic_cast<Spieler *>( getThis() ) ) );
             break;
         case FEUERBALL:
             geschosseGeschossen++;
-            zSpiel->setSpielerZuletztGeschossen( (Spieler *)getThis() );
-            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_FEUERBALL, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, (Spieler *)getThis() ) );
+            zSpiel->setSpielerZuletztGeschossen( dynamic_cast<Spieler *>( getThis() ) );
+            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), geschossTempo, GESCHOSS_FEUERBALL, getAusrichtung(), (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, dynamic_cast<Spieler *>( getThis() ) ) );
             break;
         case ENTERHAKEN:
             addEffekt( new EnterhakenEffect( zSpiel->zResources(), this, getAusrichtung() ) );
             break;
         case MINE:
             geschosseGeschossen++;
-            zSpiel->setSpielerZuletztGeschossen( (Spieler *)getThis() );
-            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), 0, GESCHOSS_MINE, MITTE, (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, (Spieler *)getThis() ) );
+            zSpiel->setSpielerZuletztGeschossen( dynamic_cast<Spieler *>( getThis() ) );
+            zSpiel->addGeschoss( new Geschoss( zSpiel->zResources(), zSpiel->getNextId(), 0, GESCHOSS_MINE, MITTE, (int)x + (int)getWidth() / 2, (int)y + (int)getHeight() / 2, dynamic_cast<Spieler *>( getThis() ) ) );
             break;
         default:
             break;
         }
         Ereignis *e = new Ereignis( SPIELER_BENUTZT_GEGENSTAND );
-        e->addParameter( "Betroffener Spieler", getThis() );
+        e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
         e->addParameter( "Betroffener Gegenstand", new GegenstandTypVar( typ ) );
         zSpiel->throwEvent( e );
     }
@@ -663,11 +663,11 @@ bool Spieler::addItem( GegenstandTyp typ, int anz, Spiel *zSpiel )
         if( inv.canAddItem( typ ) )
         {
             zSpiel->setItemZuletztAufgehoben( typ );
-            zSpiel->setSpielerZuletztGegenstandAufgehoben( (Spieler *)getThis() );
+            zSpiel->setSpielerZuletztGegenstandAufgehoben( dynamic_cast<Spieler *>( getThis() ) );
             itemsAufgehoben += anz;
             inv.addItem( typ, anz );
             Ereignis *e = new Ereignis( SPIELER_BEKOMMT_GEGENSTAND );
-            e->addParameter( "Betroffener Spieler", getThis() );
+            e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
             e->addParameter( "Betroffener Gegenstand", new GegenstandTypVar( typ ) );
             e->addParameter( "Anzahl", new Integer( anz ) );
             zSpiel->throwEvent( e );
@@ -679,17 +679,17 @@ bool Spieler::addItem( GegenstandTyp typ, int anz, Spiel *zSpiel )
     else
     {
         zSpiel->setItemZuletztAufgehoben( typ );
-        zSpiel->setSpielerZuletztGegenstandAufgehoben( (Spieler *)getThis() );
+        zSpiel->setSpielerZuletztGegenstandAufgehoben( dynamic_cast<Spieler *>( getThis() ) );
         itemsAufgehoben += anz;
         Ereignis *e = new Ereignis( SPIELER_BEKOMMT_GEGENSTAND );
-        e->addParameter( "Betroffener Spieler", getThis() );
+        e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
         e->addParameter( "Betroffener Gegenstand", new GegenstandTypVar( typ ) );
         e->addParameter( "Anzahl", new Integer( anz ) );
         zSpiel->throwEvent( e );
         for( int i = 0; i < anz; i++ )
         {
             Ereignis *e = new Ereignis( SPIELER_BENUTZT_GEGENSTAND );
-            e->addParameter( "Betroffener Spieler", getThis() );
+            e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
             e->addParameter( "Betroffener Gegenstand", new GegenstandTypVar( typ ) );
             zSpiel->throwEvent( e );
             itemsVerwendet++;
@@ -721,11 +721,11 @@ bool Spieler::addItem( GegenstandTyp typ, int anz, Spiel *zSpiel )
 // heilt auch um den lebensraub prozentsatz
 void Spieler::addGemachterSchaden( float schaden, Spiel *zSpiel )
 {
-    zSpiel->setSpielerZuletztSchadenGemacht( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztSchadenGemacht( dynamic_cast<Spieler *>( getThis() ) );
     schadenGemacht += schaden;
     heilung( schaden / 100 * lebensraub, zSpiel );
     Ereignis *e = new Ereignis( SPIELER_MACHT_SCHADEN );
-    e->addParameter( "Betroffener Spieler", getThis() );
+    e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
     e->addParameter( "Wert", new Float( schaden ) );
     zSpiel->throwEvent( e );
 }
@@ -741,11 +741,11 @@ void Spieler::nimmSchaden( float schaden, Spieler *zVerursacher, Richtung r, Spi
     schaden = leben < schaden ? leben : schaden;
     schadenGenommen += schaden;
     leben -= schaden;
-    zSpiel->setSpielerZuletztSchadenGenommen( (Spieler *)getThis() );
+    zSpiel->setSpielerZuletztSchadenGenommen( dynamic_cast<Spieler *>( getThis() ) );
     if( zVerursacher )
         zVerursacher->addGemachterSchaden( schaden, zSpiel );
     Ereignis *e = new Ereignis( SPIELER_NIMMT_SCHADEN );
-    e->addParameter( "Betroffener Spieler", getThis() );
+    e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
     e->addParameter( "Wert", new Float( schaden ) );
     zSpiel->throwEvent( e );
     showSchaden = 1;
@@ -764,12 +764,12 @@ void Spieler::nimmSchaden( float schaden, Spieler *zVerursacher, Richtung r, Spi
         team->addTod();
         amLeben = 0;
         tode++;
-        zSpiel->setSpielerZuletztGestorben( (Spieler *)getThis() );
+        zSpiel->setSpielerZuletztGestorben( dynamic_cast<Spieler *>( getThis() ) );
         if( zVerursacher )
             zVerursacher->addKill();
         zSpiel->addAnimation( new SingleAnimation( getX(), getY(), getWidth(), getHeight(), resources->getResource( R_SPIELER_STIRBT, color ) ) );
         Ereignis *e = new Ereignis( SPIELER_STIRBT );
-        e->addParameter( "Betroffener Spieler", getThis() );
+        e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
         zSpiel->throwEvent( e );
     }
 }
@@ -781,9 +781,9 @@ void Spieler::heilung( float heal, Spiel *zSpiel, bool show )
         heal = heal + leben > maxLeben ? maxLeben - leben : heal;
         lebenGeheilt += heal;
         leben += heal;
-        zSpiel->setSpielerZuletztGeheilt( (Spieler *)getThis() );
+        zSpiel->setSpielerZuletztGeheilt( dynamic_cast<Spieler *>( getThis() ) );
         Ereignis *e = new Ereignis( SPIELER_WIRD_GEHEILT );
-        e->addParameter( "Betroffener Spieler", getThis() );
+        e->addParameter( "Betroffener Spieler", dynamic_cast<Spieler *>( getThis() ) );
         e->addParameter( "Wert", new Float( heal ) );
         zSpiel->throwEvent( e );
         if( show )
@@ -909,7 +909,7 @@ Team *Spieler::zTeam() const
 
 Team *Spieler::getTeam() const
 {
-    return team ? (Team *)team->getThis() : 0;
+    return team ? dynamic_cast<Team *>( team->getThis() ) : 0;
 }
 
 int Spieler::getFarbe() const

+ 8 - 15
StickmanWorldOnline/SpielerGUI.cpp

@@ -2,9 +2,9 @@
 
 SpielerGUI::SpielerGUI( ResourceRegistry *zResources )
 {
-    resources = zResources->getThis();
+    resources = dynamic_cast<ResourceRegistry *>( zResources->getThis() );
     spieler = 0;
-    schrift = zResources->getSchrift();
+    schrift = dynamic_cast<Schrift *>( zResources->getUIFactory().initParam.schrift->getThis() );
     erf = zResources->zResource( R_GUI_ERF, 0 )->getImage( 0 );
     erfRand = zResources->zResource( R_GUI_ERF_RAND, 0 )->getImage( 0 );
     ausw = zResources->zResource( R_GUI_INVENTAR_AUSWAHL, 0 )->getImage( 0 );
@@ -13,28 +13,21 @@ SpielerGUI::SpielerGUI( ResourceRegistry *zResources )
     lebenRand = zResources->zResource( R_GUI_LEBEN_RAND, 0 )->getImage( 0 );
     levelRand = zResources->zResource( R_GUI_LEVEL_RAND, 0 )->getImage( 0 );
     spielerBild = zResources->zResource( R_GUI_SPIELER, 0 )->getImage( 0 );
-    levelT = new TextFeld();
+    levelT = zResources->getUIFactory().createTextFeld( zResources->getUIFactory().initParam );
     levelT->setStyle( TextFeld::Style::Text | TextFeld::Style::Center );
-    levelT->setSchriftZ( schrift->getThis() );
     levelT->setText( "0" );
-    levelT->setSchriftFarbe( 0xFFFFFFFF );
     levelT->setSize( 75, 20 );
     levelT->setPosition( 162, 0 );
-    lebenB = new FBalken();
+    lebenB = zResources->getUIFactory().createFBalken( zResources->getUIFactory().initParam );
     lebenB->setStyle( FBalken::Style::Sichtbar | FBalken::Style::FFarbe | FBalken::Style::L_R | FBalken::Style::Aktionen );
     lebenB->setSize( 178, 18 );
-    lebenB->setFBgFarbe( 0xFF00FF00 );
-    lebenB->setSchriftZ( schrift->getThis() );
-    lebenB->setSFarbe( 0xFFFFFFFF );
-    lebenB->setSSize( 12 );
     lebenB->setPosition( 111, 31 );
-    itemAnzahlT = new TextFeld();
+    itemAnzahlT = zResources->getUIFactory().createTextFeld( zResources->getUIFactory().initParam );
     itemAnzahlT->setStyle( TextFeld::Style::Text );
-    itemAnzahlT->setSchriftZ( schrift->getThis() );
+    itemAnzahlT->setSchriftZ( dynamic_cast<Schrift *>( schrift->getThis() ) );
     itemAnzahlT->setSize( 40, 20 );
-    spielerInfo = new TextFeld();
+    spielerInfo = zResources->getUIFactory().createTextFeld( zResources->getUIFactory().initParam );
     spielerInfo->setStyle( TextFeld::Style::Text );
-    spielerInfo->setSchriftZ( schrift->getThis() );
     spielerInfo->setSchriftFarbe( 0xFFA0A0A0 );
     spielerInfo->setSize( 290, 170 );
     spielerInfo->setPosition( 5, 225 );
@@ -124,7 +117,7 @@ void SpielerGUI::render( Bild &rObj )
         "Rüstung: " + (int)spieler->getArmor() + " %\n" +
         "Bonusschaden: " + (int)spieler->getSchadenBonus() + " %\n" +
         "Lebensraub: " + (int)spieler->getLebensRaub() + " %\n" +
-        "Lebensregeneration: " + ((int)(spieler->getLebensRegenneration() * 100) / 100.f) + " /s\n" +
+        "Lebensregeneration: " + ( (int)( spieler->getLebensRegenneration() * 100 ) / 100.f ) + " /s\n" +
         "Abklingzeitverringerung: " + (int)spieler->getAbklingZeitVerringerung();
     spielerInfo->setText( info );
     spielerInfo->render( rObj );

+ 312 - 360
StickmanWorldOnline/StatistikChat.cpp

@@ -10,473 +10,425 @@
 
 // Inhalt der ChatListeSpieler Klasse aus StatistikChat.h
 // Konstruktor
-ChatListeSpieler::ChatListeSpieler( int accountId, int eigeneId, Schrift *zSchrift, BilderV *bilder, KSGClient::InformationServerClient *zInfoc,
-									bool istFreund, void( *addChatF )( void*, int ), void( *addFreundF )( void*, int ),
-									void( *accountAnsehenF )( void *, int ), void *param )
-									: addChatF( addChatF ),
-									addFreundF( addFreundF ),
-									accountAnsehenF( accountAnsehenF ),
-									nachrichtParam( param ),
-									accountId( accountId ),
-									bg( new AlphaFeld() ),
-									name( initTextFeld( 0, 0, 133, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Rahmen | TextFeld::Style::VCenter, "" ) ),
-									accountAnsehen( initKnopf( 133, 0, 20, 20, 0, 0, "" ) ),
-									nachrichtSenden( initKnopf( 153, 0, 20, 20, 0, 0, "" ) ),
-									freundesanfrageSenden( initKnopf( 173, 0, 20, 20, 0, 0, "" ) ),
-									pos( 0, 0 ),
-									gr( 133, 20 ),
-									online( 1 ),
-									minKnopfX( 113 - ( ( ( accountId != eigeneId ) + !istFreund ) * 20 ) ),
-									knopfX( 133 ),
-									mausIn( 0 ),
-									tickVal( 0 ),
-									rend( 0 ),
-									ref( 1 )
+ChatListeSpieler::ChatListeSpieler( int accountId, int eigeneId, UIInit &uiFactory, BilderV *bilder, KSGClient::InformationServerClient *zInfoc,
+                                    bool istFreund, void( *addChatF )( void *, int ), void( *addFreundF )( void *, int ),
+                                    void( *accountAnsehenF )( void *, int ), void *param )
+    : ReferenceCounter(),
+    addChatF( addChatF ),
+    addFreundF( addFreundF ),
+    accountAnsehenF( accountAnsehenF ),
+    nachrichtParam( param ),
+    accountId( accountId ),
+    bg( new AlphaFeld() ),
+    name( initTextFeld( 0, 0, 133, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::Rahmen | TextFeld::Style::VCenter, "" ) ),
+    accountAnsehen( initKnopf( 133, 0, 20, 20, uiFactory, 0, "" ) ),
+    nachrichtSenden( initKnopf( 153, 0, 20, 20, uiFactory, 0, "" ) ),
+    freundesanfrageSenden( initKnopf( 173, 0, 20, 20, uiFactory, 0, "" ) ),
+    pos( 0, 0 ),
+    gr( 133, 20 ),
+    online( 1 ),
+    minKnopfX( 113 - ( ( ( accountId != eigeneId ) + !istFreund ) * 20 ) ),
+    knopfX( 133 ),
+    mausIn( 0 ),
+    tickVal( 0 ),
+    rend( 0 )
 {
-	Bild *ansehenBild = bilder->get( "data/client/bilder/chat.ltdb/ansehen.png" );
-	Bild *nachrichtBild = bilder->get( "data/client/bilder/chat.ltdb/nachricht.png" );
-	Bild *einladungBild = bilder->get( "data/client/bilder/chat.ltdb/neuerfreund.png" );
-	bg->setSize( gr );
-	bg->setFarbe( 0x0000FF00 );
-	bg->setStrength( -4 );
-	name->setText( zInfoc->getSpielerName( accountId ) );
-	accountAnsehen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
-	accountAnsehen->setHintergrundBildZ( ansehenBild );
-	nachrichtSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
-	nachrichtSenden->setHintergrundBildZ( nachrichtBild );
-	freundesanfrageSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
-	freundesanfrageSenden->setHintergrundBildZ( einladungBild );
+    Bild *ansehenBild = bilder->get( "data/client/bilder/chat.ltdb/ansehen.png" );
+    Bild *nachrichtBild = bilder->get( "data/client/bilder/chat.ltdb/nachricht.png" );
+    Bild *einladungBild = bilder->get( "data/client/bilder/chat.ltdb/neuerfreund.png" );
+    bg->setSize( gr );
+    bg->setFarbe( 0x0000FF00 );
+    bg->setStrength( -4 );
+    name->setText( zInfoc->getSpielerName( accountId ) );
+    accountAnsehen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+    accountAnsehen->setHintergrundBildZ( ansehenBild );
+    nachrichtSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+    nachrichtSenden->setHintergrundBildZ( nachrichtBild );
+    freundesanfrageSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+    freundesanfrageSenden->setHintergrundBildZ( einladungBild );
 }
 
 // Destruktor
 ChatListeSpieler::~ChatListeSpieler()
 {
-	bg->release();
-	name->release();
-	accountAnsehen->release();
-	nachrichtSenden->release();
-	freundesanfrageSenden->release();
+    bg->release();
+    name->release();
+    accountAnsehen->release();
+    nachrichtSenden->release();
+    freundesanfrageSenden->release();
 }
 
 // nicht constant
 void ChatListeSpieler::setOffline()
 {
-	online = 0;
+    online = 0;
 }
 
 void ChatListeSpieler::setPosition( int y )
 {
-	if( pos.y != y )
-		rend = 1;
-	pos.y = y;
+    if( pos.y != y )
+        rend = 1;
+    pos.y = y;
 }
 
 void ChatListeSpieler::doPublicMausEreignis( MausEreignis &me )
 {
-	int mx = me.mx;
-	int my = me.my;
-	me.mx -= pos.x;
-	me.my -= pos.y;
-	if( me.mx > 0 && me.mx < gr.x && me.my > 0 && me.my < gr.y )
-		mausIn = 1;
-	else
-		mausIn = 0;
-	me.mx += 133 - knopfX;
-	bool vera = me.verarbeitet;
-	accountAnsehen->doPublicMausEreignis( me );
-	int aktion = ( me.verarbeitet && !vera ) ? 1 : 0;
-	nachrichtSenden->doPublicMausEreignis( me );
-	aktion = ( me.verarbeitet && !vera && !aktion ) ? 2 : aktion;
-	freundesanfrageSenden->doPublicMausEreignis( me );
-	aktion = ( me.verarbeitet && !vera && !aktion ) ? 3 : aktion;
-	me.mx -= 133 - knopfX;
-	if( me.id == ME_RLinks && mausIn )
-	{
-		switch( aktion )
-		{
-		case 1:
-			accountAnsehenF( nachrichtParam, accountId );
-			break;
-		case 2:
-			addChatF( nachrichtParam, accountId );
-			break;
-		case 3:
-			addFreundF( nachrichtParam, accountId );
-			break;
-		}
-	}
-	me.mx = mx;
-	me.my = my;
+    int mx = me.mx;
+    int my = me.my;
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( me.mx > 0 && me.mx < gr.x && me.my > 0 && me.my < gr.y )
+        mausIn = 1;
+    else
+        mausIn = 0;
+    me.mx += 133 - knopfX;
+    bool vera = me.verarbeitet;
+    accountAnsehen->doPublicMausEreignis( me );
+    int aktion = ( me.verarbeitet && !vera ) ? 1 : 0;
+    nachrichtSenden->doPublicMausEreignis( me );
+    aktion = ( me.verarbeitet && !vera && !aktion ) ? 2 : aktion;
+    freundesanfrageSenden->doPublicMausEreignis( me );
+    aktion = ( me.verarbeitet && !vera && !aktion ) ? 3 : aktion;
+    me.mx -= 133 - knopfX;
+    if( me.id == ME_RLinks && mausIn )
+    {
+        switch( aktion )
+        {
+        case 1:
+            accountAnsehenF( nachrichtParam, accountId );
+            break;
+        case 2:
+            addChatF( nachrichtParam, accountId );
+            break;
+        case 3:
+            addFreundF( nachrichtParam, accountId );
+            break;
+        }
+    }
+    me.mx = mx;
+    me.my = my;
 }
 
 bool ChatListeSpieler::tick( double tickVal )
 {
-	rend |= name->tick( tickVal );
-	rend |= accountAnsehen->tick( tickVal );
-	rend |= nachrichtSenden->tick( tickVal );
-	rend |= freundesanfrageSenden->tick( tickVal );
-	this->tickVal += tickVal * 60;
-	int val = ( int )this->tickVal;
-	if( val )
-	{
-		this->tickVal -= val;
-		if( mausIn && knopfX != minKnopfX )
-		{
-			if( knopfX - val < minKnopfX )
-				knopfX = minKnopfX;
-			else
-				knopfX -= val;
-			rend = 1;
-		}
-		if( !mausIn && knopfX != gr.x )
-		{
-			if( knopfX + val > gr.x )
-				knopfX = gr.x;
-			else
-				knopfX += val;
-			rend = 1;
-		}
-		if( !online && bg->getFarbe() != 0x00FF0000 )
-		{
-			int g = ( bg->getFarbe() >> 8 ) & 0xFF;
-			if( g - val < 0 )
-				bg->setFarbe( 0x00FF0000 );
-			else
-			{
-				bg->setFarbe( ( ( ( g - val ) << 8 ) & 0xFF00 ) | ( bg->getFarbe() & 0xFFFF00FF ) );
-				bg->setFarbe( ( ( ( 255 - ( g - val ) ) << 16 ) & 0xFF0000 ) | ( bg->getFarbe() & 0xFF00FFFF ) );
-			}
-			rend = 1;
-		}
-	}
-	bool ret = rend;
-	rend = 0;
-	return ret;
+    rend |= name->tick( tickVal );
+    rend |= accountAnsehen->tick( tickVal );
+    rend |= nachrichtSenden->tick( tickVal );
+    rend |= freundesanfrageSenden->tick( tickVal );
+    this->tickVal += tickVal * 60;
+    int val = (int)this->tickVal;
+    if( val )
+    {
+        this->tickVal -= val;
+        if( mausIn && knopfX != minKnopfX )
+        {
+            if( knopfX - val < minKnopfX )
+                knopfX = minKnopfX;
+            else
+                knopfX -= val;
+            rend = 1;
+        }
+        if( !mausIn && knopfX != gr.x )
+        {
+            if( knopfX + val > gr.x )
+                knopfX = gr.x;
+            else
+                knopfX += val;
+            rend = 1;
+        }
+        if( !online && bg->getFarbe() != 0x00FF0000 )
+        {
+            int g = ( bg->getFarbe() >> 8 ) & 0xFF;
+            if( g - val < 0 )
+                bg->setFarbe( 0x00FF0000 );
+            else
+            {
+                bg->setFarbe( ( ( ( g - val ) << 8 ) & 0xFF00 ) | ( bg->getFarbe() & 0xFFFF00FF ) );
+                bg->setFarbe( ( ( ( 255 - ( g - val ) ) << 16 ) & 0xFF0000 ) | ( bg->getFarbe() & 0xFF00FFFF ) );
+            }
+            rend = 1;
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
 }
 
 void ChatListeSpieler::render( Bild &zRObj )
 {
-	if( !zRObj.setDrawOptions( pos, gr ) )
-		return;
-	bg->render( zRObj );
-	name->render( zRObj );
-	zRObj.addScrollOffset( 133 - knopfX, 0 );
-	accountAnsehen->render( zRObj );
-	nachrichtSenden->render( zRObj );
-	freundesanfrageSenden->render( zRObj );
-	zRObj.releaseDrawOptions();
+    if( !zRObj.setDrawOptions( pos, gr ) )
+        return;
+    bg->render( zRObj );
+    name->render( zRObj );
+    zRObj.addScrollOffset( 133 - knopfX, 0 );
+    accountAnsehen->render( zRObj );
+    nachrichtSenden->render( zRObj );
+    freundesanfrageSenden->render( zRObj );
+    zRObj.releaseDrawOptions();
 }
 
 // constant
 int ChatListeSpieler::getAccountId() const
 {
-	return accountId;
-}
-
-// Reference Counting
-ChatListeSpieler *ChatListeSpieler::getThis()
-{
-	ref++;
-	return this;
-}
-
-ChatListeSpieler *ChatListeSpieler::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return accountId;
 }
 
 
 // Inhalt der ChatListe Klasse aus StatistikChat.h
 // Konstruktor
-ChatListe::ChatListe( int eigeneId, KSGClient::InformationServerClient *infoc, Schrift *schrift, BilderV *bilder,
-					  void( *addChat )( void*, int ), void( *addFreund )( void*, int ),
-					  void( *accountAnsehen )( void *, int ), void *param )
-					  : addChat( addChat ),
-					  addFreund( addFreund ),
-					  accountAnsehen( accountAnsehen ),
-					  nachrichtParam( nachrichtParam ),
-					  eigeneId( eigeneId ),
-					  spieler( new RCArray< ChatListeSpieler >() ),
-					  vScroll( new VScrollBar() ),
-					  pos( 620, 295 ),
-					  gr( 150, 150 ),
-					  infoc( infoc ),
-					  schrift( schrift ),
-					  bilder( bilder ),
-					  ram( new LRahmen() ),
-					  rend( 0 ),
-					  ref( 1 )
+ChatListe::ChatListe( int eigeneId, KSGClient::InformationServerClient *infoc, UIInit &uiFactory, BilderV *bilder,
+                      void( *addChat )( void *, int ), void( *addFreund )( void *, int ),
+                      void( *accountAnsehen )( void *, int ), void *param )
+    : ReferenceCounter(),
+    addChat( addChat ),
+    addFreund( addFreund ),
+    accountAnsehen( accountAnsehen ),
+    nachrichtParam( nachrichtParam ),
+    eigeneId( eigeneId ),
+    spieler( new RCArray< ChatListeSpieler >() ),
+    vScroll( new VScrollBar() ),
+    pos( 620, 295 ),
+    gr( 150, 150 ),
+    infoc( infoc ),
+    uiFactory( uiFactory ),
+    bilder( bilder ),
+    ram( new LRahmen() ),
+    rend( 0 )
 {
-	vScroll->setKlickScroll( 10 );
-	vScroll->update( 0, 148 );
-	ram->setFarbe( 0xFFFFFFFF );
-	ram->setSize( 150, 150 );
+    vScroll->setKlickScroll( 10 );
+    vScroll->update( 0, 148 );
+    ram->setFarbe( 0xFFFFFFFF );
+    ram->setSize( 150, 150 );
 }
 
 // Destruktor
 ChatListe::~ChatListe()
 {
-	spieler->release();
-	vScroll->release();
-	infoc->release();
-	schrift->release();
-	ram->release();
+    spieler->release();
+    vScroll->release();
+    infoc->release();
+    ram->release();
 }
 
 // nicht constant
 void ChatListe::addSpieler( int accountId, bool istFreund )
 {
-	int anz = spieler->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		if( spieler->z( i ) && spieler->z( i )->getAccountId() == accountId )
-			return;
-	}
-	ChatListeSpieler *s = new ChatListeSpieler( accountId, eigeneId, schrift, bilder, infoc, istFreund, addChat, addFreund, accountAnsehen, nachrichtParam );
-	s->setPosition( anz * 20 );
-	spieler->add( s );
-	rend = 1;
+    int anz = spieler->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        if( spieler->z( i ) && spieler->z( i )->getAccountId() == accountId )
+            return;
+    }
+    ChatListeSpieler *s = new ChatListeSpieler( accountId, eigeneId, uiFactory, bilder, infoc, istFreund, addChat, addFreund, accountAnsehen, nachrichtParam );
+    s->setPosition( anz * 20 );
+    spieler->add( s );
+    rend = 1;
 }
 
 void ChatListe::setOffline( int accountId )
 {
-	int anz = spieler->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		if( spieler->z( i ) && spieler->z( i )->getAccountId() == accountId )
-		{
-			spieler->z( i )->setOffline();
-			return;
-		}
-	}
+    int anz = spieler->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        if( spieler->z( i ) && spieler->z( i )->getAccountId() == accountId )
+        {
+            spieler->z( i )->setOffline();
+            return;
+        }
+    }
 }
 
 void ChatListe::doPublicMausEreignis( MausEreignis &me )
 {
-	int mx = me.mx;
-	int my = me.my;
-	me.mx -= pos.x;
-	me.my -= pos.y - vScroll->getScroll();
-	vScroll->doMausMessage( 134, 1, 15, 148, me );
-	int anz = spieler->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		if( spieler->z( i ) )
-			spieler->z( i )->doPublicMausEreignis( me );
-	}
-	me.mx = mx;
-	me.my = my;
+    int mx = me.mx;
+    int my = me.my;
+    me.mx -= pos.x;
+    me.my -= pos.y - vScroll->getScroll();
+    vScroll->doMausMessage( 134, 1, 15, 148, me );
+    int anz = spieler->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        if( spieler->z( i ) )
+            spieler->z( i )->doPublicMausEreignis( me );
+    }
+    me.mx = mx;
+    me.my = my;
 }
 
 bool ChatListe::tick( double tickVal )
 {
-	rend |= vScroll->getRend();
-	int anz = spieler->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		if( spieler->z( i ) )
-			rend |= spieler->z( i )->tick( tickVal );
-	}
-	bool ret = rend;
-	rend = 0;
-	return ret;
+    rend |= vScroll->getRend();
+    int anz = spieler->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        if( spieler->z( i ) )
+            rend |= spieler->z( i )->tick( tickVal );
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
 }
 
 void ChatListe::render( Bild &zRObj )
 {
-	if( !zRObj.setDrawOptions( pos, gr ) )
-		return;
-	int anz = spieler->getEintragAnzahl();
-	zRObj.addScrollOffset( 0, vScroll->getScroll() );
-	for( int i = 0; i < anz; i++ )
-	{
-		if( spieler->z( i ) )
-			spieler->z( i )->render( zRObj );
-	}
-	zRObj.addScrollOffset( 0, -vScroll->getScroll() );
-	vScroll->render( 134, 1, 15, 148, zRObj );
-	ram->render( zRObj );
-	zRObj.releaseDrawOptions();
-}
-
-// constant
-
-// Reference Counting
-ChatListe *ChatListe::getThis()
-{
-	ref++;
-	return this;
-}
-
-ChatListe *ChatListe::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    if( !zRObj.setDrawOptions( pos, gr ) )
+        return;
+    int anz = spieler->getEintragAnzahl();
+    zRObj.addScrollOffset( 0, vScroll->getScroll() );
+    for( int i = 0; i < anz; i++ )
+    {
+        if( spieler->z( i ) )
+            spieler->z( i )->render( zRObj );
+    }
+    zRObj.addScrollOffset( 0, -vScroll->getScroll() );
+    vScroll->render( 134, 1, 15, 148, zRObj );
+    ram->render( zRObj );
+    zRObj.releaseDrawOptions();
 }
 
 
 // Inhalt der StatistikChat Klasse aus StatistikChat.h
 // Konstruktor
-StatistikChat::StatistikChat( int eigeneId, KSGClient::SpielServerClient *spielc, KSGClient::InformationServerClient *infoc, Schrift *schrift, BilderV *bilder,
-							  void( *addNachricht )( void *, Text *, Text *, Text *, Text * ),
-							  void( *addChat )( void*, int ), void( *addFreund )( void*, int ),
-							  void( *accountAnsehen )( void *, int ), void *param )
-							  : addNachricht( addNachricht ),
-							  nachrichtParam( nachrichtParam ),
-							  spielc( spielc ),
-							  infoc( infoc ),
-							  verlauf( initTextFeld( 10, 295, 600, 150, schrift, TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::VScroll | TextFeld::Style::Mehrzeilig, "" ) ),
-							  nachricht( initTextFeld( 10, 450, 575, 20, schrift, TextFeld::Style::TextFeld, "" ) ),
-							  senden( initKnopf( 590, 450, 20, 20, 0, 0, "" ) ),
-							  verlassen( initKnopf( 630, 450, 130, 20, schrift, Knopf::Style::Sichtbar, "Verlassen" ) ),
-							  spielerListe( new ChatListe( eigeneId, infoc->getThis(), schrift, bilder, addChat, addFreund, accountAnsehen, nachrichtParam ) ),
-							  beenden( 0 ),
-							  ref( 1 )
+StatistikChat::StatistikChat( int eigeneId, KSGClient::SpielServerClient *spielc, KSGClient::InformationServerClient *infoc, UIInit &uiFactory, BilderV *bilder,
+                              void( *addNachricht )( void *, Text *, Text *, Text *, Text * ),
+                              void( *addChat )( void *, int ), void( *addFreund )( void *, int ),
+                              void( *accountAnsehen )( void *, int ), void *param )
+    : ReferenceCounter(),
+    addNachricht( addNachricht ),
+    nachrichtParam( nachrichtParam ),
+    spielc( spielc ),
+    infoc( infoc ),
+    verlauf( initTextFeld( 10, 295, 600, 150, uiFactory, TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::VScroll | TextFeld::Style::Mehrzeilig, "" ) ),
+    nachricht( initTextFeld( 10, 450, 575, 20, uiFactory, TextFeld::Style::TextFeld, "" ) ),
+    senden( initKnopf( 590, 450, 20, 20, uiFactory, 0, "" ) ),
+    verlassen( initKnopf( 630, 450, 130, 20, uiFactory, Knopf::Style::Sichtbar, "Verlassen" ) ),
+    spielerListe( new ChatListe( eigeneId, infoc->getThis(), uiFactory, bilder, addChat, addFreund, accountAnsehen, nachrichtParam ) ),
+    beenden( 0 )
 {
-	Bild *sendenBild = bilder->get( "data/client/bilder/chat.ltdb/senden.png" );
-	senden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
-	senden->setHintergrundBildZ( sendenBild );
+    Bild *sendenBild = bilder->get( "data/client/bilder/chat.ltdb/senden.png" );
+    senden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+    senden->setHintergrundBildZ( sendenBild );
 }
 
 // Destruktor
 StatistikChat::~StatistikChat()
 {
-	spielc->release();
-	infoc->release();
-	verlauf->release();
-	nachricht->release();
-	senden->release();
-	verlassen->release();
-	spielerListe->release();
+    spielc->release();
+    infoc->release();
+    verlauf->release();
+    nachricht->release();
+    senden->release();
+    verlassen->release();
+    spielerListe->release();
 }
 
 // nicht constant
 void StatistikChat::addSpieler( int accountId, bool istFreund )
 {
-	spielerListe->addSpieler( accountId, istFreund );
+    spielerListe->addSpieler( accountId, istFreund );
 }
 
 void StatistikChat::spielerOffline( int accountId )
 {
-	spielerListe->setOffline( accountId );
+    spielerListe->setOffline( accountId );
 }
 
 void StatistikChat::addChatNachricht( int vonAccount, char *nachricht )
 {
-	Text *txt = vonAccount ? infoc->getSpielerName( vonAccount ) : 0;
-	if( !txt )
-		txt = new Text();
-	else
-		*txt += ": ";
-	*txt += nachricht;
-	*txt += "\n";
-	verlauf->zTextRenderer()->textFormatieren( txt, verlauf->getBreite() - 15 );
-	verlauf->zText()->append( txt );
-	verlauf->updateVScroll();
+    Text *txt = vonAccount ? infoc->getSpielerName( vonAccount ) : 0;
+    if( !txt )
+        txt = new Text();
+    else
+        *txt += ": ";
+    *txt += nachricht;
+    *txt += "\n";
+    verlauf->zTextRenderer()->textFormatieren( txt, verlauf->getBreite() - 15 );
+    verlauf->zText()->append( txt );
+    verlauf->updateVScroll();
 }
 
 void StatistikChat::doPublicMausEreignis( MausEreignis &me )
 {
-	verlauf->doPublicMausEreignis( me );
-	nachricht->doPublicMausEreignis( me );
-	spielerListe->doPublicMausEreignis( me );
-	bool vera = me.verarbeitet;
-	senden->doPublicMausEreignis( me );
-	int aktion = ( me.verarbeitet && !vera ) ? 1 : 0;
-	verlassen->doPublicMausEreignis( me );
-	aktion = ( me.verarbeitet && !vera && !aktion ) ? 2 : aktion;
-	if( me.id == ME_RLinks )
-	{
-		if( aktion == 1 )
-		{
-			if( nachricht->zText()->getLength() )
-			{
-				short län = 1 + nachricht->zText()->getLength();
-				char *bytes = new char[ län ];
-				bytes[ 0 ] = 1;
-				for( int i = 0; i < län - 1; i++ )
-					bytes[ i + 1 ] = nachricht->zText()->getText()[ i ];
-				if( !spielc->statistikNachricht( län, bytes ) )
-					addNachricht( nachrichtParam, new Text( "Fehler" ), new Text( "Die Nachricht konnte nicht gesendet werden." ), new Text( "Ok" ), 0 );
-				else
-				{
-					nachricht->setAuswahl( 0, 0 );
-					nachricht->setText( "" );
-				}
-				delete[] bytes;
-			}
-		}
-		if( aktion == 2 )
-			beenden = 1;
-	}
+    verlauf->doPublicMausEreignis( me );
+    nachricht->doPublicMausEreignis( me );
+    spielerListe->doPublicMausEreignis( me );
+    bool vera = me.verarbeitet;
+    senden->doPublicMausEreignis( me );
+    int aktion = ( me.verarbeitet && !vera ) ? 1 : 0;
+    verlassen->doPublicMausEreignis( me );
+    aktion = ( me.verarbeitet && !vera && !aktion ) ? 2 : aktion;
+    if( me.id == ME_RLinks )
+    {
+        if( aktion == 1 )
+        {
+            if( nachricht->zText()->getLength() )
+            {
+                short län = 1 + nachricht->zText()->getLength();
+                char *bytes = new char[ län ];
+                bytes[ 0 ] = 1;
+                for( int i = 0; i < län - 1; i++ )
+                    bytes[ i + 1 ] = nachricht->zText()->getText()[ i ];
+                if( !spielc->statistikNachricht( län, bytes ) )
+                    addNachricht( nachrichtParam, new Text( "Fehler" ), new Text( "Die Nachricht konnte nicht gesendet werden." ), new Text( "Ok" ), 0 );
+                else
+                {
+                    nachricht->setAuswahl( 0, 0 );
+                    nachricht->setText( "" );
+                }
+                delete[] bytes;
+            }
+        }
+        if( aktion == 2 )
+            beenden = 1;
+    }
 }
 
 void StatistikChat::doTastaturEreignis( TastaturEreignis &te )
 {
-	bool vera = te.verarbeitet;
-	nachricht->doTastaturEreignis( te );
-	if( !vera && te.verarbeitet && te.id == TE_Release && te.taste == T_Enter )
-	{
-		if( nachricht->zText()->getLength() )
-		{
-			short län = 1 + nachricht->zText()->getLength();
-			char *bytes = new char[ län ];
-			bytes[ 0 ] = 1;
-			for( int i = 0; i < län - 1; i++ )
-				bytes[ i + 1 ] = nachricht->zText()->getText()[ i ];
-			if( !spielc->statistikNachricht( län, bytes ) )
-				addNachricht( nachrichtParam, new Text( "Fehler" ), new Text( "Die Nachricht konnte nicht gesendet werden." ), new Text( "Ok" ), 0 );
-			else
-			{
-				nachricht->setAuswahl( 0, 0 );
-				nachricht->setText( "" );
-			}
-			delete[] bytes;
-		}
-	}
+    bool vera = te.verarbeitet;
+    nachricht->doTastaturEreignis( te );
+    if( !vera && te.verarbeitet && te.id == TE_Release && te.taste == T_Enter )
+    {
+        if( nachricht->zText()->getLength() )
+        {
+            short län = 1 + nachricht->zText()->getLength();
+            char *bytes = new char[ län ];
+            bytes[ 0 ] = 1;
+            for( int i = 0; i < län - 1; i++ )
+                bytes[ i + 1 ] = nachricht->zText()->getText()[ i ];
+            if( !spielc->statistikNachricht( län, bytes ) )
+                addNachricht( nachrichtParam, new Text( "Fehler" ), new Text( "Die Nachricht konnte nicht gesendet werden." ), new Text( "Ok" ), 0 );
+            else
+            {
+                nachricht->setAuswahl( 0, 0 );
+                nachricht->setText( "" );
+            }
+            delete[] bytes;
+        }
+    }
 }
 
 bool StatistikChat::tick( double tickVal )
 {
-	bool rend = verlauf->tick( tickVal );
-	rend |= nachricht->tick( tickVal );
-	rend |= senden->tick( tickVal );
-	rend |= verlassen->tick( tickVal );
-	rend |= spielerListe->tick( tickVal );
-	return rend;
+    bool rend = verlauf->tick( tickVal );
+    rend |= nachricht->tick( tickVal );
+    rend |= senden->tick( tickVal );
+    rend |= verlassen->tick( tickVal );
+    rend |= spielerListe->tick( tickVal );
+    return rend;
 }
 
 void StatistikChat::render( Bild &zRObj )
 {
-	verlauf->render( zRObj );
-	nachricht->render( zRObj );
-	senden->render( zRObj );
-	verlassen->render( zRObj );
-	spielerListe->render( zRObj );
+    verlauf->render( zRObj );
+    nachricht->render( zRObj );
+    senden->render( zRObj );
+    verlassen->render( zRObj );
+    spielerListe->render( zRObj );
 }
 
 // constant
 bool StatistikChat::hatVerlassen()
 {
-	return beenden;
-}
-
-// Reference Counting
-StatistikChat *StatistikChat::getThis()
-{
-	ref++;
-	return this;
-}
-
-StatistikChat *StatistikChat::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return beenden;
 }

+ 86 - 99
StickmanWorldOnline/StatistikChat.h

@@ -6,127 +6,114 @@
 #include <KSGNetwork.h>
 #include <BilderV.h>
 #include <Rahmen.h>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
-class ChatListeSpieler
+class ChatListeSpieler : public virtual ReferenceCounter
 {
 private:
-	void( *addChatF )( void *, int );
-	void( *addFreundF )( void *, int );
-	void( *accountAnsehenF )( void *, int );
-	void *nachrichtParam;
-	int accountId;
-	AlphaFeld *bg;
-	TextFeld *name;
-	Knopf *accountAnsehen;
-	Knopf *nachrichtSenden;
-	Knopf *freundesanfrageSenden;
-	Punkt pos;
-	Punkt gr;
-	bool online;
-	int minKnopfX;
-	int knopfX;
-	bool mausIn;
-	double tickVal;
-	bool rend;
-	int ref;
+    void( *addChatF )( void *, int );
+    void( *addFreundF )( void *, int );
+    void( *accountAnsehenF )( void *, int );
+    void *nachrichtParam;
+    int accountId;
+    AlphaFeld *bg;
+    TextFeld *name;
+    Knopf *accountAnsehen;
+    Knopf *nachrichtSenden;
+    Knopf *freundesanfrageSenden;
+    Punkt pos;
+    Punkt gr;
+    bool online;
+    int minKnopfX;
+    int knopfX;
+    bool mausIn;
+    double tickVal;
+    bool rend;
 
 public:
-	// Konstruktor
-	ChatListeSpieler( int accountId, int eigeneId, Schrift *zSchrift, BilderV *bilder, KSGClient::InformationServerClient *zInfoc,
-											  bool istFreund, void( *addChatF )( void*, int ), void( *addFreundF )( void*, int ),
-											  void( *accountAnsehenF )( void *, int ), void *param );
-	// Destruktor
-	~ChatListeSpieler();
-	// nicht constant
-	void setOffline();
-	void setPosition( int y );
-	void doPublicMausEreignis( MausEreignis &me );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// constant
-	int getAccountId() const;
-	// Reference Counting
-	ChatListeSpieler *getThis();
-	ChatListeSpieler *release();
+    // Konstruktor
+    ChatListeSpieler( int accountId, int eigeneId, UIInit &uiFactory, BilderV *bilder, KSGClient::InformationServerClient *zInfoc,
+                      bool istFreund, void( *addChatF )( void *, int ), void( *addFreundF )( void *, int ),
+                      void( *accountAnsehenF )( void *, int ), void *param );
+    // Destruktor
+    ~ChatListeSpieler();
+    // nicht constant
+    void setOffline();
+    void setPosition( int y );
+    void doPublicMausEreignis( MausEreignis &me );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
+    // constant
+    int getAccountId() const;
 };
 
-class ChatListe
+class ChatListe : public virtual ReferenceCounter
 {
 private:
-	void( *addChat )( void *, int );
-	void( *addFreund )( void *, int );
-	void( *accountAnsehen )( void *, int );
-	void *nachrichtParam;
-	int eigeneId;
-	RCArray< ChatListeSpieler > *spieler;
-	VScrollBar *vScroll;
-	Punkt pos;
-	Punkt gr;
+    void( *addChat )( void *, int );
+    void( *addFreund )( void *, int );
+    void( *accountAnsehen )( void *, int );
+    void *nachrichtParam;
+    int eigeneId;
+    RCArray< ChatListeSpieler > *spieler;
+    VScrollBar *vScroll;
+    Punkt pos;
+    Punkt gr;
     KSGClient::InformationServerClient *infoc;
-	Schrift *schrift;
-	BilderV *bilder;
-	LRahmen *ram;
-	bool rend;
-	int ref;
+    UIInit uiFactory;
+    BilderV *bilder;
+    LRahmen *ram;
+    bool rend;
 
 public:
-	// Konstruktor
-	ChatListe( int eigeneId, KSGClient::InformationServerClient *infoc, Schrift *schrift, BilderV *bilder,
-									   void( *addChat )( void*, int ), void( *addFreund )( void*, int ),
-									   void( *accountAnsehen )( void *, int ), void *param );
-	// Destruktor
-	~ChatListe();
-	// nicht constant
-	void addSpieler( int accountId, bool istFreund );
-	void setOffline( int accountId );
-	void doPublicMausEreignis( MausEreignis &me );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// constant
-
-	// Reference Counting
-	ChatListe *getThis();
-	ChatListe *release();
+    // Konstruktor
+    ChatListe( int eigeneId, KSGClient::InformationServerClient *infoc, UIInit &uiFactory, BilderV *bilder,
+               void( *addChat )( void *, int ), void( *addFreund )( void *, int ),
+               void( *accountAnsehen )( void *, int ), void *param );
+    // Destruktor
+    ~ChatListe();
+    // nicht constant
+    void addSpieler( int accountId, bool istFreund );
+    void setOffline( int accountId );
+    void doPublicMausEreignis( MausEreignis &me );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
 };
 
-class StatistikChat
+class StatistikChat : public virtual ReferenceCounter
 {
 private:
-	void( *addNachricht )( void *, Text *, Text *, Text *, Text * );
-	void *nachrichtParam;
+    void( *addNachricht )( void *, Text *, Text *, Text *, Text * );
+    void *nachrichtParam;
     KSGClient::SpielServerClient *spielc;
     KSGClient::InformationServerClient *infoc;
-	TextFeld *verlauf;
-	TextFeld *nachricht;
-	Knopf *senden;
-	Knopf *verlassen;
-	ChatListe *spielerListe;
-	bool beenden;
-	int ref;
+    TextFeld *verlauf;
+    TextFeld *nachricht;
+    Knopf *senden;
+    Knopf *verlassen;
+    ChatListe *spielerListe;
+    bool beenden;
 
 public:
-	// Konstruktor
-	StatistikChat( int eigeneId, KSGClient::SpielServerClient *spielc, KSGClient::InformationServerClient *infoc, Schrift *schrift, BilderV *bilder,
-										   void( *addNachricht )( void *, Text *, Text *, Text *, Text * ),
-										   void( *addChat )( void*, int ), void( *addFreund )( void*, int ),
-										   void( *accountAnsehen )( void *, int ), void *param );
-	// Destruktor
-	~StatistikChat();
-	// nicht constant
-	void addSpieler( int accountId, bool istFreund );
-	void spielerOffline( int accountId );
-	void addChatNachricht( int vonAccount, char *nachricht );
-	void doPublicMausEreignis( MausEreignis &me );
-	void doTastaturEreignis( TastaturEreignis &te );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// constant
-	bool hatVerlassen();
-	// Reference Counting
-	StatistikChat *getThis();
-	StatistikChat *release();
+    // Konstruktor
+    StatistikChat( int eigeneId, KSGClient::SpielServerClient *spielc, KSGClient::InformationServerClient *infoc, UIInit &uiFactory, BilderV *bilder,
+                   void( *addNachricht )( void *, Text *, Text *, Text *, Text * ),
+                   void( *addChat )( void *, int ), void( *addFreund )( void *, int ),
+                   void( *accountAnsehen )( void *, int ), void *param );
+    // Destruktor
+    ~StatistikChat();
+    // nicht constant
+    void addSpieler( int accountId, bool istFreund );
+    void spielerOffline( int accountId );
+    void addChatNachricht( int vonAccount, char *nachricht );
+    void doPublicMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
+    // constant
+    bool hatVerlassen();
 };
 
 #endif

+ 29 - 45
StickmanWorldOnline/StatistikTabelle.cpp

@@ -7,29 +7,29 @@
 // Inhalt der StatistikTabelle Klasse aus StatistikTabelle.h
 // Konstruktor
 StatistikTabelle::StatistikTabelle( Array< SSDSpieler * > *ssdgs, Array< SSDTeam * > *ssdgt,
-                                    Schrift *zSchrift, Bildschirm *zScreen, bool historie )
-    : schrift( zSchrift->getThis() ),
+                                    UIInit &uiFactory, bool historie )
+    : ReferenceCounter(),
+    uiFactory( uiFactory ),
     ssdgs( ssdgs ),
     ssdgt( ssdgt ),
-    stAuswahl( initAuswahlBox( 10, 10, 120, 20, zSchrift, ABSTYLE, { "Spieler", "Teams" } ) ),
-    sortAuswahlGS( initAuswahlBox( 270, 10, 120, 20, zSchrift, ABSTYLE, { "Spielername", "Teamname",
+    stAuswahl( initAuswahlBox( 10, 10, 120, 20, uiFactory, ABSTYLE, { "Spieler", "Teams" } ) ),
+    sortAuswahlGS( initAuswahlBox( 270, 10, 120, 20, uiFactory, ABSTYLE, { "Spielername", "Teamname",
     "Spielerfarbe", "Teamfarbe", "Schaden bekommen", "Schaden gemacht", "Leben geheilt",
     "Präzision", "Punkte", "Kills", "Tode", "Items aufgehoben", "Items benutzt" } ) ),
-    sortAuswahlGT( initAuswahlBox( 270, 10, 120, 20, zSchrift, ABSTYLE, { "Teamname", "Teamfarbe",
+    sortAuswahlGT( initAuswahlBox( 270, 10, 120, 20, uiFactory, ABSTYLE, { "Teamname", "Teamfarbe",
     "Punkte", "Kills", "Tode" } ) ),
-    sortRichtungGS( initAuswahlBox( 400, 10, 120, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
-    sortRichtungGT( initAuswahlBox( 400, 10, 120, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
-    gesamtSpieler( initObjTabelle( 10, 40, 760, 245, zSchrift, OTSTYLE, { { "Spielername", 120, 20, 200 },
+    sortRichtungGS( initAuswahlBox( 400, 10, 120, 20, uiFactory, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+    sortRichtungGT( initAuswahlBox( 400, 10, 120, 20, uiFactory, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+    gesamtSpieler( initObjTabelle( 10, 40, 760, 245, uiFactory, OTSTYLE, { { "Spielername", 120, 20, 200 },
     { "Teamname", 120, 20, 120 }, { "Spielerfarbe", 100, 20, 100 }, { "Teamfarbe", 100, 20, 100 },
     { "Schaden bekommen", 130, 20, 130 }, { "Schaden gemacht", 130, 20, 130 },
     { "Leben geheilt", 120, 20, 140 }, { "Präzision", 60, 20, 60 }, { "Punkte", 50, 20, 50 },
     { "Kills", 40, 20, 40 }, { "Tode", 40, 20, 40 }, { "Items aufgehoben", 120, 20, 120 },
     { "Items benutzt", 80, 20, 60 } }, 20 ) ),
-    gesamtTeam( initObjTabelle( 10, 40, 760, 245, zSchrift, OTSTYLE, { { "Teamname", 120, 20, 120 },
+    gesamtTeam( initObjTabelle( 10, 40, 760, 245, uiFactory, OTSTYLE, { { "Teamname", 120, 20, 120 },
     { "Teamfarbe", 100, 20, 100 }, { "Punkte", 50, 20, 50 }, { "Kills", 40, 20, 40 }, { "Tode", 40, 20, 40 } }, 20 ) ),
     teamS( 0 ),
-    rend( 0 ),
-    ref( 1 )
+    rend( 0 )
 {
     tabelleFüllen( gesamtSpieler );
     tabelleFüllen( gesamtTeam );
@@ -45,7 +45,6 @@ StatistikTabelle::StatistikTabelle( Array< SSDSpieler * > *ssdgs, Array< SSDTeam
 // Destruktor
 StatistikTabelle::~StatistikTabelle()
 {
-    schrift->release();
     ssdgs->release();
     ssdgt->release();
     stAuswahl->release();
@@ -181,21 +180,21 @@ void StatistikTabelle::tabelleF
             int i = reihenfolge.get( j );
             zT->addZeile( Text( "Spieler " ) += ssdgs->get( i )->spielerNummer );
             int zNum = zT->getZeilenNummer( Text( "Spieler " ) += ssdgs->get( i )->spielerNummer );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Spielername" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, ssdgs->get( i )->spielerName ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamname" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, ssdgs->get( i )->teamName ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Spielerfarbe" ), zNum, initTextFeld( 0, 0, 0, 0, 0, TextFeld::Style::Sichtbar | TextFeld::Style::Hintergrund, 0 ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Spielername" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, ssdgs->get( i )->spielerName ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamname" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, ssdgs->get( i )->teamName ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Spielerfarbe" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Sichtbar | TextFeld::Style::Hintergrund, 0 ) );
             ( (TextFeld *)zT->zZeichnung( zT->getSpaltenNummer( "Spielerfarbe" ), zNum ) )->setHintergrundFarbe( ssdgs->get( i )->spielerFarbe );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamfarbe" ), zNum, initTextFeld( 0, 0, 0, 0, 0, TextFeld::Style::Sichtbar | TextFeld::Style::Hintergrund, 0 ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamfarbe" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Sichtbar | TextFeld::Style::Hintergrund, 0 ) );
             ( (TextFeld *)zT->zZeichnung( zT->getSpaltenNummer( "Teamfarbe" ), zNum ) )->setHintergrundFarbe( ssdgs->get( i )->teamFarbe );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Schaden bekommen" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgs->get( i )->schadenBekommen ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Schaden gemacht" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgs->get( i )->schadenGemacht ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Leben geheilt" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgs->get( i )->lebenGeheilt ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Präzision" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ( ssdgs->get( i )->schüsse ? ( 100 * ssdgs->get( i )->treffer / ssdgs->get( i )->schüsse ) : 0 ) ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Punkte" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgs->get( i )->punkte ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Kills" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgs->get( i )->kills ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Tode" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgs->get( i )->tode ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Items aufgehoben" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text( ssdgs->get( i )->itemsAufgehoben ) ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Items benutzt" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text( ssdgs->get( i )->itemsVerwendet ) ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Schaden bekommen" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgs->get( i )->schadenBekommen ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Schaden gemacht" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgs->get( i )->schadenGemacht ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Leben geheilt" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgs->get( i )->lebenGeheilt ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Präzision" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ( ssdgs->get( i )->schüsse ? ( 100 * ssdgs->get( i )->treffer / ssdgs->get( i )->schüsse ) : 0 ) ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Punkte" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgs->get( i )->punkte ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Kills" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgs->get( i )->kills ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Tode" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgs->get( i )->tode ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Items aufgehoben" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text( ssdgs->get( i )->itemsAufgehoben ) ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Items benutzt" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text( ssdgs->get( i )->itemsVerwendet ) ) );
         }
         return;
     }
@@ -265,12 +264,12 @@ void StatistikTabelle::tabelleF
             int i = reihenfolge.get( j );
             zT->addZeile( Text( "Team " ) += ssdgt->get( i )->teamNummer );
             int zNum = zT->getZeilenNummer( Text( "Team " ) += ssdgt->get( i )->teamNummer );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamname" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, ssdgt->get( i )->teamName ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamfarbe" ), zNum, initTextFeld( 0, 0, 0, 0, 0, TextFeld::Style::Sichtbar | TextFeld::Style::Hintergrund, 0 ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamname" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, ssdgt->get( i )->teamName ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Teamfarbe" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Sichtbar | TextFeld::Style::Hintergrund, 0 ) );
             ( (TextFeld *)zT->zZeichnung( zT->getSpaltenNummer( "Teamfarbe" ), zNum ) )->setHintergrundFarbe( ssdgt->get( i )->teamFarbe );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Punkte" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgt->get( i )->punkte ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Kills" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgt->get( i )->kills ) );
-            zT->setZeichnungZ( zT->getSpaltenNummer( "Tode" ), zNum, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text, Text() += ssdgt->get( i )->tode ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Punkte" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgt->get( i )->punkte ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Kills" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgt->get( i )->kills ) );
+            zT->setZeichnungZ( zT->getSpaltenNummer( "Tode" ), zNum, initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text, Text() += ssdgt->get( i )->tode ) );
         }
         return;
     }
@@ -366,19 +365,4 @@ void StatistikTabelle::render( Bild &zRObj )
     }
     // Auswahl Boxen
     stAuswahl->render( zRObj );
-}
-
-// Reference Counting
-StatistikTabelle *StatistikTabelle::getThis()
-{
-    ref++;
-    return this;
-}
-
-StatistikTabelle *StatistikTabelle::release()
-{
-    ref--;
-    if( !ref )
-        delete this;
-    return 0;
 }

+ 25 - 28
StickmanWorldOnline/StatistikTabelle.h

@@ -3,42 +3,39 @@
 
 #include <Tabelle.h>
 #include <AuswahlBox.h>
+#include <UIInitialization.h>
 #include "SpielStatistikDaten.h"
 
 using namespace Framework;
 
-class StatistikTabelle
+class StatistikTabelle : public virtual ReferenceCounter
 {
 private:
-	Schrift *schrift;
-	Array< SSDSpieler* > *ssdgs;
-	Array< SSDTeam* > *ssdgt;
-	AuswahlBox *stAuswahl;
-	AuswahlBox *sortAuswahlGS;
-	AuswahlBox *sortAuswahlGT;
-	AuswahlBox *sortRichtungGS;
-	AuswahlBox *sortRichtungGT;
-	ObjTabelle *gesamtSpieler;
-	ObjTabelle *gesamtTeam;
-	bool teamS;
-	bool rend;
-	int ref;
-	// privat
-	void tabelleLehren( ObjTabelle *zT, bool überschrift );
-	void tabelleFüllen( ObjTabelle *zT );
+    UIInit uiFactory;
+    Array< SSDSpieler * > *ssdgs;
+    Array< SSDTeam * > *ssdgt;
+    AuswahlBox *stAuswahl;
+    AuswahlBox *sortAuswahlGS;
+    AuswahlBox *sortAuswahlGT;
+    AuswahlBox *sortRichtungGS;
+    AuswahlBox *sortRichtungGT;
+    ObjTabelle *gesamtSpieler;
+    ObjTabelle *gesamtTeam;
+    bool teamS;
+    bool rend;
+    // privat
+    void tabelleLehren( ObjTabelle *zT, bool überschrift );
+    void tabelleFüllen( ObjTabelle *zT );
 
 public:
-	// Konstruktor
-	StatistikTabelle( Array< SSDSpieler* > *ssdgs, Array< SSDTeam* > *ssdgt, Schrift *zSchrift, Bildschirm *zScreen, bool historie = 0 );
-	// Destruktor
-	~StatistikTabelle();
-	// nicht constant
-	void doPublicMausEreignis( MausEreignis &me );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// Reference Counting
-	StatistikTabelle *getThis();
-	StatistikTabelle *release();
+    // Konstruktor
+    StatistikTabelle( Array< SSDSpieler * > *ssdgs, Array< SSDTeam * > *ssdgt, UIInit &uiFactory, bool historie = 0 );
+    // Destruktor
+    ~StatistikTabelle();
+    // nicht constant
+    void doPublicMausEreignis( MausEreignis &me );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
 };
 
 #endif

+ 9 - 0
StickmanWorldOnline/StickmanWorldOnline.vcxproj

@@ -28,6 +28,8 @@
     <ClCompile Include="DLLStart.cpp" />
     <ClCompile Include="DrachenAuge.cpp" />
     <ClCompile Include="Drop.cpp" />
+    <ClCompile Include="Editor.cpp" />
+    <ClCompile Include="EditorKarte.cpp" />
     <ClCompile Include="Effect.cpp" />
     <ClCompile Include="Ende.cpp" />
     <ClCompile Include="Enterhaken.cpp" />
@@ -37,8 +39,10 @@
     <ClCompile Include="Geist.cpp" />
     <ClCompile Include="Geschoss.cpp" />
     <ClCompile Include="Initialisierung.cpp" />
+    <ClCompile Include="EditorKlient.cpp" />
     <ClCompile Include="Leben.cpp" />
     <ClCompile Include="LebenRune.cpp" />
+    <ClCompile Include="Model.cpp" />
     <ClCompile Include="Reader.cpp" />
     <ClCompile Include="Resource.cpp" />
     <ClCompile Include="Rolle.cpp" />
@@ -64,6 +68,7 @@
     <ClCompile Include="Tunnel.cpp" />
     <ClCompile Include="Umlenkung.cpp" />
     <ClCompile Include="Variablen.cpp" />
+    <ClCompile Include="View.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Aktionen.h" />
@@ -83,6 +88,7 @@
     <ClInclude Include="Ende.h" />
     <ClInclude Include="Enterhaken.h" />
     <ClInclude Include="Ereignis.h" />
+    <ClInclude Include="Frage.h" />
     <ClInclude Include="GameObject.h" />
     <ClInclude Include="Gegenstand.h" />
     <ClInclude Include="Geist.h" />
@@ -92,6 +98,8 @@
     <ClInclude Include="Interface.h" />
     <ClInclude Include="Leben.h" />
     <ClInclude Include="LebenRune.h" />
+    <ClInclude Include="Model.h" />
+    <ClInclude Include="Nachricht.h" />
     <ClInclude Include="Reader.h" />
     <ClInclude Include="Resource.h" />
     <ClInclude Include="RightTools.h" />
@@ -119,6 +127,7 @@
     <ClInclude Include="Tunnel.h" />
     <ClInclude Include="Umlenkung.h" />
     <ClInclude Include="Variablen.h" />
+    <ClInclude Include="View.h" />
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <VCProjectVersion>15.0</VCProjectVersion>

+ 48 - 9
StickmanWorldOnline/StickmanWorldOnline.vcxproj.filters

@@ -28,6 +28,18 @@
     <Filter Include="Resources">
       <UniqueIdentifier>{c7883eee-d9b9-4f59-a0e6-d567836f0a90}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Editor\Dialogs">
+      <UniqueIdentifier>{7c3eba13-7b06-4c2d-9fdc-8f459ebfbe6b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Editor\Abstract">
+      <UniqueIdentifier>{8290dae5-bc10-4dd1-8e30-86e3b74e2408}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Editor\Karte">
+      <UniqueIdentifier>{04ac8771-d1fb-462f-a2bb-38ecffe2700c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Editor\Klient">
+      <UniqueIdentifier>{23326a64-d0a7-491d-b177-4829823bfc86}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Ende.cpp">
@@ -161,23 +173,29 @@
     <ClCompile Include="Bestenliste.cpp">
       <Filter>Spiel\Objekte</Filter>
     </ClCompile>
+    <ClCompile Include="Editor.cpp">
+      <Filter>Editor</Filter>
+    </ClCompile>
+    <ClCompile Include="View.cpp">
+      <Filter>Editor\Abstract</Filter>
+    </ClCompile>
+    <ClCompile Include="Model.cpp">
+      <Filter>Editor\Abstract</Filter>
+    </ClCompile>
+    <ClCompile Include="EditorKarte.cpp">
+      <Filter>Editor\Karte</Filter>
+    </ClCompile>
+    <ClCompile Include="EditorKlient.cpp">
+      <Filter>Editor\Klient</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Aufzeichnung.h">
       <Filter>Aufzeichnung</Filter>
     </ClInclude>
-    <ClInclude Include="Dialog.h">
-      <Filter>Editor</Filter>
-    </ClInclude>
     <ClInclude Include="Editor.h">
       <Filter>Editor</Filter>
     </ClInclude>
-    <ClInclude Include="EditorKarte.h">
-      <Filter>Editor</Filter>
-    </ClInclude>
-    <ClInclude Include="EditorKlient.h">
-      <Filter>Editor</Filter>
-    </ClInclude>
     <ClInclude Include="HistorieStatistik.h">
       <Filter>Statistik</Filter>
     </ClInclude>
@@ -320,5 +338,26 @@
     <ClInclude Include="Bestenliste.h">
       <Filter>Spiel\Objekte</Filter>
     </ClInclude>
+    <ClInclude Include="Dialog.h">
+      <Filter>Editor\Dialogs</Filter>
+    </ClInclude>
+    <ClInclude Include="Nachricht.h">
+      <Filter>Editor\Dialogs</Filter>
+    </ClInclude>
+    <ClInclude Include="Frage.h">
+      <Filter>Editor\Dialogs</Filter>
+    </ClInclude>
+    <ClInclude Include="Model.h">
+      <Filter>Editor\Abstract</Filter>
+    </ClInclude>
+    <ClInclude Include="View.h">
+      <Filter>Editor\Abstract</Filter>
+    </ClInclude>
+    <ClInclude Include="EditorKarte.h">
+      <Filter>Editor\Karte</Filter>
+    </ClInclude>
+    <ClInclude Include="EditorKlient.h">
+      <Filter>Editor\Klient</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

+ 1 - 1
StickmanWorldOnline/Sturm.cpp

@@ -77,5 +77,5 @@ bool SturmEffect::istGegenstandErlaubt( GegenstandTyp typ ) const
 
 Resource *SturmEffect::getCurrentResource()
 {
-    return annimation ? annimation->getThis() : 0;
+    return annimation ? dynamic_cast<Resource *>( annimation->getThis() ) : 0;
 }

+ 7 - 7
StickmanWorldOnline/Timer.cpp

@@ -11,7 +11,7 @@ Timer::Timer( Schrift *zSchrift, int id, const char *name, int maxZeit, int x, i
     sichtbar = visible;
     this->autoWiederhohlung = autoWiederhohlung;
     tr.setSchriftSize( 12 );
-    tr.setSchriftZ( zSchrift->getThis() );
+    tr.setSchriftZ( dynamic_cast<Schrift *>( zSchrift->getThis() ) );
     this->runns = runns;
     this->pause = 0;
     this->farbe = farbe;
@@ -24,18 +24,18 @@ void Timer::start( Spiel *zSpiel, bool restart )
     currentTime = (float)maxZeit;
     runns = true;
     pause = 0;
-    zSpiel->setTimerZuletztGestartet( (Timer *)getThis() );
+    zSpiel->setTimerZuletztGestartet( dynamic_cast<Timer *>( getThis() ) );
     Ereignis *e = new Ereignis( TIMER_BEGINNT );
-    e->addParameter( "Betroffener Timer", this->getThis() );
+    e->addParameter( "Betroffener Timer", dynamic_cast<Timer *>( this->getThis() ) );
     zSpiel->throwEvent( e );
 }
 
 void Timer::setPause( Spiel *zSpiel, bool pause )
 {
     if( pause && !this->pause )
-        zSpiel->setTimerZuletztPausiert( (Timer *)getThis() );
+        zSpiel->setTimerZuletztPausiert( dynamic_cast<Timer *>( getThis() ) );
     if( !pause && this->pause )
-        zSpiel->setTimerZuletztFortgesetzt( (Timer *)getThis() );
+        zSpiel->setTimerZuletztFortgesetzt( dynamic_cast<Timer *>( getThis() ) );
     this->pause = pause;
 }
 
@@ -66,10 +66,10 @@ void Timer::tick( double time, Spiel *zSpiel )
         currentTime -= (float)time;
         if( currentTime <= 0 )
         {
-            zSpiel->setTimerZuletztAbgelaufen( (Timer *)getThis() );
+            zSpiel->setTimerZuletztAbgelaufen( dynamic_cast<Timer *>( getThis() ) );
             runns = 0;
             Ereignis *e = new Ereignis( TIMER_RUNNS_OUT );
-            e->addParameter( "Betroffener Timer", this->getThis() );
+            e->addParameter( "Betroffener Timer", dynamic_cast<Timer *>( this->getThis() ) );
             zSpiel->throwEvent( e );
             if( autoWiederhohlung )
                 start( zSpiel );

+ 11 - 72
StickmanWorldOnline/Trigger.cpp

@@ -3,10 +3,10 @@
 
 
 VarPointer::VarPointer( const char *name, Variable *var )
+    : ReferenceCounter()
 {
     this->name = name;
     this->var = var;
-    ref = 1;
 }
 
 VarPointer::~VarPointer()
@@ -29,7 +29,7 @@ void VarPointer::setVariable( Variable *var )
 
 Variable *VarPointer::getVariable() const
 {
-    return var ? var->getThis() : 0;
+    return var ? dynamic_cast<Variable *>( var->getThis() ) : 0;
 }
 
 Variable *VarPointer::zVariable() const
@@ -42,24 +42,10 @@ VarPointer::operator Variable *( ) const
     return var;
 }
 
-VarPointer *VarPointer::getThis()
-{
-    ref++;
-    return this;
-}
-
-VarPointer *VarPointer::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 
 LocalMemory::LocalMemory()
-{
-    ref = 1;
-}
+    : ReferenceCounter()
+{}
 
 LocalMemory::~LocalMemory()
 {}
@@ -97,25 +83,12 @@ Variable *LocalMemory::zVariable( const char *name )
     return 0;
 }
 
-LocalMemory *LocalMemory::getThis()
-{
-    ref++;
-    return this;
-}
-
-LocalMemory *LocalMemory::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 
 ProgramCounter::ProgramCounter()
+    : ReferenceCounter()
 {
     current.add( 0 );
     depth = 0;
-    ref = 1;
 }
 
 ProgramCounter::~ProgramCounter()
@@ -153,24 +126,11 @@ int ProgramCounter::currentPosition() const
     return current.get( depth );
 }
 
-ProgramCounter *ProgramCounter::getThis()
-{
-    ref++;
-    return this;
-}
-
-ProgramCounter *ProgramCounter::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 
 Bedingung::Bedingung( Aktion *expression )
+    : ReferenceCounter()
 {
     this->expression = expression;
-    ref = 1;
 }
 
 Bedingung::~Bedingung()
@@ -199,17 +159,9 @@ bool Bedingung::check( Spiel *zSpiel, Ereignis *zEreignis )
     return isTrue( var );
 }
 
-Bedingung *Bedingung::getThis()
+Aktion *Bedingung::zExpression() const
 {
-    ref++;
-    return this;
-}
-
-Bedingung *Bedingung::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
+    return expression;
 }
 
 
@@ -280,7 +232,7 @@ TriggerRun *Trigger::runTrigger( Ereignis *e, Spiel *zSpiel )
         }
     }
     runCount++;
-    return new TriggerRun( (Trigger *)getThis(), e, zSpiel );
+    return new TriggerRun( dynamic_cast<Trigger *>( getThis() ), e, zSpiel );
 }
 
 int Trigger::getId() const
@@ -305,12 +257,12 @@ bool Trigger::istAktiv() const
 
 
 TriggerRun::TriggerRun( Trigger *trig, Ereignis *e, Spiel *zSpiel )
+    : ReferenceCounter()
 {
     trigger = trig;
     ereignis = e;
     this->zSpiel = zSpiel;
     waitCount = 0;
-    ref = 1;
 }
 
 TriggerRun::~TriggerRun()
@@ -340,18 +292,5 @@ bool TriggerRun::runNext( double t )
 
 Trigger *TriggerRun::getTrigger() const
 {
-    return (Trigger *)trigger->getThis();
-}
-
-TriggerRun *TriggerRun::getThis()
-{
-    ref++;
-    return this;
-}
-
-TriggerRun *TriggerRun::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
+    return  dynamic_cast<Trigger *>( trigger->getThis() );
 }

+ 6 - 20
StickmanWorldOnline/Trigger.h

@@ -9,12 +9,11 @@ using namespace Framework;
 class TriggerRun;
 class Spiel;
 
-class VarPointer
+class VarPointer : public virtual ReferenceCounter
 {
 private:
     Variable *var;
     Text name;
-    int ref;
 
 public:
     VarPointer( const char *name, Variable *var );
@@ -24,15 +23,12 @@ public:
     Variable *getVariable() const;
     Variable *zVariable() const;
     operator Variable *( ) const;
-    VarPointer *getThis();
-    VarPointer *release();
 };
 
-class LocalMemory
+class LocalMemory : public virtual ReferenceCounter
 {
 private:
     RCArray< VarPointer > vars;
-    int ref;
 
 public:
     LocalMemory();
@@ -40,16 +36,13 @@ public:
     void setVar( const char *name, Variable *var );
     Variable *getVariable( const char *name );
     Variable *zVariable( const char *name );
-    LocalMemory *getThis();
-    LocalMemory *release();
 };
 
-class ProgramCounter
+class ProgramCounter : public virtual ReferenceCounter
 {
 private:
     Array< int > current;
     int depth;
-    int ref;
 
 public:
     ProgramCounter();
@@ -59,23 +52,19 @@ public:
     void stepOut();
     Text getUniqueString() const;
     int currentPosition() const;
-    ProgramCounter *getThis();
-    ProgramCounter *release();
 };
 
-class Bedingung
+class Bedingung : public virtual ReferenceCounter
 {
 private:
     Aktion *expression;
-    int ref;
 
 public:
     Bedingung( Aktion *expression );
     ~Bedingung();
     void setExpression( Aktion *expr );
     bool check( Spiel *zSpiel, Ereignis *zEreignis );
-    Bedingung *getThis();
-    Bedingung *release();
+    Aktion *zExpression() const;
 };
 
 class Trigger : public Variable
@@ -106,7 +95,7 @@ public:
     bool istAktiv() const;
 };
 
-class TriggerRun
+class TriggerRun : public virtual ReferenceCounter
 {
 private:
     Trigger *trigger;
@@ -116,7 +105,6 @@ private:
     ProgramCounter counter;
     int programCounter;
     double waitCount;
-    int ref;
 
 public:
     TriggerRun( Trigger *trig, Ereignis *e, Spiel *zSpiel );
@@ -124,6 +112,4 @@ public:
     // gibt 0 zurück, wenn der Auslöser vollständig durchgelaufen ist
     bool runNext( double t );
     Trigger *getTrigger() const;
-    TriggerRun *getThis();
-    TriggerRun *release();
 };

+ 2 - 2
StickmanWorldOnline/Tunnel.cpp

@@ -11,7 +11,7 @@ Tunnel::Tunnel( ResourceRegistry *zResources, int id, int x, int y, int width, i
     this->zielX = zielX;
     this->zielY = zielY;
     texturScale = 1;
-    textur = zResources->zResource( R_TUNNEL, 0 )->getImages()->getThis();
+    textur = dynamic_cast<Bild *>( zResources->zResource( R_TUNNEL, 0 )->getImages()->getThis() );
 }
 
 void Tunnel::setZielX( int x )
@@ -26,7 +26,7 @@ void Tunnel::setZielY( int y )
 
 void Tunnel::addBenutzung( Spiel *zSpiel )
 {
-    zSpiel->setTunnelZuletztBenutzt( (Tunnel *)getThis() );
+    zSpiel->setTunnelZuletztBenutzt( dynamic_cast<Tunnel *>( getThis() ) );
     benutzt++;
 }
 

+ 3 - 3
StickmanWorldOnline/Umlenkung.cpp

@@ -11,7 +11,7 @@ Umlenkung::Umlenkung( ResourceRegistry *zResources, int id, int x, int y, int br
     this->aktiv = aktiv;
     benutzt = 0;
     abklingzeitVerbleibend = 0;
-    this->resources = zResources->getThis();
+    this->resources = dynamic_cast<ResourceRegistry *>( zResources->getThis() );
     setRichtung( richtung );
 }
 
@@ -41,7 +41,7 @@ void Umlenkung::setRichtung( Richtung r )
     if( textur )
         textur->release();
     if( richtung == RECHTS )
-        textur = resources->zResource( R_UMLENKUNG, 0 )->getImages()->getThis();
+        textur = dynamic_cast<Bild *>( resources->zResource( R_UMLENKUNG, 0 )->getImages()->getThis() );
     else if( richtung == LINKS )
     {
         Bild *r = resources->zResource( R_UMLENKUNG, 0 )->getImages();
@@ -85,7 +85,7 @@ void Umlenkung::addBenutzt( Spiel *zSpiel )
         }
     }
     abklingzeitVerbleibend = (float)maxAbklingzeit;
-    zSpiel->setUmlenkungZuletztBenutzt( (Umlenkung *)getThis() );
+    zSpiel->setUmlenkungZuletztBenutzt( dynamic_cast<Umlenkung *>( getThis() ) );
 }
 
 void Umlenkung::tick( double time )

+ 4 - 17
StickmanWorldOnline/Variablen.cpp

@@ -53,9 +53,9 @@ bool operator==( VariableTyp a, VariableTyp b )
         return ( a == (int)BARIERE || a == (int)BASE || a == (int)GEGENSTAND || a == (int)GESCHOSS ||
                  a == (int)SCHALTER || a == (int)SCHIENE || a == (int)SPIELER || a == (int)TIMER ||
                  a == (int)TUNNEL || a == (int)UMLENKUNG || a == (int)GAME_OBJEKT || a == (int)ALLE ) &&
-                 ( b == (int)BARIERE || b == (int)BASE || b == (int)GEGENSTAND || b == (int)GESCHOSS ||
-                   b == (int)SCHALTER || b == (int)SCHIENE || b == (int)SPIELER || b == (int)TIMER || b == (int)TUNNEL ||
-                   b == (int)UMLENKUNG || b == (int)GAME_OBJEKT || b == (int)ALLE );
+            ( b == (int)BARIERE || b == (int)BASE || b == (int)GEGENSTAND || b == (int)GESCHOSS ||
+              b == (int)SCHALTER || b == (int)SCHIENE || b == (int)SPIELER || b == (int)TIMER || b == (int)TUNNEL ||
+              b == (int)UMLENKUNG || b == (int)GAME_OBJEKT || b == (int)ALLE );
     }
     return (int)a == (int)b;
 }
@@ -67,9 +67,9 @@ bool operator!=( VariableTyp a, VariableTyp b )
 
 
 Variable::Variable( VariableTyp typ )
+    : ReferenceCounter()
 {
     this->typ = typ;
-    ref = 1;
 }
 
 Variable::~Variable()
@@ -80,19 +80,6 @@ VariableTyp Variable::getVariableTyp() const
     return typ;
 }
 
-Variable *Variable::getThis()
-{
-    ref++;
-    return this;
-}
-
-Variable *Variable::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 bool isTrue( Variable *v )
 {
     if( !v )

+ 12 - 4
StickmanWorldOnline/Variablen.h

@@ -88,18 +88,15 @@ enum GegenstandTyp
 bool operator==( VariableTyp a, VariableTyp b );
 bool operator!=( VariableTyp a, VariableTyp b );
 
-class Variable
+class Variable : public virtual ReferenceCounter
 {
 private:
     VariableTyp typ;
-    int ref;
 
 public:
     Variable( VariableTyp typ );
     virtual ~Variable();
     VariableTyp getVariableTyp() const;
-    Variable *getThis();
-    Variable *release();
 };
 
 bool isTrue( Variable *v );
@@ -148,4 +145,15 @@ public:
     Float( float value );
     void setValue( float value );
     float getValue() const;
+};
+
+class Template : public Variable
+{
+private:
+    int id;
+
+public:
+    Template( VariableTyp typ, int id );
+    void setId( int id );
+    int getId() const;
 };

+ 20 - 0
StickmanWorldOnline/View.cpp

@@ -0,0 +1,20 @@
+#include "View.h"
+
+View::View()
+    : ReferenceCounter()
+{}
+
+View::~View()
+{}
+
+
+ActionView::ActionView( std::function< void( Model * ) > f )
+    : View()
+{
+    this->f = f;
+}
+
+void ActionView::update( Model *m )
+{
+    f( m );
+}

+ 24 - 0
StickmanWorldOnline/View.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include <functional>
+#include <ReferenceCounter.h>
+
+class Model;
+
+class View : public virtual Framework::ReferenceCounter
+{
+public:
+    View();
+    virtual ~View();
+    virtual void update( Model *m ) = 0;
+};
+
+class ActionView : public View
+{
+private:
+    std::function< void( Model * ) > f;
+
+public:
+    ActionView( std::function< void( Model * ) > f );
+    void update( Model *m ) override;
+};