#include "../config.h" #include "boss.h" #include "bullet.h" #include #include #include #include #include "../utilities/fast_trig.h" #include #include "collections.h" #include "player.h" #include "../utilities/vector2D.h" extern bopti_image_t img_Lifebar; extern bopti_image_t img_Boss1; extern bopti_image_t img_BossGun; extern font_t milifont_prop; extern std::vector MyEnemiesBullets; extern Player *MyPlayer; #define NB_PIECES_BOSS 12 #define NB_GUNS 12 libnum::num XdataBossInternal[NB_PIECES_BOSS]; libnum::num YdataBossInternal[NB_PIECES_BOSS]; libnum::num XdataBossExternal[NB_PIECES_BOSS]; libnum::num YdataBossExternal[NB_PIECES_BOSS]; BossPart Pieces[NB_PIECES_BOSS*2]; libnum::num xGuns[NB_GUNS]; libnum::num yGuns[NB_GUNS]; BossGun Guns[NB_GUNS]; #include void savedata( void ) { FILE* exportfp = fopen("databosPtxt", "w" ); if(exportfp) { fprintf(exportfp, "Points : \n" ); for( int i=0; i 0; if (((P3x - P1x) * as_y - (P3y - P1y) * as_x > 0) == s_ab) return false; if (((P3x - P2x) * (Py - P2y) - (P3y - P2y)*(Px - P2x) > 0) != s_ab) return false; return true; } Boss::Boss( int16_t _x, int16_t _y, uint8_t _id ) { x = libnum::num(_x); y = libnum::num(_y); ID = _id; speed = 1; toberemoved = false; width = img_Boss1.width/2; height = img_Boss1.height/2; xmin = (int) x - width; xmax = (int) x + width; ymin = (int) y - height; ymax = (int) y + height; if (ID==0) { life = 1000; life0 = 1000; } hasTrajectory=false; lastshoot0 = rtc_ticks(); lastshoot1 = rtc_ticks(); radiusInt = libnum::num( 80 ); radiusExt = libnum::num( 90 ); rotAngle = 0.0f; rotSpeed = 2; this->Update(0.0f); for( int i=0; iDeleteRegistry(); } void Boss::Update( float dt ) { if (hasTrajectory) { pathToFollow->CalculatePosition( &accumulatedTime, dt, speed, true, &x, &y ); } xmin = (int) x - width; xmax = (int) x + width; ymin = (int) y - height; ymax = (int) y + height; rotAngle += rotSpeed * dt / 25000.0f; if (rotAngle>360.0f) rotAngle-=360.0f; /* Management of the shield part of the boss (rotating circles made of triangles)*/ uint16_t angleint = (uint16_t) rotAngle; uint16_t angledelta = (uint16_t) (360/NB_PIECES_BOSS); for( int i=0; ix + this->radiusInt * FastCosInt( angleint ); YdataBossInternal[ i ] = this->y + this->radiusInt * FastSinInt( angleint ); angleint += angledelta; if (angleint>=360) angleint -= 360; } // Pour le cercle Exterieur on se décale d'un demi-incrément d'angle pour le sommet du triangle angleint = (uint16_t) rotAngle + angledelta/2; if (angleint>=360) angleint -= 360; for( int i=0; ix + this->radiusExt * FastCosInt( angleint ); YdataBossExternal[ i ] = this->y + this->radiusExt * FastSinInt( angleint ); angleint += angledelta; if (angleint>=360) angleint -= 360; } /* Management of the Guns part of the boss (rotating cannons made of sprites)*/ angledelta = (uint16_t) (360/NB_GUNS); angleint = (uint16_t) rotAngle + angledelta/2; if (angleint>=360) angleint -= 360; for( int i=0; ix + (this->radiusInt + this->radiusExt) / 2 * FastCosInt( angleint ); yGuns[i] = this->y + (this->radiusInt + this->radiusExt) / 2 * FastSinInt( angleint ); angleint += angledelta; if (angleint>=360) angleint -= 360; } uint32_t tempshoot = rtc_ticks(); bool hasExternalGun = false; if (Shoot_OK( tempshoot, BULLET_ENEMY_RED )) { /* shoot from the rotating cannons (aiming directly the position of the player )*/ for( int i=0; ix - xGuns[i], MyPlayer->y - yGuns[i] ); shootDirection.Normalise(); Bullet *b = new Bullet( xGuns[i] , yGuns[i], shootDirection.x, shootDirection.y, BULLET_ENEMY_RED ); MyEnemiesBullets.push_back( b ); hasExternalGun = true; } } } if (hasExternalGun==false) if(Shoot_OK( tempshoot, BULLET_ENEMY_GREEN )) { /* central shoot from the main ship only if no more other gun shooting */ Bullet *b0 = new Bullet( xmin, (int) y, -3, 0, BULLET_ENEMY_GREEN ); MyEnemiesBullets.push_back( b0 ); Bullet *b1 = new Bullet( xmin, (int) y, -2, -2, BULLET_ENEMY_BLUE ); MyEnemiesBullets.push_back( b1 ); Bullet *b2 = new Bullet( xmin, (int) y, -2, 2, BULLET_ENEMY_BLUE ); MyEnemiesBullets.push_back( b2 ); Bullet *b3 = new Bullet( xmin, (int) y, -3, -1, BULLET_ENEMY_GREEN ); MyEnemiesBullets.push_back( b3 ); Bullet *b4 = new Bullet( xmin, (int) y, -3, 1, BULLET_ENEMY_GREEN ); MyEnemiesBullets.push_back( b4 ); } } void Boss::Render( void ) { if (toberemoved==false) { for( int i=0; ilife0*2/3) azrp_subimage_p8_effect((int) x - img_Lifebar.width/2, ymin - 9, &img_Lifebar, 0, 7, (img_Lifebar.width*life)/life0, 5, DIMAGE_NONE ); else if (life>life0/3) azrp_subimage_p8_effect((int) x - img_Lifebar.width/2, ymin - 9, &img_Lifebar, 0, 12, (img_Lifebar.width*life)/life0, 5, DIMAGE_NONE ); else azrp_subimage_p8_effect((int) x - img_Lifebar.width/2, ymin - 9, &img_Lifebar, 0, 17, (img_Lifebar.width*life)/life0, 5, DIMAGE_NONE ); }; } bool Boss::Test_Impact( Bullet *projectile ) { /* We check if the bullet collides with teh shield of the boss */ for( int i=0; i< NB_PIECES_BOSS; i++ ) { if (Pieces[i*2].toberemoved == false) { if (Is_Point_Inside_Triangle( (int) projectile->x, (int) projectile->y, (int) XdataBossExternal[ Pieces[i*2].P1 ], (int) YdataBossExternal[ Pieces[i*2].P1 ], (int) XdataBossExternal[ Pieces[i*2].P2 ], (int) YdataBossExternal[ Pieces[i*2].P2 ], (int) XdataBossInternal[ Pieces[i*2].P3 ], (int) YdataBossInternal[ Pieces[i*2].P3 ] )) { Pieces[i*2].life -= projectile->strength; if (Pieces[i*2].life<=0) { Pieces[i*2].toberemoved = true; Create_Explosion( (int) projectile->x, (int) projectile->y ); } projectile->toberemoved = true; return true; } } if (Pieces[i*2+1].toberemoved == false) { if (Is_Point_Inside_Triangle( (int) projectile->x, (int) projectile->y, (int) XdataBossInternal[ Pieces[i*2+1].P1 ], (int) YdataBossInternal[ Pieces[i*2+1].P1 ], (int) XdataBossInternal[ Pieces[i*2+1].P2 ], (int) YdataBossInternal[ Pieces[i*2+1].P2 ], (int) XdataBossExternal[ Pieces[i*2+1].P3 ], (int) YdataBossExternal[ Pieces[i*2+1].P3 ] )) { Pieces[i*2+1].life -= projectile->strength; if (Pieces[i*2+1].life<=0) { Pieces[i*2+1].toberemoved = true; Create_Explosion( (int) projectile->x, (int) projectile->y ); } projectile->toberemoved = true; return true; } } } /* We check if the bullet collides with the cannons of the boss */ for( int i=0; ix >= (int) xGuns[i] - img_BossGun.width/2 && projectile->x <= (int) xGuns[i] + img_BossGun.width/2 && projectile->y >= (int) yGuns[i] - img_BossGun.height/2 && projectile->y <= (int) yGuns[i] + img_BossGun.height/2 ) { Guns[i].life -= projectile->strength; if (Guns[i].life<0) { Guns[i].toberemoved = true; Create_Explosion( (int) projectile->x, (int) projectile->y ); } projectile->toberemoved = true; return true; } } } /* We check if the bullet collides with the main ship part of the boss */ if (projectile->x >= xmin && projectile->x <= xmax && projectile->y >= ymin && projectile->y <= ymax ) { life -= projectile->strength; if (life<0) { this->toberemoved = true; Create_Explosion( (int) projectile->x, (int) projectile->y ); } projectile->toberemoved = true; return true; } else return false; } bool Boss::Shoot_OK( uint32_t tempshoot, uint8_t shootID ) { if (shootID==BULLET_ENEMY_RED) { if(tempshoot-lastshoot0>1) { lastshoot0=tempshoot; return true; } else return false; } else if (shootID==BULLET_ENEMY_GREEN) { if(tempshoot-lastshoot1>1) { lastshoot1=tempshoot; return true; } else return false; } else return false; }