#include "Spieler.h" #include "Team.h" #include "Laser.h" #include "Karte.h" #include "SSKlient.h" #include // Inhalt der Spieler Klasse aus Spieler.h // Konstruktor Spieler::Spieler( SpielerStr *zStr ) : Model2DObject() { activeSkills = new RCArray< ActiveSkill >(); accountId = 0; sNum = zStr->id; farbe = 0; team = 0; klient = 0; level = 1; for( int i = 0; i < T_MAX; i++ ) tastatur[ i ] = 0; amLeben = 1; schussAbk = 0; energieAbk = 0; repAbk = 0; reinkAbk = 0; maxReinkAbk = 5; startPos = zStr->pos; setPosition( startPos ); setDrehung( (float)zStr->rot ); beschleunigung = zStr->beschleunigung; energie = zStr->maxEnergie; stability = zStr->maxStability; reparatur = zStr->reparatur; laserIntensity = zStr->laserIntensity; laserEffizienz = zStr->laserEffizienz; akkuLeistung = zStr->akkuLeistung; maxEnergie = zStr->maxEnergie; maxStability = zStr->maxStability; laserTempo = zStr->laserTempo; netzwerk = zStr->netzwerk; wendigkeit = zStr->wendigkeit; antriebEffizienz = zStr->antriebEffizienz; energieSchild = zStr->energieSchild; energieSchildEffizienz = zStr->energieSchildEffizienz; skillPunkte = zStr->skillPunkte; schadenBekommen = 0; schadenGemacht = 0; treibstoffVerbraucht = 0; shots = 0; treffer = 0; punkte = 0; kills = 0; tode = 0; zeitAmLeben = 0; zeitTod = 0; ep = 0; nextSkillEp = 80; needWiederbelebung = 0; } // Destruktor Spieler::~Spieler() { if( team ) team->release(); if( klient ) klient->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 + team->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 + team->reparatur ) * factor + bonus; } double Spieler::calculateLaserIntensity() { double factor = 1; double bonus = 0; for( auto s = activeSkills->getIterator(); s; s++ ) { factor *= s->getLaserIntensityFactor(); bonus += s->getLaserIntensityBonus(); } return ( laserIntensity + team->laserIntensity ) * 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 + team->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 + team->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 + team->maxEnergie ) * factor + bonus; } double Spieler::calculateMaxStability() { double factor = 1; double bonus = 0; for( auto s = activeSkills->getIterator(); s; s++ ) { factor *= s->getMaxStabilityFactor(); bonus += s->getMaxStabilityBonus(); } return ( maxStability + team->maxStability ) * 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 + team->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 + team->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 + team->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 + team->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 + team->energieSchildEffizienz ) * factor + bonus; } // 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::offline() { klient->offline(); } void Spieler::online( SSKlientV *zKlient ) { klient->online( zKlient ); } void Spieler::setModelData( Model2DData *data ) { for( auto i = data->polygons->getIterator(); i; i++ ) { if( i._.name->istGleich( "engine_l" ) ) { stL = *i._.schwerpunkt; Vertex l, r; for( int j = 0; j < 4; j++ ) { if( i._.tKordinaten->get( j ).y == 1.f ) { if( i._.tKordinaten->get( j ).x == 0.f ) l = i._.vertex->get( j ); if( i._.tKordinaten->get( j ).x == 1.f ) r = i._.vertex->get( j ); } } kL = ( ( l + ( r - l ) * 0.5 ) - stL ); } if( i._.name->istGleich( "engine_r" ) ) { stR = *i._.schwerpunkt; Vertex l, r; for( int j = 0; j < 4; j++ ) { if( i._.tKordinaten->get( j ).y == 1.f ) { if( i._.tKordinaten->get( j ).x == 0.f ) l = i._.vertex->get( j ); if( i._.tKordinaten->get( j ).x == 1.f ) r = i._.vertex->get( j ); } } kR = ( ( l + ( r - l ) * 0.5 ) - stR ); } if( i._.name->istGleich( "engine_m" ) ) { stM = *i._.schwerpunkt; Vertex l, r; for( int j = 0; j < 4; j++ ) { if( i._.tKordinaten->get( j ).y == 1.f ) { if( i._.tKordinaten->get( j ).x == 0.f ) l = i._.vertex->get( j ); if( i._.tKordinaten->get( j ).x == 1.f ) r = i._.vertex->get( j ); } } kM = ( ( l + ( r - l ) * 0.5 ) - stM ); } } kL.normalize(); kR.normalize(); kM.normalize(); setModel( data ); } void Spieler::setAccountId( int id ) { accountId = id; } void Spieler::setTeam( Team *team ) { if( this->team ) this->team->release(); this->team = team; } void Spieler::setSpielerFarbe( int farbe ) { this->farbe = farbe; } void Spieler::setKlient( Klient *klient ) { if( this->klient ) this->klient->release(); this->klient = klient; } bool Spieler::setTastataturStatus( TastaturStatus ts, bool aktiv ) { if( tastatur[ ts ] == aktiv || !amLeben ) return 0; tastatur[ ts ] = aktiv; return 1; } bool Spieler::tick( const WeltInfo& info, double zeit ) { wInfo = info; if( !team ) return 0; reinkAbk -= zeit; if( reinkAbk < 0 ) reinkAbk = 0; if( !reinkAbk && !amLeben ) { // Wiederbelebung needWiederbelebung = 1; return 0; } if( amLeben ) { for( auto s = activeSkills->getIterator(); s; s++ ) s->tick( zeit ); schussAbk -= zeit; energieAbk -= zeit; if( schussAbk < 0 ) schussAbk = 0; if( energieAbk < 0 ) energieAbk = 0; repAbk -= zeit; if( repAbk < 0 ) repAbk = 0; if( tastatur[ T_GAS ] ) { double treibstoff = 0.5 * ( calculateBeschleunigung() / 15 ) * zeit * ( 100 / calculateAntriebEffizienz() ); treibstoffVerbraucht += treibstoff; float factor = 1; if( treibstoff > energie ) factor = (float)( energie / treibstoff ); if( factor > 0 ) impuls( getWorldPos( stM ), getWorldDir( kM ) * (float)zeit * (float)calculateBeschleunigung() * factor ); energie -= treibstoff * factor; } if( tastatur[ T_ROT_R ] ) { double treibstoff = 0.25 * ( calculateWendigkeit() / 15 ) * zeit * ( 100 / calculateAntriebEffizienz() ); treibstoffVerbraucht += treibstoff; float factor = 1; if( treibstoff > energie ) factor = (float)( energie / treibstoff ); if( factor > 0 ) impuls( getWorldPos( stL ), getWorldDir( kL ) * (float)zeit * (float)calculateWendigkeit() * factor ); energie -= treibstoff * factor; } if( tastatur[ T_ROT_L ] ) { double treibstoff = 0.25 * ( calculateWendigkeit() / 15 ) * zeit * ( 100 / calculateAntriebEffizienz() ); treibstoffVerbraucht += treibstoff; float factor = 1; if( treibstoff > energie ) factor = (float)( energie / treibstoff ); if( factor > 0 ) impuls( getWorldPos( stR ), getWorldDir( kR ) * (float)zeit * (float)calculateWendigkeit() * factor ); energie -= treibstoff * factor; } Model2DObject::tick( info, zeit ); if( !energieAbk ) { energie += calculateAkkuLeistung() * zeit; if( energie > calculateMaxEnergie() ) energie = calculateMaxEnergie(); } if( !repAbk ) { stability += calculateReparatur() * zeit; if( stability > calculateMaxStability() ) stability = calculateMaxStability(); } zeitAmLeben += zeit; } else zeitTod += zeit; return 0; } bool Spieler::setSkill( int art ) { if( !skillPunkte ) return 0; skillPunkte--; switch( art ) { case 0: // Max Stabilität maxStability += 10; stability += 10; team->maxStability = team->getMaxStabilityBonus(); break; case 1: // Max Energie maxEnergie += 10; team->maxEnergie = team->getMaxEnergieBonus(); break; case 2: // Reparatur reparatur += 0.15; team->reparatur = team->getReperaturBonus(); break; case 3: // Laser Intensität laserIntensity += 4; team->laserIntensity = team->getLaserIntensityBonus(); break; case 4: // Laser Effizienz laserEffizienz += 1.5; team->laserEffizienz = team->getLaserEffizienzBonus(); break; case 5: // Laser Tempo laserTempo += 15; team->laserTempo = team->getLaserTempoBonus(); break; case 6: // Beschleunigung beschleunigung += 10; team->beschleunigung = team->getBeschleunigungBonus(); break; case 7: // Wendigkeit wendigkeit += 2.5; team->wendigkeit = team->getWendigkeitBonus(); break; case 8: // Netzwerk netzwerk += 1; team->maxStability = team->getMaxStabilityBonus(); team->maxEnergie = team->getMaxEnergieBonus(); team->reparatur = team->getReperaturBonus(); team->laserIntensity = team->getLaserIntensityBonus(); team->laserEffizienz = team->getLaserEffizienzBonus(); team->laserTempo = team->getLaserTempoBonus(); team->beschleunigung = team->getBeschleunigungBonus(); team->wendigkeit = team->getWendigkeitBonus(); team->akkuLeistung = team->getAkkuLeistungBonus(); team->antriebEffizienz = team->getAntriebEffizienzBonus(); team->energieSchild = team->getEnergieSchildBonus(); team->energieSchildEffizienz = team->getEnergieSchildEffizienzBonus(); break; case 9: // Akkuleistung akkuLeistung += 0.12; team->akkuLeistung = team->getAkkuLeistungBonus(); break; case 10: // Akkuleistung antriebEffizienz += 10; team->antriebEffizienz = team->getAntriebEffizienzBonus(); break; case 11: // Energie Schild energieSchild += 0.075; team->energieSchild = team->getEnergieSchildBonus(); break; case 12: // Energie Schild Effizienz energieSchildEffizienz += 10; team->energieSchildEffizienz = team->getEnergieSchildEffizienzBonus(); break; } return 1; } Laser *Spieler::getLaser( int sId ) { if( !amLeben || !tastatur[ T_FEUER ] || schussAbk || !team ) return 0; double kosten = ( calculateLaserIntensity() / 2 + calculateLaserTempo() / 9 ) * ( 1 / ( calculateLaserEffizienz() / 25 ) ); if( kosten < 1 ) kosten = 1; if( kosten > energie ) return 0; energie -= kosten; schussAbk = 1; energieAbk = 1.5; shots++; Vertex sSpeed = ( Vertex( lowPrecisionCos( rotation ), lowPrecisionSin( rotation ) ) * (float)calculateLaserTempo() ); sSpeed += speed; return new Laser( sId, getPosition(), sSpeed, sNum, calculateLaserIntensity() ); } bool Spieler::nimmSchaden( double &intensity, int sLevel ) { 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; schadenBekommen += intensity; energieAbk = 1.5; repAbk = 2; if( stability <= 0 ) { amLeben = 0; setCollision( 0 ); tode++; stability = 0; reinkAbk += maxReinkAbk; maxReinkAbk++; punkte--; } else { float levelFactor = (float)sLevel / (float)level; addEp( ( (float)originalIntens / 20 ) * levelFactor ); } return stability == 0; } void Spieler::machSchaden( double intensity, int sLevel, bool erf ) { schadenGemacht += intensity; addTreffer( (float)intensity, sLevel, erf ); } void Spieler::addKill( int sLevel, bool erf ) { float levelFactor = (float)sLevel / (float)level; if( erf ) addEp( 80 * levelFactor ); kills++; punkte++; maxReinkAbk--; if( maxReinkAbk < 5 ) maxReinkAbk = 5; } void Spieler::addTreffer( float intensity, int sLevel, bool erf ) { treffer++; float levelFactor = (float)sLevel / (float)level; if( erf ) addEp( ( intensity / 10 ) * levelFactor ); } void Spieler::wiederbeleben() { for( auto s = activeSkills->getIterator(); s; s++ ) s->reset(); needWiederbelebung = 0; setPosition( startPos ); reinkAbk = maxReinkAbk * 2; energie = calculateMaxEnergie(); stability = calculateMaxStability(); schussAbk = 0; energieAbk = 0; repAbk = 0; setSpeed( 0, 0 ); setDrehung( 0 ); setDrehungSpeed( 0 ); for( int i = 0; i < T_MAX; i++ ) tastatur[ i ] = 0; amLeben = 1; setCollision( 1 ); } void Spieler::addEp( float ep ) { this->ep += ep; while( this->ep >= nextSkillEp ) { level++; skillPunkte++; this->ep -= nextSkillEp; nextSkillEp *= 1.025f; } } // constant int Spieler::getAccountId() const { return accountId; } bool Spieler::istOnline() const { return klient ? klient->istOnline() : 0; } Klient *Spieler::zKlient() const { return klient; } bool Spieler::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 ) ); } // Raumschiff Eigenschaften double Spieler::getTeamMaxEnergieBonus() const { return maxEnergie / 100 * netzwerk; } double Spieler::getTeamMaxStabilityBonus() const { return maxStability / 100 * netzwerk; } double Spieler::getTeamReparaturBonus() const { return reparatur / 100 * netzwerk; } double Spieler::getTeamLaserIntensityBonus() const { return laserIntensity / 100 * netzwerk; } double Spieler::getTeamLaserEffizienzBonus() const { return laserEffizienz / 100 * netzwerk; } double Spieler::getTeamAkkuLeistungBonus() const { return akkuLeistung / 100 * netzwerk; } double Spieler::getTeamLaserTempoBonus() const { return laserTempo / 100 * netzwerk; } double Spieler::getTeamBeschleunigungBonus() const { return beschleunigung / 100 * netzwerk; } double Spieler::getTeamWendigkeitBonus() const { return wendigkeit / 100 * netzwerk; } double Spieler::getTeamAntriebEffizienzBonus() const { return antriebEffizienz / 100 * netzwerk; } double Spieler::getTeamEnergieSchildBonus() const { return energieSchild / 100 * netzwerk; } double Spieler::getTeamEnergieSchildEffizienzBonus() const { return energieSchildEffizienz / 100 * netzwerk; } bool Spieler::istAmLeben() const { return amLeben; } // Statistik Werte int Spieler::getSpielerNummer() const { return sNum; } Team *Spieler::zTeam() const { return team; } int Spieler::getSpielerFarbe() const { return farbe; } int Spieler::getSchadenBekommen() const { return (int)schadenBekommen; } int Spieler::getSchadenGemacht() const { return (int)schadenGemacht; } int Spieler::getTreibstoffVerbraucht() const { return (int)treibstoffVerbraucht; } int Spieler::getShots() const { return shots; } int Spieler::getTreffer() const { return treffer; } int Spieler::getPunkte() const { return punkte; } int Spieler::getKills() const { return kills; } int Spieler::getTode() const { return tode; } int Spieler::getZeitAmLeben() const { return (int)zeitAmLeben; } int Spieler::getZeitTod() const { return (int)zeitTod; } bool Spieler::doNeedWiederbelebung() const { return needWiederbelebung; } float Spieler::getEp() const { return ep; } int Spieler::getSkillP() const { return skillPunkte; } int Spieler::getLevel() const { return level; } // Reference Counting Spieler *Spieler::getThis() { ref++; return this; } Spieler *Spieler::release() { ref--; if( !ref ) delete this; return 0; }