osb/source/game/StarLiquidsDatabase.cpp

157 lines
6.1 KiB
C++
Raw Permalink Normal View History

2023-06-20 04:33:09 +00:00
#include "StarLiquidsDatabase.hpp"
#include "StarLexicalCast.hpp"
#include "StarAssets.hpp"
#include "StarJsonExtra.hpp"
#include "StarMaterialDatabase.hpp"
#include "StarRoot.hpp"
namespace Star {
LiquidSettings::LiquidSettings() : id(EmptyLiquidId) {}
LiquidsDatabase::LiquidsDatabase() {
auto assets = Root::singleton().assets();
auto materialDatabase = Root::singleton().materialDatabase();
auto config = assets->json("/liquids.config");
auto liquidEngineParameters = config.get("liquidEngineParameters");
m_liquidEngineParameters.lateralMoveFactor = liquidEngineParameters.getFloat("lateralMoveFactor");
m_liquidEngineParameters.spreadOverfillUpFactor = liquidEngineParameters.getFloat("spreadOverfillUpFactor");
m_liquidEngineParameters.spreadOverfillLateralFactor = liquidEngineParameters.getFloat("spreadOverfillLateralFactor");
m_liquidEngineParameters.spreadOverfillDownFactor = liquidEngineParameters.getFloat("spreadOverfillDownFactor");
m_liquidEngineParameters.pressureEqualizeFactor = liquidEngineParameters.getFloat("pressureEqualizeFactor");
m_liquidEngineParameters.pressureMoveFactor = liquidEngineParameters.getFloat("pressureMoveFactor");
m_liquidEngineParameters.maximumPressureLevelImbalance = liquidEngineParameters.getFloat("maximumPressureLevelImbalance");
m_liquidEngineParameters.minimumLivenPressureChange = liquidEngineParameters.getFloat("minimumLivenPressureChange");
m_liquidEngineParameters.minimumLivenLevelChange = liquidEngineParameters.getFloat("minimumLivenLevelChange");
m_liquidEngineParameters.minimumLiquidLevel = liquidEngineParameters.getFloat("minimumLiquidLevel");
m_liquidEngineParameters.interactTransformationLevel = liquidEngineParameters.getFloat("interactTransformationLevel");
m_backgroundDrain = config.getFloat("backgroundDrain");
m_liquidNames["empty"] = EmptyLiquidId;
2024-03-15 10:28:11 +00:00
auto& liquids = assets->scanExtension("liquid");
2023-06-20 04:33:09 +00:00
assets->queueJsons(liquids);
2024-03-15 10:28:11 +00:00
for (auto& file : liquids) {
2023-06-20 04:33:09 +00:00
try {
auto liquidConfig = assets->json(file);
unsigned id = liquidConfig.getUInt("liquidId");
if (id != (LiquidId)id)
2023-06-27 10:23:44 +00:00
throw LiquidException(strf("Liquid id {} does not fall in the valid range, wrapped to {}\n", id, (LiquidId)id));
2023-06-20 04:33:09 +00:00
auto entry = make_shared<LiquidSettings>();
entry->id = (LiquidId)id;
entry->name = liquidConfig.getString("name");
entry->path = file;
entry->config = liquidConfig;
JsonObject descriptions;
for (auto pair : liquidConfig.iterateObject())
if (pair.first.endsWith("Description"))
descriptions[pair.first] = pair.second;
descriptions["description"] = liquidConfig.getString("description", "");
entry->descriptions = descriptions;
entry->tickDelta = liquidConfig.getUInt("tickDelta");
entry->liquidColor = jsonToVec4B(liquidConfig.get("color"));
if (liquidConfig.contains("radiantLight")) {
auto lightLevel = jsonToVec3B(liquidConfig.get("radiantLight"));
entry->radiantLightLevel = Color::rgb(lightLevel).toRgbF();
}
entry->itemDrop = ItemDescriptor(liquidConfig.get("itemDrop", {}));
entry->statusEffects = liquidConfig.getArray("statusEffects", {});
for (auto const& interaction : liquidConfig.getArray("interactions", {})) {
LiquidId liquid = interaction.getUInt("liquid");
LiquidInteractionResult interactionResult;
if (auto materialResult = interaction.optString("materialResult"))
interactionResult = makeLeft<MaterialId>(materialDatabase->materialId(*materialResult));
else if (auto liquidResult = interaction.optUInt("liquidResult"))
interactionResult = makeRight<LiquidId>(*liquidResult);
else
throw LiquidException::format(
2023-06-27 10:23:44 +00:00
"Neither resultMaterial or resultLiquid specified in liquid interaction of liquid {}", entry->id);
2023-06-20 04:33:09 +00:00
entry->interactions[liquid] = interactionResult;
}
m_settings.set(entry->id, entry);
m_liquidNames.add(entry->name, entry->id);
} catch (StarException const& e) {
2023-06-27 10:23:44 +00:00
throw LiquidException(strf("Error loading liquid file {}", file), e);
2023-06-20 04:33:09 +00:00
}
}
}
LiquidCellEngineParameters LiquidsDatabase::liquidEngineParameters() const {
return m_liquidEngineParameters;
}
StringList LiquidsDatabase::liquidNames() const {
return m_liquidNames.keys();
}
List<LiquidSettingsConstPtr> LiquidsDatabase::allLiquidSettings() const {
return filtered<List<LiquidSettingsConstPtr>>(m_settings, mem_fn(&LiquidSettingsConstPtr::operator bool));
}
LiquidId LiquidsDatabase::liquidId(String const& str) const {
return m_liquidNames.get(str);
}
String LiquidsDatabase::liquidName(LiquidId liquidId) const {
if (liquidId == EmptyLiquidId)
return "empty";
else if (auto settings = liquidSettings(liquidId))
return settings->name;
2023-06-27 10:23:44 +00:00
throw LiquidException::format("invalid liquid id {}", liquidId);
2023-06-20 04:33:09 +00:00
}
String LiquidsDatabase::liquidDescription(LiquidId liquidId, String const& species) const {
if (liquidId == EmptyLiquidId)
return String();
else if (auto settings = liquidSettings(liquidId))
return settings->descriptions.getString(
2023-06-27 10:23:44 +00:00
strf("{}Description", species), settings->descriptions.getString("description"));
throw LiquidException::format("invalid liquid id {}", liquidId);
2023-06-20 04:33:09 +00:00
}
String LiquidsDatabase::liquidDescription(LiquidId liquidId) const {
if (liquidId == EmptyLiquidId)
return String();
else if (auto settings = liquidSettings(liquidId))
return settings->descriptions.getString("description");
2023-06-27 10:23:44 +00:00
throw LiquidException::format("invalid liquid id {}", liquidId);
2023-06-20 04:33:09 +00:00
}
Maybe<String> LiquidsDatabase::liquidPath(LiquidId liquidId) const {
if (liquidId == EmptyLiquidId)
return {};
else if (auto settings = liquidSettings(liquidId))
return settings->path;
return {};
}
Maybe<Json> LiquidsDatabase::liquidConfig(LiquidId liquidId) const {
if (liquidId == EmptyLiquidId)
return {};
else if (auto settings = liquidSettings(liquidId))
return settings->config;
return {};
}
Maybe<LiquidInteractionResult> LiquidsDatabase::interact(LiquidId target, LiquidId other) const {
if (auto settings = liquidSettings(target))
return settings->interactions.value(other);
return {};
}
}