//extendable! class LiquidInfo { string m_LiquidClassName; string m_LiquidDisplayName; int m_LiquidType; float m_TemperatureLiquidFreezeThreshold = float.LOWEST; float m_TemperatureLiquidThawThreshold = float.LOWEST; float m_TemperatureLiquidBoilThreshold = Cooking.LIQUID_BOILING_POINT; float m_Flammability; ref NutritionalProfile m_NutriProfile; void LiquidInfo(string className, NutritionalProfile profile) { m_NutriProfile = profile; Init(className); } protected void Init(string className) { string path = "cfgLiquidDefinitions " + className; m_LiquidClassName = className; GetGame().ConfigGetTextRaw(string.Format("%1 displayName", path), m_LiquidDisplayName); GetGame().FormatRawConfigStringKeys(m_LiquidDisplayName); m_LiquidType = GetGame().ConfigGetInt(string.Format("%1 type", path)); if (GetGame().ConfigIsExisting(string.Format("%1 liquidFreezeThreshold", path))) m_TemperatureLiquidFreezeThreshold = GetGame().ConfigGetFloat(string.Format("%1 liquidFreezeThreshold", path)); if (GetGame().ConfigIsExisting(string.Format("%1 liquidThawThreshold", path))) m_TemperatureLiquidThawThreshold = GetGame().ConfigGetFloat(string.Format("%1 liquidThawThreshold", path)); if (GetGame().ConfigIsExisting(string.Format("%1 liquidBoilingThreshold", path))) m_TemperatureLiquidBoilThreshold = GetGame().ConfigGetFloat(string.Format("%1 liquidBoilingThreshold", path)); m_Flammability = GetGame().ConfigGetFloat(string.Format("%1 flammability", path)); } } class Liquid { static ref map m_AllLiquidsByType = new map; //DEPRECATED! static ref map m_AllLiquidsByName = new map; //DEPRECATED! static ref map m_LiquidInfosByType = new map; static ref map m_LiquidInfosByName = new map; static bool m_Init = InitAllLiquids(); static string GetLiquidClassname(int liquid_type) { LiquidInfo info = m_LiquidInfosByType.Get(liquid_type); if (info) { return info.m_LiquidClassName; } return ""; } static bool InitAllLiquids() { if (!g_Game) return false; string cfg_classname = "cfgLiquidDefinitions"; string property_value = "NULL_PROPERTY"; int cfg_item_count = g_Game.ConfigGetChildrenCount(cfg_classname); for (int i = 0; i < cfg_item_count; i++) { string liquid_class_name; GetGame().ConfigGetChildName(cfg_classname, i, liquid_class_name); string liquid_full_path = string.Format("%1 %2",cfg_classname, liquid_class_name); int config_liquid_type = GetGame().ConfigGetInt(string.Format("%1 type", liquid_full_path)); NutritionalProfile profile = SetUpNutritionalProfile(config_liquid_type, liquid_class_name); LiquidInfo info = new LiquidInfo(liquid_class_name, profile); m_LiquidInfosByType.Insert(config_liquid_type, info); m_LiquidInfosByName.Insert(liquid_class_name, info); //legacy stuff m_AllLiquidsByType.Insert(config_liquid_type, profile); m_AllLiquidsByName.Insert(liquid_class_name, profile); } return true; } //--------------------------------------------------------------------------------------------------------- static void Transfer(ItemBase source_ent, ItemBase target_ent, float quantity = -1) { if (!Liquid.CanTransfer(source_ent, target_ent)) return; float source_quantity = source_ent.GetQuantity(); float target_quantity = target_ent.GetQuantity(); float targetCfgWeight = target_ent.m_ConfigWeight; int source_liquid_type = source_ent.GetLiquidType(); float available_capacity = target_ent.GetQuantityMax() - target_quantity; float quantity_to_transfer; //transfers all if (quantity == -1) { quantity_to_transfer = Math.Clamp(source_quantity,0,available_capacity); } //transfers exact ammount else { quantity_to_transfer = Math.Clamp(Math.Min(source_quantity,quantity),0,available_capacity); } PluginTransmissionAgents m_mta = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents)); m_mta.TransmitAgents(source_ent, target_ent, AGT_TRANSFER_COPY); source_ent.AddQuantity(-quantity_to_transfer); float retultTemp = (source_ent.GetTemperature() * quantity_to_transfer + target_ent.GetTemperature() * (targetCfgWeight + target_quantity)) / (targetCfgWeight + target_quantity + quantity_to_transfer); target_ent.SetTemperature(retultTemp); AffectContainerOnTransfer(target_ent,source_liquid_type,quantity_to_transfer,source_ent.GetTemperature()); Liquid.FillContainer(target_ent,source_liquid_type,quantity_to_transfer); } static bool CanTransfer(ItemBase source_ent, ItemBase target_ent) { if (!source_ent || !target_ent) return false; Barrel_ColorBase barrelTarget = Barrel_ColorBase.Cast(target_ent); Barrel_ColorBase barrelSource = Barrel_ColorBase.Cast(source_ent); if ((barrelTarget && !barrelTarget.IsOpen()) || (barrelSource && !barrelSource.IsOpen())) { return false; } if (source_ent.GetIsFrozen()) { return false; } float source_quantity = source_ent.GetQuantity(); if (source_quantity <= 0) { //Debug.Log("source has no quantity", "LiquidTransfer"); return false;//if there is nothing to transfer } int source_liquid_type = source_ent.GetLiquidType(); if (source_liquid_type < 1) { //Debug.Log("source has some quantity, but does not have a valid liquidType set, liquidType = "+ToString(source_liquid_type), "LiquidTransfer"); return false;//if source is not a container } if (!CanFillContainer(target_ent,source_liquid_type)) { return false; } return true; } static void FillContainer(ItemBase container, int liquid_type, float amount) { if (!CanFillContainer(container,liquid_type)) { return; } //filling container.SetLiquidType(liquid_type); container.AddQuantity(amount); } //! Filled from any enviro source (fuel feed, pond, snow...) static void FillContainerEnviro(ItemBase container, int liquid_type, float amount, bool inject_agents = true) { float containerCfgWeight = container.m_ConfigWeight; float retultTemp = (GetLiquidTypeEnviroTemperature(liquid_type) * amount + container.GetTemperature() * (containerCfgWeight + container.GetQuantity())) / (container.GetQuantity() + containerCfgWeight + amount); container.SetTemperature(retultTemp); AffectContainerOnFill(container,liquid_type,amount); FillContainer(container, TranslateLiquidType(liquid_type), amount); if (inject_agents) { PluginTransmissionAgents plugin = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents)); int agtSource; switch (liquid_type) { case LIQUID_FRESHWATER: case LIQUID_RIVERWATER: case LIQUID_STILLWATER: agtSource = AGT_WATER_POND; break; case LIQUID_SNOW: agtSource = AGT_SNOW; break; case LIQUID_HOTWATER: agtSource = AGT_WATER_HOT_SPRING; break; default: agtSource = AGT_NONE; break; } plugin.TransmitAgents(NULL, container, agtSource, amount); } } //! from enviro source static void AffectContainerOnFill(ItemBase container, int liquid_type, float amount) { container.AffectLiquidContainerOnFill(liquid_type,amount); } static void AffectContainerOnTransfer(ItemBase container, int liquidType, float amount, float sourceLiquidTransfer) { container.AffectLiquidContainerOnTransfer(liquidType,amount,sourceLiquidTransfer); } static bool IsLiquidDrinkWater(int liquidType) { if (liquidType & (LIQUID_GROUP_DRINKWATER)) return true; return false; } //! Translates 'administrative' liquid types into liquid types with valid config class static int TranslateLiquidType(int liquidType) { if (IsLiquidDrinkWater(liquidType)) return LIQUID_WATER; else return liquidType; } static bool CanFillContainer(ItemBase container, int liquid_type, bool ignore_fullness_check = false) { if (!container) return false; bool is_container_full = container.IsFullQuantity(); if (is_container_full && !ignore_fullness_check) { //Debug.Log("container is full", "LiquidTransfer"); return false; } int container_mask = container.GetLiquidContainerMask(); if (container_mask == 0) { //Debug.Log("target is not a container", "LiquidTransfer"); return false;//if the target liquidContainerType is set to 0 } if ((liquid_type & container_mask) == 0) { //Debug.Log("target liquidContainerType does not support this liquid type", "LiquidTransfer"); return false; } float container_quantity = container.GetQuantity(); int container_liquid_type = container.GetLiquidType(); if (container_quantity > 0 && container_liquid_type != liquid_type) { //Debug.Log("target is not empty AND is of different liquid type than liquid_type added in", "LiquidTransfer"); return false; } return true; } //! Gets liquid temperature from the enviroment /*! \param[in] liquidType Type of liquid. */ static float GetLiquidTypeEnviroTemperature(int liquidType) { float ret = GetGame().GetMission().GetWorldData().GetLiquidTypeEnviroTemperature(liquidType); //ret = Math.Max(ret,GetLiquidFreezeThreshold(liquidType)); return ret; } private static string GetLiquidConfigProperty(int liquid_type, string property_name, bool is_nutrition_property = false) { string cfg_classname = "cfgLiquidDefinitions"; string property_value = "NULL_PROPERTY"; if (!g_Game) return property_value; int cfg_item_count = g_Game.ConfigGetChildrenCount(cfg_classname); for (int i = 0; i < cfg_item_count; i++) { string liquid_class_name; GetGame().ConfigGetChildName(cfg_classname, i, liquid_class_name); string liquid_full_path = string.Format("%1 %2", cfg_classname, liquid_class_name); int config_liquid_type = GetGame().ConfigGetInt(string.Format("%1 type", liquid_full_path)); if (config_liquid_type == liquid_type)// found the specific class, now lets extract the values { if (!is_nutrition_property) { GetGame().ConfigGetText(string.Format("%1 %2", liquid_full_path, property_name), property_value); return property_value; } else { GetGame().ConfigGetText(string.Format("%1 Nutrition %2", liquid_full_path, property_name), property_value); return property_value; } } } return property_value; } static NutritionalProfile GetNutritionalProfileByType(int liquid_type) { LiquidInfo info = m_LiquidInfosByType.Get(liquid_type); if (info && info.m_NutriProfile) return info.m_NutriProfile; return null; } static NutritionalProfile GetNutritionalProfileByName(string class_name) { LiquidInfo info = m_LiquidInfosByName.Get(class_name); if (info && info.m_NutriProfile) return info.m_NutriProfile; return null; } static NutritionalProfile SetUpNutritionalProfile(int liquid_type, string liquid_class_name) { NutritionalProfile profile = new NutritionalProfile(); profile.m_Energy = Liquid.GetLiquidConfigProperty(liquid_type, "energy", true).ToFloat(); profile.m_NutritionalIndex = Liquid.GetLiquidConfigProperty(liquid_type, "nutritionalIndex", true).ToFloat(); profile.m_FullnessIndex = Liquid.GetLiquidConfigProperty(liquid_type, "fullnessIndex", true).ToFloat(); profile.m_WaterContent = Liquid.GetLiquidConfigProperty(liquid_type, "water", true).ToFloat(); profile.m_Toxicity = Liquid.GetLiquidConfigProperty(liquid_type, "toxicity", true).ToFloat(); profile.m_Agents = Liquid.GetLiquidConfigProperty(liquid_type, "agents", true).ToInt(); profile.m_Digestibility = Liquid.GetLiquidConfigProperty(liquid_type, "digestibility", true).ToFloat(); profile.m_AgentsPerDigest = Liquid.GetLiquidConfigProperty(liquid_type, "agentsPerDigest", true).ToFloat(); profile.MarkAsLiquid(liquid_type, liquid_class_name); return profile; } static int GetAgents(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetAgents(); } static int GetAgentsPerDigest(int liquidType) { return m_LiquidInfosByType.Get(liquidType).m_NutriProfile.m_AgentsPerDigest; } static float GetToxicity(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetToxicity(); } static float GetWaterContent(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetWaterContent(); } static float GetEnergy(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetEnergy(); } static float GetNutritionalIndex(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetNutritionalIndex(); } static string GetDisplayName(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_LiquidDisplayName; } static float GetFlammability(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_Flammability; } static float GetFullness(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetFullnessIndex(); } static float GetDigestibility(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetDigestibility(); } static float GetFreezeThreshold(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_TemperatureLiquidFreezeThreshold; } static float GetThawThreshold(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_TemperatureLiquidThawThreshold; } static float GetBoilThreshold(int liquid_type) { return m_LiquidInfosByType.Get(liquid_type).m_TemperatureLiquidBoilThreshold; } /////////////////////////// //deprecated methods below /////////////////////////// static string GetName(int liquid_type) { return Liquid.GetLiquidConfigProperty(liquid_type, "name"); } };