123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- #include "SpaceShip.h"
- struct Actor
- {
- Uint16 idY;
- Uint16 idX;
- };
- struct Laser
- {
- Uint16 idY;
- Uint16 idX;
- Uint8 r;
- Uint8 g;
- Uint8 b;
- Uint8 a;
- };
- SpaceShip::SpaceShip()
- :m_heartX(0), m_heartY(0), m_ally( false ),
- m_pos( {1100, 300, 42, 42} ),
- m_shH(0), m_shW(0), m_shape(0x0), m_solid(0x0),
- m_hiter(0x0),
- m_shieldLeft(0), m_shieldMax(0), m_shieldLast(0), m_shieldDelay(SHIELD_MAX_DELAY)
- {
- for ( int i(0); i < SHOT_NB; i++ )
- m_loading[i] = 0;
- }
- SpaceShip::SpaceShip( bool ally )
- :m_heartX(0), m_heartY(0), m_ally( ally ),
- m_pos( {1100, 300, 42, 42} ),
- m_shH(0), m_shW(0), m_shape(0x0), m_solid(0x0),
- m_hiter(0x0),
- m_shieldLeft(0), m_shieldMax(0), m_shieldLast(0), m_shieldDelay(SHIELD_MAX_DELAY)
- {
- //ctor ally setter
- }
- SpaceShip::~SpaceShip()
- {
- destroyTabs();
- }
- void SpaceShip::giveHitManager( HitManager* theHitManager )
- {
- m_hiter = theHitManager;
- }
- void SpaceShip::setPos( Sint16 x, Sint16 y )
- {
- m_pos.x = x;
- m_pos.y = y;
- }
- SDL_Rect* SpaceShip::getPos()
- {
- return &m_pos;
- }
- SDL_Rect SpaceShip::getHeartPos()
- {
- SDL_Rect rep;
- rep.x = m_pos.x + 8 * m_heartX + 4;
- rep.y = m_pos.y + 8 * m_heartY + 4;
- return rep;
- }
- bool SpaceShip::getIsAlive()
- {
- return m_solid[m_heartY][m_heartX] > 0;
- }
- SDL_Rect* SpaceShip::getHitBox()
- {
- return &m_pos;
- }
- void SpaceShip::loadShape( std::string path )
- {
- /// Reinitialisation
- // Déstruction structure et modèle
- destroyTabs();
- // Initialisation des dimensions
- m_shH = 0;
- m_shW = 0;
- m_heartY = 0;
- m_heartX = 0;
- // Initialisation du bouclier
- m_shieldLeft = 0;
- m_shieldMax = 0;
- m_shieldLast = 0;
- m_shieldDelay = SHIELD_MAX_DELAY;
- /// Lecture du fichier
- // Création du flux
- std::ifstream flux( path.c_str() );
- // Lecture du modèle
- std::queue<std::string> tempo ;
- std::string line ;
- while ( std::getline(flux, line) )
- {
- tempo.push( line );
- if ( line.length() > m_shW )
- m_shW = line.length();
- }
- /// Ecriture du shape ET du solid
- // Dimensions du vaisseau
- m_shH = tempo.size();
- m_pos.h = 8 * m_shH ;
- m_pos.w = 8 * m_shW ;
- // Création des tableaux statiques
- m_shape = new char*[ m_shH ];
- for ( int i(0); i < m_shH; i ++ )
- m_shape[i] = new char[ m_shW ];
- m_solid = new Uint8*[ m_shH ];
- for ( int i(0); i < m_shH; i ++ )
- m_solid[i] = new Uint8[ m_shW ];
- // Lecture des caractères
- for ( int i(0); i < m_shH; i++ )
- {
- line = tempo.front();
- for ( unsigned int j(0); j < m_shW; j++ )
- {
- if ( j < line.length() && line[j] != ' ' ) {
- // Présence d'une pièce
- m_shape[i][j] = line.c_str()[j];
- m_solid[i][j] = 255;
- // Détection du cœur
- if ( m_shape[i][j] == 'm' ){
- m_heartY = i;
- m_heartX = j;
- }
- }
- else {
- // Pas de bloc à cet endroit
- m_shape[i][j] = ' ';
- m_solid[i][j] = 0;
- }
- }
- tempo.pop();
- }
- /// Détection des actionneurs
- for ( int i(0); i < m_shH; i++ )
- {
- for ( unsigned int j(0); j < m_shW - 1; j++ )
- {
- // Détection d'une arme
- if ( m_shape[i][j] == '[' )
- {
- switch ( m_shape[i][j + 1] )
- {
- case '-':
- m_act[GUN_ID].push_back( { i, j + 1} );
- break;
- case '<':
- m_act[DISPER_ID].push_back( { i, j + 1} );
- break;
- case '|':
- m_act[CUTTER_ID].push_back( { i, j + 1} );
- break;
- case 'O':
- m_act[PHOTO_ID].push_back( { i, j + 1} );
- break;
- case '>':
- m_act[MISSILE_ID].push_back( { i, j + 1} );
- break;
- case '{':
- m_act[BREXIT_ID].push_back( { i, j + 1} );
- break;
- case '~':
- m_act[HECTO_ID].push_back( { i, j + 1} );
- break;
- case '=':
- m_act[SNIPER_ID].push_back( { i, j + 1} );
- break;
- default :
- break;
- }
- }
- // Détection d'un bouclier
- else if ( m_shape[i][j] == '(' && m_shape[i][j+1] == ')' )
- {
- m_shieldMax += SHIELD_1_EARN_HP;
- m_shieldLeft += SHIELD_1_EARN_HP;
- m_shieldDelay -= SHIELD_1_EARN_DELAY;
- m_shields.push_back( { i, j } );
- // Blocage du délai minimal
- if ( m_shieldDelay < SHIELD_MIN_DELAY )
- m_shieldDelay = SHIELD_MIN_DELAY;
- }
- // Détection d'un pointeur
- else if ( j < m_shW - 2 && m_shape[i][j] == '{' && m_shape[i][j+2] == '}' )
- {
- // Couleur
- Uint8 r(0), g(0), b(0);
- if ( m_shape[i][j+1] == 'y' )
- {
- b = 255;
- g = 255;
- }
- else if ( m_shape[i][j+1] == 'r' )
- {
- r = 255;
- }
- else if ( m_shape[i][j+1] == 'g' )
- {
- g = 255;
- }
- else if ( m_shape[i][j+1] == 'b' )
- {
- b = 255;
- }
- else
- {
- r = g = b = 255;
- }
- // Ajout du pointeur
- m_lasers.push_back( { i, j + 1, r, g, b, 128 } );
- }
- }
- }
- /// Inversion du vaisseau si il est allié
- if ( m_ally ){
- char sw_c;
- Uint8 sw_s;
- // Inversion des composants
- for ( unsigned int i(0); i < m_shH; i++ ) {
- for ( unsigned int j(0); j < m_shW / 2; j++ ) {
- sw_c = m_shape[i][j];
- m_shape[i][j] = m_shape[i][m_shW - j - 1];
- m_shape[i][m_shW - j - 1] = sw_c;
- sw_s = m_solid[i][j];
- m_solid[i][j] = m_solid[i][m_shW - j - 1];
- m_solid[i][m_shW - j - 1] = sw_s;
- }
- }
- // Inversion du cockpit
- m_heartX = m_shW - m_heartX - 1;
- // Inversion des armes
- for ( unsigned int i(0); i < SHOT_NB; i++) {
- for ( unsigned int k(0); k < m_act[i].size(); k++ ){
- m_act[i][k].idX = m_shW - 1 - m_act[i][k].idX;
- }
- }
- // Inversion des boucliers
- for ( unsigned int k(0); k < m_shields.size(); k++ ){
- m_shields[k].idX = m_shW - 1 - m_shields[k].idX;
- }
- // Inversion des boucliers
- for ( unsigned int k(0); k < m_lasers.size(); k++ ){
- m_lasers[k].idX = m_shW - 1 - m_lasers[k].idX;
- }
- // Traitement des caractères orientés
- for ( unsigned int i(0); i < m_shH; i++ ) {
- for ( unsigned int j(0); j < m_shW; j++ ) {
- switch ( m_shape[i][j] ){
- case '<':
- m_shape[i][j] = '>';
- break;
- case '>':
- m_shape[i][j] = '<';
- break;
- case ']':
- m_shape[i][j] = '[';
- break;
- case '[':
- m_shape[i][j] = ']';
- break;
- case ')':
- m_shape[i][j] = '(';
- break;
- case '(':
- m_shape[i][j] = ')';
- break;
- case '}':
- m_shape[i][j] = '{';
- break;
- case '{':
- m_shape[i][j] = '}';
- break;
- case '/':
- m_shape[i][j] = '\\';
- break;
- case '\\':
- m_shape[i][j] = '/';
- break;
- default :
- break;
- }
- }
- }
- }
- }
- Uint32 SpaceShip::countCPU()
- {
- Uint32 c( 0 );
- // CPU des blocs
- for ( unsigned int i(0); i < m_shH; i++ )
- {
- for ( unsigned int j(0); j < m_shW; j++ )
- {
- if ( m_shape[i][j] != ' ' )
- c += PART_CPU;
- }
- }
- // CPU des armes
- Uint32 weapCpu[SHOT_NB] = ACTOR_CPU;
- for ( unsigned int i(1); i < SHOT_NB; i++ )
- {
- c += m_act[i].size() * weapCpu[i];
- }
- // CPU des boucliers
- c += SHIELD_CPU * m_shields.size();
- // Fin
- return c;
- }
- bool SpaceShip::hasShield()
- {
- return m_shields.size() > 0;
- }
- bool SpaceShip::hasWeapon( int weapId )
- {
- return m_act[ weapId ].size() > 0;
- }
- void SpaceShip::draw( SDL_Surface* screen )
- {
- // N'affiche rien si déjà mort
- if ( !getIsAlive() )
- return ;
- // Enveloppe du bouclier
- Uint8 shieldLvl(128);
- if ( m_shieldLeft > 0 )
- {
- shieldLvl = m_shieldLeft * 255 / m_shieldMax ;
- for ( int i(-2); i < m_shH + 2; i++ )
- {
- stringRGBA( screen, m_pos.x - 16, m_pos.y + 8 * i, "+", 0, shieldLvl, shieldLvl, 255 );
- stringRGBA( screen, m_pos.x + m_pos.w + 8, m_pos.y + 8 * i, "+", 0, shieldLvl, shieldLvl, 255 );
- }
- for ( int j(-1); j <= m_shW; j++ )
- {
- stringRGBA( screen, m_pos.x + 8 * j, m_pos.y - 16, "+", 0, shieldLvl, shieldLvl, 255 );
- stringRGBA( screen, m_pos.x + 8 * j, m_pos.y + m_pos.h + 8, "+", 0, shieldLvl, shieldLvl, 255 );
- }
- }
- // Balayae du carénage
- for ( int i(0); i < m_shH; i++ )
- {
- for ( int j(0); j < m_shW; j++ )
- {
- // Existence d'une pièce
- if ( m_solid[i][j] > 0 )
- {
- char s[2];
- s[0] = m_shape[i][j];
- s[1] = 0;
- // Energie de bouclier disponible
- if ( m_shieldLeft > 0 )
- {
- stringRGBA( screen, m_pos.x + 8 * j, m_pos.y + 8 * i, s, 255 - shieldLvl, m_solid[i][j], shieldLvl, 255 );
- }
- // Affichage basique
- else
- stringRGBA( screen, m_pos.x + 8 * j, m_pos.y + 8 * i, s, 255, m_solid[i][j], m_solid[i][j], 255 );
- }
- }
- }
- // Affichage des pointeurs
- Sint16 u, v, c;
- for ( unsigned int i(0); i < m_lasers.size(); i ++ )
- {
- u = m_lasers[i].idX * 8 + m_pos.x - 9;
- v = m_lasers[i].idY * 8 + m_pos.y;
- while ( u > -8 )
- {
- stringRGBA( screen, u, v, "-", m_lasers[i].r, m_lasers[i].g, m_lasers[i].b, m_lasers[i].a );
- u -= 36;
- }
- }
- }
- void SpaceShip::fire( int weapId )
- {
- if ( ( SDL_GetTicks() - m_loading[weapId] ) > m_hiter->getDecay( weapId ) )
- {
- for ( unsigned int k(0); k < m_act[weapId].size(); k++ )
- {
- if ( m_solid[ m_act[weapId][k].idY ][ m_act[weapId][k].idX ] > 0 )
- {
- m_hiter->triggerWeapon( weapId, m_pos.x + 8*m_act[weapId][k].idX + 4, m_pos.y + 8*m_act[weapId][k].idY + 4, m_ally );
- }
- }
- m_loading[weapId] = SDL_GetTicks();
- }
- }
- void SpaceShip::update()
- {
- // Si le vaisseau n'est plus existant, alors rien n'existe
- if ( !getIsAlive() )
- return ;
- // S'il reste du bouclier, il peut absorber les dégats !
- if ( m_shieldLeft > 0 )
- {
- Sint32 deg( m_hiter->absorb( m_ally, m_shH, m_shW, m_pos ) );
- if ( deg > 0 )
- {
- // La recharge du bouclier est retardée
- m_shieldLast = SDL_GetTicks();
- // Le bouclier en prend un coup
- if ( deg > m_shieldLeft )
- m_shieldLeft = 0;
- else
- m_shieldLeft -= deg;
- }
- }
- // S'il reste un carénage, il peut subir des dégâts !
- else if ( m_hiter->colide( m_ally, m_solid, m_shH, m_shW, m_pos ) )
- {
- // La recharge du bouclier est retardée
- m_shieldLast = SDL_GetTicks();
- // Peut être que certains blocs ne sont plus attachés au vaisseau !
- integrity();
- // Certains boucliers sont peut être hors service !
- if ( m_shieldMax > 0 )
- resetShields();
- }
- // Recharge éventuelle du bouclier
- if ( m_shieldLeft < m_shieldMax && ( SDL_GetTicks() - m_shieldLast > m_shieldDelay ) )
- {
- m_shieldLeft += SHIELD_REGEN ;
- if ( m_shieldLeft > m_shieldMax ) m_shieldLeft = m_shieldMax ;
- }
- }
- void SpaceShip::destroyTabs()
- {
- // Destruction du modèle graphic
- if ( m_shape != 0x0 )
- {
- for ( int i(0); i < m_shH; i++ ) {
- delete[] m_shape[i];
- m_shape[i] = 0x0;
- }
- delete[] m_shape;
- m_shape = 0x0;
- }
- // Destruction de la carte du blindage
- if ( m_solid != 0x0 )
- {
- for ( int i(0); i < m_shH; i++ ) {
- delete[] m_solid[i];
- m_solid[i] = 0x0;
- }
- delete[] m_solid;
- m_solid = 0x0;
- }
- // Destruction des armes
- for ( unsigned int i(0); i < SHOT_NB; i++ )
- {
- m_act[i].clear();
- }
- // Destruction du bouclier
- m_shields.clear();
- // Destruction des pointeurs
- m_lasers.clear();
- }
- void SpaceShip::integrity()
- {
- // Création du tableau des liens
- Sint8 network[ m_shH ][ m_shW ];
- for ( int i(0); i < m_shH; i++ )
- {
- for ( int j(0); j < m_shW; j++ )
- {
- network[i][j] = -1;
- }
- }
- // Création du réseau
- if ( getIsAlive() )
- {
- network[ m_heartY ][ m_heartX ] = 1;
- std::queue<Actor> q; // Couples à tester
- Uint16 y, x;
- if ( m_heartY > 0 ) q.push( { m_heartY - 1, m_heartX } );
- if ( m_heartX > 0 ) q.push( { m_heartY, m_heartX - 1 } );
- if ( m_heartY + 1 < m_shH ) q.push( { m_heartY + 1, m_heartX } );
- if ( m_heartX + 1 < m_shW ) q.push( { m_heartY, m_heartX + 1} );
- while ( !q.empty() )
- {
- y = q.front().idY;
- x = q.front().idX;
- if ( m_solid[ y ][ x ] == 0 )
- {
- // Bloc détruit
- network[ y ][ x ] = 0;
- }
- else if ( ( y > 0 && network[ y - 1 ][ x ] == 1 ) // Haut
- || ( y < m_shH - 1 && network[ y + 1 ][ x ] == 1 ) // Bas
- || ( x > 0 && network[ y ][ x - 1 ] == 1 ) // Gauche
- || ( x < m_shW - 1 && network[ y ][ x + 1 ] == 1 ) ) // Droite
- {
- // Bloc présent
- network[ y ][ x ] = 1;
- // Connexion des blocs adjacents
- if ( y > 0 && network[ y - 1 ][ x ] == -1 )// Haut
- q.push( { y - 1, x } );
- if ( y < m_shH - 1 && network[ y + 1 ][ x ] == -1 )// Bas
- q.push( { y + 1, x } );
- if ( x > 0 && network[ y ][ x - 1 ] == -1 )// Gauche
- q.push( { y, x - 1 } );
- if ( x < m_shW - 1 && network[ y ][ x + 1 ] == -1 )// Doite
- q.push( { y, x + 1 } );
- }
- else
- {
- // Bloc non connecté
- network[ y ][ x ] = 0;
- }
- q.pop();
- }
- }
- // Destruction des pièces non connectées
- for ( int i(0); i < m_shH; i++ )
- {
- for ( int j(0); j < m_shW; j++ )
- {
- if ( m_solid[i][j] > 0 && network[i][j] == -1 ) {
- Sint16 vx( j - m_heartX );
- Sint16 vy( i - m_heartY );
- m_hiter->addShot( new Part( m_pos.x + j*8, m_pos.y + i*8, vx, vy, m_solid[i][j], m_shape[i][j], m_ally ) );
- m_solid[i][j] = 0;
- }
- }
- }
- }
- void SpaceShip::resetShields()
- {
- m_shieldDelay = SHIELD_MAX_DELAY;
- m_shieldMax = 0;
- for ( unsigned int k(0); k < m_shields.size(); k++ )
- {
- if ( m_solid[ m_shields[k].idY ][ m_shields[k].idX ] > 0 )
- {
- m_shieldDelay -= SHIELD_1_EARN_DELAY;
- m_shieldMax += SHIELD_1_EARN_HP;
- }
- }
- if ( m_shieldLeft > m_shieldMax )
- m_shieldLeft = m_shieldMax;
- if ( m_shieldDelay < SHIELD_MIN_DELAY )
- m_shieldDelay = SHIELD_MIN_DELAY;
- }
|