/* This file is part of Invaders. * * Copyright (C) 2020 LCM. * You may use, distribute and modify Invaders under the terms of the * GPLv3 license, available at . */ #include "bullet.hpp" #include "enemy.hpp" #include "player.hpp" #include "boss.hpp" #include "powerup.hpp" #include "definitions.hpp" #include "functions.hpp" #include "wall.hpp" using std::cout; using std::endl; using std::min; int main(int argc,char** argv) { if(argc>1){ if(strcmp(argv[1],"--uber-debug")!=0 && strcmp(argv[1],"--info")!=0 && strcmp(argv[1],"--autowin")!=0){ cout<<"Usage: "< b_list; typedef std::list e_list; typedef std::vector w_vec; typedef std::list r_list; srand(time(NULL)); //OBJECTS INIZIALIZATION player player1; //player is automatically created in [C/2][R] e_list enemies; //vector of enemies b_list bullets; //list of player's bullets b_list bombs; //list of enemies' bombs b_list powerups; //list of powerups r_list rockets; //list of rockets int refresh_time; //how long the program waits before refreshing the screen int chflag=0; //cheat flag: 0=normal, 1=cheats allowed, 2=special mode activated, 3=both special mode and cheats. boss boss1; WINDOW *Score,*BossHP; int commands[CMD_NUM]={'a','d','w','s','p',' ','l','m','q'}; //0:left,1:right,2:up,3:down,4:pause,5:shoot1,6:shoot2,7:mute,8:quit //PARAMETERS/UTILITIES double shootrate; //probability of an enemy shooting a bomb double poweruprate; //probability of a powerup being dropped int enemy_num; //number of enemies in the current match int walls_num; //number of walls int command; //keyboard input int score=0; //score: gain +100 when an enemy is destroyed and +50 when a bomb is destroyed int level=1; //difficulty level //bool sound=false; /*//PTHREAD STUFF pthread_t thread[THREADS_NUM]; int bkgd_music; //#0 int enshoot_sound; //#1 int win_theme; //#2 int lose_theme; //#3 int shoot_sound; //#4 if(argc>1){ //./invaders -m/m/mute -> the game starts with no sounds. if(strcmp(argv[1],"-s")==0 || strcmp(argv[1],"s")==0 || strcmp(argv[1],"sound")==0) sound=true; else{ cout<<"usage: "<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,3); /////////ENTERING MAIN LOOP /*if(sound) bkgd_music = pthread_create(&thread[0],NULL,pmusic,NULL); //executing background music in parallel thread*/ if(argc>1){ if(strcmp(argv[1],"--uber-debug")==0){ player1.weaponclass=5; player1.weaponclassrkt=5; player1.rocketlauncher=true; player1.length=MAX_LENGTH; } else if(strcmp(argv[1],"--autowin")==0){ Victory(boss1.name,score,level,0); endwin(); return 1; } } while(1) { napms(refresh_time); //ncurses sleep function (ms) timeout(0); command = getch(); if(command!=ERR) //READING INPUT command = tolower(command); if(command == commands[8]){ //q = exit game endwin(); //pkill_music(thread[0]); cout<alive) n_enemies++; //counts alive enemies for(e_list::iterator it=enemies.begin(); it!=e_end; ++it) { //mvaddch(it->y,it->x,' '); it->next_pos(); //evaluate new positions if(it->alive && (double)rand()/RAND_MAX<(shootrate*enemy_num/n_enemies)){ //try a bomb-dropping //if(sound) shoot_sound = pthread_create(&thread[1],NULL,penshoot_sound,NULL); it->shoot(bombs); } } } else boss1.alive = true; //if no enemy is alive, boss spawns if(boss1.alive) //if boss is alive, moves and shoots { for(int i=0;iy,it->x,' '); it->next_pos(); } bullets.unique(); //remove duplicates of bullets (i.e. player can't shoot enemies) if(!rockets.empty()) //evaluate new rockets' positions for(r_list::iterator it=rockets.begin(); it!=rockets.end(); ++it){ //mvaddch(it->y,it->x,' '); it->next_pos(); } rockets.unique(); if(!bombs.empty()) //evaluate new bombs' positions for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){ //mvaddch(it->y,it->x,' '); it->next_pos(); } bombs.unique(); //remove duplicates of bombs if(!powerups.empty()) //new powerups' positions for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){ //mvaddch(it->y,it->x,' '); it->next_pos(); } powerups.unique(); //FIXME: THIS ONLY WORKS ON CONSECUTIVE ELEMENTS OF THE LIST!! we should at least sort powerups before calling unique() interactions(player1,bullets,bombs,enemies,walls,powerups,rockets,boss1,score,poweruprate); ///////ENDGAME CHECKS if(boss1.health<1 || gameover(player1,bombs)) { /*if(sound){ pkill_music(thread[0]); win_theme = pthread_create(&thread[2],NULL,pwin_theme,NULL); }*/ WINDOW *replay; if(boss1.health<1) // YOU WON { Victory(boss1.name,score,level,chflag); replay=newwin(3,25,26,20); } else // YOU LOST { Defeat(score); replay=newwin(3,25,17,20); } box(replay,ACS_VLINE,ACS_HLINE); switch(char choice = playagain(replay)) // playagain() returns 'y', 'n' or 'q' { case 'y': case 'n': delwin(replay); timeout(500); score=0; erase(); refresh(); if(choice=='n') level = choose_level(commands); // get desired level setup_level(level, shootrate, poweruprate, refresh_time, boss1, enemy_num, walls_num); // set game parameters and boss load_enemies(enemies,enemy_num); reset(player1, enemies, boss1, bullets, bombs, walls, walls_num, powerups, rockets, chflag); // reset box, player, enemy and deletes all bullets and bombs erase(); refresh(); continue; // Go to the beginning of the main loop case 'q': endwin(); cout<