Last active
April 3, 2020 14:00
-
-
Save boformer/3a46518ec3fe224f4def to your computer and use it in GitHub Desktop.
Cities: Skylines - Street Light Replacer Mod
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 ICities; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Xml.Serialization; | |
using UnityEngine; | |
using PrefabHook; | |
using ColossalFramework.UI; | |
using ColossalFramework.Plugins; | |
namespace StreetLightReplacer | |
{ | |
public class StreetLightReplacerMod : LoadingExtensionBase, IUserMod | |
{ | |
private const string configPath = "StreetLightReplacer.xml"; | |
private StreetLightReplacerConfig _config; | |
public StreetLightReplacerConfig Config | |
{ | |
get | |
{ | |
if (_config == null) | |
{ | |
_config = StreetLightReplacerConfig.Deserialize("StreetLightReplacer.xml"); | |
if (_config == null) | |
{ | |
_config = new StreetLightReplacerConfig(); | |
_config.SetReplacement("Basic Road", "StreetLamp02"); | |
_config.SetReplacement("Highway", "#None"); | |
_config.SetReplacement("Highway Elevated", "#None"); | |
_config.SetReplacement("HighwayRamp", "#None"); | |
_config.SetReplacement("HighwayRampElevated", "#None"); | |
_config.RemoveHighwaySuspensionBridgeLights = true; | |
} | |
} | |
return _config; | |
} | |
} | |
public string Name | |
{ | |
get { return "Street Light Replacer"; } | |
} | |
public string Description | |
{ | |
get { return "Requires the Prefab Hook mod"; } | |
} | |
// Note: There are better ways to solve this | |
public void OnSettingsUI(UIHelperBase group) | |
{ | |
group.AddGroup("Note: Restart the game to apply the new options!"); | |
group.AddDropdown("Two-Lane Road", new string[] { "Street Light (Default)", "Street Lamp", "None" }, | |
Config.GetReplacement("Basic Road") == null ? 0 : (Config.GetReplacement("Basic Road").StreetLight == "#None" ? 2 : 1), | |
delegate(int sel) | |
{ | |
switch (sel) | |
{ | |
case 0: | |
Config.DeleteReplacement("Basic Road"); | |
break; | |
case 1: | |
Config.SetReplacement("Basic Road", "StreetLamp02"); | |
break; | |
case 2: | |
Config.SetReplacement("Basic Road", "#None"); | |
break; | |
} | |
StreetLightReplacerConfig.Serialize(configPath, Config); | |
}); | |
group.AddDropdown("Highway", new string[] { "Street Light (Default)", "None" }, | |
Config.GetReplacement("Highway") == null ? 0 : 1, | |
delegate(int sel) | |
{ | |
switch (sel) | |
{ | |
case 0: | |
Config.DeleteReplacement("Highway"); | |
Config.DeleteReplacement("Highway Elevated"); | |
break; | |
case 1: | |
Config.SetReplacement("Highway", "#None"); | |
Config.SetReplacement("Highway Elevated", "#None"); | |
break; | |
} | |
StreetLightReplacerConfig.Serialize(configPath, Config); | |
}); | |
group.AddDropdown("Highway Ramp", new string[] { "Street Light (Default)", "None" }, | |
Config.GetReplacement("HighwayRamp") == null ? 0 : 1, | |
delegate(int sel) | |
{ | |
switch (sel) | |
{ | |
case 0: | |
Config.DeleteReplacement("HighwayRamp"); | |
Config.DeleteReplacement("HighwayRampElevated"); | |
break; | |
case 1: | |
Config.SetReplacement("HighwayRamp", "#None"); | |
Config.SetReplacement("HighwayRampElevated", "#None"); | |
break; | |
} | |
StreetLightReplacerConfig.Serialize(configPath, Config); | |
}); | |
group.AddCheckbox("Remove lights from highway suspension bridge", Config.RemoveHighwaySuspensionBridgeLights, delegate(bool check) | |
{ | |
Config.RemoveHighwaySuspensionBridgeLights = check; | |
StreetLightReplacerConfig.Serialize(configPath, Config); | |
}); | |
} | |
public override void OnCreated(ILoading loading) | |
{ | |
base.OnCreated(loading); | |
// cancel if Prefab Hook is not installed | |
if (!IsHooked()) return; | |
// register event handlers | |
NetInfoHook.OnPreInitialization += OnPreNetInit; | |
NetInfoHook.Deploy(); | |
if (Config.RemoveHighwaySuspensionBridgeLights) | |
{ | |
BuildingInfoHook.OnPreInitialization += OnPreBuildingInit; | |
BuildingInfoHook.Deploy(); | |
} | |
} | |
public void OnPreNetInit(NetInfo prefab) | |
{ | |
if (prefab == null || prefab.m_lanes == null) return; | |
var replacement = Config.GetReplacement(prefab.name); | |
if (replacement == null) return; | |
foreach (var lane in prefab.m_lanes) | |
{ | |
if (lane == null || lane.m_laneProps == null || lane.m_laneProps.m_props == null) continue; | |
foreach (var prop in lane.m_laneProps.m_props) | |
{ | |
if (prop.m_prop != null && (prop.m_prop.name.Contains("Street Light") || prop.m_prop.name.Contains("StreetLamp"))) | |
{ | |
if(replacement != null) Debug.Log("Replace street light " + prefab.name + ": " + replacement.StreetLight); | |
if (replacement.StreetLight == "#None") | |
{ | |
prop.m_prop = null; | |
prop.m_finalProp = null; | |
} | |
else | |
{ | |
PropInfo lightProp = PrefabCollection<PropInfo>.FindLoaded(replacement.StreetLight); | |
if (lightProp == null) | |
{ | |
foreach (var col in GameObject.FindObjectsOfType<PropCollection>()) | |
{ | |
if (col == null || col.m_prefabs == null) continue; | |
foreach (var prop2 in col.m_prefabs) | |
{ | |
if (prop2 != null && prop2.name == replacement.StreetLight) | |
{ | |
lightProp = prop2; | |
break; | |
} | |
} | |
} | |
} | |
if (lightProp != null) | |
{ | |
prop.m_prop = lightProp; | |
prop.m_finalProp = lightProp; | |
} | |
else | |
{ | |
Debug.Log("Prop " + replacement.StreetLight + " not found!"); | |
} | |
} | |
} | |
} | |
} | |
} | |
//HighwayBridgeSuspensionPillar | |
// Flood Light Down White | |
// Flood Light Blue | |
public void OnPreBuildingInit(BuildingInfo prefab) | |
{ | |
if (prefab == null || prefab.m_props == null) return; | |
if (prefab.name != "HighwayBridgeSuspensionPillar") return; | |
foreach (var prop in prefab.m_props) | |
{ | |
if (prop.m_prop != null && prop.m_prop.name.Contains("Flood Light")) | |
{ | |
prop.m_prop = null; | |
prop.m_finalProp = null; | |
} | |
} | |
} | |
public override void OnLevelLoaded(LoadMode mode) | |
{ | |
base.OnLevelLoaded(mode); | |
// display warning when level is loaded if Prefab Hook is not installed | |
if (!IsHooked()) | |
{ | |
UIView.library.ShowModal<ExceptionPanel>("ExceptionPanel").SetMessage( | |
"Missing dependency", | |
"Street Light Replacer requires the 'Prefab Hook' mod to work properly. Please subscribe to the mod and restart the game!", | |
false); | |
return; | |
} | |
} | |
public override void OnReleased() | |
{ | |
base.OnReleased(); | |
if (!IsHooked()) return; | |
// revert on release | |
NetInfoHook.Revert(); | |
BuildingInfoHook.Revert(); | |
} | |
// checks if the player subscribed to the Prefab Hook mod | |
private bool IsHooked() | |
{ | |
foreach (PluginManager.PluginInfo current in PluginManager.instance.GetPluginsInfo()) | |
{ | |
if (current.publishedFileID.AsUInt64 == 530771650uL) return true; | |
} | |
return false; | |
} | |
} | |
public class StreetLightReplacerConfig | |
{ | |
public Boolean RemoveHighwaySuspensionBridgeLights { get; set; } | |
public List<Replacement> Replacements {get; private set;} | |
public StreetLightReplacerConfig() | |
{ | |
Replacements = new List<Replacement>(); | |
} | |
public class Replacement | |
{ | |
public string NetInfo { get; set; } | |
public string StreetLight { get; set; } | |
} | |
public Replacement GetReplacement(string netInfo) | |
{ | |
foreach (var r in Replacements) | |
{ | |
if (r.NetInfo == netInfo) | |
{ | |
return r; | |
} | |
} | |
return null; | |
} | |
public void SetReplacement(string netInfo, string streetLight) | |
{ | |
foreach (var r in Replacements) | |
{ | |
if (r.NetInfo == netInfo) | |
{ | |
r.StreetLight = streetLight; | |
return; | |
} | |
} | |
Replacements.Add(new Replacement { NetInfo = netInfo, StreetLight = streetLight }); | |
} | |
public void DeleteReplacement(string netInfo) | |
{ | |
foreach (var r in Replacements) | |
{ | |
if (r.NetInfo == netInfo) | |
{ | |
Replacements.Remove(r); | |
return; | |
} | |
} | |
} | |
public static StreetLightReplacerConfig Deserialize(string filename) | |
{ | |
if (!File.Exists(filename)) return null; | |
XmlSerializer xmlSerializer = new XmlSerializer(typeof(StreetLightReplacerConfig)); | |
try | |
{ | |
using (System.IO.StreamReader streamReader = new System.IO.StreamReader(filename)) | |
{ | |
return (StreetLightReplacerConfig)xmlSerializer.Deserialize(streamReader); | |
} | |
} | |
catch (Exception e) | |
{ | |
Debug.Log("Couldn't load configuration (XML malformed?)"); | |
throw e; | |
} | |
} | |
public static void Serialize(string filename, StreetLightReplacerConfig config) | |
{ | |
var xmlSerializer = new XmlSerializer(typeof(StreetLightReplacerConfig)); | |
try | |
{ | |
using (System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(filename)) | |
{ | |
xmlSerializer.Serialize(streamWriter, config); | |
} | |
} | |
catch (Exception e) | |
{ | |
Debug.Log("Couldn't create configuration file at \"" + Directory.GetCurrentDirectory() + "\""); | |
throw e; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello,
I would like to get in French language in the full game, even in game option before to start a a new game.
Is it possible for me to translate ? I do not know where is the xml file for translating or should I translate this file where all the sentences are in " " ?
Thanks for your reply.