Browse Source

Aktive Skills hinzugefügt

Kolja Strohm 5 năm trước cách đây
mục cha
commit
3998968718

+ 2 - 0
Asteroids/Asteroids.vcxproj

@@ -200,6 +200,7 @@
     <ClInclude Include="Spiel\Karte\Strukturen.h" />
     <ClInclude Include="Spiel\Objekt\SpielObjekt.h" />
     <ClInclude Include="Spiel\Schuss\Laser.h" />
+    <ClInclude Include="Spiel\Skill\Skill.h" />
     <ClInclude Include="Spiel\SpielerGUI\SpielerGUI.h" />
     <ClInclude Include="Spiel\Spieler\DeadPlayer.h" />
     <ClInclude Include="Spiel\Spieler\Spieler.h" />
@@ -234,6 +235,7 @@
     <ClCompile Include="Spiel\Karte\Strukturen.cpp" />
     <ClCompile Include="Spiel\Objekt\SpielObjekt.cpp" />
     <ClCompile Include="Spiel\Schuss\Laser.cpp" />
+    <ClCompile Include="Spiel\Skill\Skill.cpp" />
     <ClCompile Include="Spiel\SpielerGUI\SpielerGUI.cpp" />
     <ClCompile Include="Spiel\Spieler\DeadPlayer.cpp" />
     <ClCompile Include="Spiel\Spieler\Spieler.cpp" />

+ 6 - 0
Asteroids/Asteroids.vcxproj.filters

@@ -120,6 +120,9 @@
     <ClInclude Include="Editor\Abstract\View.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="Spiel\Skill\Skill.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Initialisierung\Initialisierung.cpp">
@@ -224,5 +227,8 @@
     <ClCompile Include="Editor\Abstract\Model.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="Spiel\Skill\Skill.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 3 - 3
Asteroids/Spiel/Chat/Chat.cpp

@@ -15,13 +15,11 @@ SpielChat::SpielChat()
 	rahmen->setFarbe( 0xFF909090 );
 	rahmen->setRamenBreite( 1 );
 	rahmen->setSize( 450, 200 );
-	rahmen->setPosition( 10, BildschirmGröße().y - 210 );
 	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->setPosition( rahmen->getX() + 2, rahmen->getY() + 2 );
 	verlauf->setSize( 446, 174 );
 	nachricht = new TextFeld();
 	nachricht->setStyle( TextFeld::Style::TextFeld & ~TextFeld::Style::Buffered );
@@ -30,7 +28,6 @@ SpielChat::SpielChat()
 	nachricht->setSchriftSize( 12 );
 	nachricht->setRahmenBreite( 1 );
 	nachricht->setRahmenFarbe( 0xFF909090 );
-	nachricht->setPosition( rahmen->getX() + 2, rahmen->getY() + 178 );
 	nachricht->setSize( 446, 20 );
 	ref = 1;
 }
@@ -138,6 +135,9 @@ void SpielChat::tick( double z )
 
 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 );

+ 252 - 0
Asteroids/Spiel/Skill/Skill.cpp

