Prechádzať zdrojové kódy

Objekt eigenschaften im spiel einprogrammiert

Kolja Strohm 5 rokov pred
rodič
commit
f3cc5ad4d1

+ 7 - 2
Asteroids/Karte.cpp

@@ -84,11 +84,11 @@ Team *Karte::createTeam( int tNum ) const
 
 SpielObjekt *Karte::createObjekt( int oNum ) const
 {
-	if( oNum < 0 || oNum > objekte->getEintragAnzahl() )
+	if( oNum <= 0 )
 		return 0;
     for( auto o = objekte->getIterator(); o; o++ )
     {
-        if( o->id == oNum + 1 )
+        if( o->id == oNum )
         {
             SpielObjekt *ret = new SpielObjekt( o );
             for( auto i = ressources->getIterator(); i && i._; i++ )
@@ -102,6 +102,11 @@ SpielObjekt *Karte::createObjekt( int oNum ) const
     return 0;
 }
 
+Iterator< ObjektStr * > Karte::getObjekte() const
+{
+    return objekte->getIterator();
+}
+
 int Karte::getMaxTeamAnzahl() const
 {
 	return sts ? sts->teamAnzahl : 0;

+ 1 - 0
Asteroids/Karte.h

@@ -32,6 +32,7 @@ public:
 	Spieler *createSpieler( int sNum ) const;
 	Team *createTeam( int tNum ) const;
 	SpielObjekt *createObjekt( int oNum ) const;
+    Iterator< ObjektStr * > getObjekte() const;
 	int getMaxTeamAnzahl() const;
 	int getMaxSpielerAnzahl() const;
 	int getObjektAnzahl() const;

+ 30 - 0
Asteroids/Klient.cpp

@@ -197,6 +197,36 @@ void Klient::sendeTreffer( int id, int sNum, int spielZeit, float ep, int skillP
     delete[] bytes;
 }
 
+void Klient::sendeObjektTreffer( int id, int oId, int spielZeit, float ep, int skillP )
+{
+    if( !klient )
+        return;
+    short len = 21;
+    char *bytes = new char[ len ];
+    *(int *)bytes = spielZeit;
+    *(char *)( bytes + 4 ) = 0x16;
+    *(int *)( bytes + 5 ) = id;
+    *(int *)( bytes + 9 ) = oId;
+    *(float *)( bytes + 13 ) = ep;
+    *(int *)( bytes + 17 ) = skillP;
+    klient->spielNachricht( len, bytes );
+    delete[] bytes;
+}
+
+void Klient::sendeObjektTod( int oId, int killSNum, int spielZeit )
+{
+    if( !klient )
+        return;
+    short len = 13;
+    char *bytes = new char[ len ];
+    *(int *)bytes = spielZeit;
+    *(char *)( bytes + 4 ) = 0x17;
+    *(int *)( bytes + 5 ) = oId;
+    *(int *)( bytes + 9 ) = killSNum;
+    klient->spielNachricht( len, bytes );
+    delete[] bytes;
+}
+
 void Klient::sendeAsteroidTreffer( int asteroidId, int newAsteroidId, int schussId, Vertex pos, __int64 seed, int spielZeit, float ep, int skillP )
 {
     if( !klient )

+ 2 - 0
Asteroids/SSKlient.h

@@ -37,6 +37,8 @@ public:
     void sendePixel( int asteroid, int pixelId, int spielZeit );
     void sendeEp( int pixelId, int spielerId, int spielZeit );
 	void sendeTreffer( int id, int sNum, int spielZeit, float ep, int skillP );
+    void sendeObjektTreffer( int id, int oId, int spielZeit, float ep, int skillP );
+    void sendeObjektTod( int oId, int killSNum, int spielZeit );
     void sendeAsteroidTreffer( int asteroidId, int newAsteroidId, int schussId, Vertex pos, __int64 seed, int spielZeit, float ep, int skillP );
 	void sendeWiederbelebung( int sNum, int spielZeit );
 	void sendeTod( int sNum, int killSNum, int spielZeit );

+ 72 - 24
Asteroids/Spiel.cpp

@@ -59,7 +59,11 @@ Spiel::~Spiel()
 {
     teams->release();
     stat->release();
+    for( auto s = spieler->getIterator(); s; s++ )
+        s->setTeam( 0 );
     spieler->release();
+    for( auto o = objekte->getIterator(); o; o++ )
+        o->setTeam( 0 );
     objekte->release();
     welt->release();
     asteroids->release();
@@ -138,12 +142,12 @@ void Spiel::setSpielerNummern( int anzahl, Array< int > * spielerNummern )
         for( int i = 0; i < sts->teamAnzahl; i++ )
             teams->set( karte->createTeam( i ), i );
         stat->setTeamNamen( sts->teamName->getThis() );
-        int objektAnzahl = karte->getObjektAnzahl();
-        for( int i = 0; i < objektAnzahl; i++ )
+        for( auto o = karte->getObjekte(); o; o++ )
         {
-            SpielObjekt *obj = karte->createObjekt( i );
+            SpielObjekt *obj = karte->createObjekt( o->id );
+            obj->setTeam( teams->get( o->team - 1 ) );
             welt->addObject( obj->getThis() );
-            objekte->set( obj, i );
+            objekte->add( obj );
         }
         welt->setSize( karte->getSize().x, karte->getSize().y );
         welt->setSize( 1 );
@@ -279,33 +283,33 @@ void Spiel::nachricht( int accountId, int len, char *bytes )
         }
         break;
     case 9: // Skill verwendung
+    {
+        bytes++;
+        char art = *bytes;
+        len--;
+        for( int i = 0; i < spielerAnzahl; i++ )
         {
-            bytes++;
-            char art = *bytes;
-            len--;
-            for( int i = 0; i < spielerAnzahl; i++ )
+            Spieler *tmp = spieler->z( i );
+            if( tmp && tmp->getAccountId() == accountId )
             {
-                Spieler *tmp = spieler->z( i );
-                if( tmp && tmp->getAccountId() == accountId )
+                if( !tmp->istAmLeben() )
+                    break;
+                if( !tmp->setSkill( art ) )
                 {
-                    if( !tmp->istAmLeben() )
-                        break;
-                    if( !tmp->setSkill( art ) )
-                    {
-                        saveMSG = 0;
-                        break;
-                    }
-                    for( int j = 0; j < spielerAnzahl; j++ )
-                    {
-                        Spieler *s = spieler->z( j );
-                        if( s && s->zKlient() )
-                            s->zKlient()->sendeSkillNachricht( tmp->getSpielerNummer(), art, spielZeit );
-                    }
+                    saveMSG = 0;
                     break;
                 }
+                for( int j = 0; j < spielerAnzahl; j++ )
+                {
+                    Spieler *s = spieler->z( j );
+                    if( s && s->zKlient() )
+                        s->zKlient()->sendeSkillNachricht( tmp->getSpielerNummer(), art, spielZeit );
+                }
+                break;
             }
-            break;
         }
+        break;
+    }
     case 0xA: // Use active skill
     {
         bytes++;
@@ -447,6 +451,50 @@ void Spiel::tick( double zeit )
                         break;
                     }
                 }
+                int objektAnzahl = objekte->getEintragAnzahl();
+                for( int j = 0; j < objektAnzahl; j++ )
+                {
+                    SpielObjekt *attacked = objekte->z( j );
+                    if( attacked && ( !attacked->zTeam() || attacked->zTeam()->id != team ) && attacked->doesCollideWithLaser() && attacked->istTreffer( tmp->getPosition() ) )
+                    { // Treffer
+                        Spieler *attacker = 0;
+                        for( int k = 0; k < spielerAnzahl; k++ )
+                        {
+                            Spieler *tmpS = spieler->z( k );
+                            if( tmpS && tmpS->getSpielerNummer() == tmp->getSpieler() )
+                                attacker = tmpS;
+                        }
+                        double intens = tmp->getIntensity() * ( ( tmp->getSpeed() - attacked->getSpeed() ).getLength() / 200 );
+                        bool kill = attacked->nimmSchaden( intens, attacker ? attacker->getLevel() : 1 );
+                        if( tmp->getSpeed().getLengthSq() > 0 )
+                            attacked->impuls( tmp->getPosition() - tmp->getSpeed(), tmp->getSpeed() * 0.3f );
+                        int skillP = attacker->getSkillP();
+                        attacker->machSchaden( intens, attacked->getLevel(), attacked->doesShotAddEp() );
+                        float erf = attacker->getEp();
+                        if( kill )
+                            attacker->addKill( attacked->getLevel(), attacked->doesShotAddEp() );
+                        for( int k = 0; k < spielerAnzahl; k++ )
+                        {
+                            Spieler *sp = spieler->z( k );
+                            if( sp )
+                                sp->zKlient()->sendeObjektTreffer( tmp->getId(), attacked->getObjektId(), spielZeit, erf, skillP );
+                            if( kill && sp )
+                                sp->zKlient()->sendeObjektTod( attacked->getObjektId(), tmp->getSpieler(), spielZeit );
+                        }
+                        if( kill )
+                        {
+                            if( teams->z( team - 1 ) )
+                                teams->z( team - 1 )->punkte++;
+                            if( teams->z( team - 1 )->punkte == teams->z( team - 1 )->maxPunkte )
+                                ende = 1;
+                        }
+                        welt->removeObject( tmp );
+                        shots->remove( i );
+                        anz--;
+                        i--;
+                        break;
+                    }
+                }
                 int aAnz = asteroids->getEintragAnzahl();
                 for( int j = 0; j < aAnz; j++ )
                 {

+ 133 - 43
Asteroids/SpielObjekt.cpp

@@ -6,67 +6,157 @@
 SpielObjekt::SpielObjekt( ObjektStr *zStr )
     : Model2DObject()
 {
-	id = zStr->id;
-	style = zStr->style;
-	stability = zStr->maxStability;
-	energie = zStr->maxEnergie;
-	maxStability = zStr->maxStability;
-	maxEnergie = zStr->maxEnergie;
-	energieRadius = zStr->energieRadius;
-	reparatur = zStr->reparatur;
-	akkuLeistung = zStr->akkuLeistung;
-	team = 0;
+    id = zStr->id;
+    style = zStr->style;
+    stability = zStr->maxStability;
+    energie = zStr->maxEnergie;
+    maxStability = zStr->maxStability;
+    maxEnergie = zStr->maxEnergie;
+    energieRadius = zStr->energieRadius;
+    reparatur = zStr->reparatur;
+    akkuLeistung = zStr->akkuLeistung;
+    team = 0;
+    amLeben = 1;
+    level = 1;
+    ep = 0;
+    nextSkillEp = 80;
+    setCollision( ( style | 0x4 ) == style );
 }
 
 // Destruktor
 SpielObjekt::~SpielObjekt()
 {
-	if( team )
-		team->release();
+    if( team )
+        team->release();
 }
 
 // nicht constant
+void SpielObjekt::addEp( float ep )
+{
+    this->ep += ep;
+    while( this->ep >= nextSkillEp )
+    {
+        level++;
+        this->ep -= nextSkillEp;
+        nextSkillEp *= 1.025f;
+    }
+}
+
 void SpielObjekt::setTeam( Team *team )
 {
-	if( this->team )
-		this->team->release();
-	this->team = team;
+    if( this->team )
+        this->team->release();
+    this->team = team;
 }
 
 bool SpielObjekt::tick( const WeltInfo &info, double zeit )
 {
-	repAbk -= zeit;
-	if( repAbk < 0 )
-		repAbk = 0;
-	akkuAbk -= zeit;
-	if( akkuAbk < 0 )
-		akkuAbk = 0;
-	if( !repAbk )
-	{
-		stability += reparatur * zeit;
-		if( stability > maxStability )
-			stability = maxStability;
-	}
-	if( !akkuAbk )
-	{
-		if( !team )
-		{
-			energie -= akkuLeistung * zeit;
-			if( energie < 0 )
-				energie = 0;
-		}
-		else
-		{
-			energie += akkuLeistung * zeit;
-			if( energie > maxEnergie )
-				energie = maxEnergie;
-		}
-	}
+    wInfo = info;
+    if( !amLeben )
+        return 0;
+    repAbk -= zeit;
+    if( repAbk < 0 )
+        repAbk = 0;
+    akkuAbk -= zeit;
+    if( akkuAbk < 0 )
+        akkuAbk = 0;
+    if( !repAbk )
+    {
+        stability += reparatur * zeit;
+        if( stability > maxStability )
+            stability = maxStability;
+    }
+    if( !akkuAbk )
+    {
+        if( !team )
+        {
+            energie -= akkuLeistung * zeit;
+            if( energie < 0 )
+                energie = 0;
+        }
+        else
+        {
+            energie += akkuLeistung * zeit;
+            if( energie > maxEnergie )
+                energie = maxEnergie;
+        }
+    }
+    if( ( style | 0x2 ) != style )
+    {
+        speed.x = 0;
+        speed.y = 0;
+        rSpeed = 0;
+    }
     return Model2DObject::tick( info, zeit );
 }
 
+bool SpielObjekt::nimmSchaden( double &intensity, int sLevel )
+{
+    if( ( style | 0x1 ) != style )
+    {
+        intensity = 0;
+        return 0;
+    }
+    double originalIntens = intensity;
+    /*double schieldVal = intensity - intensity / calculateEnergieSchild();
+    double schieldEVal = schieldVal / ( calculateEnergieSchildEffizienz() / 100 );
+    if( schieldEVal > energie )
+    {
+        schieldEVal = energie;
+        schieldVal = schieldEVal * ( calculateEnergieSchildEffizienz() / 100 );
+    }
+    intensity -= schieldVal;
+    energie -= schieldEVal;*/
+    stability -= intensity;
+    akkuAbk = 1.5;
+    repAbk = 2;
+    if( stability <= 0 )
+    {
+        amLeben = 0;
+        setCollision( 0 );
+        stability = 0;
+    }
+    else
+    {
+        float levelFactor = (float)sLevel / (float)level;
+        addEp( ( (float)originalIntens / 20 ) * levelFactor );
+    }
+    return stability == 0;
+}
+
 // constant
+bool SpielObjekt::doesCollideWithLaser() const
+{
+    return ( style | 0x8 ) == style;
+}
+
+bool SpielObjekt::doesShotAddEp() const
+{
+    return ( style | 0x20 ) == style;
+}
+
 Team *SpielObjekt::zTeam() const
 {
-	return team;
+    if( ( style | 0x10 ) == style )
+        return 0;
+    return team;
+}
+
+bool SpielObjekt::istTreffer( Vec2< float > pos ) const
+{
+    if( !amLeben )
+        return 0;
+    return istPunktInnen( pos ) || istPunktInnen( pos + wInfo.size ) || istPunktInnen( pos + Punkt( wInfo.size.x, 0 ) ) || istPunktInnen( pos + Punkt( 0, wInfo.size.y ) ) ||
+        istPunktInnen( pos + -wInfo.size ) || istPunktInnen( pos + Punkt( -wInfo.size.x, 0 ) ) || istPunktInnen( pos + Punkt( 0, -wInfo.size.y ) ) ||
+        istPunktInnen( pos + Punkt( -wInfo.size.x, wInfo.size.y ) ) || istPunktInnen( pos + Punkt( wInfo.size.x, -wInfo.size.y ) );
+}
+
+int SpielObjekt::getLevel() const
+{
+    return level;
+}
+
+int SpielObjekt::getObjektId() const
+{
+    return id;
 }

+ 12 - 0
Asteroids/SpielObjekt.h

@@ -22,6 +22,11 @@ private:
 	double akkuLeistung;
 	double repAbk;
 	double akkuAbk;
+    bool amLeben;
+    int level;
+    float ep;
+    float nextSkillEp;
+    WeltInfo wInfo;
 	Team *team;
 
 public:
@@ -30,10 +35,17 @@ public:
 	// Destruktor
 	~SpielObjekt();
 	// nicht constant
+    void addEp( float ep );
 	void setTeam( Team *team );
 	bool tick( const WeltInfo &info, double zeit ) override;
+    bool nimmSchaden( double &intensity, int sLevel );
 	// constant
+    bool doesCollideWithLaser() const;
+    bool doesShotAddEp() const;
 	Team *zTeam() const;
+    bool istTreffer( Vec2< float > pos ) const;
+    int getLevel() const;
+    int getObjektId() const;
 };
 
 #endif

+ 8 - 6
Asteroids/Spieler.cpp

@@ -538,16 +538,17 @@ bool Spieler::nimmSchaden( double &intensity, int sLevel )
     return stability == 0;
 }
 
-void Spieler::machSchaden( double intensity, int sLevel )
+void Spieler::machSchaden( double intensity, int sLevel, bool erf )
 {
     schadenGemacht += intensity;
-    addTreffer( (float)intensity, sLevel );
+    addTreffer( (float)intensity, sLevel, erf );
 }
 
-void Spieler::addKill( int sLevel )
+void Spieler::addKill( int sLevel, bool erf )
 {
     float levelFactor = (float)sLevel / (float)level;
-    addEp( 80 * levelFactor );
+    if( erf )
+        addEp( 80 * levelFactor );
     kills++;
     punkte++;
     maxReinkAbk--;
@@ -555,11 +556,12 @@ void Spieler::addKill( int sLevel )
         maxReinkAbk = 5;
 }
 
-void Spieler::addTreffer( float intensity, int sLevel )
+void Spieler::addTreffer( float intensity, int sLevel, bool erf )
 {
     treffer++;
     float levelFactor = (float)sLevel / (float)level;
-    addEp( ( intensity / 10 ) * levelFactor );
+    if( erf )
+        addEp( ( intensity / 10 ) * levelFactor );
 }
 
 void Spieler::wiederbeleben()

+ 3 - 3
Asteroids/Spieler.h

@@ -115,9 +115,9 @@ public:
 	bool setSkill( int art );
 	Laser *getLaser( int sId );
 	bool nimmSchaden( double &intensity, int sLevel );
-	void machSchaden( double intensity, int sLevel );
-    void addKill( int sLevel );
-    void addTreffer( float intensity, int sLevel );
+	void machSchaden( double intensity, int sLevel, bool erf = 1 );
+    void addKill( int sLevel, bool erf = 1 );
+    void addTreffer( float intensity, int sLevel, bool erf = 1 );
     void wiederbeleben();
     void addEp( float ep );
 	// constant