|
|
|
|
@@ -266,18 +266,18 @@ WorldConfig ConfigLoader::loadWorld(const std::string& path)
|
|
|
|
|
cfg.scrapDespawnSeconds = requireDouble(tbl["world"]["scrap_despawn_seconds"], file, "world.scrap_despawn_seconds");
|
|
|
|
|
cfg.tileSize_m = 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.tunnelMaxDistance = static_cast<int>(requireInt(tbl["world"]["tunnel_max_distance"], file, "world.tunnel_max_distance"));
|
|
|
|
|
cfg.tunnelMaxDistance_tiles = static_cast<int>(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.regions.asteroidWidth = static_cast<int>(requireInt(tbl["regions"]["asteroid_width"], file, "regions.asteroid_width"));
|
|
|
|
|
cfg.regions.playerBufferWidth = static_cast<int>(requireInt(tbl["regions"]["player_buffer_width"], file, "regions.player_buffer_width"));
|
|
|
|
|
cfg.regions.contestZoneWidth = static_cast<int>(requireInt(tbl["regions"]["contest_zone_width"], file, "regions.contest_zone_width"));
|
|
|
|
|
cfg.regions.enemyBufferWidth = static_cast<int>(requireInt(tbl["regions"]["enemy_buffer_width"], file, "regions.enemy_buffer_width"));
|
|
|
|
|
cfg.regions.asteroidWidth_tiles = static_cast<int>(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.contestZoneWidth_tiles = static_cast<int>(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.expansion.columnsPerExpansion = static_cast<int>(requireInt(tbl["expansion"]["columns_per_expansion"], file, "expansion.columns_per_expansion"));
|
|
|
|
|
cfg.expansion.costBuildingBlocks = static_cast<int>(requireInt(tbl["expansion"]["cost_building_blocks"], file, "expansion.cost_building_blocks"));
|
|
|
|
|
cfg.expansion.columnsPerExpansion_tiles = static_cast<int>(requireInt(tbl["expansion"]["columns_per_expansion_tiles"], file, "expansion.columns_per_expansion_tiles"));
|
|
|
|
|
cfg.expansion.costBuildingBlocks = static_cast<int>(requireInt(tbl["expansion"]["cost_building_blocks"], file, "expansion.cost_building_blocks"));
|
|
|
|
|
|
|
|
|
|
cfg.push.pushExpandColumns = static_cast<int>(requireInt(tbl["push"]["push_expand_columns"], file, "push.push_expand_columns"));
|
|
|
|
|
cfg.push.pushExpandColumns_tiles = static_cast<int>(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.waves.threatRateFormula = requireFormula(tbl["waves"]["threat_rate_formula"], file, "waves.threat_rate_formula");
|
|
|
|
|
@@ -441,11 +441,11 @@ ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
|
|
|
|
const std::string mPath = elemPath + ".movement";
|
|
|
|
|
const toml::table& mTable = requireTable(mt["movement"], file, mPath);
|
|
|
|
|
toml::table& mMt = const_cast<toml::table&>(mTable);
|
|
|
|
|
def.movement.speedFormula = requireFormula(mMt["speed_formula"], file, mPath + ".speed_formula");
|
|
|
|
|
def.movement.mainAccelerationFormula = requireFormula(mMt["main_acceleration_formula"], file, mPath + ".main_acceleration_formula");
|
|
|
|
|
def.movement.maneuveringAccelerationFormula = requireFormula(mMt["maneuvering_acceleration_formula"], file, mPath + ".maneuvering_acceleration_formula");
|
|
|
|
|
def.movement.angularAccelerationFormula = requireFormula(mMt["angular_acceleration_formula"], file, mPath + ".angular_acceleration_formula");
|
|
|
|
|
def.movement.maxRotationSpeedFormula = requireFormula(mMt["max_rotation_speed_formula"], file, mPath + ".max_rotation_speed_formula");
|
|
|
|
|
def.movement.speedFormula = requireFormula(mMt["speed_mps_formula"], file, mPath + ".speed_mps_formula");
|
|
|
|
|
def.movement.mainAccelerationFormula = requireFormula(mMt["main_acceleration_mpss_formula"], file, mPath + ".main_acceleration_mpss_formula");
|
|
|
|
|
def.movement.maneuveringAccelerationFormula = requireFormula(mMt["maneuvering_acceleration_mpss_formula"], file, mPath + ".maneuvering_acceleration_mpss_formula");
|
|
|
|
|
def.movement.angularAccelerationFormula = requireFormula(mMt["angular_acceleration_radpss_formula"], file, mPath + ".angular_acceleration_radpss_formula");
|
|
|
|
|
def.movement.maxRotationSpeedFormula = requireFormula(mMt["max_rotation_speed_radps_formula"], file, mPath + ".max_rotation_speed_radps_formula");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sensor
|
|
|
|
|
@@ -453,7 +453,7 @@ ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
|
|
|
|
const std::string snsPath = elemPath + ".sensor";
|
|
|
|
|
const toml::table& snsTable = requireTable(mt["sensor"], file, snsPath);
|
|
|
|
|
toml::table& snsMt = const_cast<toml::table&>(snsTable);
|
|
|
|
|
def.sensor.sensorRangeFormula = requireFormula(snsMt["sensor_range_formula"], file, snsPath + ".sensor_range_formula");
|
|
|
|
|
def.sensor.sensorRangeFormula = requireFormula(snsMt["sensor_range_m_formula"], file, snsPath + ".sensor_range_m_formula");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loot
|
|
|
|
|
@@ -500,8 +500,8 @@ StationsConfig ConfigLoader::loadStations(const std::string& path)
|
|
|
|
|
cfg.playerStation.level = static_cast<int>(requireInt(tbl[p]["level"], file, p + ".level"));
|
|
|
|
|
cfg.playerStation.hpFormula = requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
|
|
|
|
cfg.playerStation.damageFormula = requireFormula(tbl[p]["damage_formula"], file, p + ".damage_formula");
|
|
|
|
|
cfg.playerStation.rangeFormula = requireFormula(tbl[p]["range_formula"], file, p + ".range_formula");
|
|
|
|
|
cfg.playerStation.fireRateFormula = requireFormula(tbl[p]["fire_rate_formula"], file, p + ".fire_rate_formula");
|
|
|
|
|
cfg.playerStation.rangeFormula = 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.scrapDropFormula = requireFormula(tbl[p]["scrap_drop_formula"], file, p + ".scrap_drop_formula");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -511,8 +511,8 @@ StationsConfig ConfigLoader::loadStations(const std::string& path)
|
|
|
|
|
cfg.enemyStation.surfaceMask = requireStringArray(tbl[p]["surface_mask"], file, p + ".surface_mask");
|
|
|
|
|
cfg.enemyStation.hpFormula = requireFormula(tbl[p]["hp_formula"], file, p + ".hp_formula");
|
|
|
|
|
cfg.enemyStation.damageFormula = requireFormula(tbl[p]["damage_formula"], file, p + ".damage_formula");
|
|
|
|
|
cfg.enemyStation.rangeFormula = requireFormula(tbl[p]["range_formula"], file, p + ".range_formula");
|
|
|
|
|
cfg.enemyStation.fireRateFormula = requireFormula(tbl[p]["fire_rate_formula"], file, p + ".fire_rate_formula");
|
|
|
|
|
cfg.enemyStation.rangeFormula = 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.scrapDropFormula = requireFormula(tbl[p]["scrap_drop_formula"], file, p + ".scrap_drop_formula");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -520,24 +520,27 @@ StationsConfig ConfigLoader::loadStations(const std::string& path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Known category→stat mappings for module stat modifier discovery.
|
|
|
|
|
// addedKeySuffix: unit suffix appended before "_formula" for additive modifier keys only.
|
|
|
|
|
// Multiplicative modifier keys are always dimensionless and carry no suffix.
|
|
|
|
|
struct StatEntry
|
|
|
|
|
{
|
|
|
|
|
const char* category;
|
|
|
|
|
const char* stat;
|
|
|
|
|
const char* addedKeySuffix;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const StatEntry kKnownStats[] = {
|
|
|
|
|
{"health", "hp"},
|
|
|
|
|
{"movement", "speed"},
|
|
|
|
|
{"sensor", "sensor_range"},
|
|
|
|
|
{"weapon", "damage"},
|
|
|
|
|
{"weapon", "attack_range"},
|
|
|
|
|
{"weapon", "attack_rate"},
|
|
|
|
|
{"salvage", "collection_range"},
|
|
|
|
|
{"salvage", "cargo_capacity"},
|
|
|
|
|
{"salvage", "collection_rate"},
|
|
|
|
|
{"repair", "repair_rate"},
|
|
|
|
|
{"repair", "repair_range"},
|
|
|
|
|
{"health", "hp", ""},
|
|
|
|
|
{"movement", "speed", "_mps"},
|
|
|
|
|
{"sensor", "sensor_range", "_m"},
|
|
|
|
|
{"weapon", "damage", ""},
|
|
|
|
|
{"weapon", "attack_range", "_m"},
|
|
|
|
|
{"weapon", "attack_rate", "_hz"},
|
|
|
|
|
{"salvage", "collection_range", "_m"},
|
|
|
|
|
{"salvage", "cargo_capacity", ""},
|
|
|
|
|
{"salvage", "collection_rate", "_hz"},
|
|
|
|
|
{"repair", "repair_rate", "_hz"},
|
|
|
|
|
{"repair", "repair_range", "_m"},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|
|
|
|
@@ -592,7 +595,7 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|
|
|
|
elemPath + "." + se.category);
|
|
|
|
|
toml::table& catMt = const_cast<toml::table&>(catTable);
|
|
|
|
|
|
|
|
|
|
const std::string addedKey = std::string("added_") + se.stat + "_formula";
|
|
|
|
|
const std::string addedKey = std::string("added_") + se.stat + se.addedKeySuffix + "_formula";
|
|
|
|
|
const std::string multipliedKey = std::string("multiplied_") + se.stat + "_formula";
|
|
|
|
|
|
|
|
|
|
if (catMt.contains(addedKey))
|
|
|
|
|
@@ -622,16 +625,16 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|
|
|
|
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"))
|
|
|
|
|
if (wMt.contains("damage_formula") || wMt.contains("attack_range_m_formula")
|
|
|
|
|
|| wMt.contains("attack_rate_hz_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");
|
|
|
|
|
cap.attackRangeFormula = requireFormula(wMt["attack_range_m_formula"],
|
|
|
|
|
file, wPath + ".attack_range_m_formula");
|
|
|
|
|
cap.attackRateFormula = requireFormula(wMt["attack_rate_hz_formula"],
|
|
|
|
|
file, wPath + ".attack_rate_hz_formula");
|
|
|
|
|
def.weaponCapability = std::move(cap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -642,16 +645,16 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|
|
|
|
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")
|
|
|
|
|
|| sMt.contains("collection_rate_formula"))
|
|
|
|
|
if (sMt.contains("collection_range_m_formula") || sMt.contains("cargo_capacity_formula")
|
|
|
|
|
|| sMt.contains("collection_rate_hz_formula"))
|
|
|
|
|
{
|
|
|
|
|
ModuleSalvageCapability cap;
|
|
|
|
|
cap.collectionRangeFormula = requireFormula(sMt["collection_range_formula"],
|
|
|
|
|
file, sPath + ".collection_range_formula");
|
|
|
|
|
cap.collectionRangeFormula = requireFormula(sMt["collection_range_m_formula"],
|
|
|
|
|
file, sPath + ".collection_range_m_formula");
|
|
|
|
|
cap.cargoCapacityFormula = requireFormula(sMt["cargo_capacity_formula"],
|
|
|
|
|
file, sPath + ".cargo_capacity_formula");
|
|
|
|
|
cap.collectionRateFormula = requireFormula(sMt["collection_rate_formula"],
|
|
|
|
|
file, sPath + ".collection_rate_formula");
|
|
|
|
|
cap.collectionRateFormula = requireFormula(sMt["collection_rate_hz_formula"],
|
|
|
|
|
file, sPath + ".collection_rate_hz_formula");
|
|
|
|
|
def.salvageCapability = std::move(cap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -662,13 +665,13 @@ ModulesConfig ConfigLoader::loadModules(const std::string& path)
|
|
|
|
|
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"))
|
|
|
|
|
if (rMt.contains("repair_rate_hz_formula") || rMt.contains("repair_range_m_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");
|
|
|
|
|
cap.repairRateFormula = requireFormula(rMt["repair_rate_hz_formula"],
|
|
|
|
|
file, rPath + ".repair_rate_hz_formula");
|
|
|
|
|
cap.repairRangeFormula = requireFormula(rMt["repair_range_m_formula"],
|
|
|
|
|
file, rPath + ".repair_range_m_formula");
|
|
|
|
|
def.repairCapability = std::move(cap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|