#include "Spieler.h" #include "../../Initialisierung/Initialisierung.h" #include "../Karte/Karte.h" #include "../Define.h" #include #include "../Schuss/Laser.h" // Inhalt der Spieler Klasse aus Spieler.h // Konstruktor Spieler::Spieler( KSGClient::InformationServerClient *zInfoK, Schrift *zSchrift, SpielerStr *zStr ) : Model2DObject() { deadPlayer = 0; accountId = 0; sNum = zStr->id; farbe = 0; team = 0; info = zInfoK->getThis(); name = 0; 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; stabilität = zStr->maxStabilität; reparatur = zStr->reparatur; laserIntensität = zStr->laserIntensität; laserEffizienz = zStr->laserEffizienz; akkuLeistung = zStr->akkuLeistung; maxEnergie = zStr->maxEnergie; maxStabilität = zStr->maxStabilität; 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; schüsse = 0; treffer = 0; punkte = 0; kills = 0; tode = 0; zeitAmLeben = 0; zeitTod = 0; nText = initTextFeld( 0, 0, 152, 30, zSchrift, TextFeld::Style::Text | TextFeld::Style::Rahmen | TextFeld::Style::Center | TextFeld::Style::Hintergrund | TextFeld::Style::HAlpha, "" ); ep = 0; nextSkillEp = 80; save(); } // Destruktor Spieler::~Spieler() { info->release(); if( team ) team->release(); if( name ) name->release(); flammenL->release(); flammenR->release(); flammenM->release(); nText->release(); if( deadPlayer ) deadPlayer->release(); } double Spieler::calculateLaserCost() { double kosten = ( ( laserIntensität + team->laserIntensität ) / 2 + ( laserTempo + team->laserTempo ) / 9 ) * ( 1 / ( ( laserEffizienz + team->laserEffizienz ) / 25 ) ); if( kosten < 1 ) kosten = 1; return kosten; } // nicht constant void Spieler::setModelData( Model2DData * data, Animation2DData * zFStart, Animation2DData * zFBurn ) { 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 ); flammenM = new Textur2D(); flammenM->addAnimationZ( zFStart->getThis() ); flammenM->addAnimationZ( zFBurn->getThis() ); flammenL = new Textur2D(); flammenL->addAnimationZ( zFStart->getThis() ); flammenL->addAnimationZ( zFBurn->getThis() ); flammenR = new Textur2D(); flammenR->addAnimationZ( zFStart->getThis() ); flammenR->addAnimationZ( zFBurn->getThis() ); setTextur( flammenL->getThis(), "engine_l" ); setTextur( flammenR->getThis(), "engine_r" ); setTextur( flammenM->getThis(), "engine_m" ); } void Spieler::setAccountId( int accId ) { accountId = accId; name = info->getSpielerName( accountId ); if( name ) nText->setText( *name ); } void Spieler::setTeam( Team * team ) { if( this->team ) this->team->release(); this->team = team; nText->setHintergrundFarbe( 0xA0000000 | ( team->farbe & 0x00FFFFFF ) ); nText->setRahmenFarbe( team->farbe ); } void Spieler::setSpielerFarbe( int fc, Bild * zTextur ) { farbe = fc; nText->setSchriftFarbe( fc ); Bild *shb = new Bild(); shb->neuBild( zTextur->getBreite(), zTextur->getHeight(), 0 ); int maxP = shb->getBreite() * shb->getHeight(); int *buffer = zTextur->getBuffer(); for( int i = 0; i < maxP; i++ ) { if( buffer[ i ] ) { shb->setPixelDP( i, fc ); shb->alphaPixelDP2D( i, buffer[ i ] ); } } Textur2D *textur = new Textur2D(); textur->setTexturZ( shb ); setTextur( textur, "ship" ); } void Spieler::setTastataturStatus( TastaturStatus ts, bool aktiv ) { if( !amLeben ) { tastatur[ ts ] = aktiv; return; } tastatur[ ts ] = aktiv; if( flammenM && flammenR && flammenL ) { switch( ts ) { case T_GAS: if( aktiv ) flammenM->setAnimation( 0 ); else flammenM->setAnimation( -1 ); break; case T_ROT_L: if( aktiv ) flammenR->setAnimation( 0 ); else flammenR->setAnimation( -1 ); break; case T_ROT_R: if( aktiv ) flammenL->setAnimation( 0 ); else flammenL->setAnimation( -1 ); break; } } } bool Spieler::tick( const WeltInfo & info, double tv ) { bool ret = 0; if( !team ) return 0; tv = TICK; reinkAbk -= tv; if( reinkAbk < 0 ) reinkAbk = 0; flammenM->tick( tv ); flammenL->tick( tv ); flammenR->tick( tv ); if( amLeben ) { schussAbk -= tv; energieAbk -= tv; if( schussAbk < 0 ) schussAbk = 0; if( energieAbk < 0 ) energieAbk = 0; repAbk -= tv; if( repAbk < 0 ) repAbk = 0; if( tastatur[ T_GAS ] ) { double treibstoff = 0.5 * ( ( beschleunigung + team->beschleunigung ) / 15 ) * tv * ( 100 / ( antriebEffizienz + team->antriebEffizienz ) ); treibstoffVerbraucht += treibstoff; float factor = 1; if( treibstoff > energie ) factor = (float)( energie / treibstoff ); if( factor > 0 ) impuls( getWorldPos( stM ), getWorldDir( kM ) * (float)tv * (float)( beschleunigung + team->beschleunigung ) * factor ); energie -= treibstoff * factor; } if( tastatur[ T_ROT_R ] ) { double treibstoff = 0.25 * ( ( wendigkeit + team->wendigkeit ) / 15 ) * tv * ( 100 / ( antriebEffizienz + team->antriebEffizienz ) ); treibstoffVerbraucht += treibstoff; float factor = 1; if( treibstoff > energie ) factor = (float)( energie / treibstoff ); if( factor > 0 ) impuls( getWorldPos( stL ), getWorldDir( kL ) * (float)tv * (float)( wendigkeit + team->wendigkeit ) * factor ); energie -= treibstoff * factor; } if( tastatur[ T_ROT_L ] ) { double treibstoff = 0.25 * ( ( wendigkeit + team->wendigkeit ) / 15 ) * tv * ( 100 / ( antriebEffizienz + team->antriebEffizienz ) ); treibstoffVerbraucht += treibstoff; float factor = 1; if( treibstoff > energie ) factor = (float)( energie / treibstoff ); if( factor > 0 ) impuls( getWorldPos( stR ), getWorldDir( kR ) * (float)tv * (float)( wendigkeit + team->wendigkeit ) * factor ); energie -= treibstoff * factor; } __super::tick( info, tv ); if( !energieAbk ) { if( energie != ( maxEnergie + team->maxEnergie ) ) ret = 1; energie += ( akkuLeistung + team->akkuLeistung ) * tv; if( energie > ( maxEnergie + team->maxEnergie ) ) energie = ( maxEnergie + team->maxEnergie ); } if( !repAbk ) { if( stabilität != ( maxStabilität + team->maxStabilität ) ) ret = 1; stabilität += ( reparatur + team->reparatur ) * tv; if( stabilität > ( maxStabilität + team->maxStabilität ) ) stabilität = ( maxStabilität + team->maxStabilität ); } zeitAmLeben += tv; } else zeitTod += tv; return ret; } void Spieler::render( Mat3< float > & kamMat, Bild & zRObj, const char *kamName ) { if( !amLeben ) return; __super::render( kamMat, zRObj, kamName ); if( Text( "minimap" ).istGleich( kamName ) ) return; renderLeben( kamMat, zRObj ); } void Spieler::renderLeben( const Mat3< float > & kamMat, Bild & zRObj ) { if( !team || !amLeben ) return; nText->setPosition( (Punkt)( kamMat * getPosition() - Vertex( 76, ( zModel()->maxP.y * getSize() ) + 30 ) ) ); nText->render( zRObj ); zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 4, 150, team->farbe ); zRObj.drawLinieH( nText->getX() + 1, nText->getY() + 25, 150, team->farbe ); int l = (int)( stabilität * 100 / ( maxStabilität + team->maxStabilitä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 + team->maxEnergie ) * 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 + team->maxEnergie ) * 1.5 + 0.5 ); if( e2 > 0 ) { zRObj.drawLinieV( nText->getX() + e2, nText->getY() + 26, 3, 0xFFFFFFFF ); zRObj.drawLinieV( nText->getX() + e2 + 1, nText->getY() + 26, 3, 0xFFFFFFFF ); } } void Spieler::setSkill( int art ) { skillPunkte--; switch( art ) { case 0: // Max Stabilität maxStabilität += 10; stabilität += 10; team->maxStabilität = team->getMaxStabilitätBonus(); 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 laserIntensität += 4; team->laserIntensität = team->getLaserIntensitätBonus(); 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->maxStabilität = team->getMaxStabilitätBonus(); team->maxEnergie = team->getMaxEnergieBonus(); team->reparatur = team->getReperaturBonus(); team->laserIntensität = team->getLaserIntensitätBonus(); 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: // Antrieb Effizienz 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; } } void Spieler::nimmSchaden( double &intensität ) { double schieldVal = intensität - intensität / ( energieSchild + team->energieSchild ); double schieldEVal = schieldVal / ( ( energieSchildEffizienz + team->energieSchildEffizienz ) / 100 ); if( schieldEVal > energie ) { schieldEVal = energie; schieldVal = schieldEVal * ( ( energieSchildEffizienz + team->energieSchildEffizienz ) / 100 ); } intensität -= schieldVal; energie -= schieldEVal; stabilität -= intensität; schadenBekommen += intensität; energieAbk = 1.5; repAbk = 2; } void Spieler::calcDeadPlayerObject( Laser * zSchuss ) { Vertex hp; Polygon2D a; Polygon2D b; Punkt pa; Punkt pb; if( calcHitPoint( zSchuss->getPosition() - zSchuss->getSpeed(), zSchuss->getSpeed(), hp ) ) { zModel()->split( getObjectPos( hp ), getObjectDir( zSchuss->getSpeed() ) * 0.1f, "ship", a, b, pa, pb, []() { return rand() / (double)RAND_MAX; } ); hp = ( hp * getSize() ).rotation( getDrehung() ) + getPosition(); pa = pa.rotation( getDrehung() ) + getPosition(); pb = pb.rotation( getDrehung() ) + getPosition(); Array< Polygon2D > *npaA = new Array< Polygon2D >(); npaA->add( a ); Model2DData *npdA = new Model2DData(); npdA->erstelleModell( npaA ); Array< Polygon2D > *npaB = new Array< Polygon2D >(); npaB->add( b ); Model2DData *npdB = new Model2DData(); npdB->erstelleModell( npaB ); if( deadPlayer ) deadPlayer->release(); deadPlayer = new DeadPlayer( npdA, npdB, pa, pb, getSpeed() * ( rand() / (float)RAND_MAX ), getSpeed() * ( rand() / (float)RAND_MAX ), getDrehung(), getDrehung(), getDrehungSpeed() * ( rand() / (float)RAND_MAX ), getDrehungSpeed() * ( rand() / (float)RAND_MAX ), zTextur( "ship" ) ); } } void Spieler::machSchaden( double intensität ) { schadenGemacht += intensität; addTreffer( (float)intensität ); } void Spieler::addKill() { kills++; punkte++; skillPunkte += 2; maxReinkAbk--; if( maxReinkAbk < 5 ) maxReinkAbk = 5; } DeadPlayer *Spieler::sterben() { amLeben = 0; setCollision( 0 ); tode++; stabilität = 0; reinkAbk += maxReinkAbk; maxReinkAbk++; punkte--; return deadPlayer ? (DeadPlayer *)deadPlayer->getThis() : 0; } void Spieler::wiederbelebung() { setPosition( startPos ); reinkAbk = maxReinkAbk * 2; energie = maxEnergie + team->maxEnergie; stabilität = maxStabilität + team->maxStabilität; schussAbk = 0; energieAbk = 0; repAbk = 0; setSpeed( 0, 0 ); setDrehung( 0 ); setDrehungSpeed( 0 ); for( int i = 0; i < T_MAX; i++ ) tastatur[ i ] = 0; flammenM->setAnimation( -1 ); flammenL->setAnimation( -1 ); flammenR->setAnimation( -1 ); amLeben = 1; setCollision( 1 ); } void Spieler::hatGeschossen() { energie -= calculateLaserCost(); schussAbk = 1; energieAbk = 1.5; schüsse++; } void Spieler::addTreffer( float indens ) { treffer++; addEp( indens / 10 ); } void Spieler::addEp( float ep ) { this->ep += ep; while( this->ep >= nextSkillEp ) { skillPunkte++; this->ep -= nextSkillEp; nextSkillEp *= 1.025f; } } void Spieler::save() { last.rSpeed = getDrehungSpeed(); last.pos = getPosition(); last.speed = getSpeed(); last.rotation = getDrehung(); last.farbe = farbe; last.amLeben = amLeben; last.schussAbk = schussAbk; last.energieAbk = energieAbk; last.repAbk = repAbk; last.reinkAbk = reinkAbk; last.maxReinkAbk = maxReinkAbk; last.startPos = startPos; last.beschleunigung = beschleunigung; last.energie = energie; last.stabilität = stabilität; last.reparatur = reparatur; last.laserIntensität = laserIntensität; last.laserEffizienz = laserEffizienz; last.akkuLeistung = akkuLeistung; last.maxEnergie = maxEnergie; last.maxStabilität = maxStabilität; last.laserTempo = laserTempo; last.netzwerk = netzwerk; last.wendigkeit = wendigkeit; last.antriebEffizienz = antriebEffizienz; last.energieSchild = energieSchild; last.energieSchildEffizienz = energieSchildEffizienz; last.zeitAmLeben = zeitAmLeben; last.zeitTod = zeitTod; last.schadenBekommen = schadenBekommen; last.schadenGemacht = schadenGemacht; last.treibstoffVerbraucht = treibstoffVerbraucht; last.schüsse = schüsse; last.treffer = treffer; last.punkte = punkte; last.kills = kills; last.tode = tode; } void Spieler::load() { setDrehungSpeed( last.rSpeed ); setPosition( last.pos ); setSpeed( last.speed ); setDrehung( last.rotation ); farbe = last.farbe; amLeben = last.amLeben; setCollision( amLeben ); schussAbk = last.schussAbk; energieAbk = last.energieAbk; repAbk = last.repAbk; reinkAbk = last.reinkAbk; maxReinkAbk = last.maxReinkAbk; startPos = last.startPos; beschleunigung = last.beschleunigung; energie = last.energie; stabilität = last.stabilität; reparatur = last.reparatur; laserIntensität = last.laserIntensität; laserEffizienz = last.laserEffizienz; akkuLeistung = last.akkuLeistung; maxEnergie = last.maxEnergie; maxStabilität = last.maxStabilität; laserTempo = last.laserTempo; netzwerk = last.netzwerk; wendigkeit = last.wendigkeit; antriebEffizienz = last.antriebEffizienz; energieSchild = last.energieSchild; energieSchildEffizienz = last.energieSchildEffizienz; zeitAmLeben = last.zeitAmLeben; zeitTod = last.zeitTod; schadenBekommen = last.schadenBekommen; schadenGemacht = last.schadenGemacht; treibstoffVerbraucht = last.treibstoffVerbraucht; schüsse = last.schüsse; treffer = last.treffer; punkte = last.punkte; kills = last.kills; tode = last.tode; } // constant float Spieler::getEp() const { return ep; } float Spieler::getMaxEp() const { return nextSkillEp; } int Spieler::getAccountId() const { return accountId; } Text *Spieler::getName() const { return name ? name->getThis() : 0; } Text *Spieler::zName() const { return name; } bool Spieler::hatSkill() const { return skillPunkte != 0; } 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::getSchüsse() const { return schüsse; } 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; } double Spieler::getTeamMaxEnergieBonus() const { return maxEnergie / 100 * netzwerk; } double Spieler::getTeamMaxStabilitätBonus() const { return maxStabilität / 100 * netzwerk; } double Spieler::getTeamReparaturBonus() const { return reparatur / 100 * netzwerk; } double Spieler::getTeamLaserIntensitätBonus() const { return laserIntensität / 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; } int Spieler::getSkillP() const { return skillPunkte; }