Skip to content

Instantly share code, notes, and snippets.

@saki7
Forked from ronyx69/Relight.cs
Created April 27, 2018 10:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saki7/0b8414fc41a84136fc04d6eea0a2e311 to your computer and use it in GitHub Desktop.
Save saki7/0b8414fc41a84136fc04d6eea0a2e311 to your computer and use it in GitHub Desktop.
Source code for Relight mod. Rebalanced and customizable lighting and tonemapping. UI / saving and preset system by Simon Royer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICities;
using UnityEngine;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Xml.Serialization;
using System.IO;
using ColossalFramework.PlatformServices;
using ColossalFramework.IO;
namespace LightingRebalance
{
public class LightingRebalanceMod : LoadingExtensionBase, IUserMod
{
private GameObject gameobj;
public string Name { get { return "Relight"; } }
public string Description { get { return "Rebalanced and customizable lighting and tonemapping."; } }
public override void OnLevelLoaded(LoadMode mode)
{
base.OnLevelLoaded(mode);
if (mode == LoadMode.NewGame || mode == LoadMode.LoadGame)
{
gameobj = new GameObject();
gameobj.AddComponent<LightingRebalanceLogic>();
}
}
public override void OnLevelUnloading()
{
base.OnLevelUnloading();
if (gameobj != null)
{
UnityEngine.Object.Destroy(gameobj);
gameobj = null;
}
}
}
public class LightingRebalanceLogic : MonoBehaviour
{
// SIMON PART (UI + SAVING)
void Start()
{
instanceID = this.GetInstanceID();
LightPreset.LoadLightPresets();
if (File.Exists(CachePath))
{
LoadCache();
CalculateAll(uiValues, skyTonemappingUi);
}
else
AllToZero();
}
public bool ShowUI = false;
private Rect windowRect = new Rect(200, 200, 450, 525);
private int instanceID, windowMode = 0;
private Vector2 scrollPresets = Vector2.zero;
private string nameTextfield = "Preset Name";
public float[] uiValues, oldValues;
public bool skyTonemappingUi, oldSkyTonemappingUi;
public string CachePath = DataLocation.localApplicationData + "\\RelightCache.light";
void Update()
{
if (Input.GetKey(KeyCode.LeftShift))
{
if (Input.GetKey(KeyCode.LeftAlt))
{
if (Input.GetKeyDown(KeyCode.L))
{
ShowUI = !ShowUI;
}
}
}
if (ShowUI)
{
if (IsAnyDifference(uiValues, skyTonemappingUi, oldValues, oldSkyTonemappingUi))
{
CalculateAll(uiValues, skyTonemappingUi);
SaveCache();
}
oldValues = new float[]
{
uiValues[0], uiValues[1], uiValues[2], uiValues[3], uiValues[4], uiValues[5], uiValues[6], uiValues[7], uiValues[8], uiValues[9], uiValues[10], uiValues[11], uiValues[12]
};
oldSkyTonemappingUi = skyTonemappingUi;
}
}
void OnGUI()
{
if (ShowUI)
windowRect = GUI.Window(instanceID, windowRect, DrawWindow, "Relight");
}
void DrawWindow(int id)
{
GUI.DragWindow(new Rect(0, 0, 420, 20));
if (GUI.Button(new Rect(422, 4, 25, 20), "x"))
ShowUI = false;
windowMode = GUI.Toolbar(new Rect(5, 26, 440, 25), windowMode, new string[] { "Customization", "Presets" });
if (windowMode == 0)
{
// CUSTOMIZATION WINDOW MODE
GUI.Label(new Rect(180, 60, 150, 26), "<size=14>Tonemapping</size>");
// brightness
GUI.Label(new Rect(5, 80, 115, 30), "Brightness");
uiValues[10] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 85, 270, 25), uiValues[10], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 80, 50, 30), uiValues[10].ToString(), GUI.skin.label))
uiValues[10] = 0;
// gamma
GUI.Label(new Rect(5, 110, 115, 30), "Gamma");
uiValues[11] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 115, 270, 25), uiValues[11], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 110, 50, 30), uiValues[11].ToString(), GUI.skin.label))
uiValues[11] = 0;
// contrast
GUI.Label(new Rect(5, 140, 115, 30), "Contrast");
uiValues[12] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 145, 270, 25), uiValues[12], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 140, 50, 30), uiValues[12].ToString(), GUI.skin.label))
uiValues[12] = 0;
GUI.Label(new Rect(200, 160, 150, 26), "<size=14>Lighting</size>");
// temperature
GUI.Label(new Rect(5, 190, 115, 30), "Temperature");
uiValues[0] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 195, 270, 25), uiValues[0], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 190, 50, 30), uiValues[0].ToString(), GUI.skin.label))
uiValues[0] = 0;
// tint
GUI.Label(new Rect(5, 220, 115, 30), "Tint");
uiValues[1] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 225, 270, 25), uiValues[1], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 220, 50, 30), uiValues[1].ToString(), GUI.skin.label))
uiValues[1] = 0;
// sun temperature
GUI.Label(new Rect(5, 250, 115, 30), "Sun Temperature");
uiValues[2] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 255, 270, 25), uiValues[2], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 250, 50, 30), uiValues[2].ToString(), GUI.skin.label))
uiValues[2] = 0;
// sun tint
GUI.Label(new Rect(5, 280, 115, 30), "Sun Tint");
uiValues[3] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 285, 270, 25), uiValues[3], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 280, 50, 30), uiValues[3].ToString(), GUI.skin.label))
uiValues[3] = 0;
// sky temperature
GUI.Label(new Rect(5, 310, 115, 30), "Sky Temperature");
uiValues[4] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 315, 270, 25), uiValues[4], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 310, 50, 30), uiValues[4].ToString(), GUI.skin.label))
uiValues[4] = 0;
// sky tint
GUI.Label(new Rect(5, 340, 115, 30), "Sky Tint");
uiValues[5] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 345, 270, 25), uiValues[5], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 340, 50, 30), uiValues[5].ToString(), GUI.skin.label))
uiValues[5] = 0;
// moon temperature
GUI.Label(new Rect(5, 370, 115, 30), "Moon Temperature");
uiValues[6] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 375, 270, 25), uiValues[6], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 370, 50, 30), uiValues[6].ToString(), GUI.skin.label))
uiValues[6] = 0;
// moon tint
GUI.Label(new Rect(5, 400, 115, 30), "Moon Tint");
uiValues[7] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 405, 270, 25), uiValues[7], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 400, 50, 30), uiValues[7].ToString(), GUI.skin.label))
uiValues[7] = 0;
// moonlight
GUI.Label(new Rect(5, 430, 115, 30), "Moon Light");
uiValues[8] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 435, 270, 25), uiValues[8], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 430, 50, 30), uiValues[8].ToString(), GUI.skin.label))
uiValues[8] = 0;
// Twilight tint
GUI.Label(new Rect(5, 460, 115, 30), "Twilight Tint");
uiValues[9] = (float)(Math.Round(GUI.HorizontalSlider(new Rect(120, 465, 270, 25), uiValues[9], -1f, 1f) * 20) / 20);
if (GUI.Button(new Rect(395, 460, 50, 30), uiValues[9].ToString(), GUI.skin.label))
uiValues[9] = 0;
skyTonemappingUi = GUI.Toggle(new Rect(5, 495, 348, 28), skyTonemappingUi, " Enable Sky Tonemapping");
if (GUI.Button(new Rect(355, 491, 88, 28), "Reset All"))
AllToZero();
}
else if (windowMode == 1)
{
// PRESETS WINDOW MODE
if (LightPreset.LightPresets.Count > 0)
{
scrollPresets = GUI.BeginScrollView(new Rect(5, 55, 440, 200), scrollPresets, new Rect(0, 0, 415, LightPreset.LightPresets.Count * 30));
for (int i = 0; i < LightPreset.LightPresets.Count; i++)
{
var preset = LightPreset.LightPresets[i];
GUI.Label(new Rect(5, i * 30 + 3, 240, 25), preset.m_presetName);
if (GUI.Button(new Rect(245, i * 30, 70, 28), "Load"))
LoadPreset(preset);
if (preset.m_canBeDeleted)
{
if (GUI.Button(new Rect(320, i * 30, 70, 28), "Delete"))
LightPreset.DeletePreset(preset);
}
else
GUI.Label(new Rect(320, i * 30 + 2, 70, 28), "[ <i>Workshop</i> ]");
}
GUI.EndScrollView();
}
else
{
GUI.Box(new Rect(5, 55, 440, 200), string.Empty);
GUI.Label(new Rect(28, 60, 410, 30), "No preset found !");
}
if (GUI.Button(new Rect(5, 260, 440, 27), "Reload Presets List"))
LightPreset.LoadLightPresets();
if (File.Exists(DataLocation.localApplicationData + @"\ModConfig\RelightPresets\" + LightPreset.ToFileName(nameTextfield) + ".light"))
{
GUI.color = Color.red;
nameTextfield = GUI.TextField(new Rect(5, 290, 440, 27), nameTextfield);
GUI.Label(new Rect(5, 320, 440, 27), "<b>A preset with this name already exists !</b>", GUI.skin.button);
GUI.color = Color.white;
}
else
{
nameTextfield = GUI.TextField(new Rect(5, 290, 440, 27), nameTextfield);
if (GUI.Button(new Rect(5, 320, 440, 27), "<b>+</b> Save Preset Locally"))
CreatePreset();
}
if (GUI.Button(new Rect(5, 350, 440, 27), "Open Local Presets Folder"))
{
string path = DataLocation.localApplicationData + @"\ModConfig\RelightPresets\";
if (!Directory.Exists(DataLocation.localApplicationData + @"\ModConfig\"))
Directory.CreateDirectory(DataLocation.localApplicationData + @"\ModConfig\");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Application.OpenURL("file://" + path);
}
}
}
public static void CalculateAll(float[] values, bool skyTonemapping)
{
CalculateLighting(values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9]);
CalculateTonemapping(values[10], values[11], values[12]);
SkyTonemapping(skyTonemapping);
}
private bool IsAnyDifference(float[] valuesNew, bool skyTonemappingNew, float[] valuesOld, bool skyTonemappingOld)
{
for (int i = 0; i <= 12; i++)
{
if (valuesNew[i] != valuesOld[i])
return true;
}
return (skyTonemappingOld != skyTonemappingNew);
}
public void SaveCache()
{
if (File.Exists(CachePath))
File.Delete(CachePath);
TextWriter tw = new StreamWriter(CachePath);
tw.WriteLine("0 = " + uiValues[0]);
tw.WriteLine("1 = " + uiValues[1]);
tw.WriteLine("2 = " + uiValues[2]);
tw.WriteLine("3 = " + uiValues[3]);
tw.WriteLine("4 = " + uiValues[4]);
tw.WriteLine("5 = " + uiValues[5]);
tw.WriteLine("6 = " + uiValues[6]);
tw.WriteLine("7 = " + uiValues[7]);
tw.WriteLine("8 = " + uiValues[8]);
tw.WriteLine("9 = " + uiValues[9]);
tw.WriteLine("10 = " + uiValues[10]);
tw.WriteLine("11 = " + uiValues[11]);
tw.WriteLine("12 = " + uiValues[12]);
tw.WriteLine("skyTmpg = " + skyTonemappingUi);
tw.Close();
}
public void LoadCache()
{
if (!File.Exists(CachePath))
SaveCache();
string[] lines = File.ReadAllLines(CachePath);
var dict = new Dictionary<int, float>();
foreach (string line in lines.Where(s => s.Contains(" = ")))
{
string[] data = line.Split(new string[] { " = " }, StringSplitOptions.RemoveEmptyEntries);
if (data[0] == "skyTmpg")
{
skyTonemappingUi = bool.Parse(data[1]);
oldSkyTonemappingUi = skyTonemappingUi;
}
else
{
var id = int.Parse(data[0]);
dict[id] = 0;
dict[id] = float.Parse(data[1]);
}
}
uiValues = new float[]
{
dict[0], dict[1], dict[2], dict[3], dict[4], dict[5], dict[6], dict[7], dict[8], dict[9], dict[10], dict[11], dict[12]
};
oldValues = new float[]
{
dict[0], dict[1], dict[2], dict[3], dict[4], dict[5], dict[6], dict[7], dict[8], dict[9], dict[10], dict[11], dict[12]
};
}
public void LoadPreset(LightPreset preset)
{
uiValues = new float[]
{
preset.m_values[0], preset.m_values[1], preset.m_values[2], preset.m_values[3], preset.m_values[4], preset.m_values[5], preset.m_values[6], preset.m_values[7], preset.m_values[8], preset.m_values[9], preset.m_values[10], preset.m_values[11], preset.m_values[12]
};
oldValues = new float[]
{
preset.m_values[0], preset.m_values[1], preset.m_values[2], preset.m_values[3], preset.m_values[4], preset.m_values[5], preset.m_values[6], preset.m_values[7], preset.m_values[8], preset.m_values[9], preset.m_values[10], preset.m_values[11], preset.m_values[12]
};
skyTonemappingUi = preset.m_skyTonemapping;
oldSkyTonemappingUi = preset.m_skyTonemapping;
CalculateAll(preset.m_values, preset.m_skyTonemapping);
SaveCache();
}
public void CreatePreset()
{
LightPreset preset = new LightPreset();
preset.m_presetName = nameTextfield;
preset.m_values = new float[]
{
uiValues[0], uiValues[1], uiValues[2], uiValues[3], uiValues[4], uiValues[5], uiValues[6], uiValues[7], uiValues[8], uiValues[9], uiValues[10], uiValues[11], uiValues[12]
};
preset.m_canBeDeleted = true;
preset.m_skyTonemapping = skyTonemappingUi;
preset.SavePreset(true);
}
private void AllToZero()
{
uiValues = new float[]
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
oldValues = new float[]
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
skyTonemappingUi = true;
oldSkyTonemappingUi = skyTonemappingUi;
SaveCache();
CalculateAll(uiValues, skyTonemappingUi);
}
#region RONYX PART (LOGIC)
// Intensity Tweak
private static float tweak_Intensity = 1.90f;
// Time
private static float time_Sunrise1 = 0.23f;
private static float time_Sunrise2 = 0.27f;
private static float time_Early = 0.40f;
private static float time_Late = 0.60f;
private static float time_Sunset1 = 0.74f;
private static float time_Sunset2 = 0.76f;
// Placeholder Color
private static Color initcolor = new Color(1f, 1f, 1f, 1f);
// Lighting gradients, that will be edited and assigned, instead of creating new ones every time.
private static Gradient gradient_Direct = new Gradient
{
colorKeys = new GradientColorKey[] {
new GradientColorKey(initcolor, time_Sunrise1),
new GradientColorKey(initcolor, time_Sunrise2),
new GradientColorKey(initcolor, time_Early),
new GradientColorKey(initcolor, time_Late),
new GradientColorKey(initcolor, time_Sunset1),
new GradientColorKey(initcolor, time_Sunset2),
},
alphaKeys = new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
};
private static Gradient gradient_Sky = new Gradient
{
colorKeys = new GradientColorKey[] {
new GradientColorKey(initcolor, time_Sunrise1),
new GradientColorKey(initcolor, time_Sunrise2),
new GradientColorKey(initcolor, time_Early),
new GradientColorKey(initcolor, time_Late),
new GradientColorKey(initcolor, time_Sunset1),
new GradientColorKey(initcolor, time_Sunset2),
},
alphaKeys = new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
};
private static Gradient gradient_Equator = new Gradient
{
colorKeys = new GradientColorKey[] {
new GradientColorKey(initcolor, time_Sunrise1),
new GradientColorKey(initcolor, time_Sunrise2),
new GradientColorKey(initcolor, time_Early),
new GradientColorKey(initcolor, time_Late),
new GradientColorKey(initcolor, time_Sunset1),
new GradientColorKey(initcolor, time_Sunset2),
},
alphaKeys = new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
};
private static Gradient gradient_Ground = new Gradient
{
colorKeys = new GradientColorKey[] {
new GradientColorKey(initcolor, time_Sunrise1),
new GradientColorKey(initcolor, time_Sunrise2),
new GradientColorKey(initcolor, time_Early),
new GradientColorKey(initcolor, time_Late),
new GradientColorKey(initcolor, time_Sunset1),
new GradientColorKey(initcolor, time_Sunset2),
},
alphaKeys = new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
};
public static void CalculateLighting(float temperature, float tint, float sunTemp, float sunTint, float skyTemp, float skyTint, float moonTemp, float moonTint, float moonLight, float twilightTint)
{
// Day/Night Value
var mult_Day = 1.00f * tweak_Intensity;
var mult_Night = 0.32f * (1 + (0.7f * moonLight)) * tweak_Intensity;
var mult_Twilight = ((mult_Day * 2) + mult_Night) / 3f;
// Light Value
var mult_Ambient = 0.60f;
var mult_Sun = 0.25f;
var mult_Moon = 0.20f;
var mult_Sky = 0.95f;
var mult_Equator = 0.85f;
var mult_Ground = 0.65f;
// Main
var mult_Temperature = temperature;
var mult_Tint = tint;
var tint_Twilight = 0.08f * (twilightTint + 1);
var temp_Sun = sunTemp;
var temp_Moon = -moonTemp;
var temp_Ambient = -skyTemp;
var tint_Sun = sunTint;
var tint_Moon = moonTint;
var tint_Ambient = skyTint;
// Overall Temperature and Tint
var calc_tempMultR = 1 + (0.1f * mult_Temperature);
var calc_tempMultB = 1 - (0.1f * mult_Temperature);
var calc_tintMult = 1 + (0.1f * mult_Tint);
// Sun Temperature and Tint
var calc_tempOffset_Sun = (((temp_Sun + 1) * 0.5f) * 0.05f);
var calc_tintOffset_Sun = ((tint_Sun * 0.5f) * 0.05f);
// Moon Temperature and Tint
var calc_tempOffset_Moon = (((temp_Moon + 1) * 0.5f) * 0.1f);
var calc_tintOffset_Moon = ((tint_Moon * 0.5f) * 0.06f);
// Ambient Temperature and Tint
var calc_tempOffset_Sky = (((temp_Ambient + 1) * 0.5f) * 0.23f);
var calc_tempOffset_Equator = (((temp_Ambient + 1) * 0.5f) * 0.18f);
var calc_tempOffset_Ground = (((temp_Ambient + 1) * 0.5f) * 0.13f);
var calc_tintOffset_Ambient = tint_Ambient * 0.06f;
// Value Day
var calc_SunDay = mult_Sun * mult_Day;
var calc_SkyDay = mult_Sky * mult_Day * mult_Ambient;
var calc_EquatorDay = mult_Equator * mult_Day * mult_Ambient;
var calc_GroundDay = mult_Ground * mult_Day * mult_Ambient;
// Value Night
var calc_MoonNight = mult_Moon * mult_Night;
var calc_SkyNight = mult_Sky * mult_Night * mult_Ambient;
var calc_EquatorNight = mult_Equator * mult_Night * mult_Ambient;
var calc_GroundNight = mult_Ground * mult_Night * mult_Ambient;
// Value Twilight
var calc_SunTwilight = mult_Moon * mult_Twilight;
var calc_SkyTwilight = mult_Sky * mult_Twilight * mult_Ambient * 1.2f;
var calc_EquatorTwilight = mult_Equator * mult_Twilight * mult_Ambient * 1.2f;
var calc_GroundTwilight = mult_Ground * mult_Twilight * mult_Ambient * 1.2f;
// Day Colors
Color color_Direct_Day = new Color(
(calc_SunDay + (0.92f * calc_tempOffset_Sun)) * calc_tempMultR,
(calc_SunDay + calc_tintOffset_Sun) * calc_tintMult,
(calc_SunDay - calc_tempOffset_Sun) * calc_tempMultB,
1f);
Color color_Sky_Day = new Color(
(calc_SkyDay - calc_tempOffset_Sky) * calc_tempMultR,
(calc_SkyDay + calc_tintOffset_Ambient) * calc_tintMult,
(calc_SkyDay + (0.92f * calc_tempOffset_Sky)) * calc_tempMultB,
1f);
Color color_Equator_Day = new Color(
(calc_EquatorDay - calc_tempOffset_Equator) * calc_tempMultR,
(calc_EquatorDay + calc_tintOffset_Ambient) * calc_tintMult,
(calc_EquatorDay + (0.92f * calc_tempOffset_Equator)) * calc_tempMultB,
1f);
Color color_Ground_Day = new Color(
(calc_GroundDay - calc_tempOffset_Ground) * calc_tempMultR,
(calc_GroundDay + calc_tintOffset_Ambient) * calc_tintMult,
(calc_GroundDay + (0.92f * calc_tempOffset_Ground)) * calc_tempMultB,
1f);
// Night Colors
Color color_Direct_Night = new Color(
(calc_MoonNight - calc_tempOffset_Moon) * calc_tempMultR,
(calc_MoonNight + calc_tintOffset_Moon) * calc_tintMult,
(calc_MoonNight + calc_tempOffset_Moon) * calc_tempMultB,
1f);
Color color_Sky_Night = new Color(
(calc_SkyNight - calc_tempOffset_Sky) * calc_tempMultR,
(calc_SkyNight + calc_tintOffset_Ambient) * calc_tintMult,
(calc_SkyNight + (0.92f * calc_tempOffset_Sky)) * calc_tempMultB,
1f);
Color color_Equator_Night = new Color(
(calc_EquatorNight - calc_tempOffset_Equator) * calc_tempMultR,
(calc_EquatorNight + calc_tintOffset_Ambient) * calc_tintMult,
(calc_EquatorNight + (0.92f * calc_tempOffset_Equator)) * calc_tempMultB,
1f);
Color color_Ground_Night = new Color(
(calc_GroundNight - calc_tempOffset_Ground) * calc_tempMultR,
(calc_GroundNight + calc_tintOffset_Ambient) * calc_tintMult,
(calc_GroundNight + (0.92f * calc_tempOffset_Ground)) * calc_tempMultB,
1f);
// Twilight Colors
Color color_Direct_Twilight = new Color(
(calc_SunTwilight + calc_tempOffset_Sun + tint_Twilight) * calc_tempMultR,
(calc_SunTwilight + calc_tintOffset_Sun) * calc_tintMult,
(calc_SunTwilight - calc_tempOffset_Sun - tint_Twilight) * calc_tempMultB,
1f);
Color color_Sky_Twilight = new Color(
(calc_SkyTwilight - calc_tempOffset_Sky - tint_Twilight) * calc_tempMultR,
(calc_SkyTwilight + calc_tintOffset_Ambient - (0.1f * tint_Twilight)) * calc_tintMult,
(calc_SkyTwilight + calc_tempOffset_Sky + tint_Twilight) * calc_tempMultB,
1f);
Color color_Equator_Twilight = new Color(
(calc_EquatorTwilight - calc_tempOffset_Equator - tint_Twilight) * calc_tempMultR,
(calc_EquatorTwilight + calc_tintOffset_Ambient - (0.1f * tint_Twilight)) * calc_tintMult,
(calc_EquatorTwilight + calc_tempOffset_Equator + tint_Twilight) * calc_tempMultB,
1f);
Color color_Ground_Twilight = new Color(
(calc_GroundTwilight - calc_tempOffset_Ground - tint_Twilight) * calc_tempMultR,
(calc_GroundTwilight + calc_tintOffset_Ambient - (0.1f * tint_Twilight)) * calc_tintMult,
(calc_GroundTwilight + calc_tempOffset_Ground + tint_Twilight) * calc_tempMultB,
1f);
// Updating the colors for the gradients.
GradientAlphaKey[] gradientAlphaKeys = new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) };
GradientColorKey[] gradientColorKeys_Direct = new GradientColorKey[] {
new GradientColorKey(color_Direct_Night, time_Sunrise1),
new GradientColorKey(color_Direct_Twilight, time_Sunrise2),
new GradientColorKey(color_Direct_Day, time_Early),
new GradientColorKey(color_Direct_Day, time_Late),
new GradientColorKey(color_Direct_Twilight, time_Sunset1),
new GradientColorKey(color_Direct_Night, time_Sunset2), };
gradient_Direct.SetKeys(gradientColorKeys_Direct, gradientAlphaKeys);
GradientColorKey[] gradientColorKeys_Sky = new GradientColorKey[] {
new GradientColorKey(color_Sky_Night, time_Sunrise1),
new GradientColorKey(color_Sky_Twilight, time_Sunrise2),
new GradientColorKey(color_Sky_Day, time_Early),
new GradientColorKey(color_Sky_Day, time_Late),
new GradientColorKey(color_Sky_Twilight, time_Sunset1),
new GradientColorKey(color_Sky_Night, time_Sunset2), };
gradient_Sky.SetKeys(gradientColorKeys_Sky, gradientAlphaKeys);
GradientColorKey[] gradientColorKeys_Equator = new GradientColorKey[] {
new GradientColorKey(color_Equator_Night, time_Sunrise1),
new GradientColorKey(color_Equator_Twilight, time_Sunrise2),
new GradientColorKey(color_Equator_Day, time_Early),
new GradientColorKey(color_Equator_Day, time_Late),
new GradientColorKey(color_Equator_Twilight, time_Sunset1),
new GradientColorKey(color_Equator_Night, time_Sunset2), };
gradient_Equator.SetKeys(gradientColorKeys_Equator, gradientAlphaKeys);
GradientColorKey[] gradientColorKeys_Ground = new GradientColorKey[] {
new GradientColorKey(color_Ground_Night, time_Sunrise1),
new GradientColorKey(color_Ground_Twilight, time_Sunrise2),
new GradientColorKey(color_Ground_Day, time_Early),
new GradientColorKey(color_Ground_Day, time_Late),
new GradientColorKey(color_Ground_Twilight, time_Sunset1),
new GradientColorKey(color_Ground_Night, time_Sunset2), };
gradient_Ground.SetKeys(gradientColorKeys_Ground, gradientAlphaKeys);
// Assigning the new color gradients.
UnityEngine.Object.FindObjectOfType<DayNightProperties>().m_LightColor = gradient_Direct;
var ambient = typeof(DayNightProperties.AmbientColor);
ambient.GetField("m_SkyColor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(DayNightProperties.instance.m_AmbientColor, gradient_Sky);
ambient.GetField("m_EquatorColor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(DayNightProperties.instance.m_AmbientColor, gradient_Equator);
ambient.GetField("m_GroundColor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(DayNightProperties.instance.m_AmbientColor, gradient_Ground);
}
public static void CalculateTonemapping(float brightness, float gamma, float contrast)
{
var calc_Contrast = contrast * 1.4f;
var toneMap = GameObject.Find("Main Camera").GetComponent<ColossalFramework.ToneMapping>();
toneMap.m_Luminance = 0.10f + (calc_Contrast * 0.013f);
toneMap.m_ToneMappingBoostFactor = (1.00f + (0.5f * brightness)) / (float)Math.Pow(tweak_Intensity, 2.2f);
toneMap.m_ToneMappingGamma = 2.60f * (((gamma + 1) / 4) + 0.75f);
toneMap.m_ToneMappingParamsFilmic.A = 0.50f + (calc_Contrast * 0.13f);
toneMap.m_ToneMappingParamsFilmic.B = 0.25f - (calc_Contrast * 0.08f);
toneMap.m_ToneMappingParamsFilmic.C = 0.10f - (calc_Contrast * 0.005f);
toneMap.m_ToneMappingParamsFilmic.D = 0.70f + (calc_Contrast * 0.13f);
toneMap.m_ToneMappingParamsFilmic.E = 0.01f;
toneMap.m_ToneMappingParamsFilmic.F = 0.25f - (calc_Contrast * 0.11f);
toneMap.m_ToneMappingParamsFilmic.W = 11.20f + calc_Contrast;
}
public static void SkyTonemapping(bool enable)
{
var daynight = UnityEngine.Object.FindObjectOfType<DayNightProperties>();
daynight.m_Tonemapping = enable;
}
#endregion
}
}
public class LightPreset
{
public LightPreset() { }
public float[] m_values;
public bool m_skyTonemapping, m_canBeDeleted;
public string m_presetName, m_filePath;
public void SavePreset(bool addToPresetsList)
{
string path = DataLocation.localApplicationData + @"\ModConfig\RelightPresets\";
if (!Directory.Exists(DataLocation.localApplicationData + @"\ModConfig\"))
Directory.CreateDirectory(DataLocation.localApplicationData + @"\ModConfig\");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
this.m_canBeDeleted = true;
this.m_filePath = path + ToFileName(this.m_presetName) + ".light";
TextWriter tw = new StreamWriter(this.m_filePath);
tw.WriteLine("name = " + ((this.m_presetName == "") ? "[none]" : this.m_presetName));
tw.WriteLine("0 = " + this.m_values[0]);
tw.WriteLine("1 = " + this.m_values[1]);
tw.WriteLine("2 = " + this.m_values[2]);
tw.WriteLine("3 = " + this.m_values[3]);
tw.WriteLine("4 = " + this.m_values[4]);
tw.WriteLine("5 = " + this.m_values[5]);
tw.WriteLine("6 = " + this.m_values[6]);
tw.WriteLine("7 = " + this.m_values[7]);
tw.WriteLine("8 = " + this.m_values[8]);
tw.WriteLine("9 = " + this.m_values[9]);
tw.WriteLine("10 = " + this.m_values[10]);
tw.WriteLine("11 = " + this.m_values[11]);
tw.WriteLine("12 = " + this.m_values[12]);
tw.WriteLine("skyTmpg = " + this.m_skyTonemapping);
tw.Close();
if (addToPresetsList)
LightPresets.Add(this);
}
public static void LoadLightPresets()
{
LightPresets = new List<LightPreset>();
string path = DataLocation.localApplicationData + @"\ModConfig\RelightPresets\";
if (!Directory.Exists(DataLocation.localApplicationData + @"\ModConfig\"))
Directory.CreateDirectory(DataLocation.localApplicationData + @"\ModConfig\");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
foreach (string file in Directory.GetFiles(path, "*.light", SearchOption.AllDirectories))
{
var preset = new LightPreset();
preset.m_presetName = "[none]";
preset.m_canBeDeleted = true;
preset.m_filePath = file;
var dict = new Dictionary<int, float>();
foreach (string line in File.ReadAllLines(file).Where(s => s.Contains(" = ")))
{
string[] data = line.Split(new string[] { " = " }, StringSplitOptions.RemoveEmptyEntries);
if (data[0] == "skyTmpg")
{
preset.m_skyTonemapping = bool.Parse(data[1]);
}
else if (data[0] == "name")
{
preset.m_presetName = data[1];
}
else
{
var id = int.Parse(data[0]);
dict[id] = 0;
dict[id] = float.Parse(data[1]);
}
}
preset.m_values = new float[]
{
dict[0], dict[1], dict[2], dict[3], dict[4], dict[5], dict[6], dict[7], dict[8], dict[9], dict[10], dict[11], dict[12]
};
LightPresets.Add(preset);
}
foreach (PublishedFileId fileId in PlatformService.workshop.GetSubscribedItems())
{
string fileDir = PlatformService.workshop.GetSubscribedItemPath(fileId);
if (fileDir == null)
continue;
if (fileDir == "")
continue;
if (!Directory.Exists(fileDir))
continue;
var files = Directory.GetFiles(fileDir, "*.light", SearchOption.AllDirectories);
if (files.Any())
{
foreach (string file in files)
{
var preset = new LightPreset();
preset.m_presetName = "[none]";
preset.m_canBeDeleted = false;
var dict = new Dictionary<int, float>();
foreach (string line in File.ReadAllLines(file).Where(s => s.Contains(" = ")))
{
string[] data = line.Split(new string[] { " = " }, StringSplitOptions.RemoveEmptyEntries);
if (data[0] == "skyTmpg")
{
preset.m_skyTonemapping = bool.Parse(data[1]);
}
else if (data[0] == "name")
{
preset.m_presetName = data[1];
}
else
{
var id = int.Parse(data[0]);
dict[id] = 0;
dict[id] = float.Parse(data[1]);
}
}
preset.m_values = new float[]
{
dict[0], dict[1], dict[2], dict[3], dict[4], dict[5], dict[6], dict[7], dict[8], dict[9], dict[10], dict[11], dict[12]
};
LightPresets.Add(preset);
}
}
}
}
public static void DeletePreset(LightPreset preset)
{
if (preset.m_canBeDeleted)
{
if (File.Exists(preset.m_filePath))
File.Delete(preset.m_filePath);
if (LightPresets.Contains(preset))
LightPresets.Remove(preset);
}
}
public static List<LightPreset> LightPresets;
public static string ToFileName(string s)
{
return s.Replace(" ", "_").Replace(@"\", "").Replace("/", "").Replace("|", "").Replace("<", "").Replace(">", "").Replace("*", "").Replace(":", "").Replace("?", "").Replace("\"", "");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment