define ship roles via added modules and allow multiple weapons
This commit is contained in:
@@ -7,8 +7,13 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
#include "toml.hpp"
|
||||
|
||||
#include "Rotation.h"
|
||||
#include "ShipLayout.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -207,6 +212,42 @@ toml::table parseFile(const std::string& path, const std::string& file)
|
||||
}
|
||||
}
|
||||
|
||||
Rotation parseRotationString(const std::string& s)
|
||||
{
|
||||
if (s == "east") { return Rotation::East; }
|
||||
if (s == "south") { return Rotation::South; }
|
||||
if (s == "west") { return Rotation::West; }
|
||||
return Rotation::North;
|
||||
}
|
||||
|
||||
std::vector<PlacedModule> parsePlacedModules(const toml::array& arr,
|
||||
const std::string& file,
|
||||
const std::string& path)
|
||||
{
|
||||
std::vector<PlacedModule> result;
|
||||
result.reserve(arr.size());
|
||||
for (std::size_t i = 0; i < arr.size(); ++i)
|
||||
{
|
||||
const std::string elemPath = path + "[" + std::to_string(i) + "]";
|
||||
const toml::table* t = arr[i].as_table();
|
||||
if (t == nullptr) { continue; }
|
||||
toml::table& mt = const_cast<toml::table&>(*t);
|
||||
|
||||
const std::optional<std::string> type = mt["type"].value<std::string>();
|
||||
const std::optional<int64_t> x = mt["x"].value<int64_t>();
|
||||
const std::optional<int64_t> y = mt["y"].value<int64_t>();
|
||||
const std::optional<std::string> rot = mt["rotation"].value<std::string>();
|
||||
if (!type || !x || !y || !rot) { continue; }
|
||||
|
||||
PlacedModule pm;
|
||||
pm.moduleId = *type;
|
||||
pm.position = QPoint(static_cast<int>(*x), static_cast<int>(*y));
|
||||
pm.rotation = parseRotationString(*rot);
|
||||
result.push_back(std::move(pm));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -418,43 +459,13 @@ ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
||||
def.loot.scrapDrop = static_cast<int>(requireInt(lMt["scrap_drop"], file, lPath + ".scrap_drop"));
|
||||
}
|
||||
|
||||
// Optional: combat
|
||||
if (mt.contains("combat"))
|
||||
// Optional: default_modules (REQ-WAV-DEFAULT-MODULES)
|
||||
if (mt.contains("default_modules"))
|
||||
{
|
||||
const std::string cPath = elemPath + ".combat";
|
||||
const toml::table& cTable = requireTable(mt["combat"], file, cPath);
|
||||
toml::table& cMt = const_cast<toml::table&>(cTable);
|
||||
ShipCombat combat {
|
||||
requireFormula(cMt["damage_formula"], file, cPath + ".damage_formula"),
|
||||
requireFormula(cMt["attack_range_formula"], file, cPath + ".attack_range_formula"),
|
||||
requireFormula(cMt["attack_rate_formula"], file, cPath + ".attack_rate_formula"),
|
||||
};
|
||||
def.combat = std::move(combat);
|
||||
}
|
||||
|
||||
// Optional: salvage
|
||||
if (mt.contains("salvage"))
|
||||
{
|
||||
const std::string sPath = elemPath + ".salvage";
|
||||
const toml::table& sTable = requireTable(mt["salvage"], file, sPath);
|
||||
toml::table& sMt = const_cast<toml::table&>(sTable);
|
||||
ShipSalvage salvage;
|
||||
salvage.collectionRange = requireDouble(sMt["collection_range"], file, sPath + ".collection_range");
|
||||
salvage.cargoCapacity = static_cast<int>(requireInt(sMt["cargo_capacity"], file, sPath + ".cargo_capacity"));
|
||||
def.salvage = salvage;
|
||||
}
|
||||
|
||||
// Optional: repair
|
||||
if (mt.contains("repair"))
|
||||
{
|
||||
const std::string rPath = elemPath + ".repair";
|
||||
const toml::table& rTable = requireTable(mt["repair"], file, rPath);
|
||||
toml::table& rMt = const_cast<toml::table&>(rTable);
|
||||
ShipRepair repair {
|
||||
requireFormula(rMt["repair_rate_formula"], file, rPath + ".repair_rate_formula"),
|
||||
requireFormula(rMt["repair_range_formula"], file, rPath + ".repair_range_formula"),
|
||||
};
|
||||
def.repair = std::move(repair);
|
||||
const toml::array& modArr = requireArray(mt["default_modules"], file,
|
||||
elemPath + ".default_modules");
|
||||
def.defaultModules = parsePlacedModules(modArr, file,
|
||||
elemPath + ".default_modules");
|
||||
}
|
||||
|
||||
cfg.ships.push_back(std::move(def));
|
||||
@@ -514,9 +525,11 @@ static const StatEntry kKnownStats[] = {
|
||||
{"health", "hp"},
|
||||
{"movement", "speed"},
|
||||
{"sensor", "sensor_range"},
|
||||
{"combat", "damage"},
|
||||
{"combat", "attack_range"},
|
||||
{"combat", "attack_rate"},
|
||||
{"weapon", "damage"},
|
||||
{"weapon", "attack_range"},
|
||||
{"weapon", "attack_rate"},
|
||||
{"salvage", "collection_range"},
|
||||
{"salvage", "cargo_capacity"},
|
||||
{"repair", "repair_rate"},
|
||||
{"repair", "repair_range"},
|
||||
};
|
||||
@@ -597,6 +610,60 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
||||
}
|
||||
}
|
||||
|
||||
// Weapon capability section: [module.weapon] with base stat formulas
|
||||
if (mt.contains("weapon"))
|
||||
{
|
||||
const std::string wPath = elemPath + ".weapon";
|
||||
const toml::table& wTable = requireTable(mt["weapon"], file, wPath);
|
||||
toml::table& wMt = const_cast<toml::table&>(wTable);
|
||||
if (wMt.contains("damage_formula") || wMt.contains("attack_range_formula")
|
||||
|| wMt.contains("attack_rate_formula"))
|
||||
{
|
||||
ModuleWeaponCapability cap;
|
||||
cap.damageFormula = requireFormula(wMt["damage_formula"],
|
||||
file, wPath + ".damage_formula");
|
||||
cap.attackRangeFormula = requireFormula(wMt["attack_range_formula"],
|
||||
file, wPath + ".attack_range_formula");
|
||||
cap.attackRateFormula = requireFormula(wMt["attack_rate_formula"],
|
||||
file, wPath + ".attack_rate_formula");
|
||||
def.weaponCapability = std::move(cap);
|
||||
}
|
||||
}
|
||||
|
||||
// Salvage capability section: [module.salvage] with base stat formulas
|
||||
if (mt.contains("salvage"))
|
||||
{
|
||||
const std::string sPath = elemPath + ".salvage";
|
||||
const toml::table& sTable = requireTable(mt["salvage"], file, sPath);
|
||||
toml::table& sMt = const_cast<toml::table&>(sTable);
|
||||
if (sMt.contains("collection_range_formula") || sMt.contains("cargo_capacity_formula"))
|
||||
{
|
||||
ModuleSalvageCapability cap;
|
||||
cap.collectionRangeFormula = requireFormula(sMt["collection_range_formula"],
|
||||
file, sPath + ".collection_range_formula");
|
||||
cap.cargoCapacityFormula = requireFormula(sMt["cargo_capacity_formula"],
|
||||
file, sPath + ".cargo_capacity_formula");
|
||||
def.salvageCapability = std::move(cap);
|
||||
}
|
||||
}
|
||||
|
||||
// Repair capability section: [module.repair] with base stat formulas
|
||||
if (mt.contains("repair"))
|
||||
{
|
||||
const std::string rPath = elemPath + ".repair";
|
||||
const toml::table& rTable = requireTable(mt["repair"], file, rPath);
|
||||
toml::table& rMt = const_cast<toml::table&>(rTable);
|
||||
if (rMt.contains("repair_rate_formula") || rMt.contains("repair_range_formula"))
|
||||
{
|
||||
ModuleRepairCapability cap;
|
||||
cap.repairRateFormula = requireFormula(rMt["repair_rate_formula"],
|
||||
file, rPath + ".repair_rate_formula");
|
||||
cap.repairRangeFormula = requireFormula(rMt["repair_range_formula"],
|
||||
file, rPath + ".repair_range_formula");
|
||||
def.repairCapability = std::move(cap);
|
||||
}
|
||||
}
|
||||
|
||||
cfg.modules.push_back(std::move(def));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user