Skip to content

Commit

Permalink
Merge pull request #79 from OpenVicProject/states
Browse files Browse the repository at this point in the history
  • Loading branch information
BrickPi authored and Hop311 committed Dec 4, 2023
2 parents 444a277 + e78249b commit 50b6ab4
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/openvic-simulation/GameManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ bool GameManager::load_bookmark(Bookmark const* new_bookmark) {
}
today = bookmark->get_date();
ret &= map.apply_history_to_provinces(history_manager.get_province_manager(), today);
map.get_state_manager().generate_states(map);
// TODO - apply country history
// TODO - apply pop history
return ret;
Expand Down
5 changes: 5 additions & 0 deletions src/openvic-simulation/map/Map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "openvic-simulation/map/Region.hpp"
#include "openvic-simulation/map/TerrainType.hpp"
#include "openvic-simulation/map/State.hpp"

namespace OpenVic {
namespace fs = std::filesystem;
Expand Down Expand Up @@ -69,6 +70,8 @@ namespace OpenVic {
Province::index_t get_index_from_colour(colour_t colour) const;
bool _generate_province_adjacencies();

StateManager PROPERTY_REF(state_manager);

public:
Map();

Expand Down Expand Up @@ -98,6 +101,8 @@ namespace OpenVic {
bool add_mapmode(std::string_view identifier, Mapmode::colour_func_t colour_func);
IDENTIFIER_REGISTRY_ACCESSORS(mapmode)

REF_GETTERS(state_manager);

/* The mapmode colour image contains of a list of base colours and stripe colours. Each colour is four bytes
* in RGBA format, with the alpha value being used to interpolate with the terrain colour, so A = 0 is fully terrain
* and A = 255 is fully the RGB colour packaged with A. The base and stripe colours for each province are packed
Expand Down
2 changes: 1 addition & 1 deletion src/openvic-simulation/map/Province.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bool Province::load_positions(BuildingManager const& building_manager, ast::Node
"factory", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.factory)),
"building_construction", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.building_construction)),
"military_construction", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.military_construction)),
"building_position", ZERO_OR_ONE, expect_dictionary_keys(
"building_position", ZERO_OR_ONE, expect_dictionary_keys( // TODO: for TGC etc are building positions available for modded-in buildings? needs testing
"fort", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.fort)),
"railroad", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.railroad)),
"naval_base", ZERO_OR_ONE, expect_fvec2(assign_variable_callback(positions.navalbase))
Expand Down
4 changes: 3 additions & 1 deletion src/openvic-simulation/map/Province.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace OpenVic {
struct Map;
struct Region;
struct State;
struct Good;
struct TerrainType;
struct TerrainTypeMapping;
Expand All @@ -27,7 +28,7 @@ namespace OpenVic {
using distance_t = uint16_t;
using flags_t = uint16_t;

enum struct colony_status_t : int8_t { STATE, PROTECTORATE, COLONY };
enum struct colony_status_t : uint8_t { STATE, PROTECTORATE, COLONY };

struct adjacency_t {
friend struct Province;
Expand Down Expand Up @@ -62,6 +63,7 @@ namespace OpenVic {
private:
const index_t PROPERTY(index);
Region* PROPERTY(region);
State const* PROPERTY_RW(state);
bool PROPERTY(on_map);
bool PROPERTY(has_region);
bool PROPERTY(water);
Expand Down
83 changes: 83 additions & 0 deletions src/openvic-simulation/map/State.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "State.hpp"

#include "Map.hpp"

using namespace OpenVic;

State::State(
Country const* owner, Province const* capital, Region::provinces_t&& provinces, Province::colony_status_t colony_status
) : owner { owner }, capital { capital }, provinces { std::move(provinces) }, colony_status { colony_status } {}

StateSet::StateSet(Region const* new_region) {
if (region->get_meta()) {
Logger::error("Cannot use meta region as state template!");
}
region = new_region;

std::vector<Region::provinces_t> temp_provinces;
bool in_state = false;

for (Province* province : region->get_provinces()) {
// add to existing state if shared owner & status...
for (Region::provinces_t& provinces : temp_provinces) {
if (provinces[0] == province) {
provinces.push_back(province);
in_state = true;
break;
}
}
if (in_state) {
in_state = false;
} else {
// ...otherwise start a new state
temp_provinces.push_back({ province });
}
}

for (Region::provinces_t& provinces : temp_provinces) {
states.push_back({
/* TODO: capital province logic */
provinces[0]->get_owner(), provinces[0], std::move(provinces), provinces[0]->get_colony_status()
});
}

// Go back and assign each new state to its provinces.
for (State const& state : states) {
for (Province* province : state.get_provinces()) {
province->set_state(&state);
}
}
}

bool StateSet::add_state(State&& state) {
const auto existing = std::find(states.begin(), states.end(), state);
if (existing != states.end()) {
Logger::error("Attempted to add existing state!");
return false;
}
states.push_back(std::move(state));
return true;
}

bool StateSet::remove_state(State const* state) {
const auto existing = std::find(states.begin(), states.end(), *state);
if (existing == states.end()) {
Logger::error("Attempted to remove non-existant state!");
return false;
}
states.erase(existing);
return true;
}

StateSet::states_t& StateSet::get_states() {
return states;
}

void StateManager::generate_states(Map const& map) {
regions.clear();
regions.reserve(map.get_region_count());
for(Region const& region : map.get_regions()) {
regions.push_back(StateSet(&region));
}
Logger::info("Generated states.");
}
54 changes: 54 additions & 0 deletions src/openvic-simulation/map/State.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include "openvic-simulation/map/Province.hpp"
#include "openvic-simulation/map/Region.hpp"
#include "openvic-simulation/country/Country.hpp"

#include <deque>

namespace OpenVic {
struct State {
private:
Country const* PROPERTY_RW(owner);
Province const* PROPERTY_RW(capital);
Region::provinces_t PROPERTY(provinces);
Province::colony_status_t PROPERTY_RW(colony_status);

public:
State(
Country const* owner, Province const* capital, Region::provinces_t&& provinces,
Province::colony_status_t colony_status
);
};

inline bool operator==(const State& lhs, const State& rhs) {
return (lhs.get_owner() == rhs.get_owner() && lhs.get_colony_status() == rhs.get_colony_status());
}

struct StateSet {
using states_t = std::deque<State>;

private:
Region const* PROPERTY(region);
states_t states;

public:
StateSet(Region const* new_region);

bool add_state(State&& state);
bool remove_state(State const* state);
states_t& get_states();
};

/* Contains all current states.*/
struct StateManager {
private:
std::vector<StateSet> PROPERTY(regions);

public:
/* Creates states from current province gamestate & regions, sets province state value.
* After this function, the `regions` property is unmanaged and must be carefully updated and
* validated by functions that modify it. */
void generate_states(Map const& map);
};
} // namespace OpenVic

0 comments on commit 50b6ab4

Please sign in to comment.