functions.cpp 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051
  1. /* This file is part of Invaders.
  2. *
  3. * Copyright (C) 2020 LCM.
  4. * You may use, distribute and modify Invaders under the terms of the
  5. * GPLv3 license, available at <https://www.gnu.org/licenses/\>.
  6. */
  7. #include "functions.hpp"
  8. #include "definitions.hpp"
  9. using std::cout;
  10. using std::cin;
  11. using std::endl;
  12. using std::min;
  13. extern std::mutex m_bullets;
  14. //========RECORD'S METHODS===========
  15. void record::print()
  16. {
  17. printw("%s\t%i\n",nick.c_str(),score);
  18. }
  19. void record::printwin(WINDOW* win)
  20. {
  21. wprintw(win,"%s.......%i",nick.c_str(),score);
  22. }
  23. void record::print(std::ofstream& recordfile)
  24. {
  25. if(!recordfile.is_open())
  26. {
  27. printw("error: record file is not open ");
  28. return;
  29. }
  30. recordfile << std::setw(6) << std::left << nick << " " << score << endl;
  31. }
  32. //=======INDIPENDENT FUNCTIONS=========
  33. void print_title() //CAPITAL LETTERS TITLE!
  34. {
  35. attron(COLOR_PAIR(5));
  36. mvprintw(0,0," __ _ _ _ _ _ _ _ _ _ __");
  37. mvprintw(1,0,"__// |_ |_| |_| | |_ | |\\ | | | |_| |\\ |_ |_| |_ \\\\__");
  38. mvprintw(2,0," \\\\__ _| | | | |_ |_ | | \\| \\/ | | |/ |_ |\\ _| __//");
  39. attron(COLOR_PAIR(0));
  40. }
  41. void print_catchphrase(std::string phrase){
  42. static int head=60;
  43. static int tail=60;
  44. phrase.resize(59,' ');
  45. attron(COLOR_PAIR(4));
  46. if(head<1){
  47. head=60;
  48. }
  49. if(head<tail){
  50. move(3,0);
  51. clrtoeol();
  52. mvprintw(3,head,phrase.c_str());
  53. tail=(head+phrase.size()<60?head+phrase.size():60);
  54. }
  55. else{
  56. move(3,0);
  57. clrtoeol();
  58. for(unsigned int i=0;i<abs(phrase.size()-(60-head));i++)
  59. mvaddch(3,i,phrase[60-head+i]);
  60. for(unsigned int i=head;i<60;i++)
  61. mvaddch(3,i,phrase[i-head]);
  62. tail=(phrase.size()-(60-head)>0?phrase.size()-(60-head):60);
  63. }
  64. head--;
  65. }
  66. std::string choose_phrase(){
  67. std::string phr;
  68. int r=(int)(23*(double)rand()/RAND_MAX);
  69. switch(r){
  70. case 0:
  71. phr="Now with cheats!";
  72. break;
  73. case 1:
  74. phr="20 percent cooler than your 3D-graphics games!";
  75. break;
  76. case 2:
  77. phr="NCurses rulez!";
  78. break;
  79. case 3:
  80. phr="References to people and events are purely random.";
  81. break;
  82. case 4:
  83. phr=">>> Crush <<< Kill >>> Destroy <<< SWAG >>>";
  84. break;
  85. case 5:
  86. phr="Also try Apocalypse 2.0!";
  87. break;
  88. case 6:
  89. phr=")]=>---- # ASCII IS ART!!! # ----<=[(";
  90. break;
  91. case 7:
  92. phr="Still a better program than Isgro's ones...";
  93. break;
  94. case 8:
  95. phr="<< Oh, sul serio, minchia raga, ne'? >>";
  96. break;
  97. case 9:
  98. phr="Cool game, bro, but needs more ponies.";
  99. break;
  100. case 10:
  101. phr="Hit R!!!";
  102. break;
  103. case 11:
  104. phr="Konami Code is still fashion.";
  105. break;
  106. case 12:
  107. phr="Almost completely debugged!";
  108. break;
  109. case 13:
  110. phr="(((( Kill them with WUBZ! ))))";
  111. break;
  112. case 14:
  113. phr="choose_phrase() is best function.";
  114. break;
  115. case 15:
  116. phr="zsh: segmentation fault (core dumped) invaders";
  117. break;
  118. case 16:
  119. phr="Aliens! Aliens everywhere!";
  120. break;
  121. case 17:
  122. phr="Breaks the fourth wall! Breaks the fourth wall!";
  123. break;
  124. case 18:
  125. phr="Them customizable controls!!!";
  126. break;
  127. case 19:
  128. phr=">~~~~~~~~~~~~~~~~~~~~~< You shall be assimilated into Linux.";
  129. break;
  130. case 20:
  131. phr="Did you try inv_bossrush?";
  132. break;
  133. case 21:
  134. phr="Keep calm and FUCKIN' KILL ALIENS.";
  135. break;
  136. case 22:
  137. phr="Read the fucking `man` page!!!";
  138. break;
  139. }
  140. return phr;
  141. }
  142. void print_info(){
  143. WINDOW *info;
  144. info=newwin(20,80,0,0);
  145. box(info,ACS_VLINE,ACS_HLINE);
  146. mvwprintw(info,0,1,"Welcome to Space Invaders!");
  147. wattron(info,COLOR_PAIR(1));
  148. mvwprintw(info,2,1,"About the Game:");
  149. wattron(info,COLOR_PAIR(6));
  150. mvwprintw(info,3,1,"This is a Terminal-playable game where you control a moving cannon base");
  151. mvwprintw(info,4,1,"(");
  152. wattron(info,COLOR_PAIR(1));
  153. wprintw(info,"========");
  154. wattron(info,COLOR_PAIR(6));
  155. wprintw(info,") with the aim to destroy all the enemy Space Invaders");
  156. mvwprintw(info,5,1,"(");
  157. wattron(info,COLOR_PAIR(2));
  158. wprintw(info,"#");
  159. wattron(info,COLOR_PAIR(6));
  160. wprintw(info,") assaulting the Earth. After killing all the Space Invaders, you shall face");
  161. mvwprintw(info,6,1,"the Big Alien Boss, the most powerful of all the alien enemies.");
  162. mvwprintw(info,7,1,"During the game, mind the Powerups (");
  163. wattron(info,COLOR_PAIR(3));
  164. wprintw(info,"+");
  165. wattron(info,COLOR_PAIR(6));
  166. wprintw(info,",");
  167. wattron(info,COLOR_PAIR(1));
  168. wprintw(info,"-");
  169. wattron(info,COLOR_PAIR(6));
  170. wprintw(info,",");
  171. wattron(info,COLOR_PAIR(4));
  172. wprintw(info,"X");
  173. wattron(info,COLOR_PAIR(6));
  174. wprintw(info,") that will increase");
  175. mvwprintw(info,8,1,"your shooting power if you manage to get them.");
  176. wattron(info,COLOR_PAIR(1));
  177. mvwprintw(info,10,1,"Default Controls: ");
  178. wattron(info,COLOR_PAIR(5));
  179. mvwprintw(info,11,1,"<- ");
  180. wattron(info,COLOR_PAIR(6));
  181. wprintw(info," A or Left Arrow");
  182. wattron(info,COLOR_PAIR(5));
  183. mvwprintw(info,12,1,"-> ");
  184. wattron(info,COLOR_PAIR(6));
  185. wprintw(info," D or Right Arrow");
  186. wattron(info,COLOR_PAIR(5));
  187. mvwprintw(info,13,1,"shoot ");
  188. wattron(info,COLOR_PAIR(6));
  189. wprintw(info," spacebar");
  190. wattron(info, COLOR_PAIR(5));
  191. mvwprintw(info,14,1,"mute / unmute ");
  192. wattron(info, COLOR_PAIR(6));
  193. wprintw(info, " m");
  194. wattron(info,COLOR_PAIR(3));
  195. mvwprintw(info,16,10,"Game developed by Giacomo Parolini & Enrico Guiraud (v.4.4)");
  196. wattron(info,COLOR_PAIR(6));
  197. mvwprintw(info,18,14,"Click any key to return to the Start Menu");
  198. wattron(info,COLOR_PAIR(0));
  199. wrefresh(info);
  200. timeout(-1);
  201. if(getch()!=ERR){
  202. delwin(info);
  203. erase();
  204. refresh();
  205. }
  206. }
  207. int choose_level(int* commands)
  208. {
  209. std::string phrase;
  210. phrase=choose_phrase();
  211. char input;
  212. do{
  213. print_title();
  214. print_catchphrase(phrase);
  215. attron(COLOR_PAIR(1));
  216. mvprintw(5,0,"Choose difficulty level:");
  217. attron(COLOR_PAIR(1));
  218. mvprintw(6,0,"1- Easy");
  219. attron(COLOR_PAIR(3));
  220. mvprintw(7,0,"2- Medium");
  221. attron(COLOR_PAIR(2));
  222. mvprintw(8,0,"3- Hard");
  223. attron(COLOR_PAIR(4));
  224. mvprintw(9,0,"4- Impossible");
  225. attron(COLOR_PAIR(5));
  226. mvprintw(10,0,"i- Info");
  227. attron(COLOR_PAIR(6));
  228. mvprintw(11,0,"h- Highscores");
  229. attron(COLOR_PAIR(1));
  230. mvprintw(12,0,"c- Commands");
  231. attron(COLOR_PAIR(2));
  232. mvprintw(13,0,"q- Quit");
  233. refresh();
  234. timeout(80);
  235. input=tolower(getch());
  236. if(!(input=='1' || input=='2' || input=='3' || input=='4' || input=='i' || input=='h' || input=='r' || input =='q') && input!=ERR){
  237. attron(COLOR_PAIR(2));
  238. mvprintw(14,0,"Bad input. Please choose a number within 1 and 4.");
  239. attron(COLOR_PAIR(0));
  240. }
  241. if(input=='i')
  242. print_info();
  243. if(input=='h')
  244. print_scores();
  245. if(input=='r')
  246. phrase=choose_phrase();
  247. if(input=='c')
  248. change_commands(commands);
  249. if(input=='q'){
  250. endwin();
  251. cout<<lightgreen<<"Game exited correctly."<<none<<endl;
  252. exit(1);
  253. }
  254. }while(!(input=='1' || input=='2' || input=='3' || input=='4'));
  255. create_folder(0);
  256. return input - '0';
  257. }
  258. void setup_level(int level, double& shootr, double& poweruprate, int& refresh_t, boss& boss1, int& enemy_num, int& walls_num)
  259. {
  260. switch(level) //setting game parameters
  261. {
  262. case 1:
  263. {
  264. shootr = 0.006;
  265. refresh_t = (int)(0.09*1E3);
  266. boss bosslvl1(1,1,100,9,6,BOSS_FILE1);
  267. boss1 = bosslvl1;
  268. std::string bossname=getenv("HOME");
  269. bossname=bossname+RECORD_DIR+BOSS_FILE1+".dat";
  270. boss1.loadpicture(bossname.c_str());
  271. enemy_num=30;
  272. walls_num = 3;
  273. break;
  274. }
  275. case 2:
  276. {
  277. shootr = 0.009;
  278. refresh_t = (int)(0.09*1E3);
  279. boss bosslvl2(1,1,200,11,5,BOSS_FILE2);
  280. boss1 = bosslvl2;
  281. std::string bossname=getenv("HOME");
  282. bossname=bossname+RECORD_DIR+BOSS_FILE2+".dat";
  283. boss1.loadpicture(bossname.c_str());
  284. enemy_num=40;
  285. walls_num = 2;
  286. break;
  287. }
  288. case 3:
  289. {
  290. shootr = 0.015;
  291. refresh_t = (int)(0.08*1E3);
  292. boss bosslvl3(1,1,300,9,6,BOSS_FILE3);
  293. boss1 = bosslvl3;
  294. std::string bossname=getenv("HOME");
  295. bossname=bossname+RECORD_DIR+BOSS_FILE3+".dat";
  296. boss1.loadpicture(bossname.c_str());
  297. enemy_num=45;
  298. walls_num = 2;
  299. break;
  300. }
  301. case 4:
  302. {
  303. shootr = 0.020;
  304. refresh_t = (int)(0.07*1E3);
  305. boss bosslvl4(1,1,400,11,6,BOSS_FILE4);
  306. boss1 = bosslvl4;
  307. std::string bossname=getenv("HOME");
  308. bossname=bossname+RECORD_DIR+BOSS_FILE4+".dat";
  309. boss1.loadpicture(bossname.c_str());
  310. enemy_num=50;
  311. walls_num = 2;
  312. break;
  313. }
  314. }
  315. poweruprate = (double)AVERAGE_DROP/enemy_num;
  316. }
  317. void change_commands(int* commands){
  318. WINDOW *change;
  319. int cmd;
  320. int line=0;
  321. std::string chcommands[CMD_NUM];
  322. std::string name[CMD_NUM]={"Key Left","Key Right","Key Up","Key Down","Pause","Shoot 1","Shoot 2","Mute/Unmute","Quit"};
  323. change=newwin(CMD_NUM+10,20,0,0);
  324. keypad(change,true);
  325. box(change,ACS_VLINE,ACS_HLINE);
  326. wattron(change,COLOR_PAIR(5));
  327. mvwprintw(change,1,2,"CHANGE CONTROLS");
  328. mvwprintw(change,3,2,"(X) to exit");
  329. do{
  330. for(int i=0;i<CMD_NUM;i++){
  331. if(commands[i]==' ') chcommands[i]="Barra sp.";
  332. else chcommands[i]=(char)commands[i];
  333. if(i==line) wattron(change,COLOR_PAIR(9));
  334. mvwprintw(change,i+5,1,"%s: %s",name[i].c_str(),chcommands[i].c_str());
  335. wattron(change,COLOR_PAIR(1));
  336. }
  337. timeout(0);
  338. cmd=wgetch(change);
  339. switch(cmd){
  340. case KEY_DOWN:
  341. case 's':
  342. if(line<CMD_NUM-1) line++;
  343. break;
  344. case KEY_UP:
  345. case 'w':
  346. if(line>0) line--;
  347. break;
  348. case 'X':
  349. delwin(change);
  350. erase();
  351. refresh();
  352. return;
  353. case '\n':
  354. wattron(change,COLOR_PAIR(2));
  355. mvwprintw(change,line+5,1,"%s: %s",name[line].c_str(),chcommands[line].c_str());
  356. wrefresh(change);
  357. timeout(-1);
  358. cmd=wgetch(change);
  359. commands[line]=tolower(cmd);
  360. dump_commands(commands);
  361. wmove(change,line+5,0);
  362. wclrtoeol(change);
  363. box(change,ACS_VLINE,ACS_HLINE);
  364. wattron(change,COLOR_PAIR(1));
  365. break;
  366. }
  367. wrefresh(change);
  368. }while(cmd!='X');
  369. delwin(change);
  370. erase();
  371. refresh();
  372. return;
  373. }
  374. void dump_commands(int* commands)
  375. {
  376. std::ofstream cmd;
  377. std::string local_dir = getenv("HOME");
  378. std::string cmd_file = local_dir + RECORD_DIR + "commands";
  379. create_folder(0);
  380. cmd.open(cmd_file);
  381. if(cmd.is_open()) {
  382. for(int i = 0; i < CMD_NUM; i++) {
  383. cmd << (char)commands[i];
  384. }
  385. cmd << std::endl;
  386. cmd.close();
  387. } else {
  388. printw("error: cannot open %s", cmd_file);
  389. return;
  390. }
  391. }
  392. void read_commands(int* commands)
  393. {
  394. std::ifstream cmd;
  395. int def[CMD_NUM] = {'a', 'd', 'w', 's', 'p', ' ', 'l', 'm', 'q'}; // default
  396. std::string local_dir = getenv("HOME");
  397. std::string cmd_file = local_dir + RECORD_DIR + "commands";
  398. cmd.open(cmd_file);
  399. if(cmd.is_open()) {
  400. std::string line;
  401. getline(cmd, line);
  402. for(int i = 0; i < CMD_NUM; i++) {
  403. commands[i] = (int)line[i];
  404. }
  405. } else {
  406. for(int i = 0; i <CMD_NUM; i++) {
  407. commands[i] = def[i];
  408. }
  409. }
  410. }
  411. void load_enemies(e_list& enemies,int enemy_num)
  412. {
  413. enemies.clear();
  414. for(int i=0; i<enemy_num; ++i) //loading enemies
  415. {
  416. static int c=0, r=0;
  417. if(c>C-1)
  418. {
  419. c=0;
  420. r++;
  421. if(r>R-2) break;
  422. }
  423. enemy newenemy(c++,r);
  424. if(newenemy.y%2!=0) newenemy.direction=1;
  425. enemies.push_back(newenemy);
  426. }
  427. }
  428. char playagain(WINDOW* replay)
  429. {
  430. char answer;
  431. do
  432. {
  433. wattron(replay,COLOR_PAIR(2));
  434. mvwprintw(replay,1,3,"Play again? [y/n/q] ");
  435. answer=tolower(wgetch(replay));
  436. }while(answer!='y' && answer!='n' && answer!='q');
  437. return answer;
  438. }
  439. bool gameover(player& _player,b_list& bombs) //Checks if a bomb/enemy/boss hit the player.
  440. {
  441. for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it)
  442. if((it->x>=_player.x && it->x<_player.x+_player.length) && (it->y==_player.y) && !_player.godmode)
  443. return true;
  444. return false;
  445. }
  446. void reset(player& _player, e_list &enemies, boss& boss1, b_list& bullets, b_list& bombs, w_vec& walls, int walls_num, b_list& powerups, r_list& rockets, int& chflag)
  447. {
  448. _player.x=C/2; //resetting initial position and stats of player1
  449. _player.y=R-1;
  450. _player.weaponclass=0;
  451. _player.length=8;
  452. _player.rocketlauncher=FALSE;
  453. int c=0, r=0;
  454. e_list::const_iterator e_end = enemies.end();
  455. for(e_list::iterator it = enemies.begin(); it!=e_end; ++it) //resetting all the enemies
  456. {
  457. if(c==C)
  458. {
  459. c=0;
  460. r++;
  461. }
  462. it->alive = true;
  463. it->x=c++;
  464. it->y=r;
  465. if(it->y%2==0) it->direction=0;
  466. else it->direction=1;
  467. }
  468. boss1.alive = false;
  469. bullets.clear(); //destroying all bullets/bombs/etc
  470. bombs.clear();
  471. powerups.clear();
  472. rockets.clear();
  473. chflag=0;
  474. walls.resize(walls_num);
  475. for(int i=0;i<walls_num;i++)
  476. walls[i].create((i+1)*(C/(3*walls_num+1))+i*(2*C/(3*walls_num+1)),2*R/3,(int)min(6,2*C/(3*(int)(walls_num)+1)),2,5);
  477. }
  478. bool enemyalive(e_list &enemies)
  479. {
  480. bool isalive = false;
  481. e_list::const_iterator end = enemies.end();
  482. for(e_list::iterator it=enemies.begin(); it!=end; ++it)
  483. if(it->alive==true)
  484. {
  485. isalive = true;
  486. break;
  487. }
  488. return isalive;
  489. }
  490. bool operator<(record record1, record record2)
  491. {
  492. if(record1.score<record2.score) return true;
  493. else return false;
  494. }
  495. void pause_game(int& chflag){
  496. WINDOW *pause;
  497. char c;
  498. std::string cheat;
  499. char Cheat[7];
  500. pause=newwin(5,17,15,15);
  501. box(pause,ACS_VLINE,ACS_HLINE);
  502. wattron(pause,COLOR_PAIR(5));
  503. mvwprintw(pause,1,3,"GAME PAUSED");
  504. mvwprintw(pause,3,2,"(P) to resume");
  505. do{
  506. c=tolower(wgetch(pause));
  507. if(c=='c'){ //cheats!
  508. nocbreak();
  509. wmove(pause,2,5);
  510. echo();
  511. wattron(pause,COLOR_PAIR(4));
  512. wscanw(pause,"%s",Cheat);
  513. cbreak();
  514. noecho();
  515. if(std::strcmp(Cheat,CHEAT_CODE)==0){
  516. if(chflag==0)
  517. chflag=1;
  518. if(chflag==2)
  519. chflag=3;
  520. waddch(pause,'\a');
  521. }
  522. delwin(pause);
  523. erase();
  524. refresh();
  525. return;
  526. }
  527. else if(c=='p'){
  528. delwin(pause);
  529. erase();
  530. refresh();
  531. return;
  532. }
  533. }while(c!='c' && c!='p');
  534. }
  535. void write_score(WINDOW* Score,int score){
  536. wattron(Score,COLOR_PAIR(6));
  537. mvwprintw(Score,1,2,"SCORE");
  538. wattron(Score,COLOR_PAIR(1));
  539. mvwprintw(Score,2,2,"%i",score);
  540. }
  541. void write_bosshp(WINDOW* BossHP,int hp,int hpmax,std::string name){
  542. wattron(BossHP,COLOR_PAIR(3));
  543. mvwprintw(BossHP,0,1,"%s",name.c_str()); //writes boss's name
  544. wattron(BossHP,COLOR_PAIR(8));
  545. int i=0;
  546. for(i=0;i<(int)(15*(double)(hp)/hpmax);i++) mvwaddch(BossHP,1,i,' '); //draws green spaces
  547. i++;
  548. wattron(BossHP,COLOR_PAIR(7));
  549. for(;i<15;i++) mvwaddch(BossHP,1,i,' '); //draws red spaces (total spaces are 15)
  550. if((double)hp/hpmax>.5)
  551. wattron(BossHP,COLOR_PAIR(1));
  552. else if((double)hp/hpmax>.25)
  553. wattron(BossHP,COLOR_PAIR(3));
  554. else
  555. wattron(BossHP,COLOR_PAIR(2));
  556. wmove(BossHP,2,0);
  557. wdeleteln(BossHP);
  558. mvwprintw(BossHP,2,0,"%i / %i HP",hp,hpmax); //writes boss's hp / hpmax (color depends on hp/hpmax ratio)
  559. }
  560. void Victory(std::string name,int score,int level,int chflag){
  561. score+=1500*level;
  562. WINDOW *victory;
  563. victory=newwin(19,32,7,17);
  564. box(victory,ACS_VLINE,ACS_HLINE);
  565. wattron(victory,COLOR_PAIR(1));
  566. mvwprintw(victory,2,4,"YOU DEFEATED %s!",name.c_str());
  567. wattron(victory,COLOR_PAIR(3));
  568. mvwprintw(victory,4,5,"+ %i pts!",level*1500);
  569. wattron(victory,COLOR_PAIR(1));
  570. mvwprintw(victory,4,5,"YOU WON!");
  571. wattron(victory,COLOR_PAIR(3));
  572. mvwprintw(victory,4,5,"Your score is: %i",score);
  573. wrefresh(victory);
  574. if(chflag==0)
  575. refreshrecords(score,victory);
  576. else{
  577. wattron(victory,COLOR_PAIR(4));
  578. mvwprintw(victory,7,3,"I think you used cheats...");
  579. }
  580. wrefresh(victory);
  581. delwin(victory);
  582. }
  583. void Defeat(int score){
  584. WINDOW *defeat;
  585. defeat=newwin(10,32,7,17);
  586. box(defeat,ACS_VLINE,ACS_HLINE);
  587. wattron(defeat,COLOR_PAIR(2));
  588. mvwprintw(defeat,3,10,"GAME OVER!");
  589. wattron(defeat,COLOR_PAIR(3));
  590. mvwprintw(defeat,6,4,"Your score was: %i pts!",score);
  591. wrefresh(defeat);
  592. delwin(defeat);
  593. }
  594. void get_SpecialMode(int c,int& chflag,boss& boss1,e_list& enemies,b_list& bullets,b_list& bombs,r_list& rockets){
  595. if(get_KonamiCode(c)){
  596. activate_combo(boss1,enemies,bullets,bombs,rockets);
  597. if(chflag==0)
  598. chflag=2;
  599. if(chflag==1)
  600. chflag=3;
  601. }
  602. }
  603. bool get_KonamiCode(int c){ //UP,UP,DOWN,DOWN,LEFT,RIGHT,LEFT,RIGHT,B,A
  604. static int combo=0;
  605. switch(combo){
  606. case 0:
  607. case 1:
  608. if(c==KEY_UP) combo++;
  609. else if(c!=ERR) combo=0;
  610. break;
  611. case 2:
  612. case 3:
  613. if(c==KEY_DOWN) combo++;
  614. else if(c!=ERR) combo=0;
  615. break;
  616. case 4:
  617. case 6:
  618. if(c==KEY_LEFT) combo++;
  619. else if(c!=ERR) combo=0;
  620. break;
  621. case 5:
  622. case 7:
  623. if(c==KEY_RIGHT) combo++;
  624. else if(c!=ERR) combo=0;
  625. break;
  626. case 8:
  627. if(c=='b') combo++;
  628. else if(c!=ERR) combo=0;
  629. break;
  630. case 9:
  631. if(c=='a'){
  632. return true;
  633. }
  634. else if(c!=ERR) combo=0;
  635. break;
  636. }
  637. return false;
  638. }
  639. void get_cheat(char command,player& player1,e_list& enemies,double& shootrate){
  640. switch(command){
  641. case '+':
  642. if(player1.weaponclass<5) player1.weaponclass++; //increase weaponclass
  643. break;
  644. case '\\':
  645. if(player1.weaponclass>1) player1.weaponclass--; //decrease weaponclass
  646. break;
  647. case '-':
  648. if(player1.length>2){ //decrease size
  649. mvaddch(player1.y,player1.x+player1.length-1,' ');
  650. player1.length--;
  651. }
  652. break;
  653. case '*':
  654. if(player1.length<MAX_LENGTH) player1.length++; //increase size
  655. break;
  656. case 'n': //nuke enemies
  657. for(e_list::iterator it=enemies.begin();it!=enemies.end();it++){
  658. it->alive=false;
  659. mvaddch(it->y,it->x,' ');
  660. }
  661. break;
  662. case 'r': //activate rocketlauncher and increase weaponclassrkt
  663. if(!(player1.rocketlauncher)) player1.rocketlauncher=TRUE;
  664. else if(player1.weaponclassrkt<MAX_WEAPONCLASS) player1.weaponclassrkt++;
  665. break;
  666. case 'e': //decrease weaponclassrkt and deactivate rocketlauncher
  667. if(player1.weaponclassrkt>0) player1.weaponclassrkt--;
  668. else player1.rocketlauncher=FALSE;
  669. break;
  670. case 'u': //trigger uber mode
  671. player1.rocketlauncher=TRUE;
  672. player1.weaponclass=MAX_WEAPONCLASS;
  673. player1.weaponclassrkt=MAX_WEAPONCLASSRKT;
  674. player1.length=MAX_LENGTH;
  675. break;
  676. case 'g': //trigger/untrigger godmode
  677. player1.godmode=!player1.godmode;
  678. break;
  679. case 'f': //freeze: enemies won't shoot.
  680. shootrate=0;
  681. break;
  682. }
  683. }
  684. void activate_combo(boss& boss1,e_list& enemies,b_list& bullets,b_list& bombs,r_list& rockets){ //if the player performs the Konami Code, the normal boss is replaced with BIG_ALIENBOSS
  685. boss bossextra(1,1,500,17,5,BOSS_FILE5);
  686. boss1 = bossextra;
  687. std::string bossname=getenv("HOME");
  688. bossname=bossname+RECORD_DIR+BOSS_FILE5+".dat";
  689. boss1.loadpicture(bossname.c_str());
  690. for(int i=0;i<7;){
  691. attron(COLOR_PAIR(i++));
  692. mvprintw(15,15,"SPECIAL MODE ACTIVATED!!!");
  693. refresh();
  694. napms(150);
  695. }
  696. attron(COLOR_PAIR(0));
  697. napms(1500);
  698. for(e_list::iterator i=enemies.begin();i!=enemies.end();i++)
  699. i->alive=false;
  700. bullets.clear();
  701. bombs.clear();
  702. rockets.clear();
  703. erase();
  704. }
  705. //=============BOX'S REPLACEMENT FUNCTIONS============================
  706. void draw(player& player1,b_list& bullets,b_list& bombs,e_list& enemies,w_vec& walls,b_list& powerups,r_list& rockets,boss& boss1){
  707. struct point
  708. {
  709. point() { x=y=0; }
  710. point(int X, int Y) { x=X; y=Y; }
  711. int x,y;
  712. };
  713. static std::vector<point> bullets_p, enemies_p, bombs_p, powerups_p, rockets_p, walls_p, player_p, boss_p;
  714. //REDRAW BULLETS
  715. for(auto bullet_p: bullets_p)
  716. mvaddch(bullet_p.y,bullet_p.x,' ');
  717. bullets_p.clear();
  718. attron(COLOR_PAIR(3));
  719. for(auto bullet: bullets)
  720. {
  721. mvaddch(bullet.y,bullet.x,BULLET_SPRITE);
  722. bullets_p.push_back(point(bullet.x,bullet.y));
  723. }
  724. //REDRAW BOMBS
  725. for(auto bomb_p: bombs_p)
  726. mvaddch(bomb_p.y,bomb_p.x,' ');
  727. bombs_p.clear();
  728. attron(COLOR_PAIR(6));
  729. for(auto bomb: bombs)
  730. {
  731. //if(bomb.y<R)
  732. mvaddch(bomb.y,bomb.x,BOMB_SPRITE);
  733. bombs_p.push_back(point(bomb.x,bomb.y));
  734. }
  735. //REDRAW ENEMIES
  736. for(auto enemy_p: enemies_p)
  737. mvaddch(enemy_p.y,enemy_p.x,' ');
  738. enemies_p.clear();
  739. attron(COLOR_PAIR(2));
  740. for(auto enemy: enemies)
  741. {
  742. if(enemy.alive==true)
  743. {
  744. mvaddch(enemy.y,enemy.x,ENEMY_SPRITE);
  745. enemies_p.push_back(point(enemy.x,enemy.y));
  746. }
  747. }
  748. //REDRAW ROCKETS
  749. for(auto rocket_p: rockets_p)
  750. mvaddch(rocket_p.y,rocket_p.x,' ');
  751. rockets_p.clear();
  752. attron(COLOR_PAIR(3));
  753. for(auto rocket: rockets)
  754. {
  755. mvaddch(rocket.y,rocket.x,ROCKET_SPRITE);
  756. rockets_p.push_back(point(rocket.x,rocket.y));
  757. }
  758. //REDRAW POWERUPS
  759. for(auto powerup_p: powerups_p)
  760. mvaddch(powerup_p.y,powerup_p.x,' ');
  761. powerups_p.clear();
  762. for(auto powerup: powerups){
  763. if(powerup.id == 64){
  764. attron(COLOR_PAIR(3));
  765. mvaddch(powerup.y,powerup.x,POWERUP1_SPRITE);
  766. }
  767. else if(powerup.id == 128){
  768. attron(COLOR_PAIR(1));
  769. mvaddch(powerup.y,powerup.x,POWERUP2_SPRITE);
  770. }
  771. else{
  772. attron(COLOR_PAIR(4));
  773. mvaddch(powerup.y,powerup.x,POWERUP3_SPRITE);
  774. }
  775. powerups_p.push_back(point(powerup.x,powerup.y));
  776. }
  777. //REDRAW BOSS
  778. for(auto boss_point: boss_p)
  779. mvaddch(boss_point.y,boss_point.x,' ');
  780. boss_p.clear();
  781. if(boss1.alive)
  782. for(int i=boss1.y; i<boss1.y+boss1.height; i++)
  783. for(int j=boss1.x; j<boss1.x+boss1.width; j++){
  784. if(boss1.health>.5*boss1.healthmax)
  785. attron(COLOR_PAIR(5));
  786. else if(boss1.health>.25*boss1.healthmax)
  787. attron(COLOR_PAIR(3));
  788. else
  789. attron(COLOR_PAIR(2));
  790. mvaddch(i,j,boss1.picture[i-boss1.y][j-boss1.x]);
  791. boss_p.push_back(point(j,i));
  792. }
  793. //REDRAW PLAYER
  794. for(auto play_point: player_p)
  795. mvaddch(play_point.y,play_point.x,' ');
  796. player_p.clear();
  797. if(player1.godmode) attron(COLOR_PAIR(5));
  798. else attron(COLOR_PAIR(1));
  799. for(int i=player1.x;i<player1.x+player1.length;++i)
  800. {
  801. mvaddch(player1.y,i,PLAYER_SPRITE);
  802. player_p.push_back(point(i,player1.y));
  803. }
  804. //REDRAW WALLS
  805. for(auto wall_p: walls_p)
  806. mvaddch(wall_p.y,wall_p.x,' ');
  807. walls_p.clear();
  808. for(std::size_t i=0;i<walls.size();i++)
  809. for(int k=0;k<walls[i].width;k++)
  810. for(int j=0;j<walls[i].height;j++){
  811. if(walls[i].health[j][k]==1) attron(COLOR_PAIR(2));
  812. else attron(COLOR_PAIR(4));
  813. if(walls[i].health[j][k]>0)
  814. {
  815. mvaddch(j+walls[i].y,k+walls[i].x,WALL_SPRITE);
  816. walls_p.push_back(point(k+walls[i].x,j+walls[i].y));
  817. }
  818. }
  819. }
  820. void drop_powerup(int x,int y,b_list& powerups)
  821. {
  822. 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"
  823. if((double)rand()/RAND_MAX<1./ROCKET_RATIO){ //1 powerup out of ROCKET_RATIO*POWERUP_RATIO is a "X" (ID 512)
  824. powerup newpowerup(x,y,512);
  825. powerups.push_back(newpowerup);
  826. }
  827. else{
  828. powerup newpowerup(x,y,128);
  829. powerups.push_back(newpowerup);
  830. }
  831. }
  832. else{
  833. powerup newpowerup(x,y); //otherwise, it is a "+"
  834. powerups.push_back(newpowerup);
  835. }
  836. }
  837. void interactions(player& player1,b_list& bullets,b_list& bombs,e_list& enemies,w_vec& walls,b_list& powerups,r_list& rockets,boss& boss1,int& score, double poweruprate){
  838. bool should_continue;
  839. b_list::iterator it1=bullets.begin();
  840. while(it1!=bullets.end())
  841. {
  842. should_continue = false;
  843. if(it1->y<=0)
  844. { //bullet reached the ceiling
  845. it1 = bullets.erase(it1);
  846. continue;
  847. }
  848. b_list::iterator it2 = bombs.begin();
  849. while(it2!=bombs.end())
  850. {
  851. if(it1->x==it2->x && (it1->y==it2->y || it1->y==it2->y+1)){ //bullet+bomb
  852. it1=bullets.erase(it1);
  853. should_continue = true;
  854. it2=bombs.erase(it2);
  855. score+=50;
  856. break;
  857. }
  858. else
  859. ++it2;
  860. }
  861. if(should_continue) continue;
  862. for(e_list::iterator it3=enemies.begin(); it3!=enemies.end(); ++it3)
  863. if(it1->x==it3->x && it1->y==it3->y && it3->alive){ //bullet+enemy
  864. it1=bullets.erase(it1);
  865. should_continue = true;
  866. it3->alive=false;
  867. if((double)rand()/RAND_MAX<poweruprate) //a powerup is dropped
  868. drop_powerup(it3->x,it3->y+1,powerups);
  869. score+=100;
  870. break;
  871. }
  872. if(should_continue) continue;
  873. if((it1->x>=boss1.x+boss1.width/2-2 && it1->x<=boss1.x+boss1.width/2+2) && it1->y<=boss1.y+boss1.height && boss1.alive){ //bullet+boss
  874. boss1.health--;
  875. if(it1->y==boss1.y) it1=bullets.erase(it1); //bullet gets destroyed only when has reached boss's top
  876. else
  877. {
  878. ++it1;
  879. continue;
  880. }
  881. //(to make the boss lose life more quickly)
  882. }
  883. ++it1;
  884. }
  885. r_list::iterator itr=rockets.begin();
  886. while(itr != rockets.end())
  887. {
  888. should_continue = false;
  889. if(itr->y<=0) //rocket reached the ceiling
  890. {
  891. itr=rockets.erase(itr);
  892. continue;
  893. }
  894. b_list::iterator it2=bombs.begin(); //bomb+rocket
  895. while(it2!=bombs.end())
  896. {
  897. if((itr->x==it2->x && itr->y==it2->y) || (itr->v>0 && (itr->x==it2->x-1 && itr->y==it2->y+1)) || (itr->v<0 && (itr->x==it2->x+1 && itr->y==it2->y+1))){ //rocket+bomb
  898. itr=rockets.erase(itr);
  899. should_continue = true;
  900. it2=bombs.erase(it2);
  901. score+=50;
  902. break;
  903. }
  904. else
  905. ++it2;
  906. }
  907. if(should_continue) continue;
  908. e_list::iterator it3 = enemies.begin();
  909. while(it3!=enemies.end())
  910. {
  911. if(itr->x==it3->x && itr->y==it3->y){ //rocket+enemy
  912. itr=rockets.erase(itr);
  913. it3=enemies.erase(it3);
  914. should_continue = true;
  915. break;
  916. }
  917. else
  918. ++it3;
  919. }
  920. if(should_continue) continue;
  921. if((itr->x>=boss1.x+boss1.width/2-2 && itr->x<=boss1.x+boss1.width/2+2) && itr->y<=boss1.y+boss1.height && boss1.alive) //rocket+boss
  922. {
  923. boss1.health--;
  924. if(itr->y==boss1.y)
  925. {
  926. itr=rockets.erase(itr);
  927. continue;
  928. }
  929. }
  930. ++itr;
  931. }
  932. b_list::iterator itb=bombs.begin();
  933. while(itb!=bombs.end()){
  934. if(itb->y>=R) //bomb reached the floor
  935. {
  936. itb=bombs.erase(itb);
  937. continue;
  938. }
  939. if(itb->x>=player1.x && itb->x<player1.x+player1.length && itb->y>player1.y) //bomb+player
  940. {
  941. itb=bombs.erase(itb);
  942. continue;
  943. }
  944. ++itb;
  945. }
  946. b_list::iterator itp=powerups.begin();
  947. while( itp!=powerups.end()){
  948. if(itp->y==player1.y && itp->x>=player1.x && itp->x<player1.x+player1.length){
  949. switch(itp->id){
  950. case 64:
  951. if(player1.weaponclass<MAX_WEAPONCLASS) player1.weaponclass++;
  952. break;
  953. case 128:
  954. if(player1.length>2){
  955. mvaddch(player1.y,player1.x+player1.length-1,' ');
  956. player1.length--;
  957. }
  958. break;
  959. case 512:
  960. if(!(player1.rocketlauncher)) player1.rocketlauncher=TRUE;
  961. else if(player1.weaponclassrkt<MAX_WEAPONCLASSRKT) player1.weaponclassrkt++;
  962. break;
  963. }
  964. itp=powerups.erase(itp);
  965. continue;
  966. }
  967. if(itp->y>=R) //powerup reached the floor
  968. {
  969. itp=powerups.erase(itp);
  970. continue;
  971. }
  972. ++itp;
  973. }
  974. for(size_t i=0;i<walls.size();i++)
  975. for(int j=0;j<walls[i].width;j++)
  976. for(int k=0;k<walls[i].height;k++)
  977. {
  978. if(walls[i].health[k][j]>0)
  979. {
  980. b_list::iterator it1=bullets.begin();
  981. while(it1!=bullets.end())
  982. {
  983. if(it1->x==walls[i].x+j && it1->y==walls[i].y+k){
  984. it1=bullets.erase(it1);
  985. walls[i].health[k][j]--;
  986. }
  987. else
  988. ++it1;
  989. }
  990. b_list::iterator it2=bombs.begin();
  991. while(it2!=bombs.end())
  992. {
  993. if(it2->x==walls[i].x+j && it2->y==walls[i].y+k){
  994. it2=bombs.erase(it2);
  995. walls[i].health[k][j]--;
  996. }
  997. else
  998. ++it2;
  999. }
  1000. r_list::iterator it3=rockets.begin();
  1001. while(it3!=rockets.end())
  1002. {
  1003. if(it3->x==walls[i].x+j && it3->y==walls[i].y+k){
  1004. it3=rockets.erase(it3);
  1005. walls[i].health[k][j]--;
  1006. }
  1007. else
  1008. ++it3;
  1009. }
  1010. b_list::iterator it4=powerups.begin();
  1011. while(it4!=powerups.end())
  1012. {
  1013. if(it4->x==walls[i].x+j && it4->y==walls[i].y+k){
  1014. it4=powerups.erase(it4);
  1015. }
  1016. else
  1017. ++it4;
  1018. }
  1019. }
  1020. }
  1021. }
  1022. //********** SAVE FUNCTIONS *****************************
  1023. void refreshrecords(int newscore,WINDOW* win)
  1024. {
  1025. r_vec records;
  1026. std::string nick;
  1027. record newrecord;
  1028. std::string local_recpath;
  1029. std::string local_dir=getenv("HOME"); //get environment variable $HOME
  1030. local_dir+=RECORD_DIR; //we set local_dir and local_recpath: ~/.local/share/invaders/records.dat
  1031. local_recpath=local_dir;
  1032. local_recpath+=RECORD_FILE;
  1033. wattron(win,COLOR_PAIR(5));
  1034. mvwprintw(win,6,5,"Please insert your nick");
  1035. mvwprintw(win,7,2,"(up to 5 characters): ");
  1036. wattron(win,COLOR_PAIR(1));
  1037. echo();
  1038. char getnick[6];
  1039. wscanw(win,"%s",getnick);
  1040. nick=getnick;
  1041. nick.resize(5,'.');
  1042. noecho();
  1043. std::ifstream recordin(local_recpath.c_str()); //first, check if local_recpath exists; if not, create it.
  1044. if(recordin) //note that local_recpath is actually a symlink to global_recpath
  1045. {
  1046. recordin >> newrecord.nick;
  1047. recordin >> newrecord.score;
  1048. while(!recordin.eof())
  1049. {
  1050. records.push_back(newrecord);
  1051. recordin >> newrecord.nick;
  1052. recordin >> newrecord.score;
  1053. }
  1054. recordin.close();
  1055. newrecord.score=newscore;
  1056. newrecord.nick=nick;
  1057. records.push_back(newrecord);
  1058. sort(records.rbegin(), records.rend());
  1059. wattron(win,COLOR_PAIR(6));
  1060. mvwprintw(win,9,11,"TOP FIVE");
  1061. wattron(win,COLOR_PAIR(0));
  1062. int count=0;
  1063. for(r_vec::iterator it=records.begin(); (it!=records.begin()+5 && it!=records.end()); ++it,++count)
  1064. {
  1065. wmove(win,10+count,9);
  1066. it->printwin(win);
  1067. }
  1068. count=0;
  1069. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it)
  1070. {
  1071. count++;
  1072. if(*it==newrecord)
  1073. {
  1074. mvwprintw(win,16,3,"You're number %i out of %i",count,records.size());
  1075. break;
  1076. }
  1077. }
  1078. std::ofstream recordout(local_recpath.c_str());
  1079. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it)
  1080. it->print(recordout);
  1081. recordout.close();
  1082. }
  1083. else //records.dat not found
  1084. {
  1085. //if local_recpath does not exist, then we must create the local_dir.
  1086. recordin.close();
  1087. recordin.clear();
  1088. create_folder(0);
  1089. //now we check if global_recpath exists.
  1090. std::string global_recpath=GLOBAL_DIR; //global_recpath is GLOBAL_DIR/records.dat
  1091. global_recpath+=RECORD_FILE;
  1092. //we try to open GLOBAL_DIR/records.dat
  1093. std::ifstream globalin(global_recpath.c_str());
  1094. if(!globalin){
  1095. globalin.close();
  1096. globalin.clear();
  1097. create_folder(1); //try to create global_dir (will fail if already
  1098. std::ofstream globalout(global_recpath.c_str()); //exists) and save the global_recpath.
  1099. globalout.close();
  1100. globalout.clear();
  1101. chmod(global_recpath.c_str(),S_IRWXG | S_IRWXU | S_IRWXO);
  1102. }
  1103. else{
  1104. //just save to GLOBAL_DIR/records.dat
  1105. globalin >> newrecord.nick;
  1106. globalin >> newrecord.score;
  1107. while(!globalin.eof())
  1108. {
  1109. records.push_back(newrecord);
  1110. globalin >> newrecord.nick;
  1111. globalin >> newrecord.score;
  1112. }
  1113. globalin.close();
  1114. }
  1115. //finally, create the symlink to global_recpath
  1116. symlink(global_recpath.c_str(),local_recpath.c_str());
  1117. newrecord.score=newscore;
  1118. newrecord.nick=nick;
  1119. records.push_back(newrecord);
  1120. sort(records.rbegin(), records.rend());
  1121. //and save there the records.
  1122. std::ofstream recordout(local_recpath.c_str());
  1123. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it)
  1124. it->print(recordout);
  1125. recordout.close();
  1126. }
  1127. }
  1128. void print_scores(){
  1129. r_vec records;
  1130. std::string recordpath;
  1131. std::string record_dir=getenv("HOME");
  1132. record_dir+=RECORD_DIR;
  1133. recordpath=record_dir;
  1134. recordpath+=RECORD_FILE;
  1135. std::ifstream recordin(recordpath.c_str());
  1136. record newrecord;
  1137. int i=1;
  1138. if(recordin){
  1139. WINDOW *recs;
  1140. recs=newwin(25,30,0,0);
  1141. box(recs,ACS_VLINE,ACS_HLINE);
  1142. wattron(recs,COLOR_PAIR(5));
  1143. mvwprintw(recs,1,1,"======= HIGHSCORES =======");
  1144. wattron(recs,COLOR_PAIR(0));
  1145. recordin >> newrecord.nick;
  1146. recordin >> newrecord.score;
  1147. while(!recordin.eof() && i<21)
  1148. {
  1149. records.push_back(newrecord);
  1150. recordin >> newrecord.nick;
  1151. recordin >> newrecord.score;
  1152. i++;
  1153. }
  1154. recordin.close();
  1155. i=1;
  1156. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it){
  1157. if(i<10)
  1158. mvwprintw(recs,i+2,1,"0%i- ",i);
  1159. else
  1160. mvwprintw(recs,i+2,1,"%i- ",i);
  1161. it->printwin(recs);
  1162. i++;
  1163. }
  1164. wrefresh(recs);
  1165. timeout(-1);
  1166. if(getch()!=ERR){
  1167. delwin(recs);
  1168. erase();
  1169. refresh();
  1170. }
  1171. }
  1172. else{
  1173. WINDOW *recs;
  1174. std::string host=getenv("USER");
  1175. recs=newwin(5,3+host.length()+record_dir.length(),5,5);
  1176. box(recs,ACS_VLINE,ACS_HLINE);
  1177. wattron(recs,COLOR_PAIR(5));
  1178. mvwprintw(recs,1,1,"Save file:");
  1179. mvwprintw(recs,2,1,"%s",record_dir.c_str());
  1180. mvwprintw(recs,3,1,"%s not found.",RECORD_FILE);
  1181. //mvwprintw(recs,4,1,"not found.");
  1182. wrefresh(recs);
  1183. timeout(-1);
  1184. if(getch()!=ERR){
  1185. delwin(recs);
  1186. erase();
  1187. refresh();
  1188. }
  1189. }
  1190. }
  1191. //=========== THREADS FUNCTIONS ==============================
  1192. void *pmusic(void *arg){
  1193. while(1){
  1194. system("beep 330 -l 150 -n -f 1 -l 40 -n -f 494 -l 159 -n -f 1 -l 40 -n -f 660 -l 150 -n -f 1 -l 40 -n -f 590 -l 150 -n -f 660 -l 150 -n -f 494 -l 100 -n -f 494 -l 100 -n -f 523 -l 150 -n -f 1 -l 40 -n -f 440 -l 150 -n -f 1 -l 40 -n -f 494 -l 150 -n -f 1 -l 40 -n -f 392 -l 100 -n -f 392 -l 100 -n -f 440 -l 150 -n -f 370 -l 150 -n -f 1 -l 40 -n -f 392 -l 150 -n -f 1 -l 40 -n -f 330 -l 100 -n -f 330 -l 100 -n -f 370 -l 150 -n -f 1 -l 40 -n -f 294 -l 150 -n -f 1 -l 40 -n -f 330 -l 150 -n -f 247 -l 100 -n -f 247 -l 100 -n -f 261 -l 150 -n -f 1 -l 40 -n -f 311 -l 150 -n -f 1 -l 40 -n -f 330 -l 150 -n -f 1 -l 40 -n -f 247 -l 100 -n -f 247 -l 100 -n -f 262 -l 150 -n -f 1 -l 40 -n -f 370 -l 150 -n -f 1 -l 40 -n -f 330 -l 150 -n -f 1 -l 40 -n -f 494 -l 159 -n -f 1 -l 40 -n -f 660 -l 150 -n -f 1 -l 40 -n -f 590 -l 150 -n -f 660 -l 150 -n -f 494 -l 100 -n -f 494 -l 100 -n -f 523 -l 150 -n -f 1 -l 40 -n -f 440 -l 150 -n -f 1 -l 40 -n -f 494 -l 150 -n -f 1 -l 40 -n -f 392 -l 100 -n -f 392 -l 100 -n -f 440 -l 150 -n -f 370 -l 150 -n -f 1 -l 40 -n -f 392 -l 150 -n -f 1 -l 40 -n -f 330 -l 100 -n -f 330 -l 100 -n -f 370 -l 150 -n -f 1 -l 40 -n -f 294 -l 150 -n -f 1 -l 40 -n -f 330 -l 150 -n -f 247 -l 100 -n -f 247 -l 100 -n -f 261 -l 150 -n -f 1 -l 40 -n -f 311 -l 150 -n -f 1 -l 40 -n -f 330 -l 150 -n -f 1 -l 40 -n -f 247 -l 100 -n -f 247 -l 100 -n -f 262 -l 150 -n -f 1 -l 40 -n -f 370 -l 150 -n -f 1 -l 40 -n -f 330 -l 150 -n -f 1 -l 40 2> /dev/null");
  1195. napms(2000);
  1196. }
  1197. (void)arg; // Werror=unused-parameter
  1198. return NULL;
  1199. }
  1200. void *pshoot_sound(void *arg){
  1201. system("beep -f 1000 -l 30 -n -f 850 -l 30 2> /dev/null");
  1202. (void)arg; // Werror=unused-parameter
  1203. return NULL;
  1204. }
  1205. void *penshoot_sound(void *arg){
  1206. system("beep -f 1500 -l 30 -n -f 1000 -l 30 2> /dev/null");
  1207. (void)arg; // Werror=unused-parameter
  1208. return NULL;
  1209. }
  1210. void *pwin_theme(void *arg){
  1211. system("beep -f 1000 -l 150 -n -f 800 -l 150 -n -f 1000 -l 150 -n -f 1500 -l 600 2> /dev/null");
  1212. (void)arg; // Werror=unused-parameter
  1213. return NULL;
  1214. }
  1215. void *plose_theme(void *arg){
  1216. system("beep -f 700 -l 150 -n -f 585 -l 150 -n -f 550 -l 150 -n -f 520 -l 600 2> /dev/null");
  1217. (void)arg; // Werror=unused-parameter
  1218. return NULL;
  1219. }
  1220. void pkill_music(pthread_t thread){
  1221. pthread_cancel(thread);
  1222. system("beep -f 1 2> /dev/null");
  1223. system("pkill beep"); // May be too brutal
  1224. }
  1225. //=========BOSSRUSH FUNCTIONS=======================
  1226. int choose_level_bossrush(int* commands)
  1227. {
  1228. std::string phrase;
  1229. phrase=choose_phrase();
  1230. char input;
  1231. do{
  1232. print_title();
  1233. print_catchphrase(phrase);
  1234. attron(COLOR_PAIR(1));
  1235. mvprintw(5,0,"Choose difficulty level:");
  1236. attron(COLOR_PAIR(1));
  1237. mvprintw(6,0,"1- Easy");
  1238. attron(COLOR_PAIR(3));
  1239. mvprintw(7,0,"2- Medium");
  1240. attron(COLOR_PAIR(2));
  1241. mvprintw(8,0,"3- Hard");
  1242. attron(COLOR_PAIR(4));
  1243. mvprintw(9,0,"4- Impossible");
  1244. attron(COLOR_PAIR(5));
  1245. mvprintw(10,0,"i- Info");
  1246. attron(COLOR_PAIR(6));
  1247. mvprintw(11,0,"h- Highscores");
  1248. attron(COLOR_PAIR(1));
  1249. mvprintw(12,0,"c- Commands");
  1250. attron(COLOR_PAIR(2));
  1251. mvprintw(13,0,"q- Quit");
  1252. refresh();
  1253. timeout(80);
  1254. input=tolower(getch());
  1255. if(!(input=='1' || input=='2' || input=='3' || input=='4' || input=='i' || input=='h' || input=='r' || input=='q') && input!=ERR){
  1256. attron(COLOR_PAIR(2));
  1257. mvprintw(14,0,"Bad input. Please choose a number within 1 and 4.");
  1258. attron(COLOR_PAIR(0));
  1259. }
  1260. if(input=='i')
  1261. print_info();
  1262. else if(input=='h')
  1263. print_scores_bossrush();
  1264. else if(input=='r')
  1265. phrase=choose_phrase();
  1266. else if(input=='c')
  1267. change_commands(commands);
  1268. else if(input=='q'){
  1269. endwin();
  1270. cout<<lightgreen<<"Game exited correctly."<<none<<endl;
  1271. exit(1);
  1272. }
  1273. }while(!(input=='1' || input=='2' || input=='3' || input=='4'));
  1274. return input - '0';
  1275. }
  1276. void setup_level_bossrush(int level, double& shootr, double& poweruprate, int& walls_num, int& refresh_t)
  1277. {
  1278. walls_num = 3;
  1279. switch(level) //setting game parameters
  1280. {
  1281. case 1:
  1282. {
  1283. shootr = 0.02;
  1284. refresh_t = (int)(0.07*1E3);
  1285. poweruprate = 0.04;
  1286. break;
  1287. }
  1288. case 2:
  1289. {
  1290. shootr = 0.02;
  1291. refresh_t = (int)(0.07*1E3);
  1292. poweruprate = 0.04;
  1293. break;
  1294. }
  1295. case 3:
  1296. {
  1297. shootr = 0.02;
  1298. refresh_t = (int)(0.07*1E3);
  1299. poweruprate = 0.04;
  1300. break;
  1301. }
  1302. case 4:
  1303. {
  1304. shootr = 0.02;
  1305. refresh_t = (int)(0.07*1E3);
  1306. poweruprate = 0.04;
  1307. walls_num = 2;
  1308. break;
  1309. }
  1310. }
  1311. }
  1312. void resetbosses(boss* Bosses,boss& boss1,player& player1,int level){
  1313. boss* bosses=Bosses;
  1314. bosses->health=bosses->healthmax;
  1315. bosses++;
  1316. bosses->health=bosses->healthmax;
  1317. bosses++;
  1318. bosses->health=bosses->healthmax;
  1319. bosses++;
  1320. bosses->health=bosses->healthmax;
  1321. bosses++;
  1322. bosses->health=bosses->healthmax;
  1323. boss1=*Bosses;
  1324. boss1.alive=true;
  1325. // NOTE(jp): level starts from 1
  1326. switch (level) {
  1327. case 1:
  1328. player1.weaponclass=2;
  1329. break;
  1330. case 2:
  1331. case 3:
  1332. player1.weaponclass=1;
  1333. break;
  1334. default:
  1335. player1.weaponclass=0;
  1336. break;
  1337. }
  1338. }
  1339. void Victory_bossrush(std::string name,int score,int level,int chflag){
  1340. score+=1500*level;
  1341. WINDOW *victory;
  1342. victory=newwin(19,32,7,17);
  1343. box(victory,ACS_VLINE,ACS_HLINE);
  1344. wattron(victory,COLOR_PAIR(1));
  1345. mvwprintw(victory,2,5,"YOU DEFEATED %s!",name.c_str());
  1346. wattron(victory,COLOR_PAIR(3));
  1347. mvwprintw(victory,4,5,"+ %i pts!",level*1500);
  1348. wattron(victory,COLOR_PAIR(1));
  1349. mvwprintw(victory,4,5,"YOU WON!");
  1350. wattron(victory,COLOR_PAIR(3));
  1351. mvwprintw(victory,4,5,"Your score is: %i",score);
  1352. wrefresh(victory);
  1353. if(chflag==0)
  1354. refreshrecords_bossrush(score,victory);
  1355. else{
  1356. wattron(victory,COLOR_PAIR(4));
  1357. mvwprintw(victory,7,3,"I think you used cheats...");
  1358. }
  1359. wrefresh(victory);
  1360. delwin(victory);
  1361. }
  1362. void refreshrecords_bossrush(int newscore,WINDOW* win)
  1363. {
  1364. r_vec records;
  1365. std::string nick;
  1366. record newrecord;
  1367. std::string local_recpath;
  1368. std::string local_dir=getenv("HOME"); //get environment variable $HOME
  1369. local_dir+=RECORD_DIR; //we set local_dir and local_recpath: ~/.local/share/invaders/records_bossrush.dat
  1370. local_recpath=local_dir;
  1371. local_recpath+=RECORD_FILE_BOSSRUSH;
  1372. wattron(win,COLOR_PAIR(5));
  1373. mvwprintw(win,6,5,"Please insert your nick");
  1374. mvwprintw(win,7,2,"(up to 5 characters): ");
  1375. wattron(win,COLOR_PAIR(1));
  1376. echo();
  1377. char getnick[6];
  1378. wscanw(win,"%s",getnick);
  1379. nick=getnick;
  1380. nick.resize(5,'.');
  1381. noecho();
  1382. std::ifstream recordin(local_recpath.c_str());
  1383. if(recordin)
  1384. {
  1385. recordin >> newrecord.nick;
  1386. recordin >> newrecord.score;
  1387. while(!recordin.eof())
  1388. {
  1389. records.push_back(newrecord);
  1390. recordin >> newrecord.nick;
  1391. recordin >> newrecord.score;
  1392. }
  1393. recordin.close();
  1394. newrecord.score=newscore;
  1395. newrecord.nick=nick;
  1396. records.push_back(newrecord);
  1397. sort(records.rbegin(), records.rend());
  1398. wattron(win,COLOR_PAIR(6));
  1399. mvwprintw(win,9,11,"TOP FIVE");
  1400. wattron(win,COLOR_PAIR(0));
  1401. int count=0;
  1402. for(r_vec::iterator it=records.begin(); (it!=records.begin()+5 && it!=records.end()); ++it,++count)
  1403. {
  1404. wmove(win,10+count,9);
  1405. it->printwin(win);
  1406. }
  1407. count=0;
  1408. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it)
  1409. {
  1410. count++;
  1411. if(*it==newrecord)
  1412. {
  1413. mvwprintw(win,16,3,"You're number %i out of %i",count,records.size());
  1414. break;
  1415. }
  1416. }
  1417. std::ofstream recordout(local_recpath.c_str());
  1418. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it)
  1419. it->print(recordout);
  1420. recordout.close();
  1421. }
  1422. else //records_bossrush.dat not found
  1423. {
  1424. recordin.close();
  1425. recordin.clear();
  1426. create_folder(0); //this will fail if local_dir already exists (possible if player played bossrush before).
  1427. //now we check if global_recpath exists.
  1428. std::string global_recpath=GLOBAL_DIR; //global_recpath is GLOBAL_DIR/records_bossrush.dat
  1429. global_recpath+=RECORD_FILE_BOSSRUSH;
  1430. //we try to open GLOBAL_DIR/records.dat
  1431. std::ifstream globalin(global_recpath.c_str());
  1432. if(!globalin){
  1433. globalin.close();
  1434. globalin.clear();
  1435. create_folder(1); //try to create global_dir (will fail if already
  1436. std::ofstream globalout(global_recpath.c_str()); //exists) and save the global_recpath.
  1437. globalout.close();
  1438. globalout.clear();
  1439. chmod(global_recpath.c_str(),S_IRWXG | S_IRWXU | S_IRWXO);
  1440. }
  1441. else{
  1442. //just save to GLOBAL_DIR/records_bossrush.dat
  1443. globalin >> newrecord.nick;
  1444. globalin >> newrecord.score;
  1445. while(!globalin.eof())
  1446. {
  1447. records.push_back(newrecord);
  1448. globalin >> newrecord.nick;
  1449. globalin >> newrecord.score;
  1450. }
  1451. globalin.close();
  1452. }
  1453. //finally, create the symlink to global_recpath
  1454. symlink(global_recpath.c_str(),local_recpath.c_str());
  1455. newrecord.score=newscore;
  1456. newrecord.nick=nick;
  1457. records.push_back(newrecord);
  1458. sort(records.rbegin(), records.rend());
  1459. //and save there the records.
  1460. std::ofstream recordout(local_recpath.c_str());
  1461. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it)
  1462. it->print(recordout);
  1463. recordout.close();
  1464. }
  1465. }
  1466. void print_scores_bossrush(){
  1467. r_vec records;
  1468. std::string recordpath;
  1469. std::string record_dir=getenv("HOME");
  1470. record_dir+=RECORD_DIR;
  1471. recordpath=record_dir;
  1472. recordpath+=RECORD_FILE_BOSSRUSH;
  1473. std::ifstream recordin(recordpath.c_str());
  1474. record newrecord;
  1475. int i=1;
  1476. if(recordin){
  1477. WINDOW *recs;
  1478. recs=newwin(25,30,0,0);
  1479. box(recs,ACS_VLINE,ACS_HLINE);
  1480. wattron(recs,COLOR_PAIR(5));
  1481. mvwprintw(recs,1,1,"======= HIGHSCORES =======");
  1482. wattron(recs,COLOR_PAIR(0));
  1483. recordin >> newrecord.nick;
  1484. recordin >> newrecord.score;
  1485. while(!recordin.eof() && i<21)
  1486. {
  1487. records.push_back(newrecord);
  1488. recordin >> newrecord.nick;
  1489. recordin >> newrecord.score;
  1490. i++;
  1491. }
  1492. recordin.close();
  1493. i=1;
  1494. for(r_vec::iterator it=records.begin(); it!=records.end(); ++it){
  1495. if(i<10)
  1496. mvwprintw(recs,i+2,1,"0%i- ",i);
  1497. else
  1498. mvwprintw(recs,i+2,1,"%i- ",i);
  1499. it->printwin(recs);
  1500. i++;
  1501. }
  1502. wrefresh(recs);
  1503. timeout(-1);
  1504. if(getch()!=ERR){
  1505. delwin(recs);
  1506. erase();
  1507. refresh();
  1508. }
  1509. }
  1510. else{
  1511. WINDOW *recs;
  1512. std::string host=getenv("USER");
  1513. recs=newwin(6,25+host.length(),5,5);
  1514. box(recs,ACS_VLINE,ACS_HLINE);
  1515. wattron(recs,COLOR_PAIR(5));
  1516. mvwprintw(recs,1,1,"Save file:");
  1517. mvwprintw(recs,2,1,"%s",record_dir.c_str());
  1518. mvwprintw(recs,3,1,"%s",RECORD_FILE_BOSSRUSH);
  1519. mvwprintw(recs,4,1,"not found.");
  1520. wrefresh(recs);
  1521. timeout(-1);
  1522. if(getch()!=ERR){
  1523. delwin(recs);
  1524. erase();
  1525. refresh();
  1526. }
  1527. }
  1528. }
  1529. void create_readme(){
  1530. std::string recordpath;
  1531. std::string record_dir=getenv("HOME");
  1532. record_dir+=RECORD_DIR;
  1533. recordpath=record_dir;
  1534. recordpath+="README.txt";
  1535. std::ifstream checkread(recordpath.c_str());
  1536. if(!checkread){
  1537. checkread.close();
  1538. checkread.clear();
  1539. std::ofstream readme(recordpath.c_str());
  1540. readme<<"#==Space Invaders=="<<endl;
  1541. readme<<"#"<<endl;
  1542. readme<<"#Original game was created and developed by Giacomo Parolini and Enrico Guiraud (year 2010-2013)"<<endl;
  1543. readme<<"#License: GNU GPL"<<endl;
  1544. readme<<"#"<<endl;
  1545. readme<<"#Game version logs:"<<endl;
  1546. readme<<"# -invaders2.0"<<endl;
  1547. readme<<"# -invaders2.1"<<endl;
  1548. readme<<"# -invaders3.0"<<endl;
  1549. readme<<"# -invaders3.1"<<endl;
  1550. readme<<"# -invaders3.2"<<endl;
  1551. readme<<"# -invaders3.3"<<endl;
  1552. readme<<"# -invaders3.4"<<endl;
  1553. readme<<"# -invaders3.5"<<endl;
  1554. readme<<"# -invaders3.6"<<endl;
  1555. readme<<"# -invaders4.0"<<endl;
  1556. readme<<"# -invaders4.1"<<endl;
  1557. readme<<"# -invaders4.2"<<endl;
  1558. readme<<"# -invaders4.3"<<endl;
  1559. readme<<"# -invaders4.3.5"<<endl;
  1560. readme<<"# -curses_invaders2.0"<<endl;
  1561. readme<<"# -curses_invaders3.0"<<endl;
  1562. readme<<"# -curses_invaders3.5"<<endl;
  1563. readme<<"# -curses_invaders4.0"<<endl;
  1564. readme<<"# -curses_invaders4.1"<<endl;
  1565. readme<<"# -curses_invaders4.2"<<endl;
  1566. readme<<"# -curses_invaders4.3"<<endl;
  1567. readme<<"# -curses_invaders4.4"<<endl;
  1568. readme<<"# -GL_invaders"<<endl;
  1569. readme<<"#"<<endl;
  1570. readme<<"#All versions are written in C++. "<<endl;
  1571. readme<<"#"<<endl;
  1572. readme<<"#curses_invaders versions were developed by Giacomo Parolini and differ from the previous ones for exploiting library <ncurses.h> for graphic terminal management."<<endl;
  1573. readme<<"#GL_invaders versions were developed by Enrico Guiraud and exploit GL libraries such as <glutm/window.h> and <glt/project.h> for graphics."<<endl;
  1574. readme<<"#"<<endl;
  1575. readme<<"#System Requirements:"<<endl;
  1576. readme<<"#All versions are Linux x-executable files, so will only run within Linux environment."<<endl;
  1577. readme<<"#However, files CAN be compiled also in MacOS environment."<<endl;
  1578. readme<<"#"<<endl;
  1579. readme<<"#curses_invaders versions require the library <ncurses.h> and may not work correctly on some terminals. Versions 3.0 and following also contain executable \"bossrush\"."<<endl;
  1580. readme<<"#"<<endl;
  1581. readme<<"#since v.4.3, game controls are customizable at the beginning of the game."<<endl;
  1582. readme<<"#v.4.4 implements shared highscores."<<endl;
  1583. readme<<"#"<<endl;
  1584. readme<<"#"<<endl;
  1585. readme<<"#CREATING AND EDITING BOSSES (at the moment unavailable: the game doesn't create the scripts automatically)"<<endl;
  1586. readme<<"#curses_invaders4.0 and following also come with the scripts checkboss.sh and setboss.sh, written by Enrico Guiraud. These scripts are used to edit the five game bosses, allowing the player to create his custom bosses. "<<endl;
  1587. readme<<"#In order to create a boss, follow these steps:"<<endl;
  1588. readme<<"# *1: create a file named <custom_boss_name>.dat and open it with any text editor (like Gedit, Vim or Notepad)."<<endl;
  1589. readme<<"# *2: \"draw\" your boss in ASCII-style. You don't have to pay attention of the rows' lengths, as checkboss.sh will fix them automatically. Just be sure the lines and the columns fit the game board (game board's dimensions are written in definitions.hpp as \"R\" and \"C\")."<<endl;
  1590. readme<<"# *3: save your file.dat and launch either checkboss.sh (if you just want to adjust your boss's dimensions) or directly setboss.sh (to add the boss to the game). Syntax of checkboss.sh is \"./checkboss.sh <bossname.dat>\" or \"./checkboss <bossname>\". Syntax of setboss.sh is \"./setboss.sh <bossname> <level>\"; the script will substitute the boss of the <level>-th game level (1=easy, 2=medium, 3=hard, 4=impossible, 5=special boss) with your custom boss. Notice that setboss.sh needs you to pass the argument WITHOUT the \".dat\"."<<endl;
  1591. readme<<"# *4: play to test your new boss! If you want to restore the original boss, just run setboss.sh once again passing the original boss as argument."<<endl;
  1592. readme<<"#"<<endl;
  1593. readme<<"#...and yes: cheats ARE available, just try and find them ;)"<<endl;
  1594. readme.close();
  1595. }
  1596. }
  1597. void create_std_bosses(){
  1598. std::string bosspath;
  1599. std::string boss_dir=getenv("HOME");
  1600. boss_dir+=RECORD_DIR;
  1601. bosspath=boss_dir;
  1602. std::string bosspath1=bosspath+BOSS_FILE1+".dat";
  1603. std::ifstream checkread(bosspath1.c_str());
  1604. if(!checkread){
  1605. std::string newrecordpath=boss_dir+RECORD_FILE; //check if .invaders/records.dat exists
  1606. std::ifstream tryrecord(newrecordpath.c_str());
  1607. if(!tryrecord){ //.invaders/records.dat does not exist, so create the .invaders directory
  1608. tryrecord.close();
  1609. tryrecord.clear();
  1610. std::string newrecordpath2=boss_dir+RECORD_FILE_BOSSRUSH; //check if .invaders/records_bossrush.dat exists
  1611. std::ifstream tryrecord2(newrecordpath2.c_str());
  1612. if(!tryrecord2){
  1613. tryrecord2.close();
  1614. tryrecord2.clear();
  1615. mkdir(boss_dir.c_str(),S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
  1616. create_readme();
  1617. //create_setsize();
  1618. //std::string setsizepath=boss_dir+"setsize.sh";
  1619. //chmod(setsizepath.c_str(),S_IRWXU);
  1620. }
  1621. }
  1622. checkread.close();
  1623. checkread.clear();
  1624. std::ofstream boss1(bosspath1.c_str());
  1625. boss1<<" _____ "<<endl;
  1626. boss1<<"// \\\\"<<endl;
  1627. boss1<<"| 0 0 |"<<endl;
  1628. boss1<<"c L P"<<endl;
  1629. boss1<<"\\ MMM /"<<endl;
  1630. boss1<<" \\_____/ "<<endl;
  1631. boss1.close();
  1632. boss1.clear();
  1633. std::string bosspath2=bosspath+BOSS_FILE2+".dat";
  1634. std::ofstream boss2(bosspath2.c_str());
  1635. boss2<<" _______ "<<endl;
  1636. boss2<<" W _ _ _ W "<<endl;
  1637. boss2<<"|_|o| |o|_|"<<endl;
  1638. boss2<<"c c P"<<endl;
  1639. boss2<<" \\__NNN__/ "<<endl;
  1640. boss2.close();
  1641. boss2.clear();
  1642. std::string bosspath3=bosspath+BOSS_FILE3+".dat";
  1643. std::ofstream boss3(bosspath3.c_str());
  1644. boss3<<" 99999 "<<endl;
  1645. boss3<<" C \\ / D "<<endl;
  1646. boss3<<"C 0 0 D"<<endl;
  1647. boss3<<"C_ ^ _D"<<endl;
  1648. boss3<<" | J | "<<endl;
  1649. boss3<<" \\_/ "<<endl;
  1650. boss3.close();
  1651. boss3.clear();
  1652. std::string bosspath4=bosspath+BOSS_FILE4+".dat";
  1653. std::ofstream boss4(bosspath4.c_str());
  1654. boss4<<" MMMMMMM "<<endl;
  1655. boss4<<" M M "<<endl;
  1656. boss4<<"| == == |"<<endl;
  1657. boss4<<"c L D"<<endl;
  1658. boss4<<" MMM MMM "<<endl;
  1659. boss4<<" MMMMMMM "<<endl;
  1660. boss4.close();
  1661. boss4.clear();
  1662. std::string bosspath5=bosspath+BOSS_FILE5+".dat";
  1663. std::ofstream boss5(bosspath5.c_str());
  1664. boss5<<" \\__ ______ __/ "<<endl;
  1665. boss5<<"\\___ = = ___/ "<<endl;
  1666. boss5<<" | | = = | | "<<endl;
  1667. boss5<<" \\_ _/ "<<endl;
  1668. boss5<<" / || \\ "<<endl;
  1669. boss5.close();
  1670. boss5.clear();
  1671. }
  1672. }
  1673. /*void create_setsize(){
  1674. std::string recordpath;
  1675. std::string record_dir=getenv("HOME");
  1676. record_dir+=RECORD_DIR;
  1677. recordpath=record_dir;
  1678. recordpath+="setsize.sh";
  1679. std::ifstream checkread(recordpath.c_str());
  1680. if(!checkread){
  1681. checkread.close();
  1682. checkread.clear();
  1683. std::ofstream setsize(recordpath.c_str());
  1684. setsize<<"#!/bin/bash"<<endl;
  1685. setsize<<"DEFAULT_R=30"<<endl;
  1686. setsize<<"DEFAULT_C=60"<<endl;
  1687. setsize<<"R=0"<<endl;
  1688. setsize<<"C=0"<<endl;
  1689. setsize<<"INPUT_FILE=definitions.hpp"<<endl;
  1690. setsize<<"trap \"rm $INPUT_FILE.tmp 2> /dev/null; exit -1\" SIGINT SIGTERM"<<endl;
  1691. setsize<<"if [[ $1 == \"default\" ]]; then"<<endl;
  1692. setsize<<"sed s/\"#define R [0-9]*\"/\"#define R $DEFAULT_R\"/ <$INPUT_FILE >$INPUT_FILE.tmp"<<endl;
  1693. setsize<<"sed s/\"#define C [0-9]*\"/\"#define C $DEFAULT_C\"/ <$INPUT_FILE.tmp >$INPUT_FILE"<<endl;
  1694. setsize<<"rm $INPUT_FILE.tmp"<<endl;
  1695. setsize<<"make clean"<<endl;
  1696. setsize<<"make -j4"<<endl;
  1697. setsize<<"exit 0"<<endl;
  1698. setsize<<"elif [[ $# -gt 0 ]]; then echo Usage: $0 \"[default]\"; exit 1"<<endl;
  1699. setsize<<"else"<<endl;
  1700. setsize<<"echo Insert new Row number \\(5-120\\)"<<endl;
  1701. setsize<<"until [[ $R -ge 5 && $R -le 120 ]]; do"<<endl;
  1702. setsize<<" read R"<<endl;
  1703. setsize<<"if [[ $R -lt 5 || $R -gt 120 ]]; then echo Invalid size.; fi"<<endl;
  1704. setsize<<"echo New R will be $R"<<endl;
  1705. setsize<<"done"<<endl;
  1706. setsize<<"echo Insert new Column number \\(5-120\\)"<<endl;
  1707. setsize<<"until [[ $C -ge 5 && $C -le 120 ]]; do"<<endl;
  1708. setsize<<" read C"<<endl;
  1709. setsize<<"if [[ $C -lt 5 || $C -gt 120 ]]; then echo Invalid size.; fi"<<endl;
  1710. setsize<<"echo New C will be $C"<<endl;
  1711. setsize<<"done"<<endl;
  1712. setsize<<"sed s/\"#define R [0-9]*\"/\"#define R $R\"/ <$INPUT_FILE >$INPUT_FILE.tmp"<<endl;
  1713. setsize<<"sed s/\"#define C [0-9]*\"/\"#define C $C\"/ <$INPUT_FILE.tmp >$INPUT_FILE"<<endl;
  1714. setsize<<"rm $INPUT_FILE.tmp"<<endl;
  1715. setsize<<"make clean"<<endl;
  1716. setsize<<"make -j4"<<endl;
  1717. setsize<<"fi"<<endl;
  1718. setsize.close();
  1719. }
  1720. }*/
  1721. void create_folder(int flag){ //0: local, 1: global
  1722. switch(flag){
  1723. case 1:
  1724. if(mkdir(GLOBAL_DIR,S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)==0){ //this will fail if local_dir already
  1725. create_readme(); //exists (possible if player played
  1726. create_std_bosses(); //bossrush before).
  1727. //create_setsize();
  1728. }
  1729. break;
  1730. default:
  1731. {
  1732. std::string local_dir=getenv("HOME");
  1733. local_dir+=RECORD_DIR;
  1734. if(mkdir(local_dir.c_str(),S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)==0){ //this will fail if local_dir already
  1735. create_readme(); //exists (possible if player played
  1736. create_std_bosses(); //bossrush before).
  1737. //create_setsize();
  1738. }
  1739. }
  1740. }
  1741. }