diff options
Diffstat (limited to 'source/game/StarLiquidsDatabase.cpp')
-rw-r--r-- | source/game/StarLiquidsDatabase.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/source/game/StarLiquidsDatabase.cpp b/source/game/StarLiquidsDatabase.cpp new file mode 100644 index 0000000..e0bcd0c --- /dev/null +++ b/source/game/StarLiquidsDatabase.cpp @@ -0,0 +1,156 @@ +#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; + + auto liquids = assets->scanExtension("liquid"); + assets->queueJsons(liquids); + + for (auto file : liquids) { + try { + auto liquidConfig = assets->json(file); + + unsigned id = liquidConfig.getUInt("liquidId"); + if (id != (LiquidId)id) + throw LiquidException(strf("Liquid id %s does not fall in the valid range, wrapped to %s\n", id, (LiquidId)id)); + + 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( + "Neither resultMaterial or resultLiquid specified in liquid interaction of liquid %d", entry->id); + + entry->interactions[liquid] = interactionResult; + } + + m_settings.set(entry->id, entry); + m_liquidNames.add(entry->name, entry->id); + } catch (StarException const& e) { + throw LiquidException(strf("Error loading liquid file %s", file), e); + } + } +} + +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; + throw LiquidException::format("invalid liquid id %d", liquidId); +} + +String LiquidsDatabase::liquidDescription(LiquidId liquidId, String const& species) const { + if (liquidId == EmptyLiquidId) + return String(); + else if (auto settings = liquidSettings(liquidId)) + return settings->descriptions.getString( + strf("%sDescription", species), settings->descriptions.getString("description")); + throw LiquidException::format("invalid liquid id %d", liquidId); +} + +String LiquidsDatabase::liquidDescription(LiquidId liquidId) const { + if (liquidId == EmptyLiquidId) + return String(); + else if (auto settings = liquidSettings(liquidId)) + return settings->descriptions.getString("description"); + throw LiquidException::format("invalid liquid id %d", liquidId); +} + +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 {}; +} + +} |