@@ -0,0 +1,252 @@
+#include "Skill.h"
+
+ActiveSkill::ActiveSkill( Bild *bild )
+{
+    current.active = 0;
+    current.time = 0;
+    maxTime = 0;
+    reloadTimeFactor = 1;
+    this->bild = bild;
+
+    beschleunigungBonus = 0;
+    reparaturBonus = 0;
+    laserIntensitätBonus = 0;
+    laserEffizienzBonus = 0;
+    akkuLeistungBonus = 0;
+    maxEnergieBonus = 0;
+    maxStabilitätBonus = 0;
+    laserTempoBonus = 0;
+    wendigkeitBonus = 0;
+    antriebEffizienzBonus = 0;
+    energieSchildBonus = 0;
+    energieSchildEffizienzBonus = 0;
+
+    beschleunigungFactor = 1;
+    reparaturFactor = 1;
+    laserIntensitätFactor = 1;
+    laserEffizienzFactor = 1;
+    akkuLeistungFactor = 1;
+    maxEnergieFactor = 1;
+    maxStabilitätFactor = 1;
+    laserTempoFactor = 1;
+    wendigkeitFactor = 1;
+    antriebEffizienzFactor = 1;
+    energieSchildFactor = 1;
+    energieSchildEffizienzFactor = 1;
+
+    ref = 1;
+    save();
+}
+
+ActiveSkill::~ActiveSkill()
+{
+    if( bild )
+        bild->release();
+}
+
+void ActiveSkill::save()
+{
+    last = current;
+}
+
+void ActiveSkill::load()
+{
+    current = last;
+}
+
+void ActiveSkill::tick( double time )
+{
+    if( current.active )
+    {
+        if( current.time < time )
+            current.active = 0;
+        else
+            current.time -= time;
+    }
+    if( !current.active )
+    {
+        current.time += time * reloadTimeFactor;
+        if( current.time > maxTime )
+            current.time = maxTime;
+    }
+}
+
+void ActiveSkill::render( int x, int y, Bild &zRObj )
+{
+    zRObj.drawBildSkall( x, y, 50, 50, *bild );
+    int length = (int)( ( current.time / maxTime ) * 50 );
+    zRObj.fillRegion( x + length, y + 50, 50 - length, 4, 0xFF000000 );
+    zRObj.fillRegion( x, y + 50, length, 4, 0xFFFFFFFF );
+}
+
+bool ActiveSkill::isActive() const
+{
+    return current.active;
+}
+
+void ActiveSkill::activate()
+{
+    current.active = 1;
+}
+
+void ActiveSkill::reset()
+{
+    current.time = 0;
+    current.active = 0;
+}
+
+
+double ActiveSkill::getBeschleunigungBonus()
+{
+    return current.active ? beschleunigungBonus : 0;
+}
+
+double ActiveSkill::getReparaturBonus()
+{
+    return current.active ? reparaturBonus : 0;
+}
+
+double ActiveSkill::getLaserIntensitätBonus()
+{
+    return current.active ? laserIntensitätBonus : 0;
+}
+
+double ActiveSkill::getLaserEffizienzBonus()
+{
+    return current.active ? laserEffizienzBonus : 0;
+}
+
+double ActiveSkill::getAkkuLeistungBonus()
+{
+    return current.active ? akkuLeistungBonus : 0;
+}
+
+double ActiveSkill::getMaxEnergieBonus()
+{
+    return current.active ? maxEnergieBonus : 0;
+}
+
+double ActiveSkill::getMaxStabilitätBonus()
+{
+    return current.active ? maxStabilitätBonus : 0;
+}
+
+double ActiveSkill::getLaserTempoBonus()
+{
+    return current.active ? laserTempoBonus : 0;
+}
+
+double ActiveSkill::getWendigkeitBonus()
+{
+    return current.active ? wendigkeitBonus : 0;
+}
+
+double ActiveSkill::getAntriebEffizienzBonus()
+{
+    return current.active ? antriebEffizienzBonus : 0;
+}
+
+double ActiveSkill::getEnergieSchildBonus()
+{
+    return current.active ? energieSchildBonus : 0;
+}
+
+double ActiveSkill::getEnergieSchildEffizienzBonus()
+{
+    return current.active ? energieSchildEffizienzBonus : 0;
+}
+
+
+double ActiveSkill::getBeschleunigungFactor()
+{
+    return current.active ? beschleunigungFactor : 1;
+}
+
+double ActiveSkill::getReparaturFactor()
+{
+    return current.active ? reparaturFactor : 1;
+}
+
+double ActiveSkill::getLaserIntensitätFactor()
+{
+    return current.active ? laserIntensitätFactor : 1;
+}
+
+double ActiveSkill::getLaserEffizienzFactor()
+{
+    return current.active ? laserEffizienzFactor : 1;
+}
+
+double ActiveSkill::getAkkuLeistungFactor()
+{
+    return current.active ? akkuLeistungFactor : 1;
+}
+
+double ActiveSkill::getMaxEnergieFactor()
+{
+    return current.active ? maxEnergieFactor : 1;
+}
+
+double ActiveSkill::getMaxStabilitätFactor()
+{
+    return current.active ? maxStabilitätFactor : 1;
+}
+
+double ActiveSkill::getLaserTempoFactor()
+{
+    return current.active ? laserTempoFactor : 1;
+}
+
+double ActiveSkill::getWendigkeitFactor()
+{
+    return current.active ? wendigkeitFactor : 1;
+}
+
+double ActiveSkill::getAntriebEffizienzFactor()
+{
+    return current.active ? antriebEffizienzFactor : 1;
+}
+
+double ActiveSkill::getEnergieSchildFactor()
+{
+    return current.active ? energieSchildFactor : 1;
+}
+
+double ActiveSkill::getEnergieSchildEffizienzFactor()
+{
+    return current.active ? energieSchildEffizienzFactor : 1;
+}
+
+ActiveSkill *ActiveSkill::getThis()
+{
+    ref++;
+    return this;
+}
+
+ActiveSkill *ActiveSkill::release()
+{
+    if( !--ref )
+        delete this;
+    return 0;
+}
+
+
+SpeedBoost::SpeedBoost( Bild *bild )
+    : ActiveSkill( bild )
+{
+    beschleunigungFactor = 2;
+    wendigkeitFactor = 2;
+    antriebEffizienzFactor = 2;
+    reloadTimeFactor = 0.02;
+    maxTime = 2;
+}
+
+
+ShieldBoost::ShieldBoost( Bild *bild )
+    : ActiveSkill( bild )
+{
+    energieSchildFactor = 2;
+    energieSchildEffizienzFactor = 2;
+    reloadTimeFactor = 0.01;
+    maxTime = 1;
+}

