class UniversalTemperatureSourceSettings { float m_UpdateInterval = 1.0; //! how often the Update is ticking float m_TemperatureItemCap = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE; //! max temperature 'non-IsSelfAdjustingTemperature' entity in vicinity will get per update (cap); float m_TemperatureItemCoef = GameConstants.TEMP_COEF_UTS; //! used to determine speed of temperature change, and some temperature subsystems float m_TemperatureCap = float.MAX; //! temperature cap that will limit the return value from GetTemperature method float m_RangeFull = 1; //! range where the full temperature is given to receiver float m_RangeMax = 2; //! maximum range where the receiver can get some temperature bool m_EnableOnTemperatureControl = false; //! enable or disable activation/deactivation on set temperature float m_ActiveTemperatureThreshold = 0.0; //! UTS will be active on temperature >= to this value float m_InactiveTemperatureThreshold = 0.0; //! UTS will be inactive on temperature < to this value bool m_Updateable = false; //! if the Update is running periodically bool m_ManualUpdate = false; //! update is called manually (ex. own tick of parent entity) bool m_IsWorldOverriden = true; //! if the stats can be overriden by coefficient/variables from WorldData (currently TemperatureCap only) vector m_Position = vector.Zero; EntityAI m_Parent = null; //! parent Entity of the UTS //! DEPRECATED bool m_AffectStat = false; float m_TemperatureMin = 0; float m_TemperatureMax = 100; } class UniversalTemperatureSourceResult { float m_TemperatureItem = 0; //! Item target temperature float m_TemperatureHeatcomfort = 0; //! Player HC target(?) value //! DEPRECATED float m_Temperature = 0; } //! original Timer deletes m_params which is unwanted class UniversalTemperatureSourceTimer : Timer { override void OnTimer() { if (m_params) { GetGame().GameScript.CallFunctionParams(m_target, m_function, null, m_params); } else { GetGame().GameScript.CallFunction(m_target, m_function, null, 0); } } override void Stop() { SetRunning(false); m_time = 0; } void SetParams(Param params) { m_params = params; } } typedef UniversalTemperatureSource UTemperatureSource; class UniversalTemperatureSource { private float m_ParentTemperaturePrevious; protected bool m_Active protected ref UniversalTemperatureSourceTimer m_Timer; protected UniversalTemperatureSourceSettings m_Settings; protected ref UniversalTemperatureSourceResult m_ResultValues; protected ref UniversalTemperatureSourceLambdaBase m_Lambda; void UniversalTemperatureSource(EntityAI pParent, UniversalTemperatureSourceSettings pSettings, UniversalTemperatureSourceLambdaBase pLambda) { m_Active = false; m_Settings = pSettings; m_Lambda = pLambda; m_ResultValues = new UniversalTemperatureSourceResult(); m_Timer = new UniversalTemperatureSourceTimer(); Init(pParent); } void ~UniversalTemperatureSource() {}; void Init(EntityAI pParent) { if (pParent) { pParent.SetUniversalTemperatureSource(this); m_Settings.m_Parent = pParent; m_Settings.m_Position = pParent.GetPosition(); } if (!m_Settings.m_ManualUpdate) { auto params = new Param2(m_Settings, m_Lambda); m_Timer.Run(m_Settings.m_UpdateInterval, this, "Update", params, m_Settings.m_Updateable); SetActive(false); } if (m_Settings.m_IsWorldOverriden) m_Settings.m_TemperatureCap += g_Game.GetMission().GetWorldData().GetUniversalTemperatureSourceCapModifier(); } vector GetPosition() { return m_Settings.m_Position; } float GetFullRange() { return m_Settings.m_RangeFull; } float GetMaxRange() { return m_Settings.m_RangeMax; } float GetTemperatureCap() { return m_Settings.m_TemperatureCap; } float GetTemperatureItemCap() { return m_Settings.m_TemperatureItemCap; } float GetTemperatureItemCoef() { return m_Settings.m_TemperatureItemCoef; } EntityAI GetParent() { return m_Settings.m_Parent; } UniversalTemperatureSourceLambdaBase GetLambda() { return m_Lambda; } bool IsActive() { if (m_Settings.m_ManualUpdate) { return m_Active; } return m_Timer && m_Timer.IsRunning(); } void SetActive(bool pActive) { if (pActive) m_Lambda.OnUTSActivate(); else m_Lambda.OnUTSDeactivate(); if (m_Settings.m_ManualUpdate) { m_Active = pActive; return; } if (pActive && !m_Timer.IsRunning()) { m_Timer.Continue(); } else { m_Timer.Stop(); } } void SetDefferedActive(bool pActive, float pSeconds) { GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLaterByName(this, "SetActive", pSeconds * 1000, false, new Param1(pActive)); } void ChangeSettings(UniversalTemperatureSourceSettings pSettings) { m_Timer.SetParams(new Param2(m_Settings, m_Lambda)); } void Update(UniversalTemperatureSourceSettings settings, UniversalTemperatureSourceLambdaBase lambda) { if (settings.m_EnableOnTemperatureControl) { float parentTemperature = GetParent().GetTemperature(); float temperatureDifference = parentTemperature - m_ParentTemperaturePrevious; if (parentTemperature >= settings.m_ActiveTemperatureThreshold && temperatureDifference > 0) SetActive(true); if (parentTemperature < settings.m_InactiveTemperatureThreshold && temperatureDifference < 0) SetActive(false); m_ParentTemperaturePrevious = parentTemperature; } if (!IsActive()) return; if (lambda) { settings.m_Position = settings.m_Parent.GetUniversalTemperatureSourcePosition(); lambda.OnBeforeExecute(); lambda.Execute(settings, m_ResultValues); lambda.OnAfterExecute(); } } //! //!DEPRECATED //! float GetTemperatureMin() { return m_Settings.m_TemperatureMin; } float GetTemperatureMax() { return m_Settings.m_TemperatureMax; } float GetTemperature() { return GetTemperatureRaw(); } float GetTemperatureRaw() { if (m_ResultValues) return m_ResultValues.m_Temperature; return 0; } } typedef UniversalTemperatureSourceDebug UTemperatureSourceDebug class UniversalTemperatureSourceDebug { const string DELIMITER_DATA = "|"; const string DELIMITER_KEYPAIR = ":"; string m_Header; string m_Data; ref array m_Names; //! names parsed from m_Pairs ref array m_Values; //! values parsed from m_Pairs ref array m_Pairs; //! keeps first iteration of parsed data from the m_Data void UniversalTemperatureSourceDebug() { m_Header = ""; m_Data = ""; m_Pairs = new array(); m_Names = new array(); m_Values = new array(); } void AddHeader(string header) { m_Header = header; } void Add(string name, string value) { m_Data = string.Format("%1%2:%3%4", m_Data, name, value, DELIMITER_DATA); } void Commit() { m_Pairs = ParseData(); ParseKeyPairs(); } int PairsCount() { return m_Pairs.Count(); } string GetHeader() { return m_Header; } string GetName(int pIndex) { if (m_Names.Count() - 1 < pIndex) { Debug.Log(string.Format("GetName index: %1 from data of length: %2", pIndex, m_Names.Count()), "UniversalTemperatureSourceDebug"); return ""; } return m_Names.Get(pIndex); } string GetValue(int pIndex) { if (m_Values.Count() - 1 < pIndex) { Debug.Log(string.Format("GetValue index: %1 from data of length: %2", pIndex, m_Values.Count()), "UniversalTemperatureSourceDebug"); return ""; } return m_Values.Get(pIndex); } protected array ParseData() { array parsed = new array(); if (m_Data) { m_Data.Split(DELIMITER_DATA, parsed); } return parsed; } protected void ParseKeyPairs() { m_Names.Clear(); m_Values.Clear(); if (m_Pairs) { for (int i = 0; i < m_Pairs.Count(); i++) { array keypair = new array(); m_Pairs.Get(i).Split(DELIMITER_KEYPAIR, keypair); m_Names.Insert(keypair[0]); m_Values.Insert(keypair[1]); } } } void Debug() { for (int i = 0; i < m_Names.Count(); i++) { Debug.Log(string.Format("%1: %2", m_Names.Get(i), m_Values.Get(i)), "UniversalTemperatureSourceDebug"); } } }