From e3a66514d57ff4acf2f02df7d86bd2cf8be0e730 Mon Sep 17 00:00:00 2001 From: Reimar Date: Tue, 8 Dec 2015 11:31:35 +0100 Subject: initial commit --- engine.cpp | 929 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 929 insertions(+) create mode 100644 engine.cpp (limited to 'engine.cpp') diff --git a/engine.cpp b/engine.cpp new file mode 100644 index 0000000..50b39ee --- /dev/null +++ b/engine.cpp @@ -0,0 +1,929 @@ +#include "engine.h" + +UserShip* getShipWithName(string shipname) +{ + string path = "data/ships/user/"; + ifstream ships; + ships.open((path + "userships.txt").c_str()); + char workaround; + ships >> workaround; + while(ships.good()) + { + string shipPath; + getline(ships, shipPath); + ifstream ins; + ins.open((path + workaround + shipPath).c_str()); +// cout << path + workaround + shipPath << endl; + char workaround2; + ins >> workaround2; + string thisShipname; + getline(ins, thisShipname); + thisShipname = workaround2 + thisShipname; + ins.close(); + if(thisShipname == shipname) + { + ships.close(); + return new UserShip(path + workaround + shipPath); + } + ships >> workaround; + } + ships.close(); + cout << "Save File corrupted: unable to find Ship with name " << shipname << endl; + return NULL; +} + +Weapon* getWeaponWithName(string weaponname) +{ + string path = "data/weapons/"; + ifstream weapons; + weapons.open((path + "weapons.txt").c_str()); + char workaround; + weapons >> workaround; + while(weapons.good()) + { + string weaponPath; + getline(weapons, weaponPath); + ifstream ins; + ins.open((path + workaround + weaponPath).c_str()); + char workaround2; + ins >> workaround2; + string thisWeaponname; + getline(ins, thisWeaponname); + thisWeaponname = workaround2 + thisWeaponname; + ins.close(); + if(thisWeaponname == weaponname) + { + weapons.close(); + return new Weapon(path + workaround + weaponPath); + } + weapons >> workaround; + } + weapons.close(); + cout << "Save File corrupted: unable to find Weapon with name " << weaponname << endl; + return NULL; +} + +Account::Account() +{ + gold = 0; + highscore = 0; + ifstream ins; + string path = "data/ships/user/"; + ins.open((path + "userships.txt").c_str()); + current = 0; + string shippath; + getline(ins, shippath); + UserShip *startShip = new UserShip(path + shippath); + ships.push_back(startShip); +} + +Account::~Account() +{ + for(int i = 0; i < (int) ships.size(); i++) + delete ships[i]; + for(int i = 0; i < (int) weapons.size(); i++) + delete weapons[i]; +} + +void Account::resetShips() +{ + for(int i = 0; i < (int) ships.size(); ++i) + { + ships[i]->reset(); +// ships[i]->hp = ships[i]->maxhp; +// ships[i]->energy = ships[i]->maxEnergy; +// ships[i]->xSpeed = 0; +// ships[i]->ySpeed = 0; + } +} + + + +Account::Account(string filename) +{ + ifstream ins; + ins.open((filename).c_str()); + getline(ins, name); + ins >> gold; + ins >> highscore; + int Nships; + ins >> Nships; + for(int i = 0; i < (int) Nships; ++i) + { + string shipname; + char workaround; + ins >> workaround; + getline(ins, shipname); + shipname = workaround + shipname; + UserShip* s = getShipWithName(shipname); + vector tu = s->getUpgradeables(); + for(int j = 0; j < (int) tu.size(); ++j) + tu[j]->load(ins); + int Nweapons; + ins >> Nweapons; + for(int j = 0; j < Nweapons; ++j) + { + ins >> workaround; + string weaponname; + getline(ins, weaponname); + weaponname = workaround + weaponname; + delete s->weapons[j]; + s->weapons[j] = getWeaponWithName(weaponname); + } + ships.push_back(s); + } + ins >> current; + int Nlevels; + ins >> Nlevels; + for(int i = 0; i < Nlevels; ++i) + { + int level; + ins >> level; + levels.push_back(level); + } + double nexp; + ins >> nexp; + addExp(nexp); + ins.close(); +} + +void Account::save() +{ + spaceto_(name); + bool was_saved = false; + ifstream ins; + ins.open("save/saves.txt"); + string line; + getline(ins, line); + if(line == name) + was_saved = true; + string allSaves = line; + while(ins.good()) + { + string line; + getline(ins, line); + if(line == name) + was_saved = true; + allSaves += "\n" + line; + } + ins.close(); + if(!was_saved) + { + ofstream makeEntry; + makeEntry.open("save/saves.txt"); + makeEntry << allSaves << '\n' << name; + } + ofstream ofs; + ofs.open(("save/" + name + ".txt").c_str()); + _tospace(name); + ofs << name << endl; + ofs << gold << endl; + ofs << highscore << endl; + ofs << ships.size() << endl; + for(int i = 0; i < (int) ships.size(); ++i) + { + ofs << ships[i]->name << endl; + vector tu = ships[i]->getUpgradeables(); + for(int j = 0; j < (int) tu.size(); ++j) + tu[j]->save(ofs); + ofs << ships[i]->weapons.size() << endl; + for(int j = 0; j < (int) ships[i]->weapons.size(); ++j) + ofs << ships[i]->weapons[j]->name << endl; + } + ofs << current << endl; + ofs << levels.size() << endl; + for(int i = 0; i < (int) levels.size(); ++i) + ofs << levels[i] << endl; + + ofs << exp; + ofs.close(); +} + +ObjectHandler::ObjectHandler(Account* newuser, SDL_Surface* newscreen, SDL_Surface* background) +{ + user = newuser; + screen = newscreen; + BG = new SlidingBackground(background,0,50); + highscore = 0; + gold = 0; +} + +void ObjectHandler::spawnEnemy(EnemyShip* enemy,double nx, double ny) +{ + enemy->x = nx; + enemy->y = ny; + enemies.push_back(enemy); +} + +ObjectHandler::~ObjectHandler() +{ + for(list::iterator i = friendlyProjectiles.begin(); i!= friendlyProjectiles.end();++i) + delete *i; + for(list::iterator i = enemyProjectiles.begin(); i!= enemyProjectiles.end();++i) + delete *i; + for(list::iterator i = enemies.begin(); i!= enemies.end();++i) + delete *i; + delete BG; +} + +void ObjectHandler::frameEnemy(EnemyShip* s, double time) +{ + vector moreProjectiles = s->frame(time); + for(int i = 0; i < (int) moreProjectiles.size(); ++i) + enemyProjectiles.push_back(moreProjectiles[i]); +} + +int ObjectHandler::frame(double time) +{ + UserShip *s = user->ships[user->current]; + //applies controles + Uint8 *keyState = SDL_GetKeyState(NULL); + s->down = -keyState[SDLK_UP]+keyState[SDLK_DOWN]; + s->right = -keyState[SDLK_LEFT]+keyState[SDLK_RIGHT]; + s->shooting = keyState[SDLK_SPACE]; + //frames the content + list::iterator l1; + list::iterator l2; + l1 = friendlyProjectiles.begin(); + while(l1 != friendlyProjectiles.end()) + { + //looking for collisions with enemies + double startx,starty; + startx = (*l1)->x; + starty = (*l1)->y; + (*l1)->frame(time); + bool hit = false; + for(l2 = enemies.begin(); l2!= enemies.end(); ++l2) + { + if((*l2)->hp > 0 && intersects((*l1)->collisionSize + (*l2)->collisionSize, startx-(*l2)->x, starty-(*l2)->y, (*l1)->x-(*l2)->x, (*l1)->y-(*l2)->y)) + { + (*l2)->hit(**l1); +// cout << (*l2)-> hp << endl; + hit = true; + break; + } + } + if(ooB(*l1,screen) || hit) + { + delete *l1; + l1 = friendlyProjectiles.erase(l1); + } + else + l1++; + } + l1 = enemyProjectiles.begin(); + while(l1 != enemyProjectiles.end()) + { + double startx = (*l1)->x; + double starty = (*l1)->y; + (*l1)->frame(time); + bool hit = false; + if(intersects((*l1)->collisionSize + s->collisionSize, startx-s->x, starty-s->y, (*l1)->x-s->x, (*l1)->y-s->y)) + { + s->hit(**l1); + hit = true; + } + if(ooB(*l1,screen) || hit) + { + delete *l1; + l1 = enemyProjectiles.erase(l1); + //return 1; + } + else + l1++; + } + //cout << enemyProjectiles.size() << endl; + l2 = enemies.begin(); + while(l2 != enemies.end()) + { + frameEnemy(*l2,time); + if((*l2)->hp <= 0) + { + highscore += (*l2)->score; + gold += (*l2)->gold; + if(user->addExp((*l2)->exp)) + { + cout << "Level Up!" << endl; + user->gold += user->getLevel() * 15; + cout << "Got " << user->getLevel() * 15 << "gold to compromise for the missing Skillsystem!" << endl; + } + delete *l2; + l2 = enemies.erase(l2); + } + else if(ooB(*l2,screen) && (*l2)->current == (*l2)->path.size()-1 && (*l2)->path[(*l2)->current] == make_pair((*l2)->x,(*l2)->y)) + { + delete *l2; + l2 = enemies.erase(l2); + } + else + l2++; + } +// cout << s->energy << endl; + if(s->hp <= 0) + return LEVEL_FAILED; + vector moreProjectiles = s->frame(time,screen); + for(int i = 0; i < (int) moreProjectiles.size(); ++i) + friendlyProjectiles.push_back(moreProjectiles[i]); + + //apply background + BG->frame(1/60.0); + BG->draw(screen); + + //draws all Objects + for(list::iterator i = enemies.begin(); i!= enemies.end();++i) + { + (*i)->draw(screen); + } + for(list::iterator i = friendlyProjectiles.begin(); i!= friendlyProjectiles.end();++i) + { + (*i)->draw(screen); + } + for(list::iterator i = enemyProjectiles.begin(); i!= enemyProjectiles.end();++i) + { + (*i)->draw(screen); + } + s->draw(screen); + return 0; +} + + + +HUD::HUD(long long *nhighscore, double *nhp, double nhpmax, double *nenergy, double nmaxEnergy, double* ngold, double* nexp) +{ + font = NULL; + textColor.r = 255; + textColor.g = 255; + textColor.b = 255; + highscore = nhighscore; + hp = nhp; + hpmax = nhpmax; + energy = nenergy; + maxEnergy = nmaxEnergy; + gold = ngold; + exp = nexp; + energyRaw = loadBMP("data/images/energy_raw2.bmp"); + SDL_Surface *bubbles = loadBMP("data/images/energy_bubbles3.bmp"); + energyBubbles = new SlidingBackground(bubbles,0,-200); + energyMasc = loadBMP("data/images/energy_masc2.bmp"); + hpRaw = loadBMP("data/images/hp_raw.bmp"); + hpMasc = loadBMP("data/images/hp_masc2.bmp"); + background = loadBMP("data/images/hud_background.bmp"); + font = TTF_OpenFont("data/fonts/OpenSans-Semibold.ttf",12); + if(font == NULL) + { + cout << "Error loading font in HUD" << endl; + } + Uint32 colorkey = SDL_MapRGB(energyMasc->format,255 , 255, 255); + SDL_SetColorKey(energyMasc, 0, colorkey); + SDL_SetColorKey(energyMasc, SDL_SRCCOLORKEY, colorkey); + SDL_SetColorKey(hpMasc, 0, colorkey); + SDL_SetColorKey(hpMasc, SDL_SRCCOLORKEY, colorkey); +} + +HUD::~HUD() +{ + SDL_FreeSurface(energyRaw); + delete energyBubbles; + SDL_FreeSurface(energyMasc); + SDL_FreeSurface(hpRaw); + SDL_FreeSurface(hpMasc); + TTF_CloseFont(font); +} + +void HUD::draw(SDL_Surface* screen) +{ + + //applying HUD-background + SDL_Rect dest,src; + dest.x = 300; + dest.y = 0; + SDL_BlitSurface(background,NULL,screen,&dest); + //making a SDL_Surface to hold the bar as it is being painted + SDL_Surface *energyBar = copyImage(energyRaw); + dest.x = 0; + dest.y = 0; + dest.w = energyBar->w; + dest.h = energyBar->h; + SDL_FillRect(energyBar,&dest,0); + //drawing Raw energy + int energyPixel = (energyRaw->h * *energy / maxEnergy); + dest.x = 0; + dest.y = energyBar->h - energyPixel; + src.w = energyRaw->w; + src.h = energyPixel; + src.x = 0; + src.y = energyRaw->h - src.h; + SDL_BlitSurface(energyRaw,&src,energyBar,&dest); + + //apply bubbles + energyBubbles->ySpeed = -60* (3.0-1.5 * *energy/ maxEnergy); + energyBubbles->frame(1/60.0); + SDL_Surface *bubbles = copyImage(energyRaw); + dest.x = 0; + dest.y = 0; + dest.w = energyBar->w; + dest.h = energyBar->h; + SDL_FillRect(bubbles,&dest,0x00000102); + energyBubbles->draw(bubbles); + //amount by wich the bubbles extend further than the raw energy + int surplus = 6 - 5* *energy/ maxEnergy; + src.w = energyBar->w; + src.h = min(energyPixel+surplus,energyBar->h); + src.x = 0; + src.y = energyRaw->h - src.h; + dest.x = 0; + dest.y = energyBar->h - min(energyPixel+surplus,energyBar->h); + SDL_BlitSurface(bubbles,&src,energyBar,&dest); + SDL_FreeSurface(bubbles); + //lay masc over everything + dest.y = energyBar->h - energyMasc->h; + src.w = energyMasc->w; + src.h = energyMasc->h; + src.x = 0; + src.y = 0; + SDL_BlitSurface(energyMasc,&src,energyBar,&dest); + dest.x = 320; + dest.y = 480 - energyBar->h; + SDL_BlitSurface(energyBar,NULL,screen,&dest); + SDL_FreeSurface(energyBar); + + //drawing Raw hp + SDL_Surface *hpBar = copyImage(hpRaw); + dest.x = 0; + dest.y = 0; + dest.w = hpRaw->w; + dest.h = hpRaw->h; + SDL_FillRect(hpBar,&dest,0); + int hpPixel = (hpRaw->h * *hp / hpmax); + dest.x = 0; + dest.y = hpBar->h - hpPixel; + src.w = hpBar->w; + src.h = hpPixel; + src.x = 0; + src.y = hpRaw->h - src.h; + SDL_BlitSurface(hpRaw,&src,hpBar,&dest); + + //lay masc over everything + dest.x = 0; + dest.y = hpBar->h - hpMasc->h; + src.w = hpMasc->w; + src.h = hpMasc->h; + src.x = 0; + src.y = 0; + SDL_BlitSurface(hpMasc,&src,hpBar,&dest); + dest.x = 360; + dest.y = 480-hpBar->h; + SDL_BlitSurface(hpBar,NULL,screen,&dest); + SDL_FreeSurface(hpBar); + + string mtemp; + SDL_Surface *message = NULL; + //display highscore + mtemp = "highscore: " + lltostr(*highscore); + message = TTF_RenderText_Solid(font, mtemp.c_str(),textColor); + if(message == NULL) + { + cout << "error rendering text in HUD" << endl; + } + dest.x = 316; + dest.y = 14; + SDL_BlitSurface(message,NULL,screen,&dest); + SDL_FreeSurface(message); + //display gold + mtemp = "gold: " + lltostr(*gold); + message = TTF_RenderText_Solid(font, mtemp.c_str(),textColor); + if(message == NULL) + { + cout << "error rendering text in HUD" << endl; + } + dest.x = 316; + dest.y = 30; + SDL_BlitSurface(message,NULL,screen,&dest); + SDL_FreeSurface(message); + //display exp + mtemp = "exp: " + lltostr(*exp); + message = TTF_RenderText_Solid(font, mtemp.c_str(),textColor); + if(message == NULL) + { + cout << "error rendering text in HUD" << endl; + } + dest.x = 316; + dest.y = 46; + SDL_BlitSurface(message,NULL,screen,&dest); + SDL_FreeSurface(message); +} + + +LevelEvent* createEvent(ifstream& ins) +{ + cout << "this Event is not yet implemented!" << endl; + return NULL; +} + + + +//generates a Wave of enemies +//[t-t0,path] +vector > > > generateWave(int number, int Nweapons,SDL_Surface* screen) +{ + double margin = 20; + double spawnLength = screen->w - 80; + vector > > > result; + bool symmetric = true; + if(number % 2 || rand()%2) + symmetric = false; + if(symmetric) + number /= 2; + bool done = false; + int mirror = rand()%2; + int attemps = 0; + while(!done && attemps < 1000) + { + attemps++; + int type = rand()%5; + switch(type) + { + case 0:{ + //diagonal line + if(number > 2) + { + done = true; + double dur = (rand()%500)/50.0; + for(int i = 0; i < number; ++i) + { + vector > path; + double spawnx; + spawnx = margin + spawnLength*i/((double) number); + if(mirror) + spawnx = screen->w - spawnx; + path.push_back(make_pair(spawnx,screen->h+margin)); + path.push_back(make_pair(spawnx,-margin)); + result.push_back(make_pair(dur - dur/number*i,path)); + } + } + break; + } + case 1:{ + //chaotic + if(!symmetric && number > 7) + { + done = true; + double dur = sqrt(number) * (rand()%1000)/500.0; + for(int i = 0; i < number; ++i) + { + vector > path; + double spawnx = margin + rand()%10000/10000.0*spawnLength; + path.push_back(make_pair(spawnx,screen->h+margin)); + path.push_back(make_pair(spawnx,-margin)); + result.push_back(make_pair(dur*((rand()%1000)/1000.0),path)); + } + } + break; + } + case 2:{ + if(number > 2) + { + //down diagonalup down + done = true; + double dur = (rand()%500)/50.0; + for(int i = 0; i < number; ++i) + { + vector > path; + double spawnx; + spawnx = margin + spawnLength*i/((double) number); + if(mirror) + spawnx = screen->w - spawnx; + path.push_back(make_pair(spawnx,screen->h-3*margin)); + path.push_back(make_pair(screen->w-spawnx,2*margin)); + path.push_back(make_pair(screen->w-spawnx,screen->h+margin)); + path.push_back(make_pair(spawnx,-margin)); + result.push_back(make_pair(dur/((double) number)*i,path)); + + } + } + break; + } + case 3:{ + //back and forth at top + if(number < 5 && Nweapons > 0) + { + done = true; + int baf = min(rand()%6+1,rand()%6+1); + int right = rand()%2; + double spawnx; + if(right) + spawnx = screen->w - margin; + else + spawnx = margin; + for(int j = 0; j < number; ++j) + { + vector > path; + for(int i = 0; i < baf; ++i) + { + if(right) + path.push_back(make_pair(screen->w-spawnx,2*margin)); + else + path.push_back(make_pair(margin,2*margin)); + right = !right; + } + if(right) + path.push_back(make_pair(margin,screen->h+margin)); + else + path.push_back(make_pair(screen->w-spawnx,screen->h + margin)); + path.push_back(make_pair(spawnx,-margin)); + result.push_back(make_pair(j/(rand()%3+2),path)); + } + } + break; + } + case 4:{ + //circles + done = true; + int rounds = min(rand()%2+1,rand()%2+1); + double spawnx = margin; + if(mirror) + spawnx = screen->w - margin; + for(int j = 0; j < number; ++j) + { + vector > path; + for(int i = 0; i < rounds*20; ++i) + { + if(mirror) + path.push_back(make_pair(screen->w*0.2*cos(2*M_PI*i/20.0)+screen->w/2.0,screen->w*0.2*sin(2*M_PI*i/20.0)+screen->h/2.0)); + else + path.push_back(make_pair(screen->w*0.2*cos(2*M_PI*i/20.0)+screen->w/2.0,-screen->w*0.2*sin(2*M_PI*i/20.0)+screen->h/2.0)); + } + if(right) + path.push_back(make_pair(margin,screen->h+margin)); + else + path.push_back(make_pair(screen->w-spawnx,screen->h + margin)); + path.push_back(make_pair(spawnx,-margin)); + result.push_back(make_pair(j/sqrt(number)*1.5,path)); + } + break; + } + default:{} + } + } + int oldsize = result.size(); + if(symmetric) + for(int i = 0; i < oldsize; ++i) + { + vector > path; + for(int j = 0; j < (int) result[i].second.size(); ++j) + { + path.push_back(make_pair(screen->w-result[i].second[j].first,result[i].second[j].second)); + } + result.push_back(make_pair(result[i].first,path)); + } + if(attemps == 1000) + cout << "failed to generate wave with " << number << " units!" << endl; + return result; +} + +/*structure of a LevelFile +IntroLevel #name +data/images/bg_stars.bmp #path of background +30 #speed of background +1 #wether to randomize background position +60 #duration [s] +12346543 #seed +2 #number of Shiptypes +data/tork_capsule.txt #path of Ship +50 #how many of them should spawn +data/tork_spacerocket.txt #path of Ship +12 #how many +1 #how many events shall happen +0.5 #percentage of completion the event happens +****event***** #an event as specified in createEvent +*/ +LevelGenerator::LevelGenerator(string filename, Account* user, SDL_Surface* nscreen) +{ + vector shouldSpawn; + screen = nscreen; + SDL_Surface* fakeScreen = loadBMP("data/images/game_screen.bmp"); + current = 0; + completed = 0; + event = false; + + ifstream ins; + ins.open(filename.c_str()); + if(!ins.is_open()) + { + cout << "Error: Could not open Level file " << filename << endl; + return; + } + getline(ins, name); + string backgroundPath; + getline(ins, backgroundPath); + SDL_Surface* background = loadBMP(backgroundPath); + OH = new ObjectHandler(user, fakeScreen,background); + UserShip *s = user->ships[user->current]; + hud = new HUD(&OH->highscore, &s->hp, s->maxhp, &s->energy, s->maxEnergy, &OH->gold, user->getExpPointer()); + ins >> OH->BG->ySpeed; + bool rdbg; + ins >> rdbg; + OH->BG->setRandom(rdbg); + ins >> duration; + ins >> seed; + int NShipTypes; + ins >> NShipTypes; + for(;NShipTypes;NShipTypes--) + { + char workaround; + //discards \n + ins >> workaround; + string shipFilename; + getline(ins, shipFilename); + EnemyShip* enemy = new EnemyShip(workaround + shipFilename); + prototypes.push_back(enemy); + for(int l = 0; l < (int) enemy->weapons.size(); ++l) + for(int i = 0; i < (int) enemy->weapons[l]->sounds.size(); ++i) + for(int j = 0; j < (int) enemy->weapons[l]->sounds[i].size(); ++j) + toDelete.push_back(enemy->weapons[l]->sounds[i][j]); + int number; + ins >> number; + shouldSpawn.push_back(number); + } + int NEvents; + ins >> NEvents; + for(;NEvents;NEvents--) + { + double eventtime = 0; + ins >> eventtime; + events.push_back(make_pair(eventtime,createEvent(ins))); + } + s->x = OH->screen->w/2; + s->y = OH->screen->h - 30; + srand(seed); + //Fill up the Queue + double spawnTotal = 0; + int spawnMax = 0; + for(int i = 0; i < (int) shouldSpawn.size(); ++i) + { + spawnTotal += shouldSpawn[i]; + spawnMax = max(spawnMax,shouldSpawn[i]); + } + for(int i = 0; i < (int) prototypes.size(); ++i) + { + int rest = shouldSpawn[i]; + int Nwaves = shouldSpawn[i]*duration/spawnTotal/(rand()%8+2.5); + if(Nwaves == 0) + Nwaves = 1; + vector willSpawn; + for(int j = 0; j < Nwaves; ++j) + { + willSpawn.push_back(rest/(Nwaves-j)); + rest -= willSpawn[j]; + } + //random the evenly distributed wavesizes a bit + if(Nwaves > 1) + for(int j = 0; j < Nwaves; ++j) + { + int temp = 1; + if(shouldSpawn[i]/Nwaves >= 2) + { + temp = rand()%((int) shouldSpawn[i]/Nwaves); + temp = min(temp,rand()%((int) shouldSpawn[i]/Nwaves)); + temp = min(temp,rand()%((int) shouldSpawn[i]/Nwaves)); + temp = min(temp,rand()%((int) shouldSpawn[i]/Nwaves)); + } + if(temp == 0) + temp = 1; + int index = rand()%Nwaves; + if(willSpawn[j] < temp) + temp = willSpawn[j]; + if(willSpawn[j] - temp < sqrt(shouldSpawn[i])/3) + temp = willSpawn[j]; + + willSpawn[j] -= temp; + willSpawn[index] += temp; + } +// cout << "Waves randomed a bit!" << endl; +// cout << "Generated for " << i << endl; +// cout << Nwaves << " waves" << endl; +// for(int l = 0; l < Nwaves; ++l) +// { +// cout << willSpawn[l] << " "; +// } +// cout << endl; + double currentTime = 1; + //generate the waves + for(int j = 0; j < (int) willSpawn.size(); ++j) + { + if(willSpawn[j] > 0) + { + //determine the time of the wave + if((j != 0 || shouldSpawn[i] != spawnMax) && ((int) (duration - currentTime)/(Nwaves-j)*2) > 1) + { + currentTime += min(duration- currentTime - 15, (double) (rand()%((int) (duration - currentTime)/(Nwaves-j)*2))); + } + vector > > > temp = generateWave(willSpawn[j],prototypes[i]->weapons.size(),OH->screen); + int realSpawn = 0; + for(int k = 0; k < (int) temp.size(); ++k) + { + spawnQueue.push_back(make_pair((temp[k].first+currentTime)/duration,make_pair(i,temp[k].second))); + realSpawn++; + } + } + } + +// int attemps = 0; +// while(rest && attemps < 1000) +// { +// double waveTime = rand()%10000/10000.0*(duration-15)/duration; +// if(!(rand()%3)) +// waveTime = max(waveTime,rand()%1000/1000.0-15/duration); +// int NperWave = 0; +// if(rest < 3) +// NperWave = rand()%2 + 1; +// else +// { +// NperWave = rand()%((int) (shouldSpawn[i]/1.8 - shouldSpawn[i]/10.0))+1; +// NperWave = min(NperWave, (int) rand()%((int) (shouldSpawn[i]/1.8 - shouldSpawn[i]/10.0)))+1; +// NperWave = min(NperWave, (int) rand()%((int) (shouldSpawn[i]/1.8 - shouldSpawn[i]/10.0)))+1; +// } +//// cout << waveTime << " " << rest << " " << NperWave << endl; +// if(NperWave > rest) +// NperWave = rest; +// vector > > > temp = generateWave(NperWave,OH->screen); +// for(int j = 0; j < (int) temp.size(); ++j) +// { +// spawnQueue.push_back(make_pair(temp[j].first/duration+waveTime,make_pair(i,temp[j].second))); +// } +// rest-= NperWave; +// attemps++; +// } +// if(attemps == 1000) +// cout << "failed to generate level at unit " << i << endl; + } + sort(spawnQueue.begin(),spawnQueue.end()); +// for(int i = 0; i < spawnQueue.size(); ++i) +// { +// cout << spawnQueue[i].first +// } + srand(time(0)); + +} + +LevelGenerator::~LevelGenerator() +{ + SDL_FreeSurface(OH->screen); + delete OH; + for(int i = 0; i < (int) prototypes.size(); ++i) + delete prototypes[i]; + for(int i = 0; i < (int) events.size(); ++i) + delete events[i].second; + delete hud; + for(int i = 0; i < (int) toDelete.size(); ++i) + delete toDelete[i]; +} + +int LevelGenerator::frame(double time) +{ +// double oldcompleted = completed; + completed += time / duration; + if(!event) + { + //cout << current << " " << completed << endl; + //spawn enemies + while(current != (int) spawnQueue.size() && spawnQueue[current].first < completed) + { + EnemyShip* enemy = new EnemyShip(*prototypes[spawnQueue[current].second.first]); + enemy->x = spawnQueue[current].second.second[spawnQueue[current].second.second.size()-1].first; + enemy->y = spawnQueue[current].second.second[spawnQueue[current].second.second.size()-1].second; + spawnQueue[current].second.second.pop_back(); + enemy->path = spawnQueue[current].second.second; + OH->spawnEnemy(enemy, enemy->x,enemy->y); + OH->frameEnemy(enemy, (completed - spawnQueue[current].first) * duration); + current++; + } + if(completed > 1) + { + return LEVEL_COMPLETED; + } + } + + + int result = OH->frame(time); + SDL_Rect r; + r.w = screen->w; + r.h = screen->h; + r.x = 0; + r.y = 0; + SDL_FillRect(screen,&r,0); + r.w = OH->screen->w; + r.h = OH->screen->h; + r.x = 0; + r.y = 0; + r.w+=2; + r.h+=2; + SDL_FillRect(screen,&r,0xFFFFFFFF); + r.x = 1; + r.y = 1; + r.w--; + r.h--; + SDL_BlitSurface(OH->screen,NULL,screen,&r); + hud->draw(screen); + return result; +} -- cgit v1.2.3