Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added HeatMap.xlsx
Binary file not shown.
Binary file added mod-structure/1.4/Assemblies/HeatMap.dll
Binary file not shown.
Binary file added mod-structure/1.5/Assemblies/HeatMap.dll
Binary file not shown.
2 changes: 2 additions & 0 deletions mod-structure/About/About.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<author>Falconne</author>
<description>Adds an overlay toggle button to show a temperature based colour gradient over indoor areas: green for the human comfort zone, getting bluer and redder for colder and hotter rooms respectively.</description>
<supportedVersions>
<li>1.5</li>
<li>1.4</li>
<li>1.3</li>
<li>1.2</li>
<li>1.1</li>
Expand Down
85 changes: 68 additions & 17 deletions mod-structure/Languages/English/Keyed/FALCHM_LanguageData.xml
Original file line number Diff line number Diff line change
@@ -1,43 +1,94 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<FALCHM.OverrideVanillaOverlay>Override vanilla overlay</FALCHM.OverrideVanillaOverlay>
<FALCHM.OverrideVanillaOverlayDesc>Use Heat Map's overlay instead of the vanilla overlay.
(default: {default})</FALCHM.OverrideVanillaOverlayDesc>

<FALCHM.ShowIndoorsOnly>Only overlay indoor areas</FALCHM.ShowIndoorsOnly>
<FALCHM.ShowIndoorsOnlyDesc>Only show the overlay for indoors areas.
(default: {default})</FALCHM.ShowIndoorsOnlyDesc>

<FALCHM.OverlayOpacity>Opacity of overlay</FALCHM.OverlayOpacity>
<FALCHM.OverlayOpacityDesc>Reduce this value to make the overlay more transparent.</FALCHM.OverlayOpacityDesc>
<FALCHM.OverlayOpacityDesc>Reduce this value to make the overlay more transparent.
(default: {default}%)</FALCHM.OverlayOpacityDesc>

<FALCHM.UpdateDelay>Overlay update delay</FALCHM.UpdateDelay>
<FALCHM.UpdateDelayDesc>Number of ticks delay between overlay updates while game is unpaused. Lower numbers provide smoother updates, but may affect performance on low end machines.</FALCHM.UpdateDelayDesc>
<FALCHM.UpdateDelayDesc>Number of ticks delay between widget and temperature text updates while game is unpaused. Lower numbers provide smoother updates, but may affect performance on low end machines.
(default: {default})</FALCHM.UpdateDelayDesc>

<FALCHM.ShowOutDoorThermometer>Show outdoor thermometer</FALCHM.ShowOutDoorThermometer>
<FALCHM.ShowOutDoorThermometerDesc>Displays a widget in the top right hand corner of the UI showing current outdoor temperature.</FALCHM.ShowOutDoorThermometerDesc>
<FALCHM.ShowOutDoorThermometerDesc>Displays a widget in the top right hand corner of the UI showing current outdoor temperature.
(default: {default})</FALCHM.ShowOutDoorThermometerDesc>

<FALCHM.ThermometerOpacity>Opacity of thermometer</FALCHM.ThermometerOpacity>
<FALCHM.ThermometerOpacityDesc>Reduce this value to make the outdoor temperature thermometer background color more transparent.</FALCHM.ThermometerOpacityDesc>
<FALCHM.ThermometerOpacityDesc>Reduce this value to make the outdoor temperature thermometer background colour more transparent.
(default: {default}%)</FALCHM.ThermometerOpacityDesc>

<FALCHM.ThermometerFixed>Lock thermometer position</FALCHM.ThermometerFixed>
<FALCHM.ThermometerFixedDesc>Locks the thermometer widget in place, disabling shift-click dragging.</FALCHM.ThermometerFixedDesc>
<FALCHM.ThermometerFixedDesc>Locks the thermometer widget in place, disabling shift-click dragging.
(default: {default})</FALCHM.ThermometerFixedDesc>