+ 99 - 0
Asteroids/Spiel/Skill/Skill.h

@@ -0,0 +1,99 @@
+#pragma once
+
+#include <Bild.h>
+
+using namespace Framework;
+
+class ActiveSkill
+{
+protected:
+    struct SkillDataSave
+    {
+        bool active;
+        double time;
+    } current, last;
+    double maxTime;
+    int ref;
+    double reloadTimeFactor;
+    Bild *bild;
+
+    // skill bonus added when active
+    double beschleunigungBonus;
+    double reparaturBonus;
+    double laserIntensitätBonus;
+    double laserEffizienzBonus;
+    double akkuLeistungBonus;
+    double maxEnergieBonus;
+    double maxStabilitätBonus;
+    double laserTempoBonus;
+    double wendigkeitBonus;
+    double antriebEffizienzBonus;
+    double energieSchildBonus;
+    double energieSchildEffizienzBonus;
+
+    // skil multiplier when active
+    double beschleunigungFactor;
+    double reparaturFactor;
+    double laserIntensitätFactor;
+    double laserEffizienzFactor;
+    double akkuLeistungFactor;
+    double maxEnergieFactor;
+    double maxStabilitätFactor;
+    double laserTempoFactor;
+    double wendigkeitFactor;
+    double antriebEffizienzFactor;
+    double energieSchildFactor;
+    double energieSchildEffizienzFactor;
+
+public:
+    ActiveSkill( Bild *bild );
+    ~ActiveSkill();
+    void save();
+    void load();
+    void tick( double time );
+    void render( int x, int y, Bild &zRObj );
+    bool isActive() const;
+    void activate();
+    void reset();
+
+    double getBeschleunigungBonus();
+    double getReparaturBonus();
+    double getLaserIntensitätBonus();
+    double getLaserEffizienzBonus();
+    double getAkkuLeistungBonus();
+    double getMaxEnergieBonus();
+    double getMaxStabilitätBonus();
+    double getLaserTempoBonus();
+    double getWendigkeitBonus();
+    double getAntriebEffizienzBonus();
+    double getEnergieSchildBonus();
+    double getEnergieSchildEffizienzBonus();
+
+    double getBeschleunigungFactor();
+    double getReparaturFactor();
+    double getLaserIntensitätFactor();
+    double getLaserEffizienzFactor();
+    double getAkkuLeistungFactor();
+    double getMaxEnergieFactor();
+    double getMaxStabilitätFactor();
+    double getLaserTempoFactor();
+    double getWendigkeitFactor();
+    double getAntriebEffizienzFactor();
+    double getEnergieSchildFactor();
+    double getEnergieSchildEffizienzFactor();
+
+    ActiveSkill *getThis();
+    ActiveSkill *release();
+};
+
+class SpeedBoost : public ActiveSkill
+{
+public:
+    SpeedBoost( Bild *bild );
+};
+
+class ShieldBoost : public ActiveSkill
+{
+public:
+    ShieldBoost( Bild *bild );
+};

+ 104 - 0
Asteroids/Spiel/SpielKlasse.cpp

@@ -14,6 +14,8 @@
 // Konstruktor
 SpielKlasse::SpielKlasse()
 {
+    shieldBoost = 0;
+    speedBoost = 0;
     spielZeit = -1;
     rZeit = 0;
     rendern = 0;
@@ -101,6 +103,10 @@ SpielKlasse::~SpielKlasse()
     schüsse->release();
     pixel->release();
     delete[] tasten;
+    if( speedBoost )
+        speedBoost->release();
+    if( shieldBoost )
+        shieldBoost->release();
 }
 
 // privat
