Permalink
Browse files

Species/civs are behind their own API.

  • Loading branch information...
thebracket committed May 18, 2017
1 parent c382e31 commit 563f176f708318980e0bbf3fce7a9ec63a76a4be
@@ -4,6 +4,7 @@
#include <cereal/cereal.hpp>
#include <cereal/types/polymorphic.hpp>
#include "../raws/species.hpp"
#include "../raws/defs/civilization_t.hpp"
using namespace rltk;
@@ -5,15 +5,16 @@
#include "../../utils/string_utils.hpp"
#include "../../components/game_stats.hpp"
#include "../../raws/lua_bridge.hpp"
#include "../../raws/defs/civilization_t.hpp"
constexpr int n_civs = WORLD_WIDTH;
std::string get_random_species(random_number_generator &rng, const int tech_level=0) {
std::vector<std::string> eligible;
for (auto it=civ_defs.begin(); it!=civ_defs.end(); ++it) {
if (it->second.tech_level == tech_level) eligible.push_back(it->first);
}
each_civilization_def([&eligible, &tech_level] (std::string ctag, civilization_t * it) {
if (it->tech_level == tech_level) eligible.push_back(ctag);
});
if (eligible.empty()) throw std::runtime_error("No suitable civs available!");
return eligible[rng.roll_dice(1, eligible.size())-1];
@@ -45,9 +46,9 @@ void planet_build_initial_civs(planet_t &planet, rltk::random_number_generator &
// Name generation
using namespace string_tables;
auto civ_finder = civ_defs.find(civ.species_tag);
const std::string civ_name_func = "civ_name_gen_" + civ_finder->second.name_generator;
const std::string civ_leader_func = "leader_name_gen_" + civ_finder->second.name_generator;
auto civ_finder = get_civ_def(civ.species_tag);
const std::string civ_name_func = "civ_name_gen_" + civ_finder->name_generator;
const std::string civ_leader_func = "leader_name_gen_" + civ_finder->name_generator;
civ.name = lua_str_func(civ_name_func, rng.roll_dice(1,1000)) + std::string(" of the ") + loc_name;
if (str_contains(civ.name, "{LASTNAME}")) {
civ.name = str_replace(civ.name, "{LASTNAME}", string_table(LAST_NAMES)->random_entry(rng));
@@ -64,12 +65,12 @@ void planet_build_initial_civs(planet_t &planet, rltk::random_number_generator &
}
civ.origin = loc_name;
std::cout << "Welcome: " << civ.name << ", lead by " << civ.leader_name << "\n";
civ.glyph = get_species_def(civ_finder->second.species_tag)->worldgen_glyph;
civ.glyph = get_species_def(civ_finder->species_tag)->worldgen_glyph;
// Appearance
if (get_species_def(civ_finder->second.species_tag)->render_composite) {
civ.skin_color = get_species_def(civ_finder->second.species_tag)->skin_colors[rng.roll_dice(1, get_species_def(civ_finder->second.species_tag)->skin_colors.size())-1];
civ.hair_color = get_species_def(civ_finder->second.species_tag)->hair_colors[rng.roll_dice(1, get_species_def(civ_finder->second.species_tag)->hair_colors.size())-1];
if (get_species_def(civ_finder->species_tag)->render_composite) {
civ.skin_color = get_species_def(civ_finder->species_tag)->skin_colors[rng.roll_dice(1, get_species_def(civ_finder->species_tag)->skin_colors.size())-1];
civ.hair_color = get_species_def(civ_finder->species_tag)->hair_colors[rng.roll_dice(1, get_species_def(civ_finder->species_tag)->hair_colors.size())-1];
civ.hair_style = BALD;
const int style_roll = rng.roll_dice(1, 4);
@@ -123,8 +124,8 @@ std::string random_unit_type(const civilization_t &civ, random_number_generator
void planet_build_civ_year(const int year, planet_t &planet, random_number_generator &rng, civ_t &civ, const std::size_t &id) {
//std::cout << year << ", " << civ.name << "\n";
auto civ_f = civ_defs.find(civ.species_tag);
auto species_f = get_species_def(civ_f->second.species_tag);
auto civ_f = get_civ_def(civ.species_tag);
auto species_f = get_species_def(civ_f->species_tag);
// Total build points, find settlements
int bp = 0;
@@ -140,8 +141,8 @@ void planet_build_civ_year(const int year, planet_t &planet, random_number_gener
}
for (auto &unit : planet.civs.units) {
if (unit.owner_civ == id) {
auto unit_finder = civ_f->second.units.find(unit.unit_type);
if (unit_finder == civ_f->second.units.end()) {
auto unit_finder = civ_f->units.find(unit.unit_type);
if (unit_finder == civ_f->units.end()) {
throw std::runtime_error(std::string("Unable to find: ") + civ.species_tag + std::string("/") + unit.unit_type);
} else {
if (unit_finder->second.bp_per_turn > 0) bp += unit_finder->second.bp_per_turn;
@@ -171,10 +172,10 @@ void planet_build_civ_year(const int year, planet_t &planet, random_number_gener
}
// Build improvements
if (bp > 9 && !civ_f->second.can_build.empty()) {
if (bp > 9 && !civ_f->can_build.empty()) {
for (auto &pidx : towns) {
if (bp > 9) {
for (auto &build : civ_f->second.can_build) {
for (auto &build : civ_f->can_build) {
bool has_one = false;
for (const auto &i : planet.civs.region_info[pidx].improvements) {
if (i == build) has_one = true;
@@ -197,18 +198,18 @@ void planet_build_civ_year(const int year, planet_t &planet, random_number_gener
}
// Tech-level improvement
if (!civ_f->second.evolves_into.empty() && bp > civ.tech_level*15 && rng.roll_dice(1,25)==1) {
if (!civ_f->evolves_into.empty() && bp > civ.tech_level*15 && rng.roll_dice(1,25)==1) {
// Evolve!
bp = 0;
++civ.tech_level;
int roll = rng.roll_dice(1, civ_f->second.evolves_into.size())-1;
civ.species_tag = civ_f->second.evolves_into[roll];
auto civ2_f = civ_defs.find(civ.species_tag);
const std::string civ_name_func = "civ_name_gen_" + civ2_f->second.name_generator;
int roll = rng.roll_dice(1, civ_f->evolves_into.size())-1;
civ.species_tag = civ_f->evolves_into[roll];
auto civ2_f = get_civ_def(civ.species_tag);
const std::string civ_name_func = "civ_name_gen_" + civ2_f->name_generator;
std::cout << civ.name << " evolves to tech level " << +civ.tech_level << " and takes the name: " << civ.name << "\n";
civ.name = lua_str_func( civ_name_func, rng.roll_dice(1, 1000) ) + std::string(" of the ") + civ.origin;
civ_f = civ2_f;
species_f = get_species_def(civ_f->second.species_tag);
species_f = get_species_def(civ_f->species_tag);
civ.glyph = species_f->worldgen_glyph;
}
@@ -219,7 +220,7 @@ void planet_build_civ_year(const int year, planet_t &planet, random_number_gener
unit_t unit;
unit.owner_civ = id;
//std::cout << "(Civ " << id << "), " << planet.civs.civs[id].species_tag << "\n";
unit.unit_type = random_unit_type(civ_f->second, rng);
unit.unit_type = random_unit_type(*civ_f, rng);
unit.world_x = civ.startx;
unit.world_y = civ.starty;
planet.civs.units.push_back(unit);
@@ -231,7 +232,7 @@ void planet_build_civ_year(const int year, planet_t &planet, random_number_gener
// Movement goes here
for (auto &unit : planet.civs.units) {
if (unit.owner_civ == id) {
int moves = civ_f->second.units[unit.unit_type].speed;
int moves = civ_f->units[unit.unit_type].speed;
while (moves > 0) {
std::set<std::size_t> candidates;
if (unit.world_x > 1 && planet.landblocks[planet.idx(unit.world_x - 1, unit.world_y)].type != block_type::WATER) candidates.insert(planet.idx(unit.world_x - 1, unit.world_y));
@@ -304,10 +305,10 @@ void planet_build_run_year(const int year, planet_t &planet, random_number_gener
const std::string ut = planet.civs.units[uid].unit_type;
const std::string st = planet.civs.civs[cit->first].species_tag;
//std::cout << st << ":" << ut << "\n";
auto civ_f = civ_defs.find(st);
if (civ_f != civ_defs.end()) {
auto u_f = civ_f->second.units.find(ut);
if (u_f != civ_f->second.units.end()) {
auto civ_f = get_civ_def(st);
if (civ_f != nullptr) {
auto u_f = civ_f->units.find(ut);
if (u_f != civ_f->units.end()) {
str += u_f->second.worldgen_strength;
}
}
@@ -17,6 +17,7 @@
#include "../../components/natural_attacks_t.hpp"
#include "../../components/renderable_composite.hpp"
#include "../region/region.hpp"
#include "../raws/defs/civilization_t.hpp"
int sentient_get_stat_mod(const std::string stat, const raw_species_t * species) {
if (!species) return 0;
@@ -185,9 +186,9 @@ void create_sentient_unit(planet_t &planet, rltk::random_number_generator &rng,
const bool announce)
{
const std::string species_tag = planet.civs.civs[civ_id].species_tag;
auto civ_f = civ_defs.find(species_tag);
auto unit_f = civ_f->second.units.find(unit_tag);
if (unit_f == civ_f->second.units.end()) {
auto civ_f = get_civ_def(species_tag);
auto unit_f = civ_f->units.find(unit_tag);
if (unit_f == civ_f->units.end()) {
std::cout << "Error loading " << unit_tag << "\n";
return;
}
@@ -18,6 +18,7 @@
#include "../../components/sleep_clock_t.hpp"
#include "../../components/item_carried.hpp"
#include "../../raws/defs/profession_t.hpp"
#include "../../raws/defs/civilization_t.hpp"
using namespace rltk;
@@ -0,0 +1,92 @@
#pragma once
/*
* Defines species dietary preferences
*/
enum diet_t { diet_omnivore, diet_herbivore, diet_carnivore };
/*
* Defines base species alignment. This will be replaced at some point.
*/
enum alignment_t { align_good, align_neutral, align_evil, align_devour };
/*
* Basic definition of a species.
*/
struct raw_species_t {
std::string tag = "";
std::string name = "";
std::string male_name = "";
std::string female_name = "";
std::string collective_name = "";
std::string description = "";
std::unordered_map<std::string,int> stat_mods;
std::vector<std::tuple<std::string, int, int>> body_parts;
diet_t diet = diet_omnivore;
alignment_t alignment = align_neutral;
bool spreads_blight = false;
int max_age = 90;
int infant_age = 5;
int child_age = 12;
uint16_t glyph = '@';
uint16_t glyph_ascii = '@';
uint16_t worldgen_glyph = '@';
bool render_composite = false;
uint16_t base_male_glyph = 352;
uint16_t base_female_glyph = 353;
std::vector<std::pair<std::string, rltk::color_t>> skin_colors;
std::vector<std::pair<std::string, rltk::color_t>> hair_colors;
};
/*
* Definitions of civilizations that can be found.
*/
struct civ_unit_natural_attack_t {
std::string type = "";
int hit_bonus = 0;
int n_dice = 0;
int die_type = 6;
int die_mod = 0;
int range = 0;
};
struct civ_equipment_t {
std::vector< std::tuple< uint8_t, std::string, std::string >> starting_clothes;
std::string melee = "";
std::string ranged = "";
std::string ammo = "";
};
struct civ_unit_sentient_t {
int n_present = 0;
uint8_t base_level = 0;
std::string tag = "";
std::string name = "";
uint8_t base_armor_class = 10;
int hp_n = 1;
int hp_dice = 10;
int hp_mod = 0;
std::string gender = "male";
std::vector<civ_unit_natural_attack_t> natural_attacks;
civ_equipment_t equipment;
};
struct civ_unit_t {
std::string tag = "";
uint8_t bp_per_turn = 0;
uint8_t speed = 0;
std::string name = "";
std::vector<civ_unit_sentient_t> sentients;
int worldgen_strength = 1;
};
struct civilization_t {
uint8_t tech_level;
std::string tag;
std::string species_tag;
std::string ai;
std::string name_generator = "normal";
std::unordered_map<std::string, civ_unit_t> units;
std::vector<std::string> evolves_into;
std::vector<std::string> can_build;
};
@@ -2,6 +2,7 @@
#include "../main/game_rng.hpp"
#include "creatures.hpp"
#include "defs/raw_creature_t.hpp"
#include "defs/civilization_t.hpp"
health_t create_health_component_sentient(const raw_species_t * species, const int base_hp)
{
View
@@ -49,7 +49,7 @@ void build_tech_tree_files() {
make_building_tree(&master);
graphviz_t civs("civ_tree.gv");
make_civ_tree(civs);
make_civ_tree(&civs);
std::ofstream script(get_save_path() + std::string("/build-tech-tree.sh"));
script << "#!/bin/bash\n";
View
@@ -1,13 +1,30 @@
#include "species.hpp"
#include "lua_bridge.hpp"
#include "apihelper.hpp"
#include "defs/civilization_t.hpp"
#include <boost/container/flat_map.hpp>
#include "graphviz.hpp"
std::unordered_map<std::string, raw_species_t> species_defs;
std::unordered_map<std::string, civilization_t> civ_defs;
boost::container::flat_map<std::string, raw_species_t> species_defs;
boost::container::flat_map<std::string, civilization_t> civ_defs;
const raw_species_t * get_species_def(const std::string &tag) noexcept
{
return api_search<raw_species_t>(species_defs, tag);
auto finder = species_defs.find(tag);
if (finder == species_defs.end()) return nullptr;
return &finder->second;
}
civilization_t * get_civ_def(const std::string tag) {
auto finder = civ_defs.find(tag);
if (finder == civ_defs.end()) return nullptr;
return &finder->second;
}
void each_civilization_def(std::function<void(std::string, civilization_t *)> func) {
for (auto it=civ_defs.begin(); it!=civ_defs.end(); ++it) {
func(it->first, &it->second);
}
}
std::size_t get_species_defs_size() noexcept
@@ -295,23 +312,23 @@ void read_species_types() noexcept
read_civ_types();
}
void make_civ_tree(graphviz_t &tree) {
void make_civ_tree(graphviz_t * tree) {
for (auto it=civ_defs.begin(); it!=civ_defs.end(); ++it) {
const auto species = species_defs.find(it->second.species_tag);
const auto species_name = species->second.tag;
// Evolutionary options
for (const auto &evolve : it->second.evolves_into) {
tree.add_node(species_name, evolve);
tree->add_node(species_name, evolve);
}
// Units
for (const auto &unit : it->second.units) {
tree.add_node(species_name, unit.second.tag, graphviz_t::graphviz_shape_t::PARALLELOGRAM);
tree->add_node(species_name, unit.second.tag, graphviz_t::graphviz_shape_t::PARALLELOGRAM);
}
for (const auto &build : it->second.can_build) {
tree.add_node(species_name, build, graphviz_t::graphviz_shape_t::HOUSE);
tree->add_node(species_name, build, graphviz_t::graphviz_shape_t::HOUSE);
}
}
}
Oops, something went wrong.

0 comments on commit 563f176

Please sign in to comment.