void CNetworkBuilding::Update( SEntityUpdateContext& ctx, int updateSlot ) { if (g_pGame->GetIGameFramework()->IsEditing()) { Reset(); return; } float curTime = gEnv->pTimer->GetAsyncTime().GetSeconds(); float newTime = fStartTime+(build_time/4); if(build_status!=-1 && gEnv->bServer) { if(curTime >= newTime && m_state!=eState_Done) { build_status++; Building(build_status); fStartTime = curTime; } } // Test //Vec3 test = GetEntity()->GetWorldPos(); //test.z = test.z+5.f; //gEnv->pRenderer->DrawLabel(test, 1.f,GetEntity()->GetName()); }
bool CNetworkBuilding::NetSerialize( TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags ) { if (aspect == POSITION_ASPECT) { if(gEnv->bServer && !gEnv->IsEditor()) { int cur_state = (int)m_state; ws->SetInt(entity_name,"BuildStatus",build_status); ws->SetInt(entity_name,"EntityState",cur_state); } EState newState = m_state; ser.EnumValue("cur_state", newState, eState_NotUsed, eState_Done); ser.Value( "build_status", build_status); if (ser.IsWriting()) { //CryLog("CNetworkBuilding::NetSerialize writing !!!"); } if (ser.IsReading()) { //CryLog("CNetworkBuilding::NetSerialize reading !!!"); m_state = newState; Building(build_status); } } return true; }
void Level::Set_Level1(){ levelOne = true; if(levelOneDrawn == false && levelOne == true){ Set_Level_Template(); for(int y = 0; y < 32; y++) Building((rand()%y), 14); // Random building locations. // Spawns an enemy obstacle. levelEnemy.Add_Enemy(); // Spawns platforms. for(int i = 0, n = 4; i < 40, n < 10; i += 8, n++) levelObject.Display_Sprite(n, levelObject.platWidth, levelObject.platHeight, levelObject.platY, levelObject.platX + i, false, 10); levelOneDrawn = true; } }
Grid::Grid( ArgParser* _args ) { args = _args; Load(); bbox.Extend(glm::vec3(width,1,length)); for (unsigned int ind = 0; ind < args->bldg_files.size(); ind++) { for(int i = 0; i < args->num_bldg_alters; ++i){ bldgs.push_back(Building(args,ind)); int temp_h = bldgs.back().getHeight(); if (temp_h > height) { height = temp_h; } } } std::vector<Lot> empty_lots; for ( int k = 0; k < length; k++ ) { for ( int i = 0; i < width; i++ ) { empty_lots.push_back(Lot(i,k)); } } for ( int h = 1; h < height; h++ ) { lots.push_back( std::vector<Lot>(empty_lots) ); } }
Building Building::getObject(vector<string> param,string sepOut,string sepIn) { Building building = Building(param,sepOut,sepIn); return building; }
//Main function int main(int argc, char* argv[]) { /* ----- // INITIALIZATION ----- */ //Seed RNG srand(time(NULL)); //Initialize all SDL subsystems if (SDL_Init(SDL_INIT_EVERYTHING) == -1) { return 1; } //Initialize SDL_TTF TTF_Init(); TTF_Font * planetFont = TTF_OpenFont("corbel.ttf", 20); //Set up the screen SDL_Surface* screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE); //Make sure screen set up if (screen == NULL) { return false; } //Set the window caption SDL_WM_SetCaption("GAEM", NULL); //Create an event manager SDL_Event event; //Store keystates Uint8* keystates; //Set up camera SDL_Rect camera = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; float camerax = 0; float cameray = 0; /* ----- GAME SETUP ----- */ //Set up ship stats std::vector<ShipStats> shipstats(10); for (int i = 0; i < 10; i++) { shipstats[i].attack = i+1; shipstats[i].defense = i+1; shipstats[i].speed = DEFAULT_FLEET_SPEED; shipstats[i].interceptRange = 200; shipstats[i].interceptDamage = 0.1; shipstats[i].interceptCD = 250; } //Set up ship type 1: Heavy ship shipstats[1].attack = 3; shipstats[1].defense = 2; shipstats[1].speed = DEFAULT_FLEET_SPEED/2; //Set up ship type 2: Fiery attack ship shipstats[2].attack = 2; shipstats[2].defense = 1; shipstats[2].speed = DEFAULT_FLEET_SPEED*1.25; //Set up buildings and building rules std::list<Building> buildings; std::vector<std::list<Building*> > buildRules; buildRules.resize(2); SDL_Surface* b01 = loadImage("b01.png"); SDL_Surface* bc01 = loadImage("bc01.png"); SDL_Surface* b02 = loadImage("b02.png"); SDL_Surface* bc02 = loadImage("bc02.png"); buildings.push_back(Building(b01, bc01, "build 0 2")); //0 buildings.push_back(Building(b02, bc02, "fire damage 2 1")); //1 buildings.push_back(Building(b01, bc01, "build 1 4")); //2 buildings.push_back(Building(b01, bc01, "build 2 2")); //3 buildings.push_back(Building(b02, bc02, "aura damage 1 total")); //4 //0 std::list<Building>::iterator bi = buildings.begin(); buildRules[0].push_back(&(*bi)); bi->setBuildTime(15000); bi++; //1 buildRules[0].push_back(&(*bi)); bi->setBuildTime(10000); bi->setRange(250); bi++; //2 buildRules[0].push_back(&(*bi)); bi->setBuildTime(15000); bi++; //3 buildRules[1].push_back(&(*bi)); bi->setBuildTime(15000); bi++; //4 buildRules[1].push_back(&(*bi)); bi->setBuildTime(10000); bi->setRange(200); bi->setCD(1000); //Building images are now in rotation caches SDL_FreeSurface(b01); SDL_FreeSurface(bc01); SDL_FreeSurface(b02); SDL_FreeSurface(bc02); //Create a list of planets std::list<Planet> planets; //The standard rate of production of basic ship 0 float ship0rate = 1.0; //The array of indicators SDL_Surface* indicator[3]; indicator[1] = loadImage("selectorb.png"); indicator[2] = loadImage("selectorr.png"); SDL_Surface* planet0img = loadImage("planet0.png"); SDL_Surface* planet1img = loadImage("planet1.png"); SDL_Surface* planet1_1img = loadImage("planet1-1.png"); //Create the planets at random //First, create two home planets std::vector<int> homestart; homestart.resize(1,3); planets.push_back(Planet(planet0img, 1.0, Vec2f(rand()%100, 100 + rand()%(LEVEL_HEIGHT-200)), 0)); planets.back().setOwner(1, indicator); planets.back().setShipRate(0, ship0rate); planets.back().setRotSpeed(M_PI/20); planets.back().addShips(3, 0); planets.push_back(Planet(planet0img, 1.0, Vec2f(LEVEL_WIDTH-(2*UNSCALED_PLANET_RADIUS)-(rand()%100), 100 + rand()%(LEVEL_HEIGHT-200)), 0)); planets.back().setOwner(2, indicator); planets.back().setShipRate(0, ship0rate); planets.back().setRotSpeed(M_PI/20); planets.back().addShips(3, 0); //Now repeatedly create planets until either a target density is reached //or we go too many tries without finding a spot for a new planet. char tries = 0; char maxTries = 10; double density = 0.13; double totalSize = LEVEL_WIDTH*LEVEL_HEIGHT; double currentSize = M_PI*UNSCALED_PLANET_RADIUS*UNSCALED_PLANET_RADIUS*2; double spacing = 23; while (currentSize/totalSize < density && tries < maxTries) { //Create a new planet at a completely random location with a random size //For now, make half normal and half volcanic float psize = (double(rand())/double(RAND_MAX))*0.7 + 0.5; Planet p(planet0img, psize, Vec2f(rand()%(LEVEL_WIDTH-int(2*UNSCALED_PLANET_RADIUS*psize)), rand()%(LEVEL_HEIGHT-int(2*UNSCALED_PLANET_RADIUS*psize))), 0);; if (rand()%2 == 0) { p.setType(0); p.setImage(planet0img); } else { p.setType(1); p.setImage(planet1img); } //Make sure it doesn't collide with any other planets bool skip = false; for (planetIter pi = planets.begin(); pi != planets.end(); pi++) { Vec2f ppos = p.pos()+Vec2f(UNSCALED_PLANET_RADIUS*p.size(),UNSCALED_PLANET_RADIUS*p.size()); Vec2f pipos = pi->pos()+Vec2f(UNSCALED_PLANET_RADIUS*pi->size(),UNSCALED_PLANET_RADIUS*pi->size()); if ((pipos-ppos).length() < p.size()*UNSCALED_PLANET_RADIUS + pi->size()*UNSCALED_PLANET_RADIUS + spacing) { //There's a collision. Increment tries and try again tries++; skip = true; break; } } if (skip) continue; //At this point, we know there's no collision. Reset tries tries = 0; //Add a few more random attributes p.setOwner(0, indicator); p.setShipRate(0, ship0rate); p.setRotSpeed((fmod(rand(),M_PI)/5) - M_PI/10); p.setDifficulty(p.size()*20 + rand()%15 - 9); //Add this planet to the current size currentSize += M_PI*(UNSCALED_PLANET_RADIUS*p.size())*(UNSCALED_PLANET_RADIUS*p.size()); //Add it to the list planets.push_back(p); } //Set up fleet list std::list<Fleet> fleets; //Set up projectile list std::list<Projectile> projectiles; //Filler to act as NULL planetIter planNull; //The currently selected planet planetIter selectPlanet = planNull; //Set up AI std::list<GalconAI> ai; //For now, AI controls player 2 GalconAISettings aiSet; aiSet.attackFraction = .8; aiSet.surplusDefecitThreshold = .25; aiSet.attackExtraNeutral = .2; aiSet.attackExtraEnemy = .7; aiSet.perPlanetAttackStrength = .5; aiSet.delay = 200; aiSet.maximumBuildingFraction = .8; aiSet.minimumDefenseForBuilding = 10; aiSet.distancePower = 1.15; ai.push_back(GalconAI(2, aiSet)); ai.begin()->init(planets, shipstats); ai.begin()->activate(); //The number of the locally playing player char localPlayer = 1; //The type of ship that will currently be sent int shipSendType = 0; //A line drawer for the main surface LineDrawer linedraw(screen); /* ----- MAIN LOOP ----- */ int time = SDL_GetTicks(); uint8_t quit = 0; while (quit == 0) { //Update time and dt //Cap FPS int dt = SDL_GetTicks() - time; float minms = 1000.0/float(FPS_CAP); if (dt < minms) SDL_Delay(minms-dt); time = SDL_GetTicks(); //Update keystates keystates = SDL_GetKeyState(NULL); //Check for arrow keys/wasd if (keystates[SDLK_UP] || keystates[SDLK_w]) { cameray -= CAMERA_SPEED * (dt/1000.0); if (cameray < 0) cameray = 0; } if (keystates[SDLK_RIGHT] || keystates[SDLK_d]) { camerax += CAMERA_SPEED * (dt/1000.0); if (camerax > LEVEL_WIDTH - SCREEN_WIDTH) camerax = LEVEL_WIDTH - SCREEN_WIDTH; } if (keystates[SDLK_DOWN] || keystates[SDLK_s]) { cameray += CAMERA_SPEED * (dt/1000.0); if (cameray > LEVEL_HEIGHT - SCREEN_HEIGHT) cameray = LEVEL_HEIGHT - SCREEN_HEIGHT; } if (keystates[SDLK_LEFT] || keystates[SDLK_a]) { camerax -= CAMERA_SPEED * (dt/1000.0); if (camerax < 0) camerax = 0; } //Update camera from camerax and cameray to struct camera.x = camerax; camera.y = cameray; //Handle events while (SDL_PollEvent(&event)) { //Quit if requested if (event.type == SDL_QUIT) { quit = 1; } //Check for escape key, QWERTY to construct buildings, or numbers to select //ship type. //BUILDING CONSTRUCTION AND TYPE SELECTION THIS WAY IS TEMPORARY if (event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { case SDLK_ESCAPE: quit = 1; break; case SDLK_q: if (selectPlanet != planNull) { if (selectPlanet->owner() != localPlayer || buildRules[selectPlanet->type()].size() < 1) break; selectPlanet->build(*(buildRules[selectPlanet->type()].begin()), buildRules); } break; case SDLK_w: if (selectPlanet != planNull) { if (selectPlanet->owner() != localPlayer || buildRules[selectPlanet->type()].size() < 2) break; selectPlanet->build(*(++buildRules[selectPlanet->type()].begin()), buildRules); } break; case SDLK_e: if (selectPlanet != planNull) { if (selectPlanet->owner() != localPlayer || buildRules[selectPlanet->type()].size() < 3) break; std::list<Building*>::iterator i; i = buildRules[selectPlanet->type()].begin(); i++; i++; selectPlanet->build(*i, buildRules); } break; case SDLK_1: shipSendType = 0; break; case SDLK_2: shipSendType = 1; break; case SDLK_3: shipSendType = 2; break; case SDLK_4: shipSendType = 3; break; case SDLK_5: shipSendType = 4; break; default: break; } } //Check for mouse clicks if (event.type == SDL_MOUSEBUTTONDOWN) { //Left click if (event.button.button == SDL_BUTTON_LEFT) { //Used to select a planet //Check if any are being clicked on selectPlanet = planNull; //Adjust mouse coordinates based on camera Vec2f click(event.button.x + camera.x, event.button.y + camera.y); for (planetIter i = planets.begin(); i != planets.end(); i++) { //See if distance from center is less than planet radius Vec2f center(i->x() + (UNSCALED_PLANET_RADIUS * i->size()), i->y() + (UNSCALED_PLANET_RADIUS * i->size())); if ((click-center).length() < UNSCALED_PLANET_RADIUS * i->size()) { //Ensure the planet belongs to this person if ((*i).owner() == localPlayer) { selectPlanet = i; break; } } } } //Right click if (event.button.button == SDL_BUTTON_RIGHT) { //Used to choose the destination for a fleet //See if we have a selected planet if (selectPlanet != planNull) { //Adjust mouse coordinates based on camera Vec2f click(event.button.x + camera.x, event.button.y + camera.y); //Check to see if any are being clicked on for (planetIter i = planets.begin(); i != planets.end(); i++) { Vec2f center(i->x() + (UNSCALED_PLANET_RADIUS * i->size()), i->y() + (UNSCALED_PLANET_RADIUS * i->size())); //See if distance from center is less than planet radius if ((click-center).length() < UNSCALED_PLANET_RADIUS * i->size()) { //Split ships from the source planet int transfer = (*selectPlanet).splitShips(0.5, shipSendType); //Make sure we actually have a ship in the fleet if (transfer > 0) { //Add the new fleet fleets.push_back(Fleet(transfer, shipSendType, shipstats[shipSendType], &(*selectPlanet), &(*i))); break; } } } } } } } //Draw a white background SDL_Rect back = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; SDL_FillRect(screen, &back, 0xFFFFFF); //Update and display fleets for (fleetIter i = fleets.begin(); i != fleets.end(); i++) { (*i).update(); //Check for arrival at destination //See if distance from center is less than planet radius Vec2f tar((*i).dest()->x() + (UNSCALED_PLANET_RADIUS*(*i).dest()->size()), (*i).dest()->y() + (UNSCALED_PLANET_RADIUS*(*i).dest()->size())); if ((tar-i->pos()).length() < UNSCALED_PLANET_RADIUS * (i->dest())->size()) { //Check if friendly or hostile if ((*i).dest()->owner() == (*i).owner()) { //Add the fleet to the new planet (*((*i).dest())).addShips(i->ships(), i->type()); } else //Hostile { //Attack! //Get ship counts before the attack std::vector<int> ships1 = i->dest()->shipcount(); int oldowner = i->dest()->owner(); //Actually do the attack (*((*i).dest())).takeAttack(i->ships(), i->type(), i->owner(), shipstats, indicator); //If the attack changed ownership of the selected planet, //deselect it if (oldowner != i->dest()->owner() && i->dest() == &(*selectPlanet)) selectPlanet = planNull; //Get ship counts after the attack std::vector<int> ships2 = i->dest()->shipcount(); //Notify the defending AI about the losses for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++) { if (oldowner != j->player()) continue; float newdefense = 0; for (unsigned int k = 0; k < ships1.size(); k++) { int diff; //If ownership has changed if (oldowner != i->dest()->owner()) { diff = ships1[k]; j->notifyPlanetLoss(i->dest()); } else { diff = ships1[k] - ships2[k]; } newdefense += diff * shipstats[k].defense; } j->notifyDefendLoss(newdefense); } //Notify the attacking AI about the losses for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++) { if (i->owner() != j->player()) continue; float lost; //If the attack failed if (i->dest()->owner() != i->owner()) { //Lost everything lost = i->ships(); } else //Successful attack { //Lose the difference lost = i->ships() - i->dest()->totalDefense(shipstats); j->notifyPlanetGain(i->dest()); } j->notifyAttackLoss(lost); } } //Delete all projectiles with this fleet as its target for (projectileIter pi = projectiles.begin(); pi != projectiles.end(); pi++) { if (pi->target() == &(*(i))) { pi = projectiles.erase(pi); pi--; } } //Delete the fleet i = fleets.erase(i); i--; continue; } //Check for interception //Compare against every other fleet for (fleetIter j = fleets.begin(); j != fleets.end(); j++) { //Atempt interception char status = i->intercept(&(*j), shipstats); //Greater than 0: Draw line if (status <= 0) continue; SDL_Color red = {255, 0, 0}; SDL_Color orange = {255, 255, 0}; linedraw.line(i->pos(), j->pos(), orange, red); //Equal to 2: Dealt damage, but didn't notify if (status == 2) { //Notify the AI before we go around deleting things for (std::list<GalconAI>::iterator k = ai.begin(); k != ai.end(); k++) { if (k->player() == j->owner()) { k->notifyFleetDamage(std::min(double(shipstats[i->type()].interceptDamage), double(j->totalDefense(shipstats)))); } } } //Equal to 3: Destroy target if (status != 3) break; //We can have the projectile code handle the cleanup later //Create a fake projectile right on top of it to deal the final blow std::stringstream convertnum; convertnum << "damage "; convertnum << shipstats[i->type()].interceptDamage*i->ships()*2; projectiles.push_back(Projectile(j->pos(), &(*j), convertnum.str(), shipstats[j->type()].speed*2)); //Don't attack more than one ship break; } (*i).display(screen, camera); } //Update and display planets for (planetIter i = planets.begin(); i != planets.end(); i++) { //Get ship counts before the update std::vector<int> ships1 = i->shipcount(); //Update the planet (*i).update(); //Get ship counts after the update std::vector<int> ships2 = i->shipcount(); //Notify a controlling AI about the construction for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++) { if (i->owner() != j->player()) continue; float newattack = 0; float newdefense = 0; for (unsigned int k = 0; k < ships1.size(); k++) { int diff = ships2[k] - ships1[k]; newattack += diff * shipstats[k].attack; newdefense += diff * shipstats[k].defense; } j->notifyConstruction(newattack, newdefense); } //If this planet is selected, add an indicator if (i == selectPlanet) { SDL_Rect temprect = {Sint16((*i).x()-10 - camera.x), Sint16((*i).y()-10 - camera.y), Uint16(UNSCALED_PLANET_RADIUS * (*i).size() * 2 + 20), Uint16(UNSCALED_PLANET_RADIUS * (*i).size() * 2 + 20)}; SDL_FillRect(screen, &temprect, SDL_MapRGB(screen->format, 100, 100, 100)); } //If this is a lava planet and it is depleted, replace the image if (i->typeInfo() < 0 && i->type() == 1) { i->setImage(planet1_1img); i->setTypeInfo(0); i->setRotSpeed(0); i->setShipRate(0, ship0rate * PLANET1_DEPLETION_PENALTY); } //Iterate over all buildings to handle effects from buildings to other objects for (unsigned int j = 0; j < i->buildcount(); j++) { //Get the building BuildingInstance* b = i->building(j); //Skip over nonexistant and incomplete buildings if (!(b->exists()) || j == Uint32(i->buildIndex())) continue; //Try to make it fire, remember result bool fire = b->fire(); //Create a string stream and vector for tokens std::stringstream ss(b->effect()); std::string item; std::vector<std::string> tokens; while (std::getline(ss, item, ' ')) { tokens.push_back(item); } //Ensure the size is at least two if (tokens.size() < 3) continue; //Parse it and apply effects that involve multiple objects //Fire projectile: fire <effect> <effectvars> <speed as multiplier> if (tokens[0] == "fire") { //Ensure size of four if (tokens.size() != 4) continue; //Loop over all potential target fleets, find closest Fleet* closest = NULL; float closestDist = -1; Vec2f coords = i->buildcoords(j); for (fleetIter k = fleets.begin(); k != fleets.end(); k++) { //Only check further if it's an enemy fleet if (k->owner() == i->owner()) continue; //Compute the distance between them double dist = (coords-k->pos()).length(); //Continue if the fleet is out of range if (dist > b->range()) continue; //Compare with previous best if (dist < closestDist || closestDist < -0.5) { closestDist = dist; closest = &(*k); } } //Fire a projectile from the building to the fleet if (closest != NULL) { if (fire) { //Create a proper string for the projectile std::string projstr; for (unsigned int word = 1; word < tokens.size()-1; word++) { projstr += tokens[word] + " "; } projectiles.push_back(Projectile(coords, closest, projstr, std::atof(tokens[tokens.size()-1].c_str()))); } } } //Aura: aura <effect> <effectvars> if (tokens[0] == "aura") { //Find number of ships in range int shipcount = 0; for (fleetIter k = fleets.begin(); k != fleets.end(); k++) { //Only check further if it's an enemy fleet if (k->owner() == i->owner()) continue; //Compute the distance between them double dist = (i->buildcoords(j)-k->pos()).length(); if (dist <= b->range()) shipcount += k->ships(); } //Deal damage with a fake projectile if (fire) { bool hit = false; for (fleetIter k = fleets.begin(); k != fleets.end(); k++) { //Only check further if it's an enemy fleet if (k->owner() == i->owner()) continue; //Compute the distance between them double dist = (i->buildcoords(j)-k->pos()).length(); if (dist > b->range()) continue; hit = true; std::string projstr; //Divide appropriately if needed if (tokens[tokens.size()-1] == "total") { std::stringstream toa; toa << atof(tokens[tokens.size()-2].c_str())*float(k->ships())/float(shipcount); tokens[tokens.size()-1] = toa.str(); } //Depleted volcanic planets don't do as much if (i->type() == 1 && i->typeInfo() <= 0) { std::stringstream toa; toa << atof(tokens[tokens.size()-2].c_str())*PLANET1_DEPLETION_PENALTY; tokens[tokens.size()-1] = toa.str(); } //Create the projectile for (unsigned int word = 1; word < tokens.size()-1; word++) { projstr += tokens[word] + " "; } projectiles.push_back(Projectile(k->pos(), &(*k), projstr, 1)); } //Volcanic planets will lost some fuel if (i->type() == 1 && hit && i->typeInfo() != 0) { i->setTypeInfo(i->typeInfo()-PLANET1_DEPLETION_RATE); if (i->typeInfo() == 0) i->setTypeInfo(-1); } } } } //for each building (*i).display(screen, planetFont, camera); } //Update and display projectiles for (projectileIter i = projectiles.begin(); i != projectiles.end(); i++) { (*i).update(); //Check if the projectile has hit its target fleet if ((i->pos() - i->target()->pos()).length() < 12.345) //MAGIC NUMBER >:( { //Tokenize string to determine effect std::stringstream ss(i->effect()); std::string item; std::vector<std::string> tokens; while (std::getline(ss, item, ' ')) { tokens.push_back(item); } //Damage: damage <amount> if (tokens[0] == "damage") { //Ensure size of two if (tokens.size() != 2) continue; //Deliver the damage //Notify the AI before we go around deleting things for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++) { if (j->player() == i->target()->owner()) { j->notifyFleetDamage(std::min(std::atof(tokens[1].c_str()), double(i->target()->totalDefense(shipstats)))); } } //Check to see if the fleet is destroyed by this if (!(i->target()->takeHit(std::atof(tokens[1].c_str()), shipstats))) { //Delete the fleet for (fleetIter fi = fleets.begin(); fi != fleets.end(); fi++) { if (&(*fi) == &(*(i->target()))) { fleets.erase(fi); break; } } //Delete all projectiles with this fleet as the target for (projectileIter pi = projectiles.begin(); pi != projectiles.end(); pi++) { if (pi->target() == i->target()) { if (pi == i) continue; pi = projectiles.erase(pi); pi--; } } } //Either way, destroy this projectile i = projectiles.erase(i); i--; continue; } } (*i).display(screen, camera); } //Perform AI calculations for (std::list<GalconAI>::iterator i = ai.begin(); i != ai.end(); i++) { //Get the command list commandList com = i->update(planets, fleets, shipstats, buildRules); //Execute each command for (commandList::iterator j = com.begin(); j != com.end(); j++) { //Extract the info from the command Planet* source = j->first; int amount = j->second.first; Planet* dest = j->second.second; //Handle building construction if (source == dest) { std::list<Building*>::iterator build = buildRules[source->type()].begin(); while (amount > 0) { amount--; build++; } //Build it! source->build((*build), buildRules); continue; } //Get the number of ships from the source std::vector<int> ships = source->shipcount(); //Send out a fleet for each ship type used std::vector<int> newfleet; newfleet.resize(ships.size()); int total = 0; for (unsigned int k = 0; k < ships.size(); k++) { //Handle it differently for attack or defense float typeTotal; if (dest->owner() == source->owner()) { //Check the total defense of this ship type typeTotal = ships[k] * shipstats[k].defense; } else { //Check the total attack of this ship type typeTotal = ships[k] * shipstats[k].attack; } //If there's more ships requested than there are of this type if (total + typeTotal <= amount) { //Add them all newfleet[k] += ships[k]; total += typeTotal; } else //More ships than space in the requested fleet { //Find the proper amount //# of ships to send = defense requested / def per ship float properAmount = (amount - total) / (typeTotal / ships[k]); newfleet[k] += properAmount; break; } } //Fleet is built, send each type that has some ships for (unsigned int k = 0; k < newfleet.size(); k++) { if (newfleet[k] == 0) continue; fleets.push_back(Fleet(newfleet[k], k, shipstats[k], source, dest)); //Also subtract the fleet from the original planet newfleet[k] *= -1; source->addShips(newfleet[k], k); } } } //Flipoo if (SDL_Flip(screen) == -1) { return 1; } } //Free surfaces SDL_FreeSurface(indicator[1]); SDL_FreeSurface(indicator[2]); SDL_FreeSurface(planet0img); SDL_FreeSurface(planet1img); SDL_FreeSurface(planet1_1img); //Clean up TTF TTF_CloseFont(planetFont); TTF_Quit(); SDL_Quit(); }
: m_building(building) , m_pointOfCare(pointOfCare) , m_floor(floor) , m_bed(bed) {} private: std::string m_building; std::string m_pointOfCare; int m_floor; int m_bed; }; TEST_CASE("ctor of Location") { const Location loc( Building("Central"), PointOfCare("Intensive Care"), Floor(3), Bed(12)); } namespace My { template<class T1, class T2> struct MaxSize { static const int value = sizeof(T1) > sizeof(T2) ? sizeof(T1) : sizeof(T2); }; } typedef My::MaxSize<int, char> MaxIntChar; typedef My::MaxSize<int, long long> MaxIntLongLong;
Block::Block(int x, int z) { blockX = x; blockZ = z; streetRenderer.initShaders("shaders/colorShader.vert", "shaders/colorShader.frag"); float floor[] = { getBlockXCoord() - (streetWidth / 2), 0, getBlockZCoord() - (streetWidth / 2), getBlockXCoord() + (blockWidth * lotScale) + (streetWidth / 2), 0, getBlockZCoord() - (streetWidth / 2), getBlockXCoord() + (blockWidth * lotScale) + (streetWidth / 2), 0, getBlockZCoord() + (blockWidth * lotScale) + (streetWidth / 2), getBlockXCoord() - (streetWidth / 2), 0, getBlockZCoord() + (blockWidth * lotScale) + (streetWidth / 2), 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0.35f, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, }; unsigned int floorIndices[] = { 0, 1, 2, 0, 2, 3 }; streetRenderer.allocBuffers(sizeof(floor), sizeof(floorIndices)); streetRenderer.subVertexData(0, sizeof(floor), floor); streetRenderer.subIndexData(0, sizeof(floorIndices), floorIndices); streetRenderer.setNumVertices(4, 6); int seed = time(0) + (x * 65537) + (z * 4730861); Noise r(seed); std::cout << "seed = " << seed << '\n'; int numLots = blockWidth * blockDepth; int maxNumBuildings = (blockWidth * 2) + (blockDepth * 2) - 4; lotArray = new int[numLots]; numBuildings = 0; buildingArray = new Building[numBuildings]; int buildingSizes[maxNumBuildings]; int lotsTaken = 0; int lotIndex = 0; while (lotsTaken < numLots) { numBuildings++; float buildingSize = (r.nextFloat() + 1) / 2.f; buildingSize *= buildingSize * buildingSize * buildingSize; buildingSize = ceil(buildingSize * numLots); if (lotsTaken + buildingSize > numLots) { buildingSize = numLots - lotsTaken; } if (numBuildings == maxNumBuildings) { buildingSize = numLots - lotsTaken; } buildingSizes[lotIndex] = buildingSize; lotsTaken += buildingSize; lotIndex++; } MathHelper::reverseBubbleSort(buildingSizes, numBuildings); for(int i = 0; i < numLots; ++i){ lotArray[i] = -1; } for(int building = 0; building < numBuildings; ++building){ int buildingSize = buildingSizes[building]; //Start position // int startOffset = (random.nextInt() % (maxNumBuildings - 1)) + 1; int startX = 0, startZ = 0; float rand1 = r.nextFloat(); float rand2 = r.nextFloat(); if(rand1 > 0.5f){ startX = (blockWidth - 1) / 2; if(rand2 > 0.5f){ startZ = 0; } else { startZ = blockDepth; } } else { startZ = (blockDepth - 1) / 2; if(rand2 > 0.5f){ startX = 0; } else { startZ = (blockWidth - 1) / 2; } } int xDir = 1, zDir = 0; while (lotArray[getLotIndex(startX, startZ)] != -1) { if (startX + xDir > blockWidth - 1) { xDir = 0; zDir = 1; } if (startZ + zDir > blockDepth - 1) { xDir = -1; zDir = 0; } if (startX + xDir < 0) { xDir = 0; zDir = -1; } if (startZ + zDir < 0) { xDir = 1; zDir = 0; } startX += xDir; startZ += zDir; } lotArray[getLotIndex(startX, startZ)] = building; /*std::cout << "\nLot array\n" << building + 1 << "\n"; for (int x = 0; x < blockWidth; ++x) { for (int z = 0; z < blockDepth; ++z) { std::cout << lotArray[getLotIndex(x, z)] + 1 << ' '; } std::cout << '\n'; }*/ for (int buildingLot = 1; buildingLot < buildingSize; ++buildingLot){ int lotX = -1, lotZ = -1; int priority = 0; for(int x = 0; x < blockWidth; ++x){ for(int z = 0; z < blockDepth; ++z){ Position position = POS_DEFAULT; Priority lotPriority = NO_CONNECTION; int numEdges = 0; int numDiags = 0; int lotX_Z = lotArray[getLotIndex(x, z)]; if(lotX_Z != -1){ continue; } int lotXM1_Z = lotArray[getLotIndex(x - 1, z)]; int lotXM1_ZP1 = lotArray[getLotIndex(x - 1, z + 1)]; int lotX_ZP1 = lotArray[getLotIndex(x, z + 1)]; int lotXP1_ZP1 = lotArray[getLotIndex(x + 1, z + 1)]; int lotXP1_Z = lotArray[getLotIndex(x + 1, z)]; int lotXP1_ZM1 = lotArray[getLotIndex(x + 1, z - 1)]; int lotX_ZM1 = lotArray[getLotIndex(x, z - 1)]; int lotXM1_ZM1 = lotArray[getLotIndex(x - 1, z - 1)]; //Check position if(((x == 0) || (x == blockWidth - 1)) && ((z == 0) || (z == blockDepth - 1))){//Corner position = POS_CORNER; } else if(x == 0 || x == blockWidth - 1 || z == 0 || z == blockDepth - 1){//Side position = POS_SIDE; } else {//Center position = POS_CENTER; } //Check edges if(x != 0 && lotXM1_Z == building){ ++numEdges; } if(x != blockWidth - 1 && lotXP1_Z == building){ ++numEdges; } if(z != 0 && lotX_ZM1 == building){ ++numEdges; } if(z != blockDepth - 1 && lotX_ZP1 == building){ ++numEdges; } //Check diagonals if (x != 0) { if(z != 0 && lotXM1_ZM1 == building){ ++numDiags; } if(z != blockDepth - 1 && lotXM1_ZP1 == building){ ++numDiags; } } if (x != blockWidth - 1) { if(z != 0 && lotXP1_ZM1 == building){ ++numDiags; } if(z != blockDepth - 1 && lotXP1_ZP1 == building){ ++numDiags; } } if(position == POS_CENTER){ if(numEdges == 0){ continue;//Check } else if(numEdges == 1){ if(numDiags == 0){ lotPriority = ONE_EDGE_NO_DIAG_CENTER; } else if(numDiags == 1){ lotPriority = ONE_EDGE_ONE_DIAG_CENTER; } } else if(numEdges == 2){ lotPriority = TWO_EDGE_ONE_DIAG_CENTER; } } else if(position == POS_CORNER){ if(numEdges == 0){ continue;//Check } else if(numEdges == 1){ if(numDiags == 0){ lotPriority = ONE_EDGE_NO_DIAG_CORNER; } else if(numDiags == 1){ lotPriority = ONE_EDGE_ONE_DIAG_CORNER; } } else if(numEdges == 2){ lotPriority = TWO_EDGE_ONE_DIAG_CORNER; } } else if(position == POS_SIDE){ if(numEdges == 0){ continue;//Check } else if(numEdges == 1){ if(numDiags == 0){ lotPriority = ONE_EDGE_NO_DIAG_SIDE; } else if(numDiags == 1){ lotPriority = ONE_EDGE_ONE_DIAG_SIDE; } } else if(numEdges == 2){ lotPriority = TWO_EDGE_ONE_DIAG_SIDE; } } if(lotPriority == priority){ if(r.nextFloat() < 0.5f){ lotX = x; lotZ = z; } } else if(lotPriority > priority){ lotX = x; lotZ = z; priority = lotPriority; } } } lotArray[getLotIndex(lotX, lotZ)] = building; /*std::cout << "\nLot array\n" << building + 1 << "\n"; for (int x = 0; x < blockWidth; ++x) { for (int z = 0; z < blockDepth; ++z) { std::cout << lotArray[getLotIndex(x, z)] + 1 << ' '; } std::cout << '\n'; }*/ } } buildingArray = new Building[numBuildings]; for(int i = 0; i < numBuildings; ++i){ buildingArray[i] = Building(buildingSizes[i], i, this); } //Printing std::cout << numBuildings << '\n'; for (int i = 0; i < numBuildings; ++i) { std::cout << "Building " << i + 1 << ": " << buildingSizes[i] << '\n'; } std::cout << "\nLot array\n\n"; for (int z = blockDepth - 1; z > -1; --z) { for (int x = 0; x < blockWidth; ++x) { std::cout << lotArray[getLotIndex(x, z)] + 1 << ' '; } std::cout << '\n'; } }