@@ -326,6 +332,15 @@ void SpielKlasse::ladeDaten()
         txt->setTexturZ( asteroidTexturD.laden( 0, name ) );
         asteroidTextures->add( txt );
     }
+    spielKlient->setLadenProzent( 98 );
+    LTDBDatei skillLTDB;
+    Text *skillLTDBPfad = new Text( gamePath->getText() );
+    skillLTDBPfad->append( "/bilder/skills.ltdb" );
+    skillLTDB.setDatei( skillLTDBPfad );
+    skillLTDB.leseDaten( 0 );
+    speedBoost = skillLTDB.laden( 0, new Text( "speedboost.png" ) );
+    spielKlient->setLadenProzent( 99 );
+    shieldBoost = skillLTDB.laden( 0, new Text( "shieldboost.png" ) );
     spielKlient->setLadenProzent( 100 );
     gamePath->release();
 }
@@ -458,6 +473,76 @@ void SpielKlasse::doTastaturEreignis( TastaturEreignis & te )
                         te.verarbeitet = 1;
                     }
                     break;
+                case '1':
+                {
+                    char byte[ 2 ] = { 0xA, 0 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '2':
+                {
+                    char byte[ 2 ] = { 0xA, 1 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '3':
+                {
+                    char byte[ 2 ] = { 0xA, 2 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '4':
+                {
+                    char byte[ 2 ] = { 0xA, 3 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '5':
+                {
+                    char byte[ 2 ] = { 0xA, 4 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '6':
+                {
+                    char byte[ 2 ] = { 0xA, 5 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '7':
+                {
+                    char byte[ 2 ] = { 0xA, 6 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '8':
+                {
+                    char byte[ 2 ] = { 0xA, 7 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '9':
+                {
+                    char byte[ 2 ] = { 0xA, 8 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
+                case '0':
+                {
+                    char byte[ 2 ] = { 0xA, 9 };
+                    spielKlient->spielNachricht( 2, byte );
+                    te.verarbeitet = 1;
+                    break;
+                }
                 }
             }
         }
@@ -604,6 +689,8 @@ void SpielKlasse::stknVerarbeitung()
                 {
                     int sNum = *(int *)bytes;
                     Spieler *tmp = spieler->z( sNum - 1 );
+                    tmp->addSkill( new ShieldBoost( shieldBoost->getThis() ) );
+                    tmp->addSkill( new SpeedBoost( speedBoost->getThis() ) );
                     bytes += 4;
                     län -= 4;
                     tmp->setAccountId( *(int *)bytes );
@@ -1096,6 +1183,23 @@ void SpielKlasse::stknVerarbeitung()
             goToPresence( presence );
             break;
         }
+        case 0x15: // Use active Skill
+        {
+            bytes++;
+            int sNum = *(int *)bytes;
+            bytes += 4;
+            län -= 4;
+            char skillId = *bytes;
+            län--;
+            goBackInTime( zeit );
+            for( auto s = spieler->getIterator(); s; s++ )
+            {
+                if( s->getSpielerNummer() == sNum )
+                    s->useSkill( skillId );
+            }
+            goToPresence( presence );
+            break;
+        }
         default:
             // Fehler beim verarbeiten
             break;

+ 2 - 0
Asteroids/Spiel/SpielKlasse.h

@@ -47,6 +47,8 @@ private:
     RCArray< Model2DData > *asteroidModels;
     RCArray< Textur2D > *asteroidTextures;
     RCArray< Pixel > *pixel;
+    Bild *speedBoost;
+    Bild *shieldBoost;
 	bool rendern;
 	int spielZeit;
 	double rZeit;

+ 194 - 29
Asteroids/Spiel/Spieler/Spieler.cpp

@@ -10,6 +10,7 @@
 Spieler::Spieler( KSGClient::InformationServerClient *zInfoK, Schrift *zSchrift, SpielerStr *zStr )
     : Model2DObject()
 {
+    activeSkills = new RCArray< ActiveSkill >();
     deadPlayer = 0;
     accountId = 0;
     sNum = zStr->id;
@@ -74,19 +75,175 @@ Spieler::~Spieler()
     nText->release();
     if( deadPlayer )
         deadPlayer->release();
+    activeSkills->release();
+}
+
+double Spieler::calculateBeschleunigung()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getBeschleunigungFactor();
+        bonus += s->getBeschleunigungBonus();
+    }
+    return ( beschleunigung + zteam->beschleunigung ) * factor + bonus;
+}
+
+double Spieler::calculateReparatur()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getReparaturFactor();
+        bonus += s->getReparaturBonus();
+    }
+    return ( reparatur + zteam->reparatur ) * factor + bonus;
+}
+
+double Spieler::calculateLaserIntensität()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getLaserIntensitätFactor();
+        bonus += s->getLaserIntensitätBonus();
+    }
+    return ( laserIntensität + zteam->laserIntensität ) * factor + bonus;
+}
+
+double Spieler::calculateLaserEffizienz()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getLaserEffizienzFactor();
+        bonus += s->getLaserEffizienzBonus();
+    }
+    return ( laserEffizienz + zteam->laserEffizienz ) * factor + bonus;
+}
+
+double Spieler::calculateAkkuLeistung()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getAkkuLeistungFactor();
+        bonus += s->getAkkuLeistungBonus();
+    }
+    return ( akkuLeistung + zteam->akkuLeistung ) * factor + bonus;
+}
+
+double Spieler::calculateMaxEnergie()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getMaxEnergieFactor();
+        bonus += s->getMaxEnergieBonus();
+    }
+    return ( maxEnergie + zteam->maxEnergie ) * factor + bonus;
+}
+
+double Spieler::calculateMaxStabilität()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getMaxStabilitätFactor();
+        bonus += s->getMaxStabilitätBonus();
+    }
+    return ( maxStabilität + zteam->maxStabilität ) * factor + bonus;
+}
+
+double Spieler::calculateLaserTempo()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getLaserTempoFactor();
+        bonus += s->getLaserTempoBonus();
+    }
+    return ( laserTempo + zteam->laserTempo ) * factor + bonus;
+}
+
+double Spieler::calculateWendigkeit()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getWendigkeitFactor();
+        bonus += s->getWendigkeitBonus();
+    }
+    return ( wendigkeit + zteam->wendigkeit ) * factor + bonus;
+}
+
+double Spieler::calculateAntriebEffizienz()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getAntriebEffizienzFactor();
+        bonus += s->getAntriebEffizienzBonus();
+    }
+    return ( antriebEffizienz + zteam->antriebEffizienz ) * factor + bonus;
+}
+
+double Spieler::calculateEnergieSchild()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getEnergieSchildFactor();
+        bonus += s->getEnergieSchildBonus();
+    }
+    return ( energieSchild + zteam->energieSchild ) * factor + bonus;
+}
+
+double Spieler::calculateEnergieSchildEffizienz()
+{
+    double factor = 1;
+    double bonus = 0;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+    {
+        factor *= s->getEnergieSchildEffizienzFactor();
+        bonus += s->getEnergieSchildEffizienzBonus();
+    }
+    return ( energieSchildEffizienz + zteam->energieSchildEffizienz ) * factor + bonus;
 }
 
 double Spieler::calculateLaserCost()
 {
-    double kosten = ( ( laserIntensität + zteam->laserIntensität ) / 2 +
-        ( laserTempo + zteam->laserTempo ) / 9 ) *
-                      ( 1 / ( ( laserEffizienz + zteam->laserEffizienz ) / 25 ) );
+    double kosten = ( calculateLaserIntensität() / 2 +
+        calculateLaserTempo() / 9 ) *
+                      ( 1 / ( calculateLaserEffizienz() / 25 ) );
     if( kosten < 1 )
         kosten = 1;
     return kosten;
 }
 
 // nicht constant