<FALCHM.ThermometerRight>Right margin of thermometer</FALCHM.ThermometerRight>
<FALCHM.ThermometerRightDesc>Changes the margin between the thermometer widget and the right of the screen. The widget can be dragged using shift-click while ingame.</FALCHM.ThermometerRightDesc>
<FALCHM.ThermometerRightDesc>Changes the margin between the thermometer widget and the right of the screen. The widget can be dragged using shift-click while ingame.
(default: {default})</FALCHM.ThermometerRightDesc>

<FALCHM.ThermometerTop>Top margin of thermometer</FALCHM.ThermometerTop>
<FALCHM.ThermometerTopDesc>Changes the margin between the thermometer widget and the top of the screen. The widget can be dragged using shift-click while ingame.</FALCHM.ThermometerTopDesc>
<FALCHM.ThermometerTopDesc>Changes the margin between the thermometer widget and the top of the screen. The widget can be dragged using shift-click while ingame.
(default: {default})</FALCHM.ThermometerTopDesc>

<FALCHM.ThermometerTooltip>Outdoor temperature.
Click to toggle heat map overlay.
Shift-click and drag to move the widget, the position can be locked in the mod settings.
This widget can be disabled in mod settings.</FALCHM.ThermometerTooltip>
<FALCHM.ShowHeatMap>Show Heat Map</FALCHM.ShowHeatMap>
<FALCHM.ShowTemperatureOverRooms>Show temperature over rooms</FALCHM.ShowTemperatureOverRooms>
<FALCHM.ShowTemperatureOverRoomsDesc>When overlay is on, this will also display the room temperature over the centre of the room.
(default: {default})</FALCHM.ShowTemperatureOverRoomsDesc>

<FALCHM.GradientHue>Colour gradient hue {index}</FALCHM.GradientHue>
<FALCHM.GradientHueDesc>Defines which colours will be used for the overlay's colour gradient. Colours are given as hue in degree.
(default: {default})

- Colours:
0°/360° = red
60° = yellow
120° = green
180° = cyan
240° = blue
300° = magenta

Each degree of temperature between min/max (default: {min} to {max} °C) has a relative gradient step width of 1, except for the values between min/max comfort temperature (default: {comfortMin} to {comfortMax} °C), which have a step width of 4.
I.e. each degree of the comfort temperature range takes up four times as much on the colour gradient as one outside of the comfort levels.
For example when using default settings green will be applied to a smaller temperature range than red or blue.</FALCHM.GradientHueDesc>

<FALCHM.UseCustomeRange>Use custom range</FALCHM.UseCustomeRange>
<FALCHM.UseCustomeRangeDesc>When off, the colour gradient automatically maps to the human comfort range as defined by the game.

When on, allows you to set a custom boundary for the blue and red ends of the gradient, in current temperature units</FALCHM.UseCustomeRangeDesc>
When on, custom temperature boundaries for the colour gradient can be set.
(default: {default})</FALCHM.UseCustomeRangeDesc>

<FALCHM.CustomRangeMin>Custom range min</FALCHM.CustomRangeMin>
<FALCHM.CustomRangeMinDesc>Blue end of gradient. Temperatures below this will be blue. Use current temperature units</FALCHM.CustomRangeMinDesc>
<FALCHM.CustomRangeMinDesc>Lower temperature limit of the colour gradient.
Temperatures below this will be coloured using colour gradient hue 0, default: blue.
Uses current temperature units
(default: {default})</FALCHM.CustomRangeMinDesc>

<FALCHM.CustomRangeMax>Custom range max</FALCHM.CustomRangeMax>
<FALCHM.CustomRangeMaxDesc>Red end of gradient. Temperatures above this will be red. Use current temperature units</FALCHM.CustomRangeMaxDesc>
<FALCHM.CustomRangeMaxDesc>Upper temperature limit of the colour gradient.
Temperatures above this will be coloured using colour gradient hue 4, default: red.
Uses current temperature units
(default: {default})</FALCHM.CustomRangeMaxDesc>

