summaryrefslogtreecommitdiff
path: root/universe/src/JsonRepository.cpp
blob: e8c8ed3089d732b66670eaeeb43cacdc1db43b78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "JsonRepository.h"

#include <fstream>
#include <functional>
#include <map>
#include <stdexcept>
#include <string>

#include <nlohmann/json.hpp>

#include <kurator/universe/NotFound.h>
#include <kurator/universe/ShipType.h>
#include <kurator/universe/TurretType.h>


using json = nlohmann::json;


namespace kurator
{
namespace universe
{


void
from_json(const json& item, ShipType& ship)
{
	item.at("name").get_to(ship.name);
	item.at("base_structure_points").get_to(ship.base_structure_points);
	item.at("base_armour_points").get_to(ship.base_armour_points);
	item.at("base_shield_points").get_to(ship.base_shield_points);
	item.at("max_speed").get_to(ship.max_speed);
}


void
from_json(const json& item, TurretType& turret)
{
	item.at("name").get_to(turret.name);
	if (item.contains("base_damage"))
		item.at("base_damage").get_to(turret.base_damage);
	if (item.contains("rounds"))
		item.at("rounds").get_to(turret.rounds);
	if (item.contains("rate_of_fire"))
		item.at("rate_of_fire").get_to(turret.rate_of_fire);
	if (item.contains("reload"))
		item.at("reload").get_to(turret.reload);
	if (item.contains("optimal_range"))
		item.at("optimal_range").get_to(turret.optimal_range);
	if (item.contains("falloff_modifier"))
		item.at("falloff_modifier").get_to(turret.falloff_modifier);
	if (item.contains("falloff_intensity"))
		item.at("falloff_intensity").get_to(turret.falloff_intensity);
}


template<typename Type>
std::map<std::string, Type>
parse(const std::string& path)
try {
	std::fstream file{path, file.binary | file.in};  // std::filesystem?
	if (!file.is_open())
		throw "could not load universe part";  // FIXME: proper errors and handling above
	std::map<std::string, Type> map;
	const auto root = json::parse(file);
	for (const auto& item : root) {
		auto def = item.get<Type>();
		map[def.name] = def;
	}
	return map;
}
catch (const json::parse_error&) {
	throw;
}


JsonRepository::JsonRepository(const std::string& path)
{
	ships = parse<ShipType>(path + "/ship_types.json");
	turrets = parse<TurretType>(path + "/turret_types.json");
}


ShipType
JsonRepository::ship_type(const std::string& id) const
try {
	return ships.at(id);
}
catch (const std::out_of_range&) {
	throw NotFound(id);
}


TurretType
JsonRepository::turret_type(const std::string& id) const
try {
	return turrets.at(id);
}
catch (const std::out_of_range&) {
	throw NotFound(id);
}


void
JsonRepository::for_ship_types(std::function<void(const ShipType&)> func) const
{
	for (const auto& [_, type] : ships)
		func(type);
}


void
JsonRepository::for_turret_types(std::function<void(const TurretType&)> func) const
{
	for (const auto& [_, type] : turrets)
		func(type);
}


}  // namespace universe
}  // namespace kurator