liquid.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. //extendable!
  2. class LiquidInfo
  3. {
  4. string m_LiquidClassName;
  5. string m_LiquidDisplayName;
  6. int m_LiquidType;
  7. float m_TemperatureLiquidFreezeThreshold = float.LOWEST;
  8. float m_TemperatureLiquidThawThreshold = float.LOWEST;
  9. float m_TemperatureLiquidBoilThreshold = Cooking.LIQUID_BOILING_POINT;
  10. float m_Flammability;
  11. ref NutritionalProfile m_NutriProfile;
  12. void LiquidInfo(string className, NutritionalProfile profile)
  13. {
  14. m_NutriProfile = profile;
  15. Init(className);
  16. }
  17. protected void Init(string className)
  18. {
  19. string path = "cfgLiquidDefinitions " + className;
  20. m_LiquidClassName = className;
  21. GetGame().ConfigGetTextRaw(string.Format("%1 displayName", path), m_LiquidDisplayName);
  22. GetGame().FormatRawConfigStringKeys(m_LiquidDisplayName);
  23. m_LiquidType = GetGame().ConfigGetInt(string.Format("%1 type", path));
  24. if (GetGame().ConfigIsExisting(string.Format("%1 liquidFreezeThreshold", path)))
  25. m_TemperatureLiquidFreezeThreshold = GetGame().ConfigGetFloat(string.Format("%1 liquidFreezeThreshold", path));
  26. if (GetGame().ConfigIsExisting(string.Format("%1 liquidThawThreshold", path)))
  27. m_TemperatureLiquidThawThreshold = GetGame().ConfigGetFloat(string.Format("%1 liquidThawThreshold", path));
  28. if (GetGame().ConfigIsExisting(string.Format("%1 liquidBoilingThreshold", path)))
  29. m_TemperatureLiquidBoilThreshold = GetGame().ConfigGetFloat(string.Format("%1 liquidBoilingThreshold", path));
  30. m_Flammability = GetGame().ConfigGetFloat(string.Format("%1 flammability", path));
  31. }
  32. }
  33. class Liquid
  34. {
  35. static ref map<int, ref NutritionalProfile> m_AllLiquidsByType = new map<int, ref NutritionalProfile>; //DEPRECATED!
  36. static ref map<string, ref NutritionalProfile> m_AllLiquidsByName = new map<string, ref NutritionalProfile>; //DEPRECATED!
  37. static ref map<int, ref LiquidInfo> m_LiquidInfosByType = new map<int, ref LiquidInfo>;
  38. static ref map<string, ref LiquidInfo> m_LiquidInfosByName = new map<string, ref LiquidInfo>;
  39. static bool m_Init = InitAllLiquids();
  40. static string GetLiquidClassname(int liquid_type)
  41. {
  42. LiquidInfo info = m_LiquidInfosByType.Get(liquid_type);
  43. if (info)
  44. {
  45. return info.m_LiquidClassName;
  46. }
  47. return "";
  48. }
  49. static bool InitAllLiquids()
  50. {
  51. if (!g_Game)
  52. return false;
  53. string cfg_classname = "cfgLiquidDefinitions";
  54. string property_value = "NULL_PROPERTY";
  55. int cfg_item_count = g_Game.ConfigGetChildrenCount(cfg_classname);
  56. for (int i = 0; i < cfg_item_count; i++)
  57. {
  58. string liquid_class_name;
  59. GetGame().ConfigGetChildName(cfg_classname, i, liquid_class_name);
  60. string liquid_full_path = string.Format("%1 %2",cfg_classname, liquid_class_name);
  61. int config_liquid_type = GetGame().ConfigGetInt(string.Format("%1 type", liquid_full_path));
  62. NutritionalProfile profile = SetUpNutritionalProfile(config_liquid_type, liquid_class_name);
  63. LiquidInfo info = new LiquidInfo(liquid_class_name, profile);
  64. m_LiquidInfosByType.Insert(config_liquid_type, info);
  65. m_LiquidInfosByName.Insert(liquid_class_name, info);
  66. //legacy stuff
  67. m_AllLiquidsByType.Insert(config_liquid_type, profile);
  68. m_AllLiquidsByName.Insert(liquid_class_name, profile);
  69. }
  70. return true;
  71. }
  72. //---------------------------------------------------------------------------------------------------------
  73. static void Transfer(ItemBase source_ent, ItemBase target_ent, float quantity = -1)
  74. {
  75. if (!Liquid.CanTransfer(source_ent, target_ent))
  76. return;
  77. float source_quantity = source_ent.GetQuantity();
  78. float target_quantity = target_ent.GetQuantity();
  79. float targetCfgWeight = target_ent.m_ConfigWeight;
  80. int source_liquid_type = source_ent.GetLiquidType();
  81. float available_capacity = target_ent.GetQuantityMax() - target_quantity;
  82. float quantity_to_transfer;
  83. //transfers all
  84. if (quantity == -1)
  85. {
  86. quantity_to_transfer = Math.Clamp(source_quantity,0,available_capacity);
  87. }
  88. //transfers exact ammount
  89. else
  90. {
  91. quantity_to_transfer = Math.Clamp(Math.Min(source_quantity,quantity),0,available_capacity);
  92. }
  93. PluginTransmissionAgents m_mta = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
  94. m_mta.TransmitAgents(source_ent, target_ent, AGT_TRANSFER_COPY);
  95. source_ent.AddQuantity(-quantity_to_transfer);
  96. float retultTemp = (source_ent.GetTemperature() * quantity_to_transfer + target_ent.GetTemperature() * (targetCfgWeight + target_quantity)) / (targetCfgWeight + target_quantity + quantity_to_transfer);
  97. target_ent.SetTemperature(retultTemp);
  98. AffectContainerOnTransfer(target_ent,source_liquid_type,quantity_to_transfer,source_ent.GetTemperature());
  99. Liquid.FillContainer(target_ent,source_liquid_type,quantity_to_transfer);
  100. }
  101. static bool CanTransfer(ItemBase source_ent, ItemBase target_ent)
  102. {
  103. if (!source_ent || !target_ent)
  104. return false;
  105. Barrel_ColorBase barrelTarget = Barrel_ColorBase.Cast(target_ent);
  106. Barrel_ColorBase barrelSource = Barrel_ColorBase.Cast(source_ent);
  107. if ((barrelTarget && !barrelTarget.IsOpen()) || (barrelSource && !barrelSource.IsOpen()))
  108. {
  109. return false;
  110. }
  111. if (source_ent.GetIsFrozen())
  112. {
  113. return false;
  114. }
  115. float source_quantity = source_ent.GetQuantity();
  116. if (source_quantity <= 0)
  117. {
  118. //Debug.Log("source has no quantity", "LiquidTransfer");
  119. return false;//if there is nothing to transfer
  120. }
  121. int source_liquid_type = source_ent.GetLiquidType();
  122. if (source_liquid_type < 1)
  123. {
  124. //Debug.Log("source has some quantity, but does not have a valid liquidType set, liquidType = "+ToString(source_liquid_type), "LiquidTransfer");
  125. return false;//if source is not a container
  126. }
  127. if (!CanFillContainer(target_ent,source_liquid_type))
  128. {
  129. return false;
  130. }
  131. return true;
  132. }
  133. static void FillContainer(ItemBase container, int liquid_type, float amount)
  134. {
  135. if (!CanFillContainer(container,liquid_type))
  136. {
  137. return;
  138. }
  139. //filling
  140. container.SetLiquidType(liquid_type);
  141. container.AddQuantity(amount);
  142. }
  143. //! Filled from any enviro source (fuel feed, pond, snow...)
  144. static void FillContainerEnviro(ItemBase container, int liquid_type, float amount, bool inject_agents = true)
  145. {
  146. float containerCfgWeight = container.m_ConfigWeight;
  147. float retultTemp = (GetLiquidTypeEnviroTemperature(liquid_type) * amount + container.GetTemperature() * (containerCfgWeight + container.GetQuantity())) / (container.GetQuantity() + containerCfgWeight + amount);
  148. container.SetTemperature(retultTemp);
  149. AffectContainerOnFill(container,liquid_type,amount);
  150. FillContainer(container, TranslateLiquidType(liquid_type), amount);
  151. if (inject_agents)
  152. {
  153. PluginTransmissionAgents plugin = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
  154. int agtSource;
  155. switch (liquid_type)
  156. {
  157. case LIQUID_FRESHWATER:
  158. case LIQUID_RIVERWATER:
  159. case LIQUID_STILLWATER:
  160. agtSource = AGT_WATER_POND;
  161. break;
  162. case LIQUID_SNOW:
  163. agtSource = AGT_SNOW;
  164. break;
  165. case LIQUID_HOTWATER:
  166. agtSource = AGT_WATER_HOT_SPRING;
  167. break;
  168. default:
  169. agtSource = AGT_NONE;
  170. break;
  171. }
  172. plugin.TransmitAgents(NULL, container, agtSource, amount);
  173. }
  174. }
  175. //! from enviro source
  176. static void AffectContainerOnFill(ItemBase container, int liquid_type, float amount)
  177. {
  178. container.AffectLiquidContainerOnFill(liquid_type,amount);
  179. }
  180. static void AffectContainerOnTransfer(ItemBase container, int liquidType, float amount, float sourceLiquidTransfer)
  181. {
  182. container.AffectLiquidContainerOnTransfer(liquidType,amount,sourceLiquidTransfer);
  183. }
  184. static bool IsLiquidDrinkWater(int liquidType)
  185. {
  186. if (liquidType & (LIQUID_GROUP_DRINKWATER))
  187. return true;
  188. return false;
  189. }
  190. //! Translates 'administrative' liquid types into liquid types with valid config class
  191. static int TranslateLiquidType(int liquidType)
  192. {
  193. if (IsLiquidDrinkWater(liquidType))
  194. return LIQUID_WATER;
  195. else
  196. return liquidType;
  197. }
  198. static bool CanFillContainer(ItemBase container, int liquid_type, bool ignore_fullness_check = false)
  199. {
  200. if (!container)
  201. return false;
  202. bool is_container_full = container.IsFullQuantity();
  203. if (is_container_full && !ignore_fullness_check)
  204. {
  205. //Debug.Log("container is full", "LiquidTransfer");
  206. return false;
  207. }
  208. int container_mask = container.GetLiquidContainerMask();
  209. if (container_mask == 0)
  210. {
  211. //Debug.Log("target is not a container", "LiquidTransfer");
  212. return false;//if the target liquidContainerType is set to 0
  213. }
  214. if ((liquid_type & container_mask) == 0)
  215. {
  216. //Debug.Log("target liquidContainerType does not support this liquid type", "LiquidTransfer");
  217. return false;
  218. }
  219. float container_quantity = container.GetQuantity();
  220. int container_liquid_type = container.GetLiquidType();
  221. if (container_quantity > 0 && container_liquid_type != liquid_type)
  222. {
  223. //Debug.Log("target is not empty AND is of different liquid type than liquid_type added in", "LiquidTransfer");
  224. return false;
  225. }
  226. return true;
  227. }
  228. //! Gets liquid temperature from the enviroment
  229. /*!
  230. \param[in] liquidType Type of liquid.
  231. */
  232. static float GetLiquidTypeEnviroTemperature(int liquidType)
  233. {
  234. float ret = GetGame().GetMission().GetWorldData().GetLiquidTypeEnviroTemperature(liquidType);
  235. //ret = Math.Max(ret,GetLiquidFreezeThreshold(liquidType));
  236. return ret;
  237. }
  238. private static string GetLiquidConfigProperty(int liquid_type, string property_name, bool is_nutrition_property = false)
  239. {
  240. string cfg_classname = "cfgLiquidDefinitions";
  241. string property_value = "NULL_PROPERTY";
  242. if (!g_Game)
  243. return property_value;
  244. int cfg_item_count = g_Game.ConfigGetChildrenCount(cfg_classname);
  245. for (int i = 0; i < cfg_item_count; i++)
  246. {
  247. string liquid_class_name;
  248. GetGame().ConfigGetChildName(cfg_classname, i, liquid_class_name);
  249. string liquid_full_path = string.Format("%1 %2", cfg_classname, liquid_class_name);
  250. int config_liquid_type = GetGame().ConfigGetInt(string.Format("%1 type", liquid_full_path));
  251. if (config_liquid_type == liquid_type)// found the specific class, now lets extract the values
  252. {
  253. if (!is_nutrition_property)
  254. {
  255. GetGame().ConfigGetText(string.Format("%1 %2", liquid_full_path, property_name), property_value);
  256. return property_value;
  257. }
  258. else
  259. {
  260. GetGame().ConfigGetText(string.Format("%1 Nutrition %2", liquid_full_path, property_name), property_value);
  261. return property_value;
  262. }
  263. }
  264. }
  265. return property_value;
  266. }
  267. static NutritionalProfile GetNutritionalProfileByType(int liquid_type)
  268. {
  269. LiquidInfo info = m_LiquidInfosByType.Get(liquid_type);
  270. if (info && info.m_NutriProfile)
  271. return info.m_NutriProfile;
  272. return null;
  273. }
  274. static NutritionalProfile GetNutritionalProfileByName(string class_name)
  275. {
  276. LiquidInfo info = m_LiquidInfosByName.Get(class_name);
  277. if (info && info.m_NutriProfile)
  278. return info.m_NutriProfile;
  279. return null;
  280. }
  281. static NutritionalProfile SetUpNutritionalProfile(int liquid_type, string liquid_class_name)
  282. {
  283. NutritionalProfile profile = new NutritionalProfile();
  284. profile.m_Energy = Liquid.GetLiquidConfigProperty(liquid_type, "energy", true).ToFloat();
  285. profile.m_NutritionalIndex = Liquid.GetLiquidConfigProperty(liquid_type, "nutritionalIndex", true).ToFloat();
  286. profile.m_FullnessIndex = Liquid.GetLiquidConfigProperty(liquid_type, "fullnessIndex", true).ToFloat();
  287. profile.m_WaterContent = Liquid.GetLiquidConfigProperty(liquid_type, "water", true).ToFloat();
  288. profile.m_Toxicity = Liquid.GetLiquidConfigProperty(liquid_type, "toxicity", true).ToFloat();
  289. profile.m_Agents = Liquid.GetLiquidConfigProperty(liquid_type, "agents", true).ToInt();
  290. profile.m_Digestibility = Liquid.GetLiquidConfigProperty(liquid_type, "digestibility", true).ToFloat();
  291. profile.m_AgentsPerDigest = Liquid.GetLiquidConfigProperty(liquid_type, "agentsPerDigest", true).ToFloat();
  292. profile.MarkAsLiquid(liquid_type, liquid_class_name);
  293. return profile;
  294. }
  295. static int GetAgents(int liquid_type)
  296. {
  297. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetAgents();
  298. }
  299. static int GetAgentsPerDigest(int liquidType)
  300. {
  301. return m_LiquidInfosByType.Get(liquidType).m_NutriProfile.m_AgentsPerDigest;
  302. }
  303. static float GetToxicity(int liquid_type)
  304. {
  305. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetToxicity();
  306. }
  307. static float GetWaterContent(int liquid_type)
  308. {
  309. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetWaterContent();
  310. }
  311. static float GetEnergy(int liquid_type)
  312. {
  313. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetEnergy();
  314. }
  315. static float GetNutritionalIndex(int liquid_type)
  316. {
  317. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetNutritionalIndex();
  318. }
  319. static string GetDisplayName(int liquid_type)
  320. {
  321. return m_LiquidInfosByType.Get(liquid_type).m_LiquidDisplayName;
  322. }
  323. static float GetFlammability(int liquid_type)
  324. {
  325. return m_LiquidInfosByType.Get(liquid_type).m_Flammability;
  326. }
  327. static float GetFullness(int liquid_type)
  328. {
  329. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetFullnessIndex();
  330. }
  331. static float GetDigestibility(int liquid_type)
  332. {
  333. return m_LiquidInfosByType.Get(liquid_type).m_NutriProfile.GetDigestibility();
  334. }
  335. static float GetFreezeThreshold(int liquid_type)
  336. {
  337. return m_LiquidInfosByType.Get(liquid_type).m_TemperatureLiquidFreezeThreshold;
  338. }
  339. static float GetThawThreshold(int liquid_type)
  340. {
  341. return m_LiquidInfosByType.Get(liquid_type).m_TemperatureLiquidThawThreshold;
  342. }
  343. static float GetBoilThreshold(int liquid_type)
  344. {
  345. return m_LiquidInfosByType.Get(liquid_type).m_TemperatureLiquidBoilThreshold;
  346. }
  347. ///////////////////////////
  348. //deprecated methods below
  349. ///////////////////////////
  350. static string GetName(int liquid_type)
  351. {
  352. return Liquid.GetLiquidConfigProperty(liquid_type, "name");
  353. }
  354. };