+void Spieler::addSkill( ActiveSkill *skill )
+{
+    activeSkills->add( skill );
+}
+
+void Spieler::useSkill( int id )
+{
+    if( activeSkills->z( id ) )
+        activeSkills->z( id )->activate();
+}
+
 void Spieler::setModelData( Model2DData * data, Animation2DData * zFStart, Animation2DData * zFBurn )
 {
     for( auto i = data->polygons->getIterator(); i; i++ )
@@ -166,7 +323,7 @@ void Spieler::setAccountId( int accId )
         nText->setText( *name );
 }
 
-void Spieler::setTeam( Team *zTeam )
+void Spieler::setTeam( Team * zTeam )
 {
     this->zteam = zTeam;
     nText->setHintergrundFarbe( 0xA0000000 | ( zteam->farbe & 0x00FFFFFF ) );
@@ -242,6 +399,8 @@ bool Spieler::tick( const WeltInfo & info, double tv )
     flammenR->tick( tv );
     if( amLeben )
     {
+        for( auto s = activeSkills->getIterator(); s; s++ )
+            s->tick( tv );
         schussAbk -= tv;
         energieAbk -= tv;
         if( schussAbk < 0 )
@@ -253,56 +412,56 @@ bool Spieler::tick( const WeltInfo & info, double tv )
             repAbk = 0;
         if( tastatur[ T_GAS ] )
         {
-            double treibstoff = 0.5 * ( ( beschleunigung + zteam->beschleunigung ) / 15 )
-                * tv * ( 100 / ( antriebEffizienz + zteam->antriebEffizienz ) );
+            double treibstoff = 0.5 * ( calculateBeschleunigung() / 15 )
+                * tv * ( 100 / calculateAntriebEffizienz() );
             treibstoffVerbraucht += treibstoff;
             float factor = 1;
             if( treibstoff > energie )
                 factor = (float)( energie / treibstoff );
             if( factor > 0 )
-                impuls( getWorldPos( stM ), getWorldDir( kM ) * (float)tv * (float)( beschleunigung + zteam->beschleunigung ) * factor );
+                impuls( getWorldPos( stM ), getWorldDir( kM ) * (float)tv * (float)calculateBeschleunigung() * factor );
             energie -= treibstoff * factor;
         }
         if( tastatur[ T_ROT_R ] )
         {
-            double treibstoff = 0.25 * ( ( wendigkeit + zteam->wendigkeit ) / 15 )
-                * tv * ( 100 / ( antriebEffizienz + zteam->antriebEffizienz ) );
+            double treibstoff = 0.25 * ( calculateWendigkeit() / 15 )
+                * tv * ( 100 / calculateAntriebEffizienz() );
             treibstoffVerbraucht += treibstoff;
             float factor = 1;
             if( treibstoff > energie )
                 factor = (float)( energie / treibstoff );
             if( factor > 0 )
-                impuls( getWorldPos( stL ), getWorldDir( kL ) * (float)tv * (float)( wendigkeit + zteam->wendigkeit ) * factor );
+                impuls( getWorldPos( stL ), getWorldDir( kL ) * (float)tv * (float)calculateWendigkeit() * factor );
             energie -= treibstoff * factor;
         }
         if( tastatur[ T_ROT_L ] )
         {
-            double treibstoff = 0.25 * ( ( wendigkeit + zteam->wendigkeit ) / 15 )
-                * tv * ( 100 / ( antriebEffizienz + zteam->antriebEffizienz ) );
+            double treibstoff = 0.25 * ( calculateWendigkeit() / 15 )
+                * tv * ( 100 / calculateAntriebEffizienz() );
             treibstoffVerbraucht += treibstoff;
             float factor = 1;
             if( treibstoff > energie )
                 factor = (float)( energie / treibstoff );
             if( factor > 0 )
-                impuls( getWorldPos( stR ), getWorldDir( kR ) * (float)tv * (float)( wendigkeit + zteam->wendigkeit ) * factor );
+                impuls( getWorldPos( stR ), getWorldDir( kR ) * (float)tv * (float)calculateWendigkeit() * factor );
             energie -= treibstoff * factor;
         }
         __super::tick( info, tv );
         if( !energieAbk )
         {
-            if( energie != ( maxEnergie + zteam->maxEnergie ) )
+            if( energie != calculateMaxEnergie() )
                 ret = 1;
-            energie += ( akkuLeistung + zteam->akkuLeistung ) * tv;
-            if( energie > ( maxEnergie + zteam->maxEnergie ) )
-                energie = ( maxEnergie + zteam->maxEnergie );
+            energie += calculateAkkuLeistung() * tv;
+            if( energie > calculateMaxEnergie() )
+                energie = calculateMaxEnergie();
         }
         if( !repAbk )
         {
-            if( stabilität != ( maxStabilität + zteam->maxStabilität ) )
+            if( stabilität != calculateMaxStabilität() )
                 ret = 1;
-            stabilität += ( reparatur + zteam->reparatur ) * tv;
-            if( stabilität > ( maxStabilität + zteam->maxStabilität ) )
-                stabilität = ( maxStabilität + zteam->maxStabilität );
+            stabilität += calculateReparatur() * tv;
+            if( stabilität > calculateMaxStabilität() )
+                stabilität = calculateMaxStabilität();
         }
         zeitAmLeben += tv;
     }
@@ -331,15 +490,15 @@ void Spieler::renderLeben( const Mat3< float > & kamMat, Bild & zRObj )
     nText->render( zRObj );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 4, 150, zteam->farbe );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 25, 150, zteam->farbe );
