Last active
September 8, 2017 17:02
-
-
Save ronyx69/b2e77772c5df261cb1ca8267bfe33bcb 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 System; | |
using System.Collections.Generic; | |
using System.Text.RegularExpressions; | |
using System.Linq; | |
using System.Text; | |
using System.Reflection; | |
using ICities; | |
using UnityEngine; | |
namespace LightEffects | |
{ | |
public class LightEffectsMod : LoadingExtensionBase, IUserMod | |
{ | |
public string Name => "Custom Light Effects"; | |
public string Description => "Loads custom light effects for props."; | |
public override void OnLevelLoaded(LoadMode mode) | |
{ | |
base.OnLevelLoaded(mode); | |
ApplyParams(); | |
} | |
public override void OnLevelUnloading() | |
{ | |
base.OnLevelUnloading(); | |
} | |
private void ApplyParams() | |
{ | |
List<string> propList = new List<string>(); | |
for (uint i = 0; i < PrefabCollection<PropInfo>.LoadedCount(); i++) | |
{ | |
var asset = PrefabCollection<PropInfo>.GetLoaded(i); | |
if (asset == null) continue; | |
if (asset.m_lodMesh == null) continue; | |
if (asset.m_lodMesh.name.Contains("LightEffect") == true) | |
{ | |
var maxRange = 0f; | |
var isInfinite = false; | |
string[] slots = asset.m_lodMesh.name.Split('#'); | |
if (asset.m_effects.Length < slots.Length) Array.Resize(ref asset.m_effects, slots.Length); | |
for (uint j = 0; j < slots.Length; j++) | |
{ | |
string[] data = slots[j].Split(' '); | |
if (data[1].Contains("_") == true) // check data[1] for '_' indicated by a vanilla effect | |
{ | |
string effectName = data[1]; | |
effectName = effectName.Replace('_', ' '); | |
var existingLightEffect = EffectCollection.FindEffect(effectName) as LightEffect; | |
var position = new Vector3(Convert.ToSingle(data[2]), Convert.ToSingle(data[3]), Convert.ToSingle(data[4])); // position of the light effect | |
var direction = new Vector3(Convert.ToSingle(data[5]), Convert.ToSingle(data[6]), Convert.ToSingle(data[7])); // direction of the light effect | |
asset.m_hasEffects = true; | |
asset.m_effects[j] = new PropInfo.Effect { m_effect = existingLightEffect, m_position = position, m_direction = direction }; | |
} | |
else | |
{ | |
var infinite = Convert.ToBoolean(data[1]); | |
if (infinite && !isInfinite) isInfinite = true; | |
var type = data[2]; // spot or point | |
var color = new Color(Convert.ToSingle(data[3]), Convert.ToSingle(data[4]), Convert.ToSingle(data[5]), 1.0f); // RGBA | |
var intensity = Convert.ToSingle(data[6]); // brightness 1-8 | |
var range = Convert.ToSingle(data[7]); // distance and glow size | |
if (range > maxRange) maxRange = range; | |
var bloom = Convert.ToSingle(data[8]); // strength of additional glow effect | |
var angle = Convert.ToSingle(data[9]); // angle of spotlight beam | |
var blink = data[10]; // none, blink, fade, pulse | |
var rotation = new Vector3(Convert.ToSingle(data[11]), Convert.ToSingle(data[12]), Convert.ToSingle(data[13])); // enable rotation on X Y Z, confusing once direction is changed | |
var rpm = Convert.ToInt32(data[14]); // rotations per minute | |
Color variation1 = new Color(Convert.ToSingle(data[15]), Convert.ToSingle(data[16]), Convert.ToSingle(data[17]), 1.0f); // random color variations | |
Color variation2 = new Color(Convert.ToSingle(data[18]), Convert.ToSingle(data[19]), Convert.ToSingle(data[20]), 1.0f); // main color gets multiplied by these | |
Color variation3 = new Color(Convert.ToSingle(data[21]), Convert.ToSingle(data[22]), Convert.ToSingle(data[23]), 1.0f); // defaults are subtle R/G/B tints | |
var position = new Vector3(Convert.ToSingle(data[24]), Convert.ToSingle(data[25]), Convert.ToSingle(data[26])); // position of the light effect | |
var direction = new Vector3(Convert.ToSingle(data[27]), Convert.ToSingle(data[28]), Convert.ToSingle(data[29])); // direction of the light effect | |
asset.m_hasEffects = true; | |
var existingLightEffect = EffectCollection.FindEffect("Flood Light Orange") as LightEffect; | |
LightEffect lightEffect = LightEffect.Instantiate(existingLightEffect); | |
lightEffect.transform.parent = existingLightEffect.transform; | |
Light light = lightEffect.gameObject.GetComponent<Light>(); | |
light.color = color; | |
light.intensity = intensity; | |
light.range = range; | |
light.spotAngle = angle; | |
if (type == "spot") light.type = LightType.Spot; | |
else light.type = LightType.Point; | |
if (blink == "blink") lightEffect.m_blinkType = LightEffect.BlinkType.Blink_050_050; | |
else if (blink == "fade") lightEffect.m_blinkType = LightEffect.BlinkType.MediumFade_500_500; | |
else if (blink == "pulse") lightEffect.m_blinkType = LightEffect.BlinkType.StrongBlaze_0125_0125; | |
else lightEffect.m_blinkType = LightEffect.BlinkType.None; | |
lightEffect.m_rotationAxis = rotation; | |
lightEffect.m_rotationSpeed = rpm; | |
lightEffect.m_spotLeaking = bloom; | |
lightEffect.m_offRange.x = 6 * Convert.ToSingle(Math.Pow(Convert.ToDouble((6 - Convert.ToSingle(data[30]) / 2.5) / 6), Convert.ToDouble(1 / 1.09))); | |
lightEffect.m_offRange.y = Mathf.Clamp(6 * Convert.ToSingle(Math.Pow(Convert.ToDouble((6 - Convert.ToSingle(data[30]) / 2.5) / 6), Convert.ToDouble(1 / 1.09))) - Convert.ToSingle(data[31]), 0, 6); | |
if (variation1 == color && variation2 == color && variation3 == color) Array.Resize(ref lightEffect.m_variationColors, 0); | |
else | |
{ | |
lightEffect.m_variationColors[0] = variation1; | |
lightEffect.m_variationColors[1] = variation2; | |
lightEffect.m_variationColors[2] = variation3; | |
} | |
lightEffect.m_batchedLight = false; | |
lightEffect.m_fadeStartDistance = (intensity * range + 10) * 3; | |
lightEffect.m_fadeEndDistance = (intensity * range + 10) * 30; | |
typeof(EffectInfo).GetField("m_refCount", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(lightEffect, 0); | |
lightEffect.InitializeEffect(); | |
asset.m_effects[j] = new PropInfo.Effect { m_effect = lightEffect, m_position = position, m_direction = direction }; | |
} | |
} | |
if ((maxRange > 1000f) || isInfinite) | |
{ | |
asset.m_maxRenderDistance = 20000f; // set it to the max range of the map 20km | |
propList.Add(asset.name); | |
} | |
} | |
} | |
var p = PropManager.instance; // late update any props | |
foreach (string propName in propList) // look through the list | |
{ | |
for (uint i = 0; i < p.m_props.m_buffer.Count(); i++) | |
{ | |
if (p.m_props.m_buffer[i].Info.name == propName) | |
{ | |
p.m_props.m_buffer[i].Info.m_maxRenderDistance = 20000f; | |
p.UpdateProp((ushort)i); | |
break; | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment