box.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include "box.hpp"
  2. void Box::refresh(b_list& bullets, b_list& bombs, e_list& enemies, player& player1, int &score, boss& boss1,w_vec &walls, b_list& powerups,r_list& rockets)
  3. {
  4. clear(); //Empty matrix
  5. upload(bullets, bombs, enemies, player1, boss1, walls, powerups, rockets); //writes id values on matrix
  6. kill(bullets, bombs, enemies, score, boss1, walls, powerups, player1, rockets); //evaluates interactions and removes what should be removed
  7. clear(); //empty again
  8. upload(bullets, bombs, enemies, player1, boss1, walls, powerups, rockets); //rewrites survived game objects' id
  9. }
  10. void Box::print() //this method is used for debugging purposes, not in game
  11. {
  12. for(int k=0; k<R; k++)
  13. {
  14. for(int l=0; l<C; l++)
  15. cout << matrix[k][l] << " ";
  16. cout << endl;
  17. }
  18. cout << endl;
  19. }
  20. void Box::clear()
  21. {
  22. for(int i=0; i<R; i++)
  23. for(int j=0; j<C; j++)
  24. matrix[i][j]=0;
  25. }
  26. void Box::upload(b_list & bullets, b_list& bombs, e_list& enemies, player& player1, boss& boss1, w_vec &walls, b_list & powerups,r_list& rockets) //writes on the box the IDs of all game objects (even if superimposed). Also uploads curses's window
  27. {
  28. e_list::const_iterator e_end = enemies.end();
  29. for(e_list::iterator it=enemies.begin(); it!=e_end; ++it)
  30. if(it->alive){
  31. attron(COLOR_PAIR(2));
  32. mvaddch(it->y,it->x,ENEMY_SPRITE);
  33. matrix[it->y][it->x]+=it->id;
  34. }
  35. if(!bullets.empty())
  36. for(b_list::iterator it=bullets.begin(); it!=bullets.end(); ++it){
  37. attron(COLOR_PAIR(3));
  38. mvaddch(it->y,it->x,BULLET_SPRITE);
  39. matrix[it->y][it->x]+=it->id;
  40. }
  41. if(!rockets.empty())
  42. for(r_list::iterator it=rockets.begin(); it!=rockets.end(); ++it){
  43. attron(COLOR_PAIR(4));
  44. mvaddch(it->y,it->x,ROCKET_SPRITE);
  45. matrix[it->y][it->x]+=it->id;
  46. }
  47. if(!bombs.empty())
  48. for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){
  49. attron(COLOR_PAIR(6));
  50. mvaddch(it->y,it->x,BOMB_SPRITE);
  51. matrix[it->y][it->x]+=it->id;
  52. }
  53. if(!powerups.empty())
  54. for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){
  55. if(it->id==64){
  56. attron(COLOR_PAIR(3));
  57. mvaddch(it->y,it->x,POWERUP1_SPRITE);
  58. }
  59. else if(it->id==128){
  60. attron(COLOR_PAIR(1));
  61. mvaddch(it->y,it->x,POWERUP2_SPRITE);
  62. }
  63. else{
  64. attron(COLOR_PAIR(4));
  65. mvaddch(it->y,it->x,POWERUP3_SPRITE);
  66. }
  67. matrix[it->y][it->x]+=it->id;
  68. }
  69. for(int i=player1.x; i<player1.x+player1.length; ++i){
  70. attron(COLOR_PAIR(1));
  71. mvaddch(player1.y,i,PLAYER_SPRITE);
  72. matrix[player1.y][i]+=player1.id;
  73. }
  74. for(unsigned int i=0;i<walls.size();i++)
  75. for(int k=0;k<walls[i].height;k++)
  76. for(int j=0;j<walls[i].width;j++)
  77. if(walls[i].health[k][j]>0){
  78. attron(COLOR_PAIR(4));
  79. if(walls[i].health[k][j]==1)
  80. attron(COLOR_PAIR(2));
  81. mvaddch(walls[i].y+k,walls[i].x+j,WALL_SPRITE);
  82. matrix[walls[i].y+k][walls[i].x+j]+=walls[i].id;
  83. }
  84. if(boss1.alive)
  85. for(int i=boss1.y; i<boss1.y+boss1.height; i++)
  86. for(int j=boss1.x; j<boss1.x+boss1.width; j++){
  87. if(boss1.health>.5*boss1.healthmax)
  88. attron(COLOR_PAIR(5));
  89. else if(boss1.health>.25*boss1.healthmax)
  90. attron(COLOR_PAIR(3));
  91. else
  92. attron(COLOR_PAIR(2));
  93. mvaddch(i,j,boss1.picture[i-boss1.y][j-boss1.x]);
  94. matrix[i][j]+=boss1.id;
  95. }
  96. }
  97. void Box::kill(b_list & bullets, b_list& bombs, e_list& enemies, int &score, boss& boss1, w_vec &walls, b_list & powerups, player& player1,r_list& rockets) //controls what changes the box's elements must undergo
  98. {
  99. for(int i=0; i<R; i++)
  100. for(int j=0; j<C; j++)
  101. {
  102. if(i==0 || i==R-1)
  103. switch(matrix[i][j]) //destroys bullets and bombs at box's limits
  104. { //DESTRUCTION SHOULD HAPPEN AFTER THEY'VE BEEN PRINTED ONCE!!
  105. case 2:
  106. case 8:
  107. case 64:
  108. case 128:
  109. case 256:
  110. case 512:
  111. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  112. break;
  113. default:
  114. break;
  115. }
  116. if(!boss1.alive && matrix[i][j]==16) destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  117. switch (matrix[i][j]) //id player=1 bullet=2 enemy=4 bomb=8 boss=16 wall=32 powerup+=64, powerup-=128, rocket=256, powerupX=512
  118. {
  119. case 2: //destruction cases: 6=enemy+bullet; 10=bomb+bullet; 14=bomb+enemy+bullet; and so on...
  120. if(i!=0)
  121. if(matrix[i-1][j]==8) //to make the bullets less 'transparent'...
  122. {
  123. destroy(i, j, bullets,bombs, enemies,powerups,rockets);
  124. destroy(i-1, j, bullets,bombs,enemies,powerups,rockets);
  125. score+=50;
  126. }
  127. break;
  128. case 6: //enemy+bullet
  129. score+=100;
  130. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  131. if((double)rand()/RAND_MAX<(double)AVERAGE_DROP/ENEMY_NUM) //a powerup is dropped (AVERAGE_DROP is the mean number of powerups dropped per play in Normal mode)
  132. {
  133. if((double)rand()/RAND_MAX<1./POWERUP_RATIO){ //1 powerup out of POWERUP_RATIO is either a "-" (with ID 128 instead of 64) or a "X"
  134. if((double)rand()/RAND_MAX<1./ROCKET_RATIO){ //1 powerup out of ROCKET_RATIO*POWERUP_RATIO is a "X" (ID 512)
  135. powerup newpowerup(j,i+1,512);
  136. powerups.push_back(newpowerup);
  137. }
  138. else{
  139. powerup newpowerup(j,i+1,128);
  140. powerups.push_back(newpowerup);
  141. }
  142. }
  143. else{
  144. powerup newpowerup(j,i+1); //otherwise, it is a "+"
  145. powerups.push_back(newpowerup);
  146. }
  147. }
  148. break;
  149. case 10: //bomb+bullet
  150. score+=50;
  151. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  152. break;
  153. case 14: //bomb+enemy+bullet
  154. score+=150;
  155. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  156. break;
  157. case 18: //boss+bullet
  158. case 272:
  159. if(j>=boss1.x+boss1.width/2-2 && j<=boss1.x+boss1.width/2+2)
  160. boss1.health--;
  161. break;
  162. case 34: //wall+bullet
  163. case 40: //wall+bomb
  164. case 288: //wall+rocket
  165. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  166. for(unsigned int k=0;k<walls.size();k++)
  167. if(j>=walls[k].x && j<=walls[k].x+walls[k].width && i>=walls[k].y && i<=walls[k].y+walls[k].height) //finds out what wall has been hit
  168. walls[k].health[i-walls[k].y][j-walls[k].x]--; //subtracts 1 HP to the hit wall's correct health matrix's element
  169. break;
  170. case 65: //"+" powerup+player
  171. if(player1.weaponclass<MAX_WEAPONCLASS)
  172. player1.weaponclass++;
  173. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  174. break;
  175. case 68: //"+" powerup+enemy
  176. case 72: //"+" powerup+bomb
  177. case 80: //"+" powerup+boss
  178. case 132: //"-" powerup+enemy [etc.]
  179. case 136:
  180. case 144:
  181. case 516: //"X" powerup+enemy [etc.]
  182. case 520:
  183. case 528:
  184. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  185. break;
  186. case 129: //"-" powerup+player
  187. if(player1.length>2){
  188. mvaddch(player1.y,player1.x+player1.length-1,' ');
  189. player1.length--;
  190. }
  191. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  192. break;
  193. case 260: //enemy+rocket
  194. case 264: //bomb+rocket
  195. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  196. break;
  197. case 513: //player+"X" powerup
  198. player1.rocketlauncher=TRUE;
  199. destroy(i,j,bullets,bombs,enemies,powerups,rockets);
  200. break;
  201. }
  202. }
  203. }
  204. void Box::destroy(int Y, int X, b_list & bullets, b_list& bombs, e_list& enemies, b_list & powerups,r_list& rockets) //destroys any bomb/enemy/bullet/powerup/rocket found in matrix[Y][X]
  205. {
  206. b_list::iterator it;
  207. r_list::iterator itr;
  208. if(!bullets.empty()){
  209. it=bullets.begin(); //we could use remove_if() if i could just think of a way...
  210. while(it!=bullets.end())
  211. {
  212. if(it->x==X && it->y==Y)
  213. {
  214. mvaddch(it->y,it->x,' ');
  215. it = bullets.erase(it);
  216. break;
  217. } else ++it;
  218. }
  219. }
  220. if(!rockets.empty()){
  221. itr=rockets.begin();
  222. while(itr!=rockets.end())
  223. {
  224. if(itr->x==X && itr->y==Y)
  225. {
  226. mvaddch(itr->y,itr->x,' ');
  227. itr = rockets.erase(itr);
  228. break;
  229. } else ++itr;
  230. }
  231. }
  232. if(!bombs.empty()){
  233. it=bombs.begin();
  234. while(it!=bombs.end())
  235. {
  236. if(it->x==X && it->y==Y)
  237. {
  238. mvaddch(it->y,it->x,' ');
  239. it = bombs.erase(it);
  240. break;
  241. } else ++it;
  242. }
  243. }
  244. if(!powerups.empty()){
  245. it=powerups.begin();
  246. while(it!=powerups.end())
  247. {
  248. if(it->x==X && it->y==Y)
  249. {
  250. mvaddch(it->y,it->x,' ');
  251. it = powerups.erase(it);
  252. break;
  253. }else ++it;
  254. }
  255. }
  256. e_list::const_iterator e_end = enemies.end();
  257. for(e_list::iterator it=enemies.begin(); it!=e_end; ++it) //this cycle destroys an enemy in X,Y (quite unefficiently?)
  258. if(it->x==X && it->y==Y)
  259. {
  260. it->alive=false;
  261. break;
  262. }
  263. }