-
-
Save taibenvenuti/bf5f6e7a54ba26527b69d3730522a3a7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ColossalFramework.IO; | |
using ColossalFramework.Plugins; | |
using ColossalFramework.UI; | |
using ICities; | |
using System; | |
using System.IO; | |
using System.Reflection; | |
using System.Xml.Serialization; | |
using UnityEngine; | |
namespace PloppableAsphalt | |
{ | |
public class PloppableAsphaltMod : IUserMod | |
{ | |
public string Name | |
{ | |
get | |
{ | |
if (!Settings.AutoDeployed) | |
{ | |
foreach (var plugin in PluginManager.instance.GetPluginsInfo()) | |
{ | |
if (plugin.isEnabled) | |
{ | |
continue; | |
} | |
if (plugin.publishedFileID.AsUInt64 == 881291183u && !plugin.isEnabled) | |
{ | |
plugin.isEnabled = true; | |
Settings.AutoDeployed = true; | |
} | |
} | |
} | |
return "Ploppable Asphalt"; | |
} | |
} | |
public string Description => "Adds ploppable asphalt props."; | |
private static Configuration settings; | |
public static Configuration Settings | |
{ | |
get | |
{ | |
if (settings == null) | |
{ | |
settings = Configuration.LoadConfiguration(); | |
if (settings == null) | |
{ | |
settings = new Configuration(); | |
Configuration.SaveConfiguration(); | |
} | |
} | |
return settings; | |
} | |
set | |
{ | |
settings = value; | |
} | |
} | |
#region UserInterface | |
private float sliderWidth = 700f; | |
private float sliderHeight = 10f; | |
private float labelSize = 1.2f; | |
private string toolTipText = "Hold SHIFT to drag all sliders"; | |
private UISlider redSlider; | |
private UISlider greenSlider; | |
private UISlider blueSlider; | |
private UITextField redLabel; | |
private UITextField greenLabel; | |
private UITextField blueLabel; | |
private static void UpdateSlider(UISlider slider, UITextField textField, float value) | |
{ | |
slider.value = value; | |
textField.text = value.ToString(); | |
} | |
public void OnSettingsUI(UIHelperBase helper) | |
{ | |
UIHelperBase sliderGroup = helper.AddGroup("\t\t\t\t\t\t RGB Values"); | |
sliderGroup.AddSpace(40); | |
redLabel = (UITextField)sliderGroup.AddTextfield(" ", Settings.AsphaltColor.r.ToString(), (t) => { }, (t) => { }); | |
redLabel.disabledTextColor = Color.red; | |
redLabel.textScale = labelSize; | |
redLabel.Disable(); | |
redSlider = (UISlider)sliderGroup.AddSlider(" ", 0f, 255f, 1f, Settings.AsphaltColor.r, (f) => | |
{ | |
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) | |
{ | |
var difference = f - Settings.AsphaltColor.r; | |
var green = Settings.AsphaltColor.g; | |
var blue = Settings.AsphaltColor.b; | |
if (blue + difference >= 0 && blue + difference <= 255) | |
{ | |
UpdateSlider(blueSlider, blueLabel, blue + difference); | |
Settings.AsphaltColor.b = blue + difference; | |
} | |
if (green + difference >= 0 && green + difference <= 255) | |
{ | |
UpdateSlider(greenSlider, greenLabel, green + difference); | |
Settings.AsphaltColor.g = green + difference; | |
} | |
redSlider.tooltipBox.isVisible = false; | |
} | |
else redSlider.tooltipBox.isVisible = true; | |
Settings.AsphaltColor.r = f; | |
UpdateSlider(redSlider, redLabel, f); | |
PloppableAsphalt.ApplyColors(); | |
}); | |
redSlider.color = Color.red; | |
redSlider.tooltip = toolTipText; | |
redSlider.scrollWheelAmount = 1f; | |
redSlider.width = sliderWidth; | |
redSlider.height = sliderHeight; | |
UpdateSlider(redSlider, redLabel, Settings.AsphaltColor.r); | |
sliderGroup.AddSpace(65); | |
greenLabel = (UITextField)sliderGroup.AddTextfield(" ", Settings.AsphaltColor.g.ToString(), (t) => { }, (t) => { }); | |
greenLabel.disabledTextColor = Color.green; | |
greenLabel.textScale = labelSize; | |
greenLabel.Disable(); | |
greenSlider = (UISlider)sliderGroup.AddSlider(" ", 0f, 255f, 1f, Settings.AsphaltColor.g, (f) => | |
{ | |
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) | |
{ | |
var difference = f - Settings.AsphaltColor.g; | |
var red = Settings.AsphaltColor.r; | |
var blue = Settings.AsphaltColor.b; | |
if (red + difference >= 0 && red + difference <= 255) | |
{ | |
UpdateSlider(redSlider, redLabel, red + difference); | |
Settings.AsphaltColor.r = red + difference; | |
} | |
if (blue + difference >= 0 && blue + difference <= 255) | |
{ | |
UpdateSlider(blueSlider, blueLabel, blue + difference); | |
Settings.AsphaltColor.b = blue + difference; | |
} | |
greenSlider.tooltipBox.isVisible = false; | |
} | |
else greenSlider.tooltipBox.isVisible = true; | |
greenSlider.RefreshTooltip(); | |
Settings.AsphaltColor.g = f; | |
UpdateSlider(greenSlider, greenLabel, f); | |
PloppableAsphalt.ApplyColors(); | |
}); | |
greenSlider.color = Color.green; | |
greenSlider.tooltip = toolTipText; | |
greenSlider.scrollWheelAmount = 1f; | |
greenSlider.width = sliderWidth; | |
greenSlider.height = sliderHeight; | |
UpdateSlider(greenSlider, greenLabel, Settings.AsphaltColor.g); | |
sliderGroup.AddSpace(65); | |
blueLabel = (UITextField)sliderGroup.AddTextfield(" ", Settings.AsphaltColor.b.ToString(), (t) => { }, (t) => { }); | |
blueLabel.disabledTextColor = Color.blue; | |
blueLabel.textScale = labelSize; | |
blueLabel.Disable(); | |
blueSlider = (UISlider)sliderGroup.AddSlider(" ", 0f, 255f, 1f, Settings.AsphaltColor.b, (f) => | |
{ | |
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) | |
{ | |
var difference = f - Settings.AsphaltColor.b; | |
var red = Settings.AsphaltColor.r; | |
var green = Settings.AsphaltColor.g; | |
if (red + difference >= 0 && red + difference <= 255) | |
{ | |
UpdateSlider(redSlider, redLabel, red + difference); | |
Settings.AsphaltColor.r = red + difference; | |
} | |
if (green + difference >= 0 && green + difference <= 255) | |
{ | |
UpdateSlider(greenSlider, greenLabel, green + difference); | |
Settings.AsphaltColor.g = green + difference; | |
} | |
blueSlider.tooltipBox.isVisible = false; | |
} | |
else blueSlider.tooltipBox.isVisible = true; | |
blueSlider.RefreshTooltip(); | |
Settings.AsphaltColor.b = f; | |
UpdateSlider(blueSlider, blueLabel, f); | |
PloppableAsphalt.ApplyColors(); | |
}); | |
blueSlider.color = Color.blue; | |
blueSlider.tooltip = toolTipText; | |
blueSlider.scrollWheelAmount = 1f; | |
blueSlider.width = sliderWidth; | |
blueSlider.height = sliderHeight; | |
UpdateSlider(blueSlider, blueLabel, Settings.AsphaltColor.b); | |
sliderGroup.AddSpace(143); | |
} | |
#endregion | |
} | |
public class Configuration | |
{ | |
[XmlIgnore] | |
private static readonly string configurationPath = Path.Combine(DataLocation.localApplicationData, "PloppableAsphalt.xml"); | |
public Color AsphaltColor = new Color(128f, 128f, 128f, 1f); | |
public bool AutoDeployed = false; | |
public Configuration() { } | |
public void OnPreSerialize() { } | |
public void OnPostDeserialize() { } | |
public static void SaveConfiguration() | |
{ | |
var fileName = configurationPath; | |
var config = PloppableAsphaltMod.Settings; | |
var serializer = new XmlSerializer(typeof(Configuration)); | |
using (var writer = new StreamWriter(fileName)) | |
{ | |
config.OnPreSerialize(); | |
serializer.Serialize(writer, config); | |
} | |
} | |
public static Configuration LoadConfiguration() | |
{ | |
var fileName = configurationPath; | |
var serializer = new XmlSerializer(typeof(Configuration)); | |
try | |
{ | |
using (var reader = new StreamReader(fileName)) | |
{ | |
var config = serializer.Deserialize(reader) as Configuration; | |
return config; | |
} | |
} | |
catch (Exception ex) | |
{ | |
Debug.Log(string.Format("[Ploppable Asphalt]: Error Parsing {0}: {1}", fileName, ex.Message.ToString())); | |
return null; | |
} | |
} | |
} | |
public class PloppableAsphaltLoading : LoadingExtensionBase | |
{ | |
public override void OnLevelUnloading() | |
{ | |
base.OnLevelUnloading(); | |
PloppableAsphalt.Loaded = false; | |
} | |
} | |
public class PloppableAsphaltThreading : ThreadingExtensionBase | |
{ | |
public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) | |
{ | |
base.OnUpdate(realTimeDelta, simulationTimeDelta); | |
if (!PloppableAsphalt.Loaded && LoadingManager.instance.m_loadingComplete) | |
{ | |
PloppableAsphalt.ApplyProperties(); | |
PloppableAsphalt.Loaded = true; | |
} | |
} | |
} | |
public class PloppableAsphalt | |
{ | |
public static bool Loaded; | |
private static Color marker = new Color(7f / 255, 42f / 255, 69f / 255, 1f); //marker used for detecting asphalt props for the first time | |
private static Shader shader; //will be used to contain the magic shader, but also will be used as a marker once the colors get replaced | |
internal static void ApplyProperties() | |
{ | |
shader = Shader.Find("Custom/Net/RoadBridge"); //the magic shader | |
for (uint i = 0; i < PrefabCollection<PropInfo>.LoadedCount(); i++) | |
{ | |
var prefab = PrefabCollection<PropInfo>.GetLoaded(i); | |
if (prefab == null) continue; | |
if (prefab.m_color0 == marker && prefab.m_color1 == marker && prefab.m_color2 == marker && prefab.m_color3 == marker) | |
{ | |
//get ACI textures, to be used as APR textures | |
Texture texture2D = new Texture2D(1, 1); | |
Texture texture2Dlod = new Texture2D(1, 1); | |
texture2D = (prefab.m_material.GetTexture("_ACIMap") as Texture2D); | |
texture2Dlod = (prefab.m_lodMaterial.GetTexture("_ACIMap") as Texture2D); | |
//change the shader | |
if (prefab.m_material != null) prefab.m_material.shader = shader; | |
if (prefab.m_lodMaterial != null) prefab.m_lodMaterial.shader = shader; | |
//add the ACI textures as APR textures | |
prefab.m_material.SetTexture("_APRMap", texture2D); | |
prefab.m_lodMaterial.SetTexture("_APRMap", texture2Dlod); | |
//set high render distance | |
//adaptive prop visibility distance mod will override this if you change the settings of that mod ingame :/ | |
prefab.m_lodRenderDistance = 100; | |
prefab.m_maxRenderDistance = 18000; | |
prefab.m_lodMaterialCombined = null; | |
prefab.m_generatedInfo.m_size.z = prefab.m_generatedInfo.m_size.z * 2.174f; | |
if (prefab.m_generatedInfo.m_size.y < 16) prefab.m_generatedInfo.m_size.y = 16f; | |
ApplyColors(); | |
} | |
} | |
} | |
internal static void AgainApplyProperties() | |
{ | |
shader = Shader.Find("Custom/Net/RoadBridge"); //the magic shader | |
for (uint i = 0; i < PrefabCollection<PropInfo>.LoadedCount(); i++) | |
{ | |
var prefab = PrefabCollection<PropInfo>.GetLoaded(i); | |
if (prefab == null) continue; | |
if (prefab.m_material.shader == shader) | |
{ | |
//get ACI textures, to be used as APR textures | |
Texture texture2Dlod = new Texture2D(1, 1); | |
texture2Dlod = (prefab.m_lodMaterial.GetTexture("_ACIMap") as Texture2D); | |
//change the shader | |
if (prefab.m_lodMaterial != null) prefab.m_lodMaterial.shader = shader; | |
//add the ACI textures as APR textures | |
prefab.m_lodMaterial.SetTexture("_APRMap", texture2Dlod); | |
//set high render distance | |
//adaptive prop visibility distance mod will override this if you change the settings of that mod ingame :/ | |
prefab.m_lodRenderDistance = 100; | |
prefab.m_maxRenderDistance = 18000; | |
prefab.m_lodMaterialCombined = null; | |
if (prefab.m_generatedInfo.m_size.y < 16) prefab.m_generatedInfo.m_size.y = 16f; | |
} | |
} | |
} | |
internal static void ApplyColors() //change the color variation for the props, slider adjustment should only call this | |
{ | |
for (uint i = 0; i < PrefabCollection<PropInfo>.LoadedCount(); i++) | |
{ | |
var rgb = PloppableAsphaltMod.Settings.AsphaltColor; | |
var prefab = PrefabCollection<PropInfo>.GetLoaded(i); | |
var color = new Color(rgb.r / 255, rgb.g / 255, rgb.b / 255); | |
if (prefab == null) continue; | |
if (prefab.m_material.shader == shader) | |
{ | |
prefab.m_color0 = color; prefab.m_color1 = color; | |
prefab.m_color2 = color; prefab.m_color3 = color; | |
} | |
} | |
Configuration.SaveConfiguration(); | |
AgainApplyProperties(); | |
} | |
} | |
public class DisableBlur : ThreadingExtensionBase | |
{ | |
private UIComponent component; | |
public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) | |
{ | |
if (component == null) component = UIView.library.Get("OptionsPanel"); | |
if (component != null && component.isVisible) | |
{ | |
UITextureSprite uITextureSprite = Util.ReadPrivate<DesaturationControl, UITextureSprite>(UnityEngine.Object.FindObjectOfType<DesaturationControl>(), "m_Target"); | |
if (uITextureSprite.opacity != 0f) | |
{ | |
uITextureSprite.opacity = 0f; | |
Util.WritePrivate<DesaturationControl, UITextureSprite>(UnityEngine.Object.FindObjectOfType<DesaturationControl>(), "m_Target", uITextureSprite); | |
} | |
} | |
} | |
} | |
public static class Util | |
{ | |
public static Q ReadPrivate<T, Q>(T o, string fieldName) | |
{ | |
FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | |
FieldInfo fieldInfo = null; | |
FieldInfo[] array = fields; | |
for (int i = 0; i < array.Length; i++) | |
{ | |
FieldInfo fieldInfo2 = array[i]; | |
if (fieldInfo2.Name == fieldName) | |
{ | |
fieldInfo = fieldInfo2; | |
break; | |
} | |
} | |
return (Q)((object)fieldInfo.GetValue(o)); | |
} | |
public static void WritePrivate<T, Q>(T o, string fieldName, object value) | |
{ | |
FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); | |
FieldInfo fieldInfo = null; | |
FieldInfo[] array = fields; | |
for (int i = 0; i < array.Length; i++) | |
{ | |
FieldInfo fieldInfo2 = array[i]; | |
if (fieldInfo2.Name == fieldName) | |
{ | |
fieldInfo = fieldInfo2; | |
break; | |
} | |
} | |
fieldInfo.SetValue(o, value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment