Skip to content

Instantly share code, notes, and snippets.

@ronyx69
Last active September 8, 2017 17:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ronyx69/b2e77772c5df261cb1ca8267bfe33bcb to your computer and use it in GitHub Desktop.
Save ronyx69/b2e77772c5df261cb1ca8267bfe33bcb to your computer and use it in GitHub Desktop.
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