-    int l = (int)( stabilität * 100 / ( maxStabilität + zteam->maxStabilität ) * 1.5 + 0.5 );
+    int l = (int)( stabilität * 100 / calculateMaxStabilität() * 1.5 + 0.5 );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 1, l, 0xFF00FF00 );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 2, l, 0xFF00FF00 );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 3, l, 0xFF00FF00 );
-    int e = (int)( energie * 100 / ( maxEnergie + zteam->maxEnergie ) * 1.5 + 0.5 );
+    int e = (int)( energie * 100 / calculateMaxEnergie() * 1.5 + 0.5 );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 26, e, 0xFF0000FF );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 27, e, 0xFF0000FF );
     zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 28, e, 0xFF0000FF );
-    int e2 = (int)( ( energie - calculateLaserCost() ) * 100 / ( maxEnergie + zteam->maxEnergie ) * 1.5 + 0.5 );
+    int e2 = (int)( ( energie - calculateLaserCost() ) * 100 / calculateMaxEnergie() * 1.5 + 0.5 );
     if( e2 > 0 )
     {
         zRObj.drawLinieV( nText->getX() + e2, nText->getY() + 26, 3, 0xFFFFFFFF );
@@ -422,12 +581,12 @@ void Spieler::setSkill( int art )
 void Spieler::nimmSchaden( double &intensität, int sLevel )
 {
     double originalIntens = intensität;
-    double schieldVal = intensität - intensität / ( energieSchild + zteam->energieSchild );
-    double schieldEVal = schieldVal / ( ( energieSchildEffizienz + zteam->energieSchildEffizienz ) / 100 );
+    double schieldVal = intensität - intensität / calculateEnergieSchild();
+    double schieldEVal = schieldVal / ( calculateEnergieSchildEffizienz() / 100 );
     if( schieldEVal > energie )
     {
         schieldEVal = energie;
-        schieldVal = schieldEVal * ( ( energieSchildEffizienz + zteam->energieSchildEffizienz ) / 100 );
+        schieldVal = schieldEVal * ( calculateEnergieSchildEffizienz() / 100 );
     }
     intensität -= schieldVal;
     energie -= schieldEVal;
@@ -503,10 +662,12 @@ DeadPlayer *Spieler::sterben()
 
 void Spieler::wiederbelebung()
 {
+    for( auto s = activeSkills->getIterator(); s; s++ )
+        s->reset();
     setPosition( startPos );
     reinkAbk = maxReinkAbk * 2;
-    energie = maxEnergie + zteam->maxEnergie;
-    stabilität = maxStabilität + zteam->maxStabilität;
+    energie = calculateMaxEnergie();
+    stabilität = calculateMaxStabilität();
     schussAbk = 0;
     energieAbk = 0;
     repAbk = 0;
@@ -589,6 +750,8 @@ void Spieler::save()
     last.kills = kills;
     last.tode = tode;
     last.level = level;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+        s->save();
 }
 
 void Spieler::load()
@@ -632,6 +795,8 @@ void Spieler::load()
     kills = last.kills;
     tode = last.tode;
     level = last.level;
+    for( auto s = activeSkills->getIterator(); s; s++ )
+        s->load();
 }
 
 // constant

+ 16 - 0
Asteroids/Spiel/Spieler/Spieler.h

@@ -8,6 +8,7 @@
 #include "../Team/Team.h"
 #include "../Karte/Strukturen.h"
 #include "DeadPlayer.h"
+#include "../Skill/Skill.h"
 
 class Team;
 class Laser;
@@ -80,6 +81,7 @@ private:
         int tode;
         int level;
     };
