Beispiel #1
0
void add_construction(region_t &region, const int x, const int y, const int z, const std::string type, bool solid, const std::size_t &civ_owner) {

    const auto idx = mapidx(x,y,z);
    region.water_level[idx] = 0;
    region.solid[idx] = false;
    region.tile_type[idx] = tile_type::FLOOR;
    region.tile_flags[idx].set(CONSTRUCTION);
    const auto plasteel = get_material_by_tag("plasteel").get();
    region.tile_material[idx] = plasteel;
    region.tile_vegetation_type[idx] = 0;

    const auto wood = get_material_by_tag("wood").get();

    if (type == "ship_wall") {
        region.tile_type[idx] = tile_type::WALL;
        region.solid[idx] = true;
        region.opaque[idx] = true;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = plasteel;
    } else if (type == "ship_window") {
        region.tile_type[idx] = tile_type::WINDOW;
        region.solid[idx] = true;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = plasteel;
    } else if (type == "ship_floor") {
        region.tile_type[idx] = tile_type::FLOOR;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = plasteel;    
    } else if (type == "hut_wall") {
        region.tile_type[idx] = tile_type::WALL;
        region.solid[idx] = true;
        region.opaque[idx] = true;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = wood;
    } else if (type == "hut_floor") {
        region.tile_type[idx] = tile_type::FLOOR;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = wood; 
    } else if (type == "ship_up") {
        region.tile_type[idx] = tile_type::STAIRS_UP;
        region.solid[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = plasteel;    
    } else if (type == "ship_down") {
        region.tile_type[idx] = tile_type::STAIRS_DOWN;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = plasteel;    
    } else if (type == "ship_updown") {
        region.tile_type[idx] = tile_type::STAIRS_UPDOWN;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = plasteel;    
    } else if (type == "hut_upstairs") {
        region.tile_type[idx] = tile_type::STAIRS_UP;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = wood;    
    } else if (type == "hut_downstairs") {
        region.tile_type[idx] = tile_type::STAIRS_DOWN;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = wood;    
    } else if (type == "hut_updownstairs") {
        region.tile_type[idx] = tile_type::STAIRS_UPDOWN;
        region.solid[idx] = false;
        region.opaque[idx] = false;
        region.tile_flags[idx].set(CONSTRUCTION);
        region.tile_material[idx] = wood;
    } else if (type == "cordex") {
        add_building("cordex", x, y, z, civ_owner);
    } else if (type == "solar_panel") {
        add_building("solar_panel", x, y, z, civ_owner);
    } else if (type == "cryo_bed") {
        add_building("cryo_bed", x, y, z, civ_owner);
    } else if (type == "storage_locker") {
        region.tile_flags[idx].set(CONSTRUCTION);
        add_building("storage_locker", x, y, z, civ_owner);
    } else if (type == "battery") {
        add_building("battery", x, y, z, civ_owner);
    } else if (type == "rtg") {
        add_building("rtg", x, y, z, civ_owner);
    } else if (type == "small_replicator") {
        add_building("small_replicator", x, y, z, civ_owner);
    } else if (type == "campfire") {
        add_building("camp_fire", x, y, z, civ_owner);
    } else if (type == "ship_door") {
        add_building("energy_door", x, y, z, civ_owner);
    } else if (type == "door") {
        //std::cout << "Door owner: " << civ_owner << "\n";
        add_building("door", x, y, z, civ_owner);
    } else {
        std::cout << "Don't know how to build a " << type << "\n";
    }
}
Beispiel #2
0
bool AI_city::add_random_building()
{
// This filters out any buildings that are just data for Areas.
  std::vector<Building_type> buildable = get_true_building_types();
  int start = rng(0, buildable.size() - 1);
  bool done = false;
  for (int i = start + 1; !done && i != start; i++) {
    if (i == buildable.size()) {
      i = 0; // Loop around to the start
      if (start == 0) {
        done = true;
      }
    }
    Building_type type = buildable[i];
    Building_datum* build_dat = Building_data[type];
    bool can_build = true;
// Check 1: Do we have available employees
    Citizen_amount jobs = build_dat->jobs;
    if (free_citizens[jobs.type] <= 0) {
      can_build = false;
    }
// Check 2: Ensure we can (and want to) pay the maintenance cost
    for (int n = 0; can_build && n < build_dat->maintenance_cost.size(); n++) {
      Resource_amount res_amt = build_dat->maintenance_cost[n];
      int deficit = resource_production[res_amt.type] - res_amt.amount;
// TODO: Don't hardcode this value.
      if (deficit < -5) {
        can_build = false;
      }
    }
// Check 3: Does it make something we want
    bool good_output = false;
    for (int n = 0; !good_output && n < build_dat->production.size(); n++) {
      Resource_amount res_amt = build_dat->production[n];
      if (resource_production.count(res_amt.type) == 0) {
// If it produces something we don't have, we want it!
        good_output = true;
      } else {
// Randomly decide if we want more of that resource.  If the building gives us
// five percent of our current output, it's an even split; the more we already
// produce the less likely it is that we want more.
        int bldg_roll = rng(0, 20 * res_amt.amount);
        int cur_roll  = rng(0, resource_production[res_amt.type]);
        if (bldg_roll >= cur_roll) {
          good_output = true;
        }
      }
    }

    if (!good_output && !build_dat->recipes.empty()) {
// If it doesn't have any constant production we want, maybe we want a recipe?
      for (int n = 0; !good_output && n < build_dat->recipes.size(); n++) {
        Recipe recipe = build_dat->recipes[n];
// Ensure that we have all the ingredients.
        bool has_ingredients = false;
        for (int m = 0;
             !has_ingredients && m < recipe.resource_ingredients.size();
             m++) {
          Resource_amount res_amt = recipe.resource_ingredients[m];
          int max_deficit = recipe.max_deficit;
          int deficit = resource_production[res_amt.type] - res_amt.amount;
          if (deficit > max_deficit) {
            has_ingredients = true;
          }
        }
        for (int m = 0;
             !has_ingredients && m < recipe.mineral_ingredients.size();
             m++) {
          Mineral_amount min_amt = recipe.mineral_ingredients[m];
          int max_deficit = recipe.max_deficit;
          int deficit = mineral_production[min_amt.type] - min_amt.amount;
          if (deficit > max_deficit) {
            has_ingredients = true;
          }
        }
// If we have the ingredients, verify that we actually want the output (same as
// above)
        if (has_ingredients) {
          Resource_amount res_amt = recipe.result;
          if (resource_production.count(res_amt.type) == 0) {
// If it produces something we don't have, we want it!
            good_output = true;
          } else {
// Randomly decide if we want more of that resource.  If the building gives us
// five percent of our current output, it's an even split; the more we already
// produce the less likely it is that we want more.
            int bldg_roll = rng(0, 20 * res_amt.amount);
            int cur_roll  = rng(0, resource_production[res_amt.type]);
            if (bldg_roll >= cur_roll) {
              good_output = true;
            }
          }
        }
      } // for (int n = 0; !good_output && n < build_dat->recipes.size(); n++)
    } // if (!good_output && !build_dat->recipes.empty())

    if (can_build && good_output) {
// We can build it, and we want to build it, so build it!
      if (add_building(type)) { // add_building() returns false on fail
        return true;
      }
    }
  } // for (int i = start_type + 1; i != start_type; i++)

// If we reach this point, we didn't find a single building we want!
  return false;
}