<FALCHM.ShowTemperatureOverRooms>Show temperature over rooms</FALCHM.ShowTemperatureOverRooms>
<FALCHM.ShowTemperatureOverRoomsDesc>When overlay is on, this will also display the room temperature over the centre of the room.</FALCHM.ShowTemperatureOverRoomsDesc>
<FALCHM.CustomRangeComfortMin>Custom comfort range min</FALCHM.CustomRangeComfortMin>
<FALCHM.CustomRangeComfortMinDesc>Lower comfort temperature.
Between min-max comfort temperature the colour changes four times as quickly as outside these limits, making small changes more noticeable.
Uses current temperature units
(default: {default})</FALCHM.CustomRangeComfortMinDesc>

<FALCHM.CustomRangeComfortMax>Custom comfort range max</FALCHM.CustomRangeComfortMax>
<FALCHM.CustomRangeComfortMaxDesc>Upper comfort temperature.
Between min-max comfort temperature the colour changes four times as quickly as outside these limits, making small changes more noticeable.
Uses current temperature units
(default: {default})</FALCHM.CustomRangeComfortMaxDesc>

<FALCHM.ThermometerTooltip>Outdoor temperature.
Click to toggle heat map overlay.
Shift-click and drag to move the widget, the position can be locked in the mod settings.
This widget can be disabled in mod settings.</FALCHM.ThermometerTooltip>
<FALCHM.ShowHeatMap>Show Heat Map</FALCHM.ShowHeatMap>
</LanguageData>
106 changes: 106 additions & 0 deletions src/HeatMap/ColorHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;

namespace HeatMap
{
public class ColorHelper
{
/// <summary>
/// Calculate a color from a color gradient between two colors
/// </summary>
/// <param name="start">Gradient start color</param>
/// <param name="end">Gradient end color</param>
/// <param name="pos">Position in color gradient; can be equal <paramref name="steps"/> to return <paramref name="end"/></param>
/// <param name="steps">Number of steps in the color gradient</param>
/// <param name="a">Alpha-Channel</param>
/// <returns></returns>
public static Color Gradient(Color start, Color end, float pos, float steps, float a = 1f)
{
if (steps <= 0)
return new Color(end.r, end.g, end.b, a);

pos %= steps + 1;

var rMin = start.r;
var rMax = end.r;
var gMin = start.g;
var gMax = end.g;
var bMin = start.b;
var bMax = end.b;

var rAverage = rMin + ((rMax - rMin) * pos / steps);
var gAverage = gMin + ((gMax - gMin) * pos / steps);
var bAverage = bMin + ((bMax - bMin) * pos / steps);

return new Color(rAverage, gAverage, bAverage, a);
}

/// <summary>
/// Creates a color gradient using <paramref name="colors"/> and <paramref name="steps"/>
/// </summary>
/// <param name="colors">Colors to be used for the gradient with relative weighting factor; relatively higher factors will make the color be used for more steps</param>
/// <param name="steps">Steps with stepwidth; longer stepwidth advances through the gradient faster</param>
/// <param name="a">Alpha-Channel</param>
/// <returns></returns>
public static List<Color> Gradient(IList<Tuple<Color, float>> colors, IList<float> steps, float a = 1f)
{
if (!(colors?.Count > 0))
{
Log.Warning("Colors must have at least 1 element");
return new List<Color> { Color.white };
}

if (!(steps?.Count > 0))
{
Log.Warning("Steps must have at least 1 element");
return new List<Color> { Color.white };
}

var stepsTotal = 0f;
foreach (var step in steps)
stepsTotal += step;
if (stepsTotal == 0)
{
Log.Warning("Steps total must be greater than 0");
return new List<Color> { Color.white };
}

var total = 0f;
for (int i = 0; i < colors.Count - 1; i++)
total += colors[i].Item2;

var offset = 0f;
var list = new List<Tuple<Color, float>>();
foreach (var item in colors)
{
list.Add(new Tuple<Color, float>(item.Item1, offset));
offset += stepsTotal * (item.Item2 / total);
}

var output = new List<Color>();
var pos = 0f;
for (int i = 0, j = 0; i < list.Count - 1; i++)
{
var item = list[i];
var next = list[i + 1];
while (pos < next.Item2)
{
output.Add(Gradient(
item.Item1,
next.Item1,
pos - item.Item2,
next.Item2 - item.Item2,
a));
pos += steps[j++];
}
}
output.Add(colors.Last().Item1);
return output;
}
}
}
Loading