+    RCArray< ActiveSkill > *activeSkills;
     int level;
     int farbe;
     bool amLeben;
@@ -124,6 +126,18 @@ private:
     float ep;
     float nextSkillEp;
 
+    double calculateBeschleunigung();
+    double calculateReparatur();
+    double calculateLaserIntensität();
+    double calculateLaserEffizienz();
+    double calculateAkkuLeistung();
+    double calculateMaxEnergie();
+    double calculateMaxStabilität();
+    double calculateLaserTempo();
+    double calculateWendigkeit();
+    double calculateAntriebEffizienz();
+    double calculateEnergieSchild();
+    double calculateEnergieSchildEffizienz();
     double calculateLaserCost();
 
 public:
@@ -132,6 +146,8 @@ public:
 	// Destruktor
 	~Spieler();
 	// nicht constant
+    void addSkill( ActiveSkill *skill );
+    void useSkill( int id );
 	void setModelData( Model2DData *data, Animation2DData *zFStart, Animation2DData *zFBurn );
 	void setAccountId( int accId );
 	void setTeam( Team *zTeam );

+ 21 - 5
Asteroids/Spiel/SpielerGUI/SpielerGUI.cpp

@@ -16,12 +16,11 @@ int getStellen( double d )
 
 // Inhalt der Ship Klasse aus Ship.h
 // Konstruktor
-SpielerGUI::SpielerGUI( Schrift *zSchrift )
+SpielerGUI::SpielerGUI( Schrift * zSchrift )
 {
     player = 0;
     ram = new LRahmen();
     ram->setSize( 200, 417 );
-    ram->setPosition( Punkt( BildschirmGröße().x - 210, 10 ) );
     ram->setFarbe( 0xFFFFFFFF );
     spieler = initTextFeld( 5, 5, 190, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
     stabilität = initTextFeld( 5, 30, 165, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
@@ -84,6 +83,7 @@ SpielerGUI::SpielerGUI( Schrift *zSchrift )
     netzwerkSkill->removeStyle( Knopf::Style::Erlaubt );
     skillPoints = initTextFeld( 5, 355, 180, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::VCenter, "" );
     speed = initTextFeld( 5, 380, 180, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::VCenter, "" );
+    renderer = new TextRenderer( zSchrift );
     ref = 1;
 }
 
@@ -123,10 +123,11 @@ SpielerGUI::~SpielerGUI()
     netzwerkSkill->release();
     skillPoints->release();
     speed->release();
+    renderer->release();
 }
 
 // nicht constant
-void SpielerGUI::update( Spieler *zSpieler )
+void SpielerGUI::update( Spieler * zSpieler )
 {
     if( !player )
         player = (Spieler *)zSpieler->getThis();
@@ -283,7 +284,7 @@ void SpielerGUI::update( Spieler *zSpieler )
     skillPoints->setText( Text( zSpieler->skillPunkte ) += " Punkte" );
 }
 
-int SpielerGUI::doMausEreignis( MausEreignis &me )
+int SpielerGUI::doMausEreignis( MausEreignis & me )
 {
     me.mx -= ram->getX();
     me.my -= ram->getY();
@@ -358,8 +359,9 @@ bool SpielerGUI::tick( double tickVal )
     return ret;
 }
 
-void SpielerGUI::render( Bild &zRObj )
+void SpielerGUI::render( Bild & zRObj )
 {
+    ram->setPosition( Punkt( zRObj.getBreite() - 210, 10 ) );
     zRObj.alphaRegion( ram->getX() + 1, ram->getY() + 1, ram->getBreite() - 2, ram->getHeight() - 2, 0xA0000000 );
     ram->render( zRObj );
     if( !zRObj.setDrawOptions( ram->getPosition() + Punkt( 1, 1 ), ram->getSize() - Punkt( 2, 2 ) ) )
@@ -410,6 +412,20 @@ void SpielerGUI::render( Bild &zRObj )
         zRObj.fillRegion( 5, ram->getHeight() - 12, (int)( ( ram->getBreite() - 12 ) * ( player->getEp() / player->getMaxEp() ) ), 5, 0xFFFFFFFF );
     }
     zRObj.releaseDrawOptions();
+    int anz = player->activeSkills->getEintragAnzahl();
+    int x = zRObj.getBreite() - anz * 51 - 1 - 220;
+    int y = zRObj.getHeight() - 56;
+    int index = 0;
+    for( auto s = player->activeSkills->getIterator(); s; s++ )
+    {
+        s->render( x + 1, y + 1, zRObj );
+        zRObj.drawLinieH( x, y, 51, 0xFFFFFFFF );
+        zRObj.drawLinieH( x, y + 55, 51, 0xFFFFFFFF );
+        zRObj.drawLinieV( x, y, 56, 0xFFFFFFFF );
+        zRObj.drawLinieV( x + 51, y, 56, 0xFFFFFFFF );
+        renderer->renderText( x + 3, y + 3, Text( ++index ), zRObj, 0xFFFFFF );
+        x += 51;
+    }
 }
 
 // Reference Counting

+ 1 - 0
Asteroids/Spiel/SpielerGUI/SpielerGUI.h

@@ -44,6 +44,7 @@ private:
 	Knopf *netzwerkSkill;
     TextFeld *skillPoints;
     Spieler *player;
+    TextRenderer *renderer;
 	int ref;
 
 public: