class PluginUniversalTemperatureSourceClient extends PluginBase
{
const int MAX_SIMULTANEOUS_UTS = 10;
protected float m_UTSAverageTemperature;
protected ref array<ref UTemperatureSourceDebug> m_UTemperatureSourceDebugs;
protected ref Widget m_RootWidget[MAX_SIMULTANEOUS_UTS];
protected TextListboxWidget m_StatListWidgets[MAX_SIMULTANEOUS_UTS];
protected TextWidget m_HeaderWidget[MAX_SIMULTANEOUS_UTS];
protected PlayerBase m_Player;
void PluginUniversalTemperatureSourceClient()
{
m_UTemperatureSourceDebugs = new array<ref UTemperatureSourceDebug>();
}
override void OnInit()
{
#ifndef NO_GUI
InitWidgets();
#endif
}
override void OnUpdate(float delta_time)
{
#ifndef NO_GUI
if (!m_Player)
{
return;
}
UpdateStatWidgets();
DrawDebugs();
#endif
}
void InitWidgets()
{
for (int i = 0; i < MAX_SIMULTANEOUS_UTS; i++)
{
m_RootWidget[i] = g_Game.GetWorkspace().CreateWidgets("gui/layouts/debug/day_z_debug_remoteinfo.layout");
m_StatListWidgets[i] = TextListboxWidget.Cast(m_RootWidget[i].FindAnyWidget("TextListboxWidget0"));
m_HeaderWidget[i] = TextWidget.Cast(m_RootWidget[i].FindAnyWidget("TextWidget0"));
}
}
void DrawDebugs()
{
foreach (UTemperatureSourceDebug utsd : m_UTemperatureSourceDebugs)
{
float fullRange = utsd.GetValue(1).ToFloat();
float maxRange = utsd.GetValue(2).ToFloat();
float temp = utsd.GetValue(3).ToFloat();
vector sphPos = utsd.GetValue(0).ToVector();
int fullRangeColor = COLOR_RED_A;
int maxRangeColor = COLOR_YELLOW_A;
if (temp < 0)
{
fullRangeColor = COLOR_GREEN_A;
maxRangeColor = COLOR_BLUE_A;
}
else if (temp == 0)
{
fullRangeColor = 0x1fefefef;
maxRangeColor = 0x1fefefef;
}
Debug.DrawCylinder(sphPos, fullRange, fullRange, fullRangeColor, ShapeFlags.ONCE|ShapeFlags.TRANSP);
Debug.DrawCylinder(sphPos, maxRange, maxRange, maxRangeColor, ShapeFlags.ONCE|ShapeFlags.TRANSP);
Debug.DrawArrow(m_Player.GetPosition(), sphPos, 1.0, 0xffffffff, ShapeFlags.ONCE|ShapeFlags.TRANSP);
}
ProcessUniversalTemperatureSources();
if (m_UTemperatureSourceDebugs.Count() > 0)
{
DbgUI.Begin("Universal Temp Sources", 10, 300);
DbgUI.Text(string.Format("Lookup radius: %1m (server-side)", PluginUniversalTemperatureSourceServer.LOOKUP_RADIUS));
DbgUI.Text(string.Format("Count: %1", m_UTemperatureSourceDebugs.Count()));
DbgUI.Text(string.Format("Avg. temp: %1 °C", m_UTSAverageTemperature));
DbgUI.End();
}
}
protected void ProcessUniversalTemperatureSources()
{
if (m_UTemperatureSourceDebugs.Count() == 0)
{
m_UTSAverageTemperature = 0;
return;
}
array<float> utsTemperatures = new array<float>();
// get temperature from the source (based on distance), save it for min/max filtering
foreach (UniversalTemperatureSourceDebug utsd : m_UTemperatureSourceDebugs)
{
//! next temp source is too far (not cleaned on server, like in Environment, client need to know about all sources in MAXRANGE)
if (vector.DistanceSq(m_Player.GetPosition(), utsd.GetValue(0).ToVector()) > Math.SqrFloat(utsd.GetValue(2).ToFloat()))
continue;
utsTemperatures.Insert(CalcTemperatureFromTemperatureSource(utsd));
}
float min = MiscGameplayFunctions.GetMinValue(utsTemperatures);
float max = MiscGameplayFunctions.GetMaxValue(utsTemperatures);
if (max > 0 && min < 0)
{
m_UTSAverageTemperature = (max + min) * 0.5;
}
else
{
m_UTSAverageTemperature = max;
}
}
protected float CalcTemperatureFromTemperatureSource(notnull UTemperatureSourceDebug utsd)
{
float distance = vector.Distance(m_Player.GetPosition(), utsd.GetValue(0).ToVector());
distance = Math.Max(distance, 0.1); //min distance cannot be 0 (division by zero)
float temperature = 0;
//! heat transfer through air to player (env temperature)
if (distance > utsd.GetValue(1).ToFloat())
{
float distFactor = Math.InverseLerp(utsd.GetValue(2).ToFloat(), utsd.GetValue(1).ToFloat(), distance);
distFactor = Math.Max(distFactor, 0.0); //! dist factor minimum should be at 0
temperature = utsd.GetValue(3).ToFloat() * distFactor;
}
else
{
temperature = utsd.GetValue(3).ToFloat();
}
//Print(temperature);
return temperature;
}
void EnableWidgets(bool enable)
{
for (int i = 0; i < MAX_SIMULTANEOUS_UTS; i++)
{
m_RootWidget[i].Show(enable);
}
}
void UpdateStatWidgets()
{
int i = 0;
int utsDebugCount = m_UTemperatureSourceDebugs.Count();
for (; i < utsDebugCount && i < MAX_SIMULTANEOUS_UTS; ++i)
{
UTemperatureSourceDebug utsd = m_UTemperatureSourceDebugs[i];
vector pos = utsd.GetValue(0).ToVector();
vector screen_pos_stats = g_Game.GetScreenPos(pos + "0 0 0");
vector screen_pos_damage = g_Game.GetScreenPos(pos + "0 2 0");
m_RootWidget[i].SetPos(screen_pos_stats[0], screen_pos_stats[1]);
if (screen_pos_stats[2] > 0 && screen_pos_stats[0] > 0 && screen_pos_stats[1] > 0)
{
m_RootWidget[i].Show(true);
UpdateStatWidget(i, utsd);
}
else
{
m_RootWidget[i].Show(false);
}
}
for (; i < MAX_SIMULTANEOUS_UTS; ++i)
{
if (m_RootWidget[i])
{
m_RootWidget[i].Show(false);
}
}
}
void UpdateStatWidget(int rowIndex, UTemperatureSourceDebug utsd)
{
m_StatListWidgets[rowIndex].ClearItems();
m_HeaderWidget[rowIndex].SetText(utsd.GetHeader());
int numPairs = utsd.PairsCount();
for (int i = 0; i < numPairs; ++i)
{
m_StatListWidgets[rowIndex].AddItem(utsd.GetName(i), null, 0, i);
m_StatListWidgets[rowIndex].SetItem(i, utsd.GetValue(i), null, 1);
}
// manually add value for distance (client only)
m_StatListWidgets[rowIndex].AddItem("distance", null, 0, numPairs);
m_StatListWidgets[rowIndex].SetItem(numPairs, vector.Distance(m_Player.GetPosition(), utsd.GetValue(0).ToVector()).ToString(), null, 1);
}
void RequestUniversalTemperatureSources(PlayerBase player, int enable)
{
//Debug.Log("RequestUniversalTemperatureSources called", "PluginUniversalTemperatureSourceClient");
if (!enable)
{
m_UTemperatureSourceDebugs.Clear();
m_Player = null;
EnableWidgets(false);
return;
}
ScriptRPC rpc = new ScriptRPC();
rpc.Write(enable);
rpc.Send(player, ERPCs.DEV_REQUEST_UTS_DEBUG, true, player.GetIdentity());
m_Player = player;
}
void PrintedDebug()
{
foreach (UTemperatureSourceDebug utsd : m_UTemperatureSourceDebugs)
{
PrintString("-------------------------------------");
utsd.Debug();
PrintString("-------------------------------------");
}
}
void OnRPC(ParamsReadContext ctx)
{
//Debug.Log("OnRPC called", "PluginUniversalTemperatureSourceClient");
//PrintedDebug();
ctx.Read(m_UTemperatureSourceDebugs);
}
}