move the shared TOML helpers into the utility namespace to avoid name collisions
This commit is contained in:
@@ -46,11 +46,11 @@ void validateUnlocks(const GameConfig& cfg)
|
|||||||
{
|
{
|
||||||
if (valid.count(id) == 0)
|
if (valid.count(id) == 0)
|
||||||
{
|
{
|
||||||
throw makeError(file, gPath, "grants unknown " + kind + " '" + id + "'");
|
throw utility::makeError(file, gPath, "grants unknown " + kind + " '" + id + "'");
|
||||||
}
|
}
|
||||||
if (!granted.insert(id).second)
|
if (!granted.insert(id).second)
|
||||||
{
|
{
|
||||||
throw makeError(file, gPath,
|
throw utility::makeError(file, gPath,
|
||||||
"grants " + kind + " '" + id + "' which is already granted by another unlock group");
|
"grants " + kind + " '" + id + "' which is already granted by another unlock group");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,13 +61,13 @@ void validateUnlocks(const GameConfig& cfg)
|
|||||||
const std::string gPath = "unlock '" + group.id + "'";
|
const std::string gPath = "unlock '" + group.id + "'";
|
||||||
if (!groupIds.insert(group.id).second)
|
if (!groupIds.insert(group.id).second)
|
||||||
{
|
{
|
||||||
throw makeError(file, gPath, "duplicate unlock group id");
|
throw utility::makeError(file, gPath, "duplicate unlock group id");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group.ships.empty() && group.modules.empty()
|
if (group.ships.empty() && group.modules.empty()
|
||||||
&& group.buildings.empty() && group.recipes.empty())
|
&& group.buildings.empty() && group.recipes.empty())
|
||||||
{
|
{
|
||||||
throw makeError(file, gPath, "grants no items (must grant at least one)");
|
throw utility::makeError(file, gPath, "grants no items (must grant at least one)");
|
||||||
}
|
}
|
||||||
|
|
||||||
checkGrants(group.ships, shipIds, grantedShipIds, "ship", gPath);
|
checkGrants(group.ships, shipIds, grantedShipIds, "ship", gPath);
|
||||||
@@ -83,7 +83,7 @@ void validateUnlocks(const GameConfig& cfg)
|
|||||||
{
|
{
|
||||||
if (groupIds.count(req) == 0)
|
if (groupIds.count(req) == 0)
|
||||||
{
|
{
|
||||||
throw makeError(file, "unlock '" + group.id + "'.requires",
|
throw utility::makeError(file, "unlock '" + group.id + "'.requires",
|
||||||
"references unknown unlock group '" + req + "'");
|
"references unknown unlock group '" + req + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
BuildingsConfig ConfigLoader::loadBuildings(const std::string& path)
|
BuildingsConfig ConfigLoader::loadBuildings(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "buildings.toml";
|
const std::string file = "buildings.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
BuildingsConfig cfg;
|
BuildingsConfig cfg;
|
||||||
const toml::array& arr = requireArray(tbl["building"], file, "building");
|
const toml::array& arr = utility::requireArray(tbl["building"], file, "building");
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arr.size(); ++i)
|
for (std::size_t i = 0; i < arr.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -22,32 +22,32 @@ BuildingsConfig ConfigLoader::loadBuildings(const std::string& path)
|
|||||||
const toml::table* bt = arr[i].as_table();
|
const toml::table* bt = arr[i].as_table();
|
||||||
if (bt == nullptr)
|
if (bt == nullptr)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath, "not a table");
|
throw utility::makeError(file, elemPath, "not a table");
|
||||||
}
|
}
|
||||||
toml::table& mt = const_cast<toml::table&>(*bt);
|
toml::table& mt = const_cast<toml::table&>(*bt);
|
||||||
|
|
||||||
BuildingDef def;
|
BuildingDef def;
|
||||||
def.id = requireString(mt["id"], file, elemPath + ".id");
|
def.id = utility::requireString(mt["id"], file, elemPath + ".id");
|
||||||
def.cost = static_cast<int>(requireInt(mt["cost"], file, elemPath + ".cost"));
|
def.cost = static_cast<int>(utility::requireInt(mt["cost"], file, elemPath + ".cost"));
|
||||||
def.playerPlaceable = requireBool(mt["player_placeable"], file, elemPath + ".player_placeable");
|
def.playerPlaceable = utility::requireBool(mt["player_placeable"], file, elemPath + ".player_placeable");
|
||||||
def.constructionTimeSeconds = requireDouble(mt["construction_time_seconds"], file, elemPath + ".construction_time_seconds");
|
def.constructionTimeSeconds = utility::requireDouble(mt["construction_time_seconds"], file, elemPath + ".construction_time_seconds");
|
||||||
def.surfaceMask = requireStringArray(mt["surface_mask"], file, elemPath + ".surface_mask");
|
def.surfaceMask = utility::requireStringArray(mt["surface_mask"], file, elemPath + ".surface_mask");
|
||||||
|
|
||||||
if (mt.contains("output_buffer_capacity"))
|
if (mt.contains("output_buffer_capacity"))
|
||||||
{
|
{
|
||||||
def.outputBufferCapacity = static_cast<int>(
|
def.outputBufferCapacity = static_cast<int>(
|
||||||
requireInt(mt["output_buffer_capacity"], file, elemPath + ".output_buffer_capacity"));
|
utility::requireInt(mt["output_buffer_capacity"], file, elemPath + ".output_buffer_capacity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mt.contains("tooltip"))
|
if (mt.contains("tooltip"))
|
||||||
{
|
{
|
||||||
def.tooltip = requireString(mt["tooltip"], file, elemPath + ".tooltip");
|
def.tooltip = utility::requireString(mt["tooltip"], file, elemPath + ".tooltip");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::optional<BuildingType> parsedType = parseBuildingType(def.id);
|
const std::optional<BuildingType> parsedType = parseBuildingType(def.id);
|
||||||
if (!parsedType)
|
if (!parsedType)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath + ".id", "unknown building id '" + def.id + "'");
|
throw utility::makeError(file, elemPath + ".id", "unknown building id '" + def.id + "'");
|
||||||
}
|
}
|
||||||
def.type = *parsedType;
|
def.type = *parsedType;
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ static const StatEntry kKnownStats[] = {
|
|||||||
ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "modules.toml";
|
const std::string file = "modules.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
ModulesConfig cfg;
|
ModulesConfig cfg;
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toml::array& arr = requireArray(tbl["module"], file, "module");
|
const toml::array& arr = utility::requireArray(tbl["module"], file, "module");
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arr.size(); ++i)
|
for (std::size_t i = 0; i < arr.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -58,27 +58,27 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
const toml::table* st = arr[i].as_table();
|
const toml::table* st = arr[i].as_table();
|
||||||
if (st == nullptr)
|
if (st == nullptr)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath, "not a table");
|
throw utility::makeError(file, elemPath, "not a table");
|
||||||
}
|
}
|
||||||
toml::table& mt = const_cast<toml::table&>(*st);
|
toml::table& mt = const_cast<toml::table&>(*st);
|
||||||
|
|
||||||
ModuleDef def;
|
ModuleDef def;
|
||||||
def.id = requireString(mt["id"], file, elemPath + ".id");
|
def.id = utility::requireString(mt["id"], file, elemPath + ".id");
|
||||||
def.surfaceMask = requireStringArray(mt["surface_mask"], file, elemPath + ".surface_mask");
|
def.surfaceMask = utility::requireStringArray(mt["surface_mask"], file, elemPath + ".surface_mask");
|
||||||
def.productionTimeSeconds = requireDouble(
|
def.productionTimeSeconds = utility::requireDouble(
|
||||||
mt["production_time_seconds"], file, elemPath + ".production_time_seconds");
|
mt["production_time_seconds"], file, elemPath + ".production_time_seconds");
|
||||||
def.fillColor = requireString(mt["fill_color"], file, elemPath + ".fill_color");
|
def.fillColor = utility::requireString(mt["fill_color"], file, elemPath + ".fill_color");
|
||||||
def.glyph = requireString(mt["glyph"], file, elemPath + ".glyph");
|
def.glyph = utility::requireString(mt["glyph"], file, elemPath + ".glyph");
|
||||||
|
|
||||||
if (mt.contains("tooltip"))
|
if (mt.contains("tooltip"))
|
||||||
{
|
{
|
||||||
def.tooltip = requireString(mt["tooltip"], file, elemPath + ".tooltip");
|
def.tooltip = utility::requireString(mt["tooltip"], file, elemPath + ".tooltip");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Materials
|
// Materials
|
||||||
{
|
{
|
||||||
const toml::array& materials = requireArray(mt["materials"], file, elemPath + ".materials");
|
const toml::array& materials = utility::requireArray(mt["materials"], file, elemPath + ".materials");
|
||||||
def.materials = parseIngredients(materials, file, elemPath + ".materials");
|
def.materials = utility::parseIngredients(materials, file, elemPath + ".materials");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat modifiers from [module.<category>] sub-tables
|
// Stat modifiers from [module.<category>] sub-tables
|
||||||
@@ -88,7 +88,7 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const toml::table& catTable = requireTable(mt[se.category], file,
|
const toml::table& catTable = utility::requireTable(mt[se.category], file,
|
||||||
elemPath + "." + se.category);
|
elemPath + "." + se.category);
|
||||||
toml::table& catMt = const_cast<toml::table&>(catTable);
|
toml::table& catMt = const_cast<toml::table&>(catTable);
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
ModuleStatModifier mod;
|
ModuleStatModifier mod;
|
||||||
mod.stat = se.stat;
|
mod.stat = se.stat;
|
||||||
mod.modifierType = "additive";
|
mod.modifierType = "additive";
|
||||||
mod.value = requireDouble(catMt[addedKey], file,
|
mod.value = utility::requireDouble(catMt[addedKey], file,
|
||||||
elemPath + "." + se.category + "." + addedKey);
|
elemPath + "." + se.category + "." + addedKey);
|
||||||
def.statModifiers.push_back(std::move(mod));
|
def.statModifiers.push_back(std::move(mod));
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
ModuleStatModifier mod;
|
ModuleStatModifier mod;
|
||||||
mod.stat = se.stat;
|
mod.stat = se.stat;
|
||||||
mod.modifierType = "multiplicative";
|
mod.modifierType = "multiplicative";
|
||||||
mod.value = requireDouble(catMt[multipliedKey], file,
|
mod.value = utility::requireDouble(catMt[multipliedKey], file,
|
||||||
elemPath + "." + se.category + "." + multipliedKey);
|
elemPath + "." + se.category + "." + multipliedKey);
|
||||||
def.statModifiers.push_back(std::move(mod));
|
def.statModifiers.push_back(std::move(mod));
|
||||||
}
|
}
|
||||||
@@ -120,17 +120,17 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
if (mt.contains("weapon"))
|
if (mt.contains("weapon"))
|
||||||
{
|
{
|
||||||
const std::string wPath = elemPath + ".weapon";
|
const std::string wPath = elemPath + ".weapon";
|
||||||
const toml::table& wTable = requireTable(mt["weapon"], file, wPath);
|
const toml::table& wTable = utility::requireTable(mt["weapon"], file, wPath);
|
||||||
toml::table& wMt = const_cast<toml::table&>(wTable);
|
toml::table& wMt = const_cast<toml::table&>(wTable);
|
||||||
if (wMt.contains("damage") || wMt.contains("attack_range_m")
|
if (wMt.contains("damage") || wMt.contains("attack_range_m")
|
||||||
|| wMt.contains("attack_rate_hz"))
|
|| wMt.contains("attack_rate_hz"))
|
||||||
{
|
{
|
||||||
ModuleWeaponCapability cap;
|
ModuleWeaponCapability cap;
|
||||||
cap.damage = static_cast<float>(requireDouble(wMt["damage"],
|
cap.damage = static_cast<float>(utility::requireDouble(wMt["damage"],
|
||||||
file, wPath + ".damage"));
|
file, wPath + ".damage"));
|
||||||
cap.attackRange_m = static_cast<float>(requireDouble(wMt["attack_range_m"],
|
cap.attackRange_m = static_cast<float>(utility::requireDouble(wMt["attack_range_m"],
|
||||||
file, wPath + ".attack_range_m"));
|
file, wPath + ".attack_range_m"));
|
||||||
cap.attackRate_hz = static_cast<float>(requireDouble(wMt["attack_rate_hz"],
|
cap.attackRate_hz = static_cast<float>(utility::requireDouble(wMt["attack_rate_hz"],
|
||||||
file, wPath + ".attack_rate_hz"));
|
file, wPath + ".attack_rate_hz"));
|
||||||
def.weaponCapability = std::move(cap);
|
def.weaponCapability = std::move(cap);
|
||||||
}
|
}
|
||||||
@@ -140,17 +140,17 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
if (mt.contains("salvage"))
|
if (mt.contains("salvage"))
|
||||||
{
|
{
|
||||||
const std::string sPath = elemPath + ".salvage";
|
const std::string sPath = elemPath + ".salvage";
|
||||||
const toml::table& sTable = requireTable(mt["salvage"], file, sPath);
|
const toml::table& sTable = utility::requireTable(mt["salvage"], file, sPath);
|
||||||
toml::table& sMt = const_cast<toml::table&>(sTable);
|
toml::table& sMt = const_cast<toml::table&>(sTable);
|
||||||
if (sMt.contains("collection_range_m") || sMt.contains("cargo_capacity")
|
if (sMt.contains("collection_range_m") || sMt.contains("cargo_capacity")
|
||||||
|| sMt.contains("collection_rate_hz"))
|
|| sMt.contains("collection_rate_hz"))
|
||||||
{
|
{
|
||||||
ModuleSalvageCapability cap;
|
ModuleSalvageCapability cap;
|
||||||
cap.collectionRange_m = static_cast<float>(requireDouble(sMt["collection_range_m"],
|
cap.collectionRange_m = static_cast<float>(utility::requireDouble(sMt["collection_range_m"],
|
||||||
file, sPath + ".collection_range_m"));
|
file, sPath + ".collection_range_m"));
|
||||||
cap.cargoCapacity = static_cast<float>(requireDouble(sMt["cargo_capacity"],
|
cap.cargoCapacity = static_cast<float>(utility::requireDouble(sMt["cargo_capacity"],
|
||||||
file, sPath + ".cargo_capacity"));
|
file, sPath + ".cargo_capacity"));
|
||||||
cap.collectionRate_hz = static_cast<float>(requireDouble(sMt["collection_rate_hz"],
|
cap.collectionRate_hz = static_cast<float>(utility::requireDouble(sMt["collection_rate_hz"],
|
||||||
file, sPath + ".collection_rate_hz"));
|
file, sPath + ".collection_rate_hz"));
|
||||||
def.salvageCapability = std::move(cap);
|
def.salvageCapability = std::move(cap);
|
||||||
}
|
}
|
||||||
@@ -160,16 +160,16 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|||||||
if (mt.contains("repair"))
|
if (mt.contains("repair"))
|
||||||
{
|
{
|
||||||
const std::string rPath = elemPath + ".repair";
|
const std::string rPath = elemPath + ".repair";
|
||||||
const toml::table& rTable = requireTable(mt["repair"], file, rPath);
|
const toml::table& rTable = utility::requireTable(mt["repair"], file, rPath);
|
||||||
toml::table& rMt = const_cast<toml::table&>(rTable);
|
toml::table& rMt = const_cast<toml::table&>(rTable);
|
||||||
if (rMt.contains("repair_rate_hz") || rMt.contains("repair_range_m"))
|
if (rMt.contains("repair_rate_hz") || rMt.contains("repair_range_m"))
|
||||||
{
|
{
|
||||||
ModuleRepairCapability cap;
|
ModuleRepairCapability cap;
|
||||||
cap.repairRate_hz = static_cast<float>(requireDouble(rMt["repair_rate_hz"],
|
cap.repairRate_hz = static_cast<float>(utility::requireDouble(rMt["repair_rate_hz"],
|
||||||
file, rPath + ".repair_rate_hz"));
|
file, rPath + ".repair_rate_hz"));
|
||||||
cap.repairAmountHp = static_cast<float>(requireDouble(rMt["repair_amount_hp"],
|
cap.repairAmountHp = static_cast<float>(utility::requireDouble(rMt["repair_amount_hp"],
|
||||||
file, rPath + ".repair_amount_hp"));
|
file, rPath + ".repair_amount_hp"));
|
||||||
cap.repairRange_m = static_cast<float>(requireDouble(rMt["repair_range_m"],
|
cap.repairRange_m = static_cast<float>(utility::requireDouble(rMt["repair_range_m"],
|
||||||
file, rPath + ".repair_range_m"));
|
file, rPath + ".repair_range_m"));
|
||||||
def.repairCapability = std::move(cap);
|
def.repairCapability = std::move(cap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ std::vector<RecipeOutput> parseRecipeOutputs(const toml::array& arr,
|
|||||||
const toml::table* t = arr[i].as_table();
|
const toml::table* t = arr[i].as_table();
|
||||||
if (t == nullptr)
|
if (t == nullptr)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath, "not a table");
|
throw utility::makeError(file, elemPath, "not a table");
|
||||||
}
|
}
|
||||||
toml::table& mt = const_cast<toml::table&>(*t);
|
toml::table& mt = const_cast<toml::table&>(*t);
|
||||||
|
|
||||||
RecipeOutput out;
|
RecipeOutput out;
|
||||||
out.item = requireString(mt["item"], file, elemPath + ".item");
|
out.item = utility::requireString(mt["item"], file, elemPath + ".item");
|
||||||
out.amount = static_cast<int>(requireInt(mt["amount"], file, elemPath + ".amount"));
|
out.amount = static_cast<int>(utility::requireInt(mt["amount"], file, elemPath + ".amount"));
|
||||||
if (const std::optional<double> p = mt["probability"].value<double>())
|
if (const std::optional<double> p = mt["probability"].value<double>())
|
||||||
{
|
{
|
||||||
out.probability = *p;
|
out.probability = *p;
|
||||||
@@ -50,10 +50,10 @@ std::vector<RecipeOutput> parseRecipeOutputs(const toml::array& arr,
|
|||||||
RecipesConfig ConfigLoader::loadRecipes(const std::string& path)
|
RecipesConfig ConfigLoader::loadRecipes(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "recipes.toml";
|
const std::string file = "recipes.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
RecipesConfig cfg;
|
RecipesConfig cfg;
|
||||||
const toml::array& arr = requireArray(tbl["recipe"], file, "recipe");
|
const toml::array& arr = utility::requireArray(tbl["recipe"], file, "recipe");
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arr.size(); ++i)
|
for (std::size_t i = 0; i < arr.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -61,37 +61,37 @@ RecipesConfig ConfigLoader::loadRecipes(const std::string& path)
|
|||||||
const toml::table* rt = arr[i].as_table();
|
const toml::table* rt = arr[i].as_table();
|
||||||
if (rt == nullptr)
|
if (rt == nullptr)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath, "not a table");
|
throw utility::makeError(file, elemPath, "not a table");
|
||||||
}
|
}
|
||||||
toml::table& mt = const_cast<toml::table&>(*rt);
|
toml::table& mt = const_cast<toml::table&>(*rt);
|
||||||
|
|
||||||
RecipeDef def;
|
RecipeDef def;
|
||||||
def.id = requireString(mt["id"], file, elemPath + ".id");
|
def.id = utility::requireString(mt["id"], file, elemPath + ".id");
|
||||||
def.durationSeconds = requireDouble(mt["duration_seconds"], file, elemPath + ".duration_seconds");
|
def.durationSeconds = utility::requireDouble(mt["duration_seconds"], file, elemPath + ".duration_seconds");
|
||||||
|
|
||||||
const std::string buildingId = requireString(mt["building"], file, elemPath + ".building");
|
const std::string buildingId = utility::requireString(mt["building"], file, elemPath + ".building");
|
||||||
const std::optional<BuildingType> parsedType = parseBuildingType(buildingId);
|
const std::optional<BuildingType> parsedType = parseBuildingType(buildingId);
|
||||||
if (!parsedType)
|
if (!parsedType)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath + ".building",
|
throw utility::makeError(file, elemPath + ".building",
|
||||||
"unknown building id '" + buildingId + "'");
|
"unknown building id '" + buildingId + "'");
|
||||||
}
|
}
|
||||||
def.building = *parsedType;
|
def.building = *parsedType;
|
||||||
|
|
||||||
if (def.building == BuildingType::Assembler && mt.contains("unlocked_at_start"))
|
if (def.building == BuildingType::Assembler && mt.contains("unlocked_at_start"))
|
||||||
{
|
{
|
||||||
def.unlockedAtStart = requireBool(mt["unlocked_at_start"], file,
|
def.unlockedAtStart = utility::requireBool(mt["unlocked_at_start"], file,
|
||||||
elemPath + ".unlocked_at_start");
|
elemPath + ".unlocked_at_start");
|
||||||
}
|
}
|
||||||
|
|
||||||
// inputs may be omitted (e.g. miner recipes). An empty array is fine.
|
// inputs may be omitted (e.g. miner recipes). An empty array is fine.
|
||||||
if (mt.contains("inputs"))
|
if (mt.contains("inputs"))
|
||||||
{
|
{
|
||||||
const toml::array& inputs = requireArray(mt["inputs"], file, elemPath + ".inputs");
|
const toml::array& inputs = utility::requireArray(mt["inputs"], file, elemPath + ".inputs");
|
||||||
def.inputs = parseIngredients(inputs, file, elemPath + ".inputs");
|
def.inputs = utility::parseIngredients(inputs, file, elemPath + ".inputs");
|
||||||
}
|
}
|
||||||
|
|
||||||
const toml::array& outputs = requireArray(mt["outputs"], file, elemPath + ".outputs");
|
const toml::array& outputs = utility::requireArray(mt["outputs"], file, elemPath + ".outputs");
|
||||||
def.outputs = parseRecipeOutputs(outputs, file, elemPath + ".outputs");
|
def.outputs = parseRecipeOutputs(outputs, file, elemPath + ".outputs");
|
||||||
|
|
||||||
// Optional icon item id (REQ-UI-RECIPE-ICON); defaults to the first output
|
// Optional icon item id (REQ-UI-RECIPE-ICON); defaults to the first output
|
||||||
@@ -99,7 +99,7 @@ RecipesConfig ConfigLoader::loadRecipes(const std::string& path)
|
|||||||
// icon is not an error (REQ-UI-ITEM-ICON).
|
// icon is not an error (REQ-UI-ITEM-ICON).
|
||||||
if (mt.contains("icon"))
|
if (mt.contains("icon"))
|
||||||
{
|
{
|
||||||
def.icon = requireString(mt["icon"], file, elemPath + ".icon");
|
def.icon = utility::requireString(mt["icon"], file, elemPath + ".icon");
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.recipes.push_back(std::move(def));
|
cfg.recipes.push_back(std::move(def));
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ std::vector<PlacedModule> parsePlacedModules(const toml::array& arr,
|
|||||||
ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "ships.toml";
|
const std::string file = "ships.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
ShipsConfig cfg;
|
ShipsConfig cfg;
|
||||||
const toml::array& arr = requireArray(tbl["ship"], file, "ship");
|
const toml::array& arr = utility::requireArray(tbl["ship"], file, "ship");
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arr.size(); ++i)
|
for (std::size_t i = 0; i < arr.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -69,58 +69,58 @@ ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
|||||||
const toml::table* st = arr[i].as_table();
|
const toml::table* st = arr[i].as_table();
|
||||||
if (st == nullptr)
|
if (st == nullptr)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath, "not a table");
|
throw utility::makeError(file, elemPath, "not a table");
|
||||||
}
|
}
|
||||||
toml::table& mt = const_cast<toml::table&>(*st);
|
toml::table& mt = const_cast<toml::table&>(*st);
|
||||||
|
|
||||||
ShipDef def;
|
ShipDef def;
|
||||||
def.id = requireString(mt["id"], file, elemPath + ".id");
|
def.id = utility::requireString(mt["id"], file, elemPath + ".id");
|
||||||
def.layout = requireStringArray(mt["layout"], file, elemPath + ".layout");
|
def.layout = utility::requireStringArray(mt["layout"], file, elemPath + ".layout");
|
||||||
|
|
||||||
// Schematic
|
// Schematic
|
||||||
{
|
{
|
||||||
const std::string bpPath = elemPath + ".schematic";
|
const std::string bpPath = elemPath + ".schematic";
|
||||||
const toml::table& bpTable = requireTable(mt["schematic"], file, bpPath);
|
const toml::table& bpTable = utility::requireTable(mt["schematic"], file, bpPath);
|
||||||
toml::table& bpMt = const_cast<toml::table&>(bpTable);
|
toml::table& bpMt = const_cast<toml::table&>(bpTable);
|
||||||
|
|
||||||
const toml::array& materials = requireArray(bpMt["materials"], file, bpPath + ".materials");
|
const toml::array& materials = utility::requireArray(bpMt["materials"], file, bpPath + ".materials");
|
||||||
def.schematic.materials = parseIngredients(materials, file, bpPath + ".materials");
|
def.schematic.materials = utility::parseIngredients(materials, file, bpPath + ".materials");
|
||||||
def.schematic.productionTimeSeconds = requireDouble(
|
def.schematic.productionTimeSeconds = utility::requireDouble(
|
||||||
bpMt["production_time_seconds"], file, bpPath + ".production_time_seconds");
|
bpMt["production_time_seconds"], file, bpPath + ".production_time_seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health
|
// Health
|
||||||
{
|
{
|
||||||
const std::string hPath = elemPath + ".health";
|
const std::string hPath = elemPath + ".health";
|
||||||
const toml::table& hTable = requireTable(mt["health"], file, hPath);
|
const toml::table& hTable = utility::requireTable(mt["health"], file, hPath);
|
||||||
toml::table& hMt = const_cast<toml::table&>(hTable);
|
toml::table& hMt = const_cast<toml::table&>(hTable);
|
||||||
def.health.hp = static_cast<float>(requireDouble(hMt["hp"], file, hPath + ".hp"));
|
def.health.hp = static_cast<float>(utility::requireDouble(hMt["hp"], file, hPath + ".hp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movement
|
// Movement
|
||||||
{
|
{
|
||||||
const std::string mPath = elemPath + ".movement";
|
const std::string mPath = elemPath + ".movement";
|
||||||
const toml::table& mTable = requireTable(mt["movement"], file, mPath);
|
const toml::table& mTable = utility::requireTable(mt["movement"], file, mPath);
|
||||||
toml::table& mMt = const_cast<toml::table&>(mTable);
|
toml::table& mMt = const_cast<toml::table&>(mTable);
|
||||||
def.movement.speed_mps = static_cast<float>(requireDouble(mMt["speed_mps"], file, mPath + ".speed_mps"));
|
def.movement.speed_mps = static_cast<float>(utility::requireDouble(mMt["speed_mps"], file, mPath + ".speed_mps"));
|
||||||
def.movement.mainAcceleration_mpss = static_cast<float>(requireDouble(mMt["main_acceleration_mpss"], file, mPath + ".main_acceleration_mpss"));
|
def.movement.mainAcceleration_mpss = static_cast<float>(utility::requireDouble(mMt["main_acceleration_mpss"], file, mPath + ".main_acceleration_mpss"));
|
||||||
def.movement.maneuveringAcceleration_mpss = static_cast<float>(requireDouble(mMt["maneuvering_acceleration_mpss"], file, mPath + ".maneuvering_acceleration_mpss"));
|
def.movement.maneuveringAcceleration_mpss = static_cast<float>(utility::requireDouble(mMt["maneuvering_acceleration_mpss"], file, mPath + ".maneuvering_acceleration_mpss"));
|
||||||
def.movement.angularAcceleration_radpss = static_cast<float>(requireDouble(mMt["angular_acceleration_radpss"], file, mPath + ".angular_acceleration_radpss"));
|
def.movement.angularAcceleration_radpss = static_cast<float>(utility::requireDouble(mMt["angular_acceleration_radpss"], file, mPath + ".angular_acceleration_radpss"));
|
||||||
def.movement.maxRotationSpeed_radps = static_cast<float>(requireDouble(mMt["max_rotation_speed_radps"], file, mPath + ".max_rotation_speed_radps"));
|
def.movement.maxRotationSpeed_radps = static_cast<float>(utility::requireDouble(mMt["max_rotation_speed_radps"], file, mPath + ".max_rotation_speed_radps"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sensor
|
// Sensor
|
||||||
{
|
{
|
||||||
const std::string snsPath = elemPath + ".sensor";
|
const std::string snsPath = elemPath + ".sensor";
|
||||||
const toml::table& snsTable = requireTable(mt["sensor"], file, snsPath);
|
const toml::table& snsTable = utility::requireTable(mt["sensor"], file, snsPath);
|
||||||
toml::table& snsMt = const_cast<toml::table&>(snsTable);
|
toml::table& snsMt = const_cast<toml::table&>(snsTable);
|
||||||
def.sensor.sensorRange_m = static_cast<float>(requireDouble(snsMt["sensor_range_m"], file, snsPath + ".sensor_range_m"));
|
def.sensor.sensorRange_m = static_cast<float>(utility::requireDouble(snsMt["sensor_range_m"], file, snsPath + ".sensor_range_m"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional: default_modules (REQ-WAV-DEFAULT-MODULES)
|
// Optional: default_modules (REQ-WAV-DEFAULT-MODULES)
|
||||||
if (mt.contains("default_modules"))
|
if (mt.contains("default_modules"))
|
||||||
{
|
{
|
||||||
const toml::array& modArr = requireArray(mt["default_modules"], file,
|
const toml::array& modArr = utility::requireArray(mt["default_modules"], file,
|
||||||
elemPath + ".default_modules");
|
elemPath + ".default_modules");
|
||||||
def.defaultModules = parsePlacedModules(modArr, file,
|
def.defaultModules = parsePlacedModules(modArr, file,
|
||||||
elemPath + ".default_modules");
|
elemPath + ".default_modules");
|
||||||
|
|||||||
@@ -9,38 +9,38 @@
|
|||||||
StationsConfig ConfigLoader::loadStations(const std::string& path)
|
StationsConfig ConfigLoader::loadStations(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "stations.toml";
|
const std::string file = "stations.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
StationsConfig cfg;
|
StationsConfig cfg;
|
||||||
|
|
||||||
// HQ
|
// HQ
|
||||||
{
|
{
|
||||||
const std::string p = "hq";
|
const std::string p = "hq";
|
||||||
cfg.hq.surfaceMask = requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
cfg.hq.surfaceMask = utility::requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
||||||
cfg.hq.hpFormula = requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
cfg.hq.hpFormula = utility::requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Player station
|
// Player station
|
||||||
{
|
{
|
||||||
const std::string p = "player_station";
|
const std::string p = "player_station";
|
||||||
cfg.playerStation.surfaceMask = requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
cfg.playerStation.surfaceMask = utility::requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
||||||
cfg.playerStation.level = static_cast<int>(requireInt(tbl[p]["level"], file, p + ".level"));
|
cfg.playerStation.level = static_cast<int>(utility::requireInt(tbl[p]["level"], file, p + ".level"));
|
||||||
cfg.playerStation.hpFormula = requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
cfg.playerStation.hpFormula = utility::requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
||||||
cfg.playerStation.damageFormula = requireFormula(tbl[p]["damage_formula"], file, p + ".damage_formula");
|
cfg.playerStation.damageFormula = utility::requireFormula(tbl[p]["damage_formula"], file, p + ".damage_formula");
|
||||||
cfg.playerStation.rangeFormula = requireFormula(tbl[p]["range_m_formula"], file, p + ".range_m_formula");
|
cfg.playerStation.rangeFormula = utility::requireFormula(tbl[p]["range_m_formula"], file, p + ".range_m_formula");
|
||||||
cfg.playerStation.fireRateFormula = requireFormula(tbl[p]["fire_rate_hz_formula"], file, p + ".fire_rate_hz_formula");
|
cfg.playerStation.fireRateFormula = utility::requireFormula(tbl[p]["fire_rate_hz_formula"], file, p + ".fire_rate_hz_formula");
|
||||||
cfg.playerStation.scrapDropFormula = requireFormula(tbl[p]["scrap_drop_formula"], file, p + ".scrap_drop_formula");
|
cfg.playerStation.scrapDropFormula = utility::requireFormula(tbl[p]["scrap_drop_formula"], file, p + ".scrap_drop_formula");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enemy station
|
// Enemy station
|
||||||
{
|
{
|
||||||
const std::string p = "enemy_station";
|
const std::string p = "enemy_station";
|
||||||
cfg.enemyStation.surfaceMask = requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
cfg.enemyStation.surfaceMask = utility::requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
||||||
cfg.enemyStation.hpFormula = requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
cfg.enemyStation.hpFormula = utility::requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
||||||
cfg.enemyStation.damageFormula = requireFormula(tbl[p]["damage_formula"], file, p + ".damage_formula");
|
cfg.enemyStation.damageFormula = utility::requireFormula(tbl[p]["damage_formula"], file, p + ".damage_formula");
|
||||||
cfg.enemyStation.rangeFormula = requireFormula(tbl[p]["range_m_formula"], file, p + ".range_m_formula");
|
cfg.enemyStation.rangeFormula = utility::requireFormula(tbl[p]["range_m_formula"], file, p + ".range_m_formula");
|
||||||
cfg.enemyStation.fireRateFormula = requireFormula(tbl[p]["fire_rate_hz_formula"], file, p + ".fire_rate_hz_formula");
|
cfg.enemyStation.fireRateFormula = utility::requireFormula(tbl[p]["fire_rate_hz_formula"], file, p + ".fire_rate_hz_formula");
|
||||||
cfg.enemyStation.scrapDropFormula = requireFormula(tbl[p]["scrap_drop_formula"], file, p + ".scrap_drop_formula");
|
cfg.enemyStation.scrapDropFormula = utility::requireFormula(tbl[p]["scrap_drop_formula"], file, p + ".scrap_drop_formula");
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg;
|
return cfg;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
UnlocksConfig ConfigLoader::loadUnlocks(const std::string& path)
|
UnlocksConfig ConfigLoader::loadUnlocks(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "unlocks.toml";
|
const std::string file = "unlocks.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
UnlocksConfig cfg;
|
UnlocksConfig cfg;
|
||||||
if (!tbl.contains("unlock"))
|
if (!tbl.contains("unlock"))
|
||||||
@@ -18,7 +18,7 @@ UnlocksConfig ConfigLoader::loadUnlocks(const std::string& path)
|
|||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toml::array& arr = requireArray(tbl["unlock"], file, "unlock");
|
const toml::array& arr = utility::requireArray(tbl["unlock"], file, "unlock");
|
||||||
|
|
||||||
for (std::size_t i = 0; i < arr.size(); ++i)
|
for (std::size_t i = 0; i < arr.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -26,33 +26,33 @@ UnlocksConfig ConfigLoader::loadUnlocks(const std::string& path)
|
|||||||
const toml::table* ut = arr[i].as_table();
|
const toml::table* ut = arr[i].as_table();
|
||||||
if (ut == nullptr)
|
if (ut == nullptr)
|
||||||
{
|
{
|
||||||
throw makeError(file, elemPath, "not a table");
|
throw utility::makeError(file, elemPath, "not a table");
|
||||||
}
|
}
|
||||||
toml::table& mt = const_cast<toml::table&>(*ut);
|
toml::table& mt = const_cast<toml::table&>(*ut);
|
||||||
|
|
||||||
UnlockGroupDef def;
|
UnlockGroupDef def;
|
||||||
def.id = requireString(mt["id"], file, elemPath + ".id");
|
def.id = utility::requireString(mt["id"], file, elemPath + ".id");
|
||||||
def.stationLevel = static_cast<int>(
|
def.stationLevel = static_cast<int>(
|
||||||
requireInt(mt["station_level"], file, elemPath + ".station_level"));
|
utility::requireInt(mt["station_level"], file, elemPath + ".station_level"));
|
||||||
if (mt.contains("requires"))
|
if (mt.contains("requires"))
|
||||||
{
|
{
|
||||||
def.requiredGroupIds = requireStringArray(mt["requires"], file, elemPath + ".requires");
|
def.requiredGroupIds = utility::requireStringArray(mt["requires"], file, elemPath + ".requires");
|
||||||
}
|
}
|
||||||
if (mt.contains("ships"))
|
if (mt.contains("ships"))
|
||||||
{
|
{
|
||||||
def.ships = requireStringArray(mt["ships"], file, elemPath + ".ships");
|
def.ships = utility::requireStringArray(mt["ships"], file, elemPath + ".ships");
|
||||||
}
|
}
|
||||||
if (mt.contains("modules"))
|
if (mt.contains("modules"))
|
||||||
{
|
{
|
||||||
def.modules = requireStringArray(mt["modules"], file, elemPath + ".modules");
|
def.modules = utility::requireStringArray(mt["modules"], file, elemPath + ".modules");
|
||||||
}
|
}
|
||||||
if (mt.contains("buildings"))
|
if (mt.contains("buildings"))
|
||||||
{
|
{
|
||||||
def.buildings = requireStringArray(mt["buildings"], file, elemPath + ".buildings");
|
def.buildings = utility::requireStringArray(mt["buildings"], file, elemPath + ".buildings");
|
||||||
}
|
}
|
||||||
if (mt.contains("recipes"))
|
if (mt.contains("recipes"))
|
||||||
{
|
{
|
||||||
def.recipes = requireStringArray(mt["recipes"], file, elemPath + ".recipes");
|
def.recipes = utility::requireStringArray(mt["recipes"], file, elemPath + ".recipes");
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.groups.push_back(std::move(def));
|
cfg.groups.push_back(std::move(def));
|
||||||
|
|||||||
@@ -10,22 +10,22 @@
|
|||||||
WorldConfig ConfigLoader::loadWorld(const std::string& path)
|
WorldConfig ConfigLoader::loadWorld(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::string file = "world.toml";
|
const std::string file = "world.toml";
|
||||||
toml::table tbl = parseFile(path, file);
|
toml::table tbl = utility::parseFile(path, file);
|
||||||
|
|
||||||
WorldConfig cfg;
|
WorldConfig cfg;
|
||||||
|
|
||||||
cfg.heightTiles = static_cast<int>(requireInt(tbl["world"]["height_tiles"], file, "world.height_tiles"));
|
cfg.heightTiles = static_cast<int>(utility::requireInt(tbl["world"]["height_tiles"], file, "world.height_tiles"));
|
||||||
cfg.refundPercentage = static_cast<int>(requireInt(tbl["world"]["refund_percentage"], file, "world.refund_percentage"));
|
cfg.refundPercentage = static_cast<int>(utility::requireInt(tbl["world"]["refund_percentage"], file, "world.refund_percentage"));
|
||||||
cfg.deconstructionTimeSeconds = requireDouble(tbl["world"]["deconstruction_time_seconds"], file, "world.deconstruction_time_seconds");
|
cfg.deconstructionTimeSeconds = utility::requireDouble(tbl["world"]["deconstruction_time_seconds"], file, "world.deconstruction_time_seconds");
|
||||||
cfg.startingBuildingBlocks = static_cast<int>(requireInt(tbl["world"]["starting_building_blocks"], file, "world.starting_building_blocks"));
|
cfg.startingBuildingBlocks = static_cast<int>(utility::requireInt(tbl["world"]["starting_building_blocks"], file, "world.starting_building_blocks"));
|
||||||
cfg.debrisDespawnSeconds = requireDouble(tbl["world"]["debris_despawn_seconds"], file, "world.debris_despawn_seconds");
|
cfg.debrisDespawnSeconds = utility::requireDouble(tbl["world"]["debris_despawn_seconds"], file, "world.debris_despawn_seconds");
|
||||||
cfg.scrapPerThreat = requireDouble(tbl["world"]["scrap_per_threat"], file, "world.scrap_per_threat");
|
cfg.scrapPerThreat = utility::requireDouble(tbl["world"]["scrap_per_threat"], file, "world.scrap_per_threat");
|
||||||
cfg.tileSize_m = requireDouble(tbl["world"]["tile_size_m"], file, "world.tile_size_m");
|
cfg.tileSize_m = utility::requireDouble(tbl["world"]["tile_size_m"], file, "world.tile_size_m");
|
||||||
cfg.beltSpeed_tps = requireDouble(tbl["world"]["belt_speed_mps"], file, "world.belt_speed_mps") / cfg.tileSize_m;
|
cfg.beltSpeed_tps = utility::requireDouble(tbl["world"]["belt_speed_mps"], file, "world.belt_speed_mps") / cfg.tileSize_m;
|
||||||
cfg.tunnelMaxDistance_tiles = static_cast<int>(requireInt(tbl["world"]["tunnel_max_distance_tiles"], file, "world.tunnel_max_distance_tiles"));
|
cfg.tunnelMaxDistance_tiles = static_cast<int>(utility::requireInt(tbl["world"]["tunnel_max_distance_tiles"], file, "world.tunnel_max_distance_tiles"));
|
||||||
cfg.departureIntervalSeconds = requireDouble(tbl["world"]["departure_interval_seconds"], file, "world.departure_interval_seconds");
|
cfg.departureIntervalSeconds = utility::requireDouble(tbl["world"]["departure_interval_seconds"], file, "world.departure_interval_seconds");
|
||||||
cfg.orbitFactor = requireDouble(tbl["world"]["orbit_factor"], file, "world.orbit_factor");
|
cfg.orbitFactor = utility::requireDouble(tbl["world"]["orbit_factor"], file, "world.orbit_factor");
|
||||||
cfg.rallyOrbitRadius_tiles = requireDouble(tbl["world"]["rally_orbit_radius_tiles"], file, "world.rally_orbit_radius_tiles");
|
cfg.rallyOrbitRadius_tiles = utility::requireDouble(tbl["world"]["rally_orbit_radius_tiles"], file, "world.rally_orbit_radius_tiles");
|
||||||
|
|
||||||
if (const std::optional<std::string> tip =
|
if (const std::optional<std::string> tip =
|
||||||
tbl["world"]["building_blocks_tooltip"].value<std::string>())
|
tbl["world"]["building_blocks_tooltip"].value<std::string>())
|
||||||
@@ -39,41 +39,41 @@ WorldConfig ConfigLoader::loadWorld(const std::string& path)
|
|||||||
cfg.artifactTooltip = *tip;
|
cfg.artifactTooltip = *tip;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.regions.asteroidWidth_tiles = static_cast<int>(requireInt(tbl["regions"]["asteroid_width_tiles"], file, "regions.asteroid_width_tiles"));
|
cfg.regions.asteroidWidth_tiles = static_cast<int>(utility::requireInt(tbl["regions"]["asteroid_width_tiles"], file, "regions.asteroid_width_tiles"));
|
||||||
cfg.regions.playerBufferWidth_tiles = static_cast<int>(requireInt(tbl["regions"]["player_buffer_width_tiles"], file, "regions.player_buffer_width_tiles"));
|
cfg.regions.playerBufferWidth_tiles = static_cast<int>(utility::requireInt(tbl["regions"]["player_buffer_width_tiles"], file, "regions.player_buffer_width_tiles"));
|
||||||
cfg.regions.contestZoneWidth_tiles = static_cast<int>(requireInt(tbl["regions"]["contest_zone_width_tiles"], file, "regions.contest_zone_width_tiles"));
|
cfg.regions.contestZoneWidth_tiles = static_cast<int>(utility::requireInt(tbl["regions"]["contest_zone_width_tiles"], file, "regions.contest_zone_width_tiles"));
|
||||||
cfg.regions.enemyBufferWidth_tiles = static_cast<int>(requireInt(tbl["regions"]["enemy_buffer_width_tiles"], file, "regions.enemy_buffer_width_tiles"));
|
cfg.regions.enemyBufferWidth_tiles = static_cast<int>(utility::requireInt(tbl["regions"]["enemy_buffer_width_tiles"], file, "regions.enemy_buffer_width_tiles"));
|
||||||
|
|
||||||
cfg.expansion.columnsPerExpansion_tiles = static_cast<int>(requireInt(tbl["expansion"]["columns_per_expansion_tiles"], file, "expansion.columns_per_expansion_tiles"));
|
cfg.expansion.columnsPerExpansion_tiles = static_cast<int>(utility::requireInt(tbl["expansion"]["columns_per_expansion_tiles"], file, "expansion.columns_per_expansion_tiles"));
|
||||||
cfg.expansion.costBuildingBlocksFormula = requireFormula(tbl["expansion"]["cost_building_blocks_formula"], file, "expansion.cost_building_blocks_formula");
|
cfg.expansion.costBuildingBlocksFormula = utility::requireFormula(tbl["expansion"]["cost_building_blocks_formula"], file, "expansion.cost_building_blocks_formula");
|
||||||
|
|
||||||
cfg.push.pushExpandColumns_tiles = static_cast<int>(requireInt(tbl["push"]["push_expand_columns_tiles"], file, "push.push_expand_columns_tiles"));
|
cfg.push.pushExpandColumns_tiles = static_cast<int>(utility::requireInt(tbl["push"]["push_expand_columns_tiles"], file, "push.push_expand_columns_tiles"));
|
||||||
cfg.push.bossAdvanceSeconds = requireDouble(tbl["push"]["boss_advance_seconds"], file, "push.boss_advance_seconds");
|
cfg.push.bossAdvanceSeconds = utility::requireDouble(tbl["push"]["boss_advance_seconds"], file, "push.boss_advance_seconds");
|
||||||
|
|
||||||
cfg.waves.threatRateFormula = requireFormula(tbl["waves"]["threat_rate_formula"], file, "waves.threat_rate_formula");
|
cfg.waves.threatRateFormula = utility::requireFormula(tbl["waves"]["threat_rate_formula"], file, "waves.threat_rate_formula");
|
||||||
cfg.waves.gapMinSeconds = requireDouble(tbl["waves"]["gap_min_seconds"], file, "waves.gap_min_seconds");
|
cfg.waves.gapMinSeconds = utility::requireDouble(tbl["waves"]["gap_min_seconds"], file, "waves.gap_min_seconds");
|
||||||
cfg.waves.gapMaxSeconds = requireDouble(tbl["waves"]["gap_max_seconds"], file, "waves.gap_max_seconds");
|
cfg.waves.gapMaxSeconds = utility::requireDouble(tbl["waves"]["gap_max_seconds"], file, "waves.gap_max_seconds");
|
||||||
cfg.waves.spawnDurationSeconds = requireDouble(tbl["waves"]["spawn_duration_seconds"], file, "waves.spawn_duration_seconds");
|
cfg.waves.spawnDurationSeconds = utility::requireDouble(tbl["waves"]["spawn_duration_seconds"], file, "waves.spawn_duration_seconds");
|
||||||
cfg.waves.bossCountdownSeconds = requireDouble(tbl["waves"]["boss_countdown_seconds"], file, "waves.boss_countdown_seconds");
|
cfg.waves.bossCountdownSeconds = utility::requireDouble(tbl["waves"]["boss_countdown_seconds"], file, "waves.boss_countdown_seconds");
|
||||||
cfg.waves.bossThreatDurationSeconds = requireDouble(tbl["waves"]["boss_threat_duration_seconds"], file, "waves.boss_threat_duration_seconds");
|
cfg.waves.bossThreatDurationSeconds = utility::requireDouble(tbl["waves"]["boss_threat_duration_seconds"], file, "waves.boss_threat_duration_seconds");
|
||||||
cfg.waves.bossQuietBeforeSeconds = requireDouble(tbl["waves"]["boss_quiet_before_seconds"], file, "waves.boss_quiet_before_seconds");
|
cfg.waves.bossQuietBeforeSeconds = utility::requireDouble(tbl["waves"]["boss_quiet_before_seconds"], file, "waves.boss_quiet_before_seconds");
|
||||||
cfg.waves.bossQuietAfterSeconds = requireDouble(tbl["waves"]["boss_quiet_after_seconds"], file, "waves.boss_quiet_after_seconds");
|
cfg.waves.bossQuietAfterSeconds = utility::requireDouble(tbl["waves"]["boss_quiet_after_seconds"], file, "waves.boss_quiet_after_seconds");
|
||||||
|
|
||||||
if (cfg.waves.gapMinSeconds > cfg.waves.gapMaxSeconds)
|
if (cfg.waves.gapMinSeconds > cfg.waves.gapMaxSeconds)
|
||||||
{
|
{
|
||||||
throw makeError(file, "waves", "gap_min_seconds > gap_max_seconds");
|
throw utility::makeError(file, "waves", "gap_min_seconds > gap_max_seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.targeting.targetScoreFormula = requireFormula(tbl["targeting"]["target_score_formula"], file, "targeting.target_score_formula");
|
cfg.targeting.targetScoreFormula = utility::requireFormula(tbl["targeting"]["target_score_formula"], file, "targeting.target_score_formula");
|
||||||
cfg.targeting.overclaimPenaltyFormula = requireFormula(tbl["targeting"]["overclaim_penalty_formula"], file, "targeting.overclaim_penalty_formula");
|
cfg.targeting.overclaimPenaltyFormula = utility::requireFormula(tbl["targeting"]["overclaim_penalty_formula"], file, "targeting.overclaim_penalty_formula");
|
||||||
cfg.targeting.hysteresis = requireDouble(tbl["targeting"]["target_hysteresis"], file, "targeting.target_hysteresis");
|
cfg.targeting.hysteresis = utility::requireDouble(tbl["targeting"]["target_hysteresis"], file, "targeting.target_hysteresis");
|
||||||
|
|
||||||
cfg.artifacts.artifactChanceFormula = requireFormula(tbl["artifacts"]["artifact_chance_formula"], file, "artifacts.artifact_chance_formula");
|
cfg.artifacts.artifactChanceFormula = utility::requireFormula(tbl["artifacts"]["artifact_chance_formula"], file, "artifacts.artifact_chance_formula");
|
||||||
cfg.artifacts.artifactWinCount = static_cast<int>(requireInt(tbl["artifacts"]["artifact_win_count"], file, "artifacts.artifact_win_count"));
|
cfg.artifacts.artifactWinCount = static_cast<int>(utility::requireInt(tbl["artifacts"]["artifact_win_count"], file, "artifacts.artifact_win_count"));
|
||||||
|
|
||||||
cfg.scroll.panSpeedSlow_tps = requireDouble(tbl["scroll"]["pan_speed_slow_tiles_per_second"], file, "scroll.pan_speed_slow_tiles_per_second");
|
cfg.scroll.panSpeedSlow_tps = utility::requireDouble(tbl["scroll"]["pan_speed_slow_tiles_per_second"], file, "scroll.pan_speed_slow_tiles_per_second");
|
||||||
cfg.scroll.panSpeedFast_tps = requireDouble(tbl["scroll"]["pan_speed_fast_tiles_per_second"], file, "scroll.pan_speed_fast_tiles_per_second");
|
cfg.scroll.panSpeedFast_tps = utility::requireDouble(tbl["scroll"]["pan_speed_fast_tiles_per_second"], file, "scroll.pan_speed_fast_tiles_per_second");
|
||||||
cfg.scroll.panRampBandWidth_tiles = static_cast<int>(requireInt(tbl["scroll"]["pan_ramp_band_width_tiles"], file, "scroll.pan_ramp_band_width_tiles"));
|
cfg.scroll.panRampBandWidth_tiles = static_cast<int>(utility::requireInt(tbl["scroll"]["pan_ramp_band_width_tiles"], file, "scroll.pan_ramp_band_width_tiles"));
|
||||||
|
|
||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
namespace utility
|
||||||
|
{
|
||||||
|
|
||||||
// --- Error helpers --------------------------------------------------------
|
// --- Error helpers --------------------------------------------------------
|
||||||
|
|
||||||
std::runtime_error makeError(const std::string& file,
|
std::runtime_error makeError(const std::string& file,
|
||||||
@@ -165,3 +168,5 @@ toml::table parseFile(const std::string& path, const std::string& file)
|
|||||||
throw std::runtime_error(oss.str());
|
throw std::runtime_error(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace utility
|
||||||
|
|||||||
@@ -13,6 +13,13 @@
|
|||||||
// Shared TOML-parsing helpers used by two or more ConfigLoader per-domain
|
// Shared TOML-parsing helpers used by two or more ConfigLoader per-domain
|
||||||
// loaders. Helpers used by exactly one domain stay local to that domain's
|
// loaders. Helpers used by exactly one domain stay local to that domain's
|
||||||
// .cpp file instead.
|
// .cpp file instead.
|
||||||
|
//
|
||||||
|
// Namespaced because the names are generic: VisualsLoader.cpp and
|
||||||
|
// BalancingConfig.cpp each have their own same-named helpers in anonymous
|
||||||
|
// namespaces, and unqualified globals here would form an overload set with
|
||||||
|
// them the moment either file includes this header.
|
||||||
|
namespace utility
|
||||||
|
{
|
||||||
|
|
||||||
// --- Error helpers ----------------------------------------------------------
|
// --- Error helpers ----------------------------------------------------------
|
||||||
|
|
||||||
@@ -59,3 +66,5 @@ std::vector<RecipeIngredient> parseIngredients(const toml::array& arr,
|
|||||||
const std::string& path);
|
const std::string& path);
|
||||||
|
|
||||||
toml::table parseFile(const std::string& path, const std::string& file);
|
toml::table parseFile(const std::string& path, const std::string& file);
|
||||||
|
|
||||||
|
} // namespace utility
|
||||||
|
|||||||
Reference in New Issue
Block a user