Exemplo n.º 1
0
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());
}
Exemplo n.º 2
0
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) );
  }
}
Exemplo n.º 5
0
Building Building::getObject(vector<string> param,string sepOut,string sepIn) {
	Building building = Building(param,sepOut,sepIn);
	return building;
}
Exemplo n.º 6
0
//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();
}
Exemplo n.º 7
0
    : 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;
Exemplo n.º 8
0
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';
	}
}