diff --git a/Heads/Changelog.txt b/Heads/Changelog.txt new file mode 100644 index 0000000..3729537 --- /dev/null +++ b/Heads/Changelog.txt @@ -0,0 +1,3 @@ +**v0.1.0** + +- First Beta Release diff --git a/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.dll b/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.dll new file mode 100644 index 0000000..0c62e18 Binary files /dev/null and b/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.dll differ diff --git a/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.version b/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.version new file mode 100644 index 0000000..eb4eea0 --- /dev/null +++ b/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.version @@ -0,0 +1,25 @@ +{ + "NAME": "Sigma Replacements: Heads", + "URL": "https://raw.githubusercontent.com/Sigma88/Sigma-Replacements/master/Heads/GameData/Sigma/Replacements/Heads/Plugins/SigmaReplacementsHeads.version", + "DOWNLOAD": "http://forum.kerbalspaceprogram.com/index.php?/topic/167233-0", + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/Sigma88/Sigma-Replacements/master/Heads/Changelog.txt", + "GITHUB": + { + "USERNAME": "Sigma88", + "REPOSITORY": "Sigma-Replacements", + "ALLOW_PRE_RELEASE": false + }, + "VERSION": + { + "MAJOR": 0, + "MINOR": 1, + "PATCH": 0, + "BUILD": 0 + }, + "KSP_VERSION": + { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 1 + } +} diff --git a/Heads/License.txt b/Heads/License.txt new file mode 100644 index 0000000..247dae2 --- /dev/null +++ b/Heads/License.txt @@ -0,0 +1,8 @@ +Sigma Replacements: Heads by Sigma88 is released under the following license: + + +All Rights Reserved + + +For more info visit the KSP Forum Thread: +http://forum.kerbalspaceprogram.com/index.php?/topic/167233-0 diff --git a/Heads/README.md b/Heads/README.md new file mode 100644 index 0000000..2703431 --- /dev/null +++ b/Heads/README.md @@ -0,0 +1,11 @@ +# Sigma Replacements: Heads + + +**Customizeable Crew Heads** + + +KSP Forum Thread: http://forum.kerbalspaceprogram.com/index.php?/topic/167233-0/ + +Download Latest Release: https://github.com/Sigma88/Sigma-Replacements/releases + +Dev version: https://github.com/Sigma88/Sigma-Replacements/tree/Heads diff --git a/README.md b/README.md index 6f32795..c06170e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # Sigma Replacements -**Hanles replacement of various KSP assets** +**Handles replacement of various KSP assets** -KSP Forum Thread: http://forum.kerbalspaceprogram.com/index.php?/topic/-0/ +KSP Forum Thread: http://forum.kerbalspaceprogram.com/index.php?/topic/167233-0/ Download Latest Release: https://github.com/Sigma88/Sigma-KerbalReplacements/releases/latest Dev versions: -- *Heads* https://github.com/Sigma88/Sigma-Replacements/tree/Heads -- *Suits* https://github.com/Sigma88/Sigma-Replacements/tree/Suits -- *Textures* https://github.com/Sigma88/Sigma-Replacements/tree/Textures +- Heads - https://github.com/Sigma88/Sigma-Replacements/tree/Heads +- Suits - https://github.com/Sigma88/Sigma-Replacements/tree/Suits +- Textures - https://github.com/Sigma88/Sigma-Replacements/tree/Textures diff --git a/[Source]/Distribution/SigmaReplacementsHeads.dll b/[Source]/Distribution/SigmaReplacementsHeads.dll new file mode 100644 index 0000000..0c62e18 Binary files /dev/null and b/[Source]/Distribution/SigmaReplacementsHeads.dll differ diff --git a/[Source]/SigmaReplacements/Heads/CustomHead.cs b/[Source]/SigmaReplacements/Heads/CustomHead.cs new file mode 100644 index 0000000..119eddf --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/CustomHead.cs @@ -0,0 +1,223 @@ +using System.Linq; +using UnityEngine; + + +namespace SigmaReplacements +{ + namespace Heads + { + internal class CustomHead : MonoBehaviour + { + // Colors + Color? pupilLeft = null; + Color? pupilRight = null; + Color? eyeballLeft = null; + Color? eyeballRight = null; + Color? upTeeth01 = null; + Color? upTeeth02 = null; + Color? tongue = null; + Color? head = null; + Color? hair = null; + Color? arm = null; + + // Textures + Texture pupilLeftTex = null; + Texture pupilRightTex = null; + Texture eyeballLeftTex = null; + Texture eyeballRightTex = null; + Texture upTeeth01Tex = null; + Texture upTeeth02Tex = null; + Texture tongueTex = null; + Texture headTex = null; + Texture hairTex = null; + Texture armTex = null; + + + // Normals + Texture pupilLeftNrm = null; + Texture pupilRightNrm = null; + Texture eyeballLeftNrm = null; + Texture eyeballRightNrm = null; + Texture upTeeth01Nrm = null; + Texture upTeeth02Nrm = null; + Texture tongueNrm = null; + Texture headNrm = null; + Texture hairNrm = null; + Texture armNrm = null; + + + void Start() + { + Debug.Log("CustomHead.Start", "In gameObject = " + gameObject); + Apply(); + } + + internal void Apply() + { + Debug.Log("CustomHead.Apply", "In gameObject = " + gameObject); + + ProtoCrewMember kerbal = GetComponent()?.part?.protoModuleCrew?.FirstOrDefault(); + if (kerbal == null) kerbal = GetComponent()?.protoCrewMember; + if (kerbal == null) kerbal = GetComponent()?.crewMember; + if (kerbal == null) kerbal = GetComponent()?.crewMember; + if (kerbal == null) kerbal = GetComponent()?.crewMember; + if (kerbal == null) kerbal = GetComponent()?.crewMember; + Debug.Log("CustomHead.Apply", "kerbal = " + kerbal); + if (kerbal == null) return; + + LoadFor(kerbal); + + ApplyTo(kerbal); + } + + void LoadFor(ProtoCrewMember kerbal) + { + Debug.Log("CustomHead.LoadFor", "kerbal = " + kerbal); + + HeadInfo.hash = ""; + int? useChance = null; + + for (int i = 0; i < HeadInfo.DataBase?.Count; i++) + { + HeadInfo info = HeadInfo.DataBase[i].GetFor(kerbal); + string collection = ""; + + if (info != null) + { + if (string.IsNullOrEmpty(collection) || collection == info.collection) + { + if (info.useChance != 1) + useChance = kerbal.Hash(info.useGameSeed) % 100; + + if (info.useChance == 1 || useChance < info.useChance * 100) + { + // Collection + collection = info.collection; + + // Colors + pupilLeft = pupilLeft ?? info.pupilLeft.Pick(kerbal, info.useGameSeed); + pupilRight = pupilRight ?? info.pupilRight.At(pupilLeft, info.pupilLeft) ?? info.pupilRight.Pick(kerbal, info.useGameSeed); + eyeballLeft = eyeballLeft ?? info.eyeballLeft.Pick(kerbal, info.useGameSeed); + eyeballRight = eyeballRight ?? info.eyeballRight.At(eyeballLeft, info.eyeballLeft) ?? info.eyeballRight.Pick(kerbal, info.useGameSeed); + upTeeth01 = upTeeth01 ?? info.upTeeth01.Pick(kerbal, info.useGameSeed); + upTeeth02 = upTeeth02 ?? info.upTeeth02.At(upTeeth01, info.upTeeth01) ?? info.upTeeth02.Pick(kerbal, info.useGameSeed); + tongue = tongue ?? info.tongue.Pick(kerbal, info.useGameSeed); + head = head ?? info.head.Pick(kerbal, info.useGameSeed); + hair = hair ?? info.hair.At(head, info.head) ?? info.hair.Pick(kerbal, info.useGameSeed); + arm = arm ?? info.arm.Pick(kerbal, info.useGameSeed); + + // Textures + pupilLeftTex = pupilLeftTex ?? info.pupilLeftTex.Pick(kerbal, info.useGameSeed); + pupilRightTex = pupilRightTex ?? info.pupilRightTex.At(pupilLeftTex, info.pupilLeftTex) ?? info.pupilRightTex.Pick(kerbal, info.useGameSeed); + eyeballLeftTex = eyeballLeftTex ?? info.eyeballLeftTex.Pick(kerbal, info.useGameSeed); + eyeballRightTex = eyeballRightTex ?? info.eyeballRightTex.At(eyeballLeftTex, info.eyeballLeftTex) ?? info.eyeballRightTex.Pick(kerbal, info.useGameSeed); + upTeeth01Tex = upTeeth01Tex ?? info.upTeeth01Tex.Pick(kerbal, info.useGameSeed); + upTeeth02Tex = upTeeth02Tex ?? info.upTeeth02Tex.At(upTeeth01Tex, info.upTeeth01Tex) ?? info.upTeeth02Tex.Pick(kerbal, info.useGameSeed); + tongueTex = tongueTex ?? info.tongueTex.Pick(kerbal, info.useGameSeed); + headTex = headTex ?? info.headTex.Pick(kerbal, info.useGameSeed); + hairTex = hairTex ?? info.hairTex.At(headTex, info.headTex) ?? info.hairTex.Pick(kerbal, info.useGameSeed); + armTex = armTex ?? info.armTex.Pick(kerbal, info.useGameSeed); + + // Normals + pupilLeftNrm = pupilLeftNrm ?? info.pupilLeftNrm.At(pupilLeftTex, info.pupilLeftTex) ?? info.pupilLeftNrm.Pick(kerbal, info.useGameSeed); + pupilRightNrm = pupilRightNrm ?? info.pupilRightNrm.At(pupilRightTex, info.pupilRightTex) ?? info.pupilRightNrm.Pick(kerbal, info.useGameSeed); + eyeballLeftNrm = eyeballLeftNrm ?? info.eyeballLeftNrm.At(eyeballLeftTex, info.eyeballLeftTex) ?? info.eyeballLeftNrm.Pick(kerbal, info.useGameSeed); + eyeballRightNrm = eyeballRightNrm ?? info.eyeballRightNrm.At(eyeballRightTex, info.eyeballRightTex) ?? info.eyeballRightNrm.Pick(kerbal, info.useGameSeed); + upTeeth01Nrm = upTeeth01Nrm ?? info.upTeeth01Nrm.At(upTeeth01Tex, info.upTeeth01Tex) ?? info.upTeeth01Nrm.Pick(kerbal, info.useGameSeed); + upTeeth02Nrm = upTeeth02Nrm ?? info.upTeeth02Nrm.At(upTeeth02Tex, info.upTeeth02Tex) ?? info.upTeeth02Nrm.Pick(kerbal, info.useGameSeed); + tongueNrm = tongueNrm ?? info.tongueNrm.At(tongueTex, info.tongueTex) ?? info.tongueNrm.Pick(kerbal, info.useGameSeed); + headNrm = headNrm ?? info.headNrm.At(headTex, info.headTex) ?? info.headNrm.Pick(kerbal, info.useGameSeed); + hairNrm = hairNrm ?? info.hairNrm.At(hairTex, info.hairTex) ?? info.hairNrm.Pick(kerbal, info.useGameSeed); + armNrm = armNrm ?? info.armNrm.At(armTex, info.armTex) ?? info.armNrm.Pick(kerbal, info.useGameSeed); + } + } + } + } + } + + void ApplyTo(ProtoCrewMember kerbal) + { + Debug.Log("CustomHead.ApplyTo", "kerbal = " + kerbal); + + Renderer[] renderers = GetComponentsInChildren(); + + for (int i = 0; i < renderers?.Length; i++) + { + string name = renderers[i]?.name; + Material material = renderers[i]?.material; + if (material == null) continue; + + if (name == "pupilLeft" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft") + { + material.SetColor(pupilLeft); + material.SetTexture(pupilLeftTex); + material.SetNormal(pupilLeftNrm); + } + + if (name == "pupilRight" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight") + { + material.SetColor(pupilRight); + material.SetTexture(pupilRightTex); + material.SetNormal(pupilRightNrm); + } + + if (name == "eyeballLeft" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft") + { + material.SetColor(eyeballLeft); + material.SetTexture(eyeballLeftTex); + material.SetNormal(eyeballLeftNrm); + } + + if (name == "eyeballRight" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight") + { + material.SetColor(eyeballRight); + material.SetTexture(eyeballRightTex); + material.SetNormal(eyeballRightNrm); + } + + if (name == "upTeeth01" || name == "downTeeth01" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01") + { + material.SetColor(upTeeth01); + material.SetTexture(upTeeth01Tex); + material.SetNormal(upTeeth01Nrm); + } + + if (name == "upTeeth02" || name == "upTeeth01" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01") + { + material.SetColor(upTeeth02); + material.SetTexture(upTeeth02Tex); + material.SetNormal(upTeeth02Nrm); + } + + if (name == "tongue") + { + material.SetColor(tongue); + material.SetTexture(tongueTex); + material.SetNormal(tongueNrm); + } + + if (name == "headMesh01" || name == "headMesh" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_polySurface51") + { + material.SetColor(head); + material.SetTexture(headTex); + material.SetNormal(headNrm); + } + + if (name == "ponytail" || name == "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pCube1") + { + material.SetColor(hair); + material.SetTexture(hairTex); + material.SetNormal(hairNrm); + } + + if (name == "hand_left01" || name == "hand_right01") + { + material.SetColor(arm); + material.SetTexture(armTex); + material.SetNormal(armNrm); + } + } + } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/DebugLogger.cs b/[Source]/SigmaReplacements/Heads/DebugLogger.cs new file mode 100644 index 0000000..cab95b5 --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/DebugLogger.cs @@ -0,0 +1,51 @@ +using UnityEngine; + + +namespace SigmaReplacements +{ + internal static class Debug + { + internal static bool debug = false; + internal static string Tag = "[SigmaLog SR]"; + + internal static void Log(string message) + { + if (debug) + { + UnityEngine.Debug.Log(Tag + ": " + message); + } + } + + internal static void Log(string Method, string message) + { + if (debug) + { + UnityEngine.Debug.Log(Tag + " " + Method + ": " + message); + } + } + } + + [KSPAddon(KSPAddon.Startup.MainMenu, true)] + class DebugWarning : MonoBehaviour + { + void Start() + { + if (Debug.debug) + { + PopupDialog.SpawnPopupDialog + ( + new Vector2(0.5f, 0.5f), + new Vector2(0.5f, 0.5f), + UserSettings.nodeName, + UserSettings.nodeName + " Warning", + "\nDebug Spam is activated.\n\n" + + "This feature will greatly affect performance:\n" + + "use it only for debugging purposes.", + "OK", + true, + UISkinManager.GetSkin("MainMenuSkin") + ); + } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/Extensions.cs b/[Source]/SigmaReplacements/Heads/Extensions.cs new file mode 100644 index 0000000..b2b964c --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/Extensions.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + + +namespace SigmaReplacements +{ + namespace Heads + { + internal static class Extensions + { + internal static void Load(this CrewMember[] array, ConfigNode node, int index) + { + CrewMember kerbal = array[index]; + HeadInfo stats = new HeadInfo(node.GetNode("Stats") ?? new ConfigNode(), new ConfigNode()); + + array[index] = new CrewMember + ( + stats?.rosterStatus ?? kerbal.type, + !string.IsNullOrEmpty(stats?.name) ? stats.name : kerbal.name, + stats?.gender ?? kerbal.gender, + stats?.trait?.Length > 0 && !string.IsNullOrEmpty(stats.trait[0]) ? stats.trait[0] : kerbal.trait, + stats?.veteran ?? kerbal.veteran, + stats?.isBadass ?? kerbal.isBadass, + stats?.courage ?? kerbal.courage, + stats?.stupidity ?? kerbal.stupidity, + stats?.experienceLevel ?? kerbal.experienceLevel + ); + } + + internal static void SetColor(this Material material, Color? color) + { + if (material != null && color != null) + { + material.color = (Color)color; + } + } + + internal static void SetTexture(this Material material, Texture newTex) + { + if (material != null && newTex != null) + { + Texture oldTex = material?.mainTexture; + + if (oldTex != null) + { + newTex.anisoLevel = oldTex.anisoLevel; + newTex.wrapMode = oldTex.wrapMode; + } + + material.mainTexture = newTex; + } + } + + internal static void SetNormal(this Material material, Texture newTex) + { + if (material != null && newTex != null) + { + material.shader = Shader.Find("Bumped Diffuse"); + + Texture oldTex = material.GetTexture("_BumpMap"); + + if (oldTex != null) + { + newTex.anisoLevel = oldTex.anisoLevel; + newTex.wrapMode = oldTex.wrapMode; + } + + material.SetTexture("_BumpMap", newTex); + } + } + + internal static Texture At(this List right, Texture item, List left) + { + if (item != null && left.Contains(item) && right?.Count > left.IndexOf(item)) + return right[left.IndexOf(item)]; + return null; + } + + internal static Color? At(this List right, Color? item, List left) + { + if (item != null && left.Contains((Color)item) && right?.Count > left.IndexOf((Color)item)) + return right[left.IndexOf((Color)item)]; + return null; + } + + internal static Texture Pick(this List list, ProtoCrewMember kerbal, bool useGameSeed) + { + if (list.Count == 1) + return list[0]; + else if (list.Count > 1) + return list[kerbal.Hash(useGameSeed) % list.Count]; + else + return null; + } + + internal static Color? Pick(this List list, ProtoCrewMember kerbal, bool useGameSeed) + { + if (list.Count == 1) + return list[0]; + else if (list.Count > 1) + return list[kerbal.Hash(useGameSeed) % list.Count]; + else + return null; + } + + internal static int Hash(this ProtoCrewMember kerbal, bool useGameSeed) + { + string hash = HeadInfo.hash; + + if (string.IsNullOrEmpty(hash)) hash = kerbal.name; + + int h = Math.Abs(hash.GetHashCode()); + + if (useGameSeed && HighLogic.CurrentGame != null) h += Math.Abs(HighLogic.CurrentGame.Seed); + + HeadInfo.hash = h.ToString(); + + return h; + } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/HeadInfo.cs b/[Source]/SigmaReplacements/Heads/HeadInfo.cs new file mode 100644 index 0000000..f74ddae --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/HeadInfo.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; +using Gender = ProtoCrewMember.Gender; +using Type = ProtoCrewMember.KerbalType; + + +namespace SigmaReplacements +{ + namespace Heads + { + internal class HeadInfo + { + // Static + internal static string hash = ""; + internal static List List = new List(); + internal static List DataBase = new List(); + + // Identifiers + internal string name = null; + + // Requirements + internal bool useGameSeed = false; + internal float useChance = 1; + internal Type? rosterStatus = null; + internal Gender? gender = null; + internal string[] trait = null; + internal bool? veteran = null; + internal bool? isBadass = null; + int minLevel = 0; + int maxLevel = 5; + float minCourage = 0; + float maxCourage = 1; + float minStupidity = 0; + float maxStupidity = 1; + // For MainMenuKerbals + internal float? courage = null; + internal float? stupidity = null; + internal int? experienceLevel = null; + + // Collection + internal string collection = ""; + + // Colors Lists + internal List pupilLeft = new List(); + internal List pupilRight = new List(); + internal List eyeballLeft = new List(); + internal List eyeballRight = new List(); + internal List upTeeth01 = new List(); + internal List upTeeth02 = new List(); + internal List tongue = new List(); + internal List head = new List(); + internal List hair = new List(); + internal List arm = new List(); + + // Textures Lists + internal List pupilLeftTex = new List(); + internal List pupilRightTex = new List(); + internal List eyeballLeftTex = new List(); + internal List eyeballRightTex = new List(); + internal List upTeeth01Tex = new List(); + internal List upTeeth02Tex = new List(); + internal List tongueTex = new List(); + internal List headTex = new List(); + internal List hairTex = new List(); + internal List armTex = new List(); + + // Normals Lists + internal List pupilLeftNrm = new List(); + internal List pupilRightNrm = new List(); + internal List eyeballLeftNrm = new List(); + internal List eyeballRightNrm = new List(); + internal List upTeeth01Nrm = new List(); + internal List upTeeth02Nrm = new List(); + internal List tongueNrm = new List(); + internal List headNrm = new List(); + internal List hairNrm = new List(); + internal List armNrm = new List(); + + + // Get + internal HeadInfo GetFor(ProtoCrewMember kerbal) + { + if (name == null || name == kerbal.name) + { + Debug.Log("HeadInfo.GetFor", "Matched name = " + name + " to kerbal name = " + kerbal.name); + if (rosterStatus == null || rosterStatus == kerbal.type) + { + Debug.Log("HeadInfo.GetFor", "Matched rosterStatus = " + rosterStatus + " to kerbal rosterStatus = " + kerbal.type); + if (gender == null || gender == kerbal.gender) + { + Debug.Log("HeadInfo.GetFor", "Matched gender = " + gender + " to kerbal gender = " + kerbal.gender); + if (trait == null || trait.Contains(kerbal.trait)) + { + Debug.Log("HeadInfo.GetFor", "Matched trait = " + trait + " to kerbal trait = " + kerbal.trait); + if (veteran == null || veteran == kerbal.veteran) + { + Debug.Log("HeadInfo.GetFor", "Matched veteran = " + veteran + " to kerbal veteran = " + kerbal.veteran); + if (isBadass == null || isBadass == kerbal.isBadass) + { + Debug.Log("HeadInfo.GetFor", "Matched isBadass = " + isBadass + " to kerbal isBadass = " + kerbal.isBadass); + if (minLevel <= kerbal.experienceLevel && maxLevel >= kerbal.experienceLevel) + { + Debug.Log("HeadInfo.GetFor", "Matched minLevel = " + minLevel + ", maxLevel = " + maxLevel + " to kerbal level = " + kerbal.experienceLevel); + if (minCourage <= kerbal.courage && maxCourage >= kerbal.courage) + { + Debug.Log("HeadInfo.GetFor", "Matched minCourage = " + minCourage + ", maxCourage = " + maxCourage + " to kerbal courage = " + kerbal.courage); + if (minStupidity <= kerbal.stupidity && maxStupidity >= kerbal.stupidity) + { + Debug.Log("HeadInfo.GetFor", "Matched minStupidity = " + minStupidity + ", maxStupidity = " + maxStupidity + " to kerbal stupidity = " + kerbal.stupidity); + Debug.Log("HeadInfo.GetFor", "Return this HeadInfo"); + return this; + } + } + } + } + } + } + } + } + } + + Debug.Log("HeadInfo.GetFor", "Return null"); + return null; + } + + + // New HeadInfo + internal HeadInfo(ConfigNode requirements, ConfigNode info) + { + Debug.Log("HeadInfo", "new HeadInfo from:"); + Debug.Log("HeadInfo", "Requirements node = " + requirements); + Debug.Log("HeadInfo", "Head node = " + info); + + // Parse HeadInfo Requirements + useGameSeed = Parse(requirements.GetValue("useGameSeed"), useGameSeed); + useChance = Parse(requirements.GetValue("useChance"), useChance); + name = requirements.GetValue("name"); + rosterStatus = Parse(requirements.GetValue("rosterStatus"), rosterStatus); + gender = Parse(requirements.GetValue("gender"), gender); + trait = requirements.HasValue("trait") ? requirements.GetValues("trait") : null; + veteran = Parse(requirements.GetValue("veteran"), veteran); + isBadass = Parse(requirements.GetValue("isBadass"), isBadass); + minLevel = Parse(requirements.GetValue("minLevel"), minLevel); + maxLevel = Parse(requirements.GetValue("maxLevel"), maxLevel); + minCourage = Parse(requirements.GetValue("minCourage"), minCourage); + maxCourage = Parse(requirements.GetValue("maxCourage"), maxCourage); + minStupidity = Parse(requirements.GetValue("minStupidity"), minStupidity); + maxStupidity = Parse(requirements.GetValue("maxStupidity"), maxStupidity); + // For MainMenuKerbals + experienceLevel = Parse(requirements.GetValue("level"), experienceLevel); + courage = Parse(requirements.GetValue("courage"), courage); + stupidity = Parse(requirements.GetValue("stupidity"), stupidity); + + + // Parse Collection + collection = info.GetValue("collection"); + + // Parse HeadInfo Colors + pupilLeft = Parse(info.GetValues("pupilLeft"), pupilLeft); + pupilRight = Parse(info.GetValues("pupilRight"), pupilRight); + eyeballLeft = Parse(info.GetValues("eyeballLeft"), eyeballLeft); + eyeballRight = Parse(info.GetValues("eyeballRight"), eyeballRight); + upTeeth01 = Parse(info.GetValues("upTeeth01"), upTeeth01); + upTeeth02 = Parse(info.GetValues("upTeeth02"), upTeeth02); + tongue = Parse(info.GetValues("tongue"), tongue); + head = Parse(info.GetValues("head"), head); + hair = Parse(info.GetValues("hair"), hair); + arm = Parse(info.GetValues("arm"), arm); + + // Parse HeadInfo Textures + pupilLeftTex = Parse(info.GetValues("pupilLeftTex"), pupilLeftTex); + pupilRightTex = Parse(info.GetValues("pupilRightTex"), pupilRightTex); + eyeballLeftTex = Parse(info.GetValues("eyeballLeftTex"), eyeballLeftTex); + eyeballRightTex = Parse(info.GetValues("eyeballRightTex"), eyeballRightTex); + upTeeth01Tex = Parse(info.GetValues("upTeeth01Tex"), upTeeth01Tex); + upTeeth02Tex = Parse(info.GetValues("upTeeth02Tex"), upTeeth02Tex); + tongueTex = Parse(info.GetValues("tongueTex"), tongueTex); + headTex = Parse(info.GetValues("headTex"), headTex); + hairTex = Parse(info.GetValues("hairTex"), hairTex); + armTex = Parse(info.GetValues("armTex"), armTex); + + // Parse HeadInfo Normals + pupilLeftNrm = Parse(info.GetValues("pupilLeftNrm"), pupilLeftNrm); + pupilRightNrm = Parse(info.GetValues("pupilRightNrm"), pupilRightNrm); + eyeballLeftNrm = Parse(info.GetValues("eyeballLeftNrm"), eyeballLeftNrm); + eyeballRightNrm = Parse(info.GetValues("eyeballRightNrm"), eyeballRightNrm); + upTeeth01Nrm = Parse(info.GetValues("upTeeth01Nrm"), upTeeth01Nrm); + upTeeth02Nrm = Parse(info.GetValues("upTeeth02Nrm"), upTeeth02Nrm); + tongueNrm = Parse(info.GetValues("tongueNrm"), tongueNrm); + headNrm = Parse(info.GetValues("headNrm"), headNrm); + hairNrm = Parse(info.GetValues("hairNrm"), hairNrm); + armNrm = Parse(info.GetValues("armNrm"), armNrm); + + // Parse Folders + ParseFolders(info.GetNode("Folders")); + } + + + // Parsers + float Parse(string s, float defaultValue) { return float.TryParse(s, out float f) ? f : defaultValue; } + float? Parse(string s, float? defaultValue) { return float.TryParse(s, out float f) ? f : defaultValue; } + bool Parse(string s, bool defaultValue) { return bool.TryParse(s, out bool b) ? b : defaultValue; } + bool? Parse(string s, bool? defaultValue) { return bool.TryParse(s, out bool b) ? b : defaultValue; } + int Parse(string s, int defaultValue) { return int.TryParse(s, out int b) ? b : defaultValue; } + int? Parse(string s, int? defaultValue) { return int.TryParse(s, out int b) ? b : defaultValue; } + + Type? Parse(string s, Type? defaultValue) + { + try { return (Type)Enum.Parse(typeof(Type), s); } + catch { return defaultValue; } + } + + Gender? Parse(string s, Gender? defaultValue) + { + try { return (Gender)Enum.Parse(typeof(Gender), s); } + catch { return defaultValue; } + } + + Texture Parse(string s, Texture defaultValue) + { + return Resources.FindObjectsOfTypeAll().FirstOrDefault(t => t.name == s) ?? defaultValue; + } + + List Parse(string[] s, List defaultValue) + { + for (int i = 0; i < s.Length; i++) + { + Texture tex = null; + tex = Parse(s[i], tex); + if (tex != null && !defaultValue.Contains(tex)) + defaultValue.Add(tex); + } + return defaultValue; + } + + Color? Parse(string s, Color? defaultValue) + { + try { return ConfigNode.ParseColor(s); } + catch { return defaultValue; } + } + + List Parse(string[] s, List defaultValue) + { + for (int i = 0; i < s.Length; i++) + { + Color? col = null; + col = Parse(s[i], col); + if (!defaultValue.Contains((Color)col)) + defaultValue.Add((Color)col); + } + + return defaultValue; + } + + void ParseFolders(ConfigNode node) + { + if (node == null) return; + + // Parse Texture Folders + pupilLeftTex = ParseFolders(node.GetValues("pupilLeftTex"), pupilLeftTex); + pupilRightTex = ParseFolders(node.GetValues("pupilRightTex"), pupilRightTex); + eyeballLeftTex = ParseFolders(node.GetValues("eyeballLeftTex"), eyeballLeftTex); + eyeballRightTex = ParseFolders(node.GetValues("eyeballRightTex"), eyeballRightTex); + upTeeth01Tex = ParseFolders(node.GetValues("upTeeth01Tex"), upTeeth01Tex); + upTeeth02Tex = ParseFolders(node.GetValues("upTeeth02Tex"), upTeeth02Tex); + tongueTex = ParseFolders(node.GetValues("tongueTex"), tongueTex); + headTex = ParseFolders(node.GetValues("headTex"), headTex); + hairTex = ParseFolders(node.GetValues("hairTex"), hairTex); + + // Parse Normal Folders + pupilLeftNrm = ParseFolders(node.GetValues("pupilLeftNrm"), pupilLeftNrm); + pupilRightNrm = ParseFolders(node.GetValues("pupilRightNrm"), pupilRightNrm); + eyeballLeftNrm = ParseFolders(node.GetValues("eyeballLeftNrm"), eyeballLeftNrm); + eyeballRightNrm = ParseFolders(node.GetValues("eyeballRightNrm"), eyeballRightNrm); + upTeeth01Nrm = ParseFolders(node.GetValues("upTeeth01Nrm"), upTeeth01Nrm); + upTeeth02Nrm = ParseFolders(node.GetValues("upTeeth02Nrm"), upTeeth02Nrm); + tongueNrm = ParseFolders(node.GetValues("tongueNrm"), tongueNrm); + headNrm = ParseFolders(node.GetValues("headNrm"), headNrm); + hairNrm = ParseFolders(node.GetValues("hairNrm"), hairNrm); + } + + List ParseFolders(string[] paths, List list) + { + for (int i = 0; i < paths?.Length; i++) + { + list.AddUniqueRange(ParseFolder(paths[i])); + } + + return list; + } + + List ParseFolder(string path) + { + if (!path.EndsWith("/")) path += "/"; + + Texture[] textures = Resources.FindObjectsOfTypeAll(); + List list = new List(); + + if (Directory.Exists("GameData/" + path)) + { + string[] files = Directory.GetFiles("GameData/" + path)?.Where(f => Path.GetExtension(f) == ".dds" || Path.GetExtension(f) == ".png")?.ToArray(); + + for (int i = 0; i < files?.Length; i++) + { + if (!string.IsNullOrEmpty(files[i])) + { + string name = path + Path.GetFileNameWithoutExtension(files[i]); + Texture texture = textures.FirstOrDefault(t => t?.name == name); + + if (texture != null) + list.AddUnique(texture); + } + } + } + + return list; + } + + + // Order DataBase + internal static void OrderDB() + { + Debug.Log("HeadInfo.OrderDB", "Total HeadInfo count = " + List?.Count); + + DataBase.AddRange(List.Where(h => !string.IsNullOrEmpty(h?.name) && !string.IsNullOrEmpty(h?.collection))); + DataBase.AddRange(List.Where(h => !string.IsNullOrEmpty(h?.name) && string.IsNullOrEmpty(h?.collection))); + DataBase.AddRange(List.Where(h => string.IsNullOrEmpty(h?.name) && !string.IsNullOrEmpty(h?.collection))); + DataBase.AddRange(List.Where(h => h != null && string.IsNullOrEmpty(h?.name) && string.IsNullOrEmpty(h?.collection))); + + Debug.Log("HeadInfo.OrderDB", "Valid HeadInfo count = " + DataBase?.Count); + } + } + } +} + diff --git a/[Source]/SigmaReplacements/Heads/Properties/AssemblyInfo.cs b/[Source]/SigmaReplacements/Heads/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3695920 --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +using System.Reflection; + +[assembly: AssemblyTitle("SigmaReplacementsHeads")] +[assembly: AssemblyDescription("Sigma Replacements: Heads")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Sigma88")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Copyright (C) Sigma88 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: KSPAssembly("SigmaReplacementsHeads", 1, 0)] +[assembly: AssemblyVersion("1.0.0")] diff --git a/[Source]/SigmaReplacements/Heads/SettingsLoader.cs b/[Source]/SigmaReplacements/Heads/SettingsLoader.cs new file mode 100644 index 0000000..826ee62 --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/SettingsLoader.cs @@ -0,0 +1,45 @@ +using UnityEngine; + + +namespace SigmaReplacements +{ + [KSPAddon(KSPAddon.Startup.MainMenu, true)] + class SettingsLoader : MonoBehaviour + { + void Start() + { + // Debug Spam + if (bool.TryParse(UserSettings.ConfigNode?.GetValue("debug"), out bool debug) && debug) Debug.debug = true; + } + } + + namespace Heads + { + [KSPAddon(KSPAddon.Startup.MainMenu, true)] + class SettingsLoader : MonoBehaviour + { + void Start() + { + // User Settings + ConfigNode[] InfoNodes = UserSettings.ConfigNode.GetNodes("Kerbal"); + + for (int i = 0; i < InfoNodes?.Length; i++) + { + ConfigNode[] requirements = InfoNodes[i].GetNodes("Requirements"); + ConfigNode head = InfoNodes[i].GetNode("Head"); + + if (requirements.Length == 0) + requirements = new[] { new ConfigNode() }; + + for (int j = 0; j < requirements.Length; j++) + { + HeadInfo.List.Add(new HeadInfo(requirements[j], head)); + } + } + + if (HeadInfo.List?.Count > 0) + HeadInfo.OrderDB(); + } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/SigmaReplacementsHeads.csproj b/[Source]/SigmaReplacements/Heads/SigmaReplacementsHeads.csproj new file mode 100644 index 0000000..c25f19f --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/SigmaReplacementsHeads.csproj @@ -0,0 +1,63 @@ + + + + + Debug + AnyCPU + {D6D14E8B-1ED9-43D1-A9D2-4F3A4A6A6F4D} + Library + Properties + SigmaReplacements.Heads + SigmaReplacementsHeads + v3.5 + 512 + + + + true + full + false + ..\..\Distribution\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + False + ..\..\..\..\[References]\KerbalSpaceProgram\Assembly-CSharp.dll + + + False + ..\..\..\..\[References]\KerbalSpaceProgram\UnityEngine.dll + + + + + \ No newline at end of file diff --git a/[Source]/SigmaReplacements/Heads/Triggers.cs b/[Source]/SigmaReplacements/Heads/Triggers.cs new file mode 100644 index 0000000..2582b8b --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/Triggers.cs @@ -0,0 +1,160 @@ +using UnityEngine; +using System.Linq; +using KSP.UI.Screens; + + +namespace SigmaReplacements +{ + namespace Heads + { + [KSPAddon(KSPAddon.Startup.MainMenu, false)] + class MenuTriggers : MonoBehaviour + { + void Start() + { + Debug.Log("MenuTriggers", "Start"); + + Transform[] transforms = Resources.FindObjectsOfTypeAll(); + + int menu = 0; + + for (int i = 0; i < transforms?.Length; i++) + { + Transform transform = transforms[i]; + + if (transform?.name == "Kerbals") + { + foreach (Transform child in transform) + { + if (child?.gameObject != null && child?.GetComponent() == null) + child.gameObject.AddComponent(); + + UIKerbalMenu kerbal = child.GetComponent(); + kerbal.crewMember = UIKerbals.menuKerbals[menu]; + menu++; + + if (child?.gameObject != null && child?.GetComponent() == null) + child.gameObject.AddComponent(); + } + } + + if (transform?.name == "WernerVonKerman") + { + if (transform?.gameObject != null && transform?.GetComponent() == null) + transform.gameObject.AddComponent(); + + if (transform?.gameObject != null && transform?.GetComponent() == null) + transform.gameObject.AddComponent(); + } + } + } + } + + [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] + class KSCTriggers : MonoBehaviour + { + void Start() + { + Debug.Log("KSCTriggers", "Start"); + + Administration admin = Resources.FindObjectsOfTypeAll().FirstOrDefault(); + + if (admin?.gameObject != null && admin.GetComponent() == null) + { + admin.gameObject.AddComponent(); + } + + + string[] names = new string[] { "Strategy_Mortimer", "Strategy_ScienceGuy", "Strategy_PRGuy", "Strategy_MechanicGuy" }; + + Transform[] transforms = Resources.FindObjectsOfTypeAll(); + + for (int i = 0; i < transforms?.Length; i++) + { + Transform transform = transforms[i]; + + if (names.Contains(transform?.name)) + { + int index = names.IndexOf(transform?.name); + + if (transform?.gameObject != null && transform?.GetComponent() == null) + transform.gameObject.AddComponent(); + + if (transform?.gameObject != null && transform?.GetComponent() == null) + transform.gameObject.AddComponent(); + } + + if (transform?.name == "instructor_Gene") + { + if (transform?.gameObject != null && transform?.GetComponent() == null) + transform.gameObject.AddComponent(); + + if (transform?.gameObject != null && transform?.GetComponent() == null) + transform.gameObject.AddComponent(); + } + } + } + } + + internal class AdminTrigger : MonoBehaviour + { + void Start() + { + Debug.Log("AdminTrigger", "Start"); + + UIKerbalStrategy[] strategies = GetComponentsInChildren(); + + for (int i = 0; i < strategies?.Length; i++) + { + if (strategies[i] != null) + strategies[i].Apply(); + } + } + } + + [KSPAddon(KSPAddon.Startup.MainMenu, true)] + class FlightTriggers : MonoBehaviour + { + void Start() + { + DontDestroyOnLoad(this); + + Debug.Log("FlightTriggers", "Start"); + + GameEvents.onVesselLoaded.Add(OnVesselLoaded); + GameEvents.onVesselCreate.Add(OnVesselLoaded); + GameEvents.onCrewOnEva.Add(OnCrewOnEva); + } + + void OnVesselLoaded(Vessel vessel) + { + Debug.Log("FlightTriggers.OnVesselLoaded", "Vessel = " + vessel); + + KerbalEVA[] kerbalEVAs = vessel.GetComponentsInChildren(true); + + for (int i = 0; i < kerbalEVAs?.Length; i++) + { + if (kerbalEVAs[i]?.GetComponent() == null) + kerbalEVAs[i].gameObject.AddComponent(); + } + + kerbalExpressionSystem[] kerbalIVAs = Resources.FindObjectsOfTypeAll(); + + for (int i = 0; i < kerbalIVAs?.Length; i++) + { + if (kerbalIVAs[i]?.GetComponent() == null) + kerbalIVAs[i].gameObject.AddComponent(); + } + } + + void OnCrewOnEva(GameEvents.FromToAction action) + { + Debug.Log("FlightTriggers.OnCrewOnEva", "Part = " + action.to); + + KerbalEVA kerbalEVA = action.to.GetComponent(); + if (kerbalEVA.GetComponent() == null) + kerbalEVA.gameObject.AddComponent(); + } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/UIKerbals.cs b/[Source]/SigmaReplacements/Heads/UIKerbals.cs new file mode 100644 index 0000000..aaa0530 --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/UIKerbals.cs @@ -0,0 +1,135 @@ +using UnityEngine; + + +namespace SigmaReplacements +{ + namespace Heads + { + internal class UIKerbals : MonoBehaviour + { + // Main Menu + static CrewMember mun1 = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Bob Kerman", ProtoCrewMember.Gender.Male, "Scientist", true, false, 0.3f, 0.1f, 0); + static CrewMember orbit1 = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Bill Kerman", ProtoCrewMember.Gender.Male, "Engineer", true, false, 0.5f, 0.8f, 0); + static CrewMember orbit2 = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Bob Kerman", ProtoCrewMember.Gender.Male, "Scientist", true, false, 0.3f, 0.1f, 0); + static CrewMember orbit3 = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Jebediah Kerman", ProtoCrewMember.Gender.Male, "Pilot", true, true, 0.5f, 0.5f, 0); + static CrewMember orbit4 = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Valentina Kerman", ProtoCrewMember.Gender.Female, "Pilot", true, true, 0.55f, 0.4f, 0); + // Instructors + static CrewMember gene = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Gene Kerman", ProtoCrewMember.Gender.Male, "Instructor", false, false, 0.6f, 0.45f, 0); + static CrewMember werner = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Wernher von Kerman", ProtoCrewMember.Gender.Male, "Instructor", false, false, 0.25f, 0.25f, 0); + // Strategy + static CrewMember mort = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Mortimer Kerman", ProtoCrewMember.Gender.Male, "StockBroker", false, false, 0.65f, 0.35f, 0); + static CrewMember linus = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Linus Kerman", ProtoCrewMember.Gender.Male, "Researcher", false, false, 0.35f, 0.3f, 0); + static CrewMember walt = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Walt Kerman", ProtoCrewMember.Gender.Male, "Marketer", false, false, 0.45f, 0.9f, 0); + static CrewMember gus = new CrewMember(ProtoCrewMember.KerbalType.Crew, "Gus Kerman", ProtoCrewMember.Gender.Male, "Mechanic", false, false, 0.45f, 0.45f, 0); + + internal static CrewMember[] menuKerbals = new[] { mun1, orbit1, orbit2, orbit3, orbit4 }; + internal static CrewMember[] instructors = new[] { gene, werner }; + internal static CrewMember[] strategy = new[] { mort, linus, walt, gus }; + } + + internal class UIKerbalMenu : MonoBehaviour + { + internal CrewMember crewMember; + } + + internal class UIKerbalWerner : MonoBehaviour + { + internal CrewMember crewMember { get { return UIKerbals.instructors[1]; } } + } + + internal class UIKerbalGene : MonoBehaviour + { + internal CrewMember crewMember { get { return UIKerbals.instructors[0]; } } + } + + internal class UIKerbalStrategy : MonoBehaviour + { + static string[] names = new string[] { "Strategy_Mortimer(Clone)", "Strategy_ScienceGuy(Clone)", "Strategy_PRGuy(Clone)", "Strategy_MechanicGuy(Clone)" }; + + internal CrewMember crewMember + { + get + { + for (int i = 0; i < names.Length; i++) + { + if (gameObject?.name == names[i]) + return UIKerbals.strategy[i]; + } + return null; + } + } + + internal void Apply() + { + CustomHead head = GetComponent(); + if (head != null) head.Apply(); + } + } + + [KSPAddon(KSPAddon.Startup.MainMenu, true)] + internal class UIKerbalLoader : MonoBehaviour + { + void Awake() + { + Debug.Log("UIKerbalLoader", "Awake"); + + ConfigNode[] MenuKerbals = UserSettings.ConfigNode.GetNodes("MenuKerbal"); + + for (int i = 0; i < MenuKerbals?.Length; i++) + { + if (int.TryParse(MenuKerbals[i]?.GetValue("index"), out int index) && index < UIKerbals.menuKerbals?.Length) + { + UIKerbals.menuKerbals.Load(MenuKerbals[i], index); + } + } + + + ConfigNode[] Instructors = UserSettings.ConfigNode.GetNodes("Instructor"); + + for (int i = 0; i < Instructors?.Length; i++) + { + if (int.TryParse(Instructors[i]?.GetValue("index"), out int index) && index < UIKerbals.instructors?.Length) + { + UIKerbals.instructors.Load(Instructors[i], index); + } + } + + + ConfigNode[] StrategyKerbals = UserSettings.ConfigNode.GetNodes("StrategyKerbal"); + + for (int i = 0; i < StrategyKerbals?.Length; i++) + { + if (int.TryParse(StrategyKerbals[i]?.GetValue("index"), out int index) && index < UIKerbals.strategy?.Length) + { + UIKerbals.strategy.Load(StrategyKerbals[i], index); + } + } + } + } + + internal class CrewMember : ProtoCrewMember + { + internal new string name = ""; + + internal CrewMember(KerbalType type, string name, Gender gender, string trait, bool veteran, bool isBadass, float courage, float stupidity, int experienceLevel) : base(type, name) + { + Debug.Log("CrewMember", "new CrewMember from stats"); + + this.type = type; + this.name = name; + this.gender = gender; + this.trait = trait; + this.veteran = veteran; + this.isBadass = isBadass; + this.courage = courage; + this.stupidity = stupidity; + this.experienceLevel = experienceLevel; + } + + CrewMember(KerbalType type) : base(type) { } + CrewMember(ProtoCrewMember copyOf) : base(copyOf) { } + CrewMember(KerbalType type, string name) : base(type, name) { } + CrewMember(Game.Modes mode, ConfigNode node, KerbalType crewType = KerbalType.Crew) : base(mode, node, crewType) { } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/UserSettings.cs b/[Source]/SigmaReplacements/Heads/UserSettings.cs new file mode 100644 index 0000000..72cf311 --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/UserSettings.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Linq; +using System.Reflection; +using UnityEngine; + + +namespace SigmaReplacements +{ + [KSPAddon(KSPAddon.Startup.Instantly, true)] + internal class UserSettings : MonoBehaviour + { + internal static ConfigNode ConfigNode + { + get + { + return GameDatabase.Instance?.GetConfigs(nodeName)?.FirstOrDefault(n => n.url == (folder.Substring(9) + file + "/" + nodeName))?.config; + } + } + + static string folder = "GameData/Sigma/Replacements/"; + static string file = "Settings"; + internal static string nodeName = "SigmaReplacements"; + + void Awake() + { + string path = Assembly.GetExecutingAssembly().Location.Replace('\\', '/'); + while (path.Substring(1).Contains("GameData/")) + path = path.Substring(1 + path.Substring(1).IndexOf("GameData/")); + + if (!Directory.Exists(folder)) + { + UnityEngine.Debug.Log(Debug.Tag + " WARNING: Missing folder => " + folder); + return; + } + + if (!File.Exists(folder + file + ".cfg")) + { + UnityEngine.Debug.Log(Debug.Tag + " WARNING: Missing file => " + folder + file + ".cfg"); + + File.WriteAllLines(folder + file + ".cfg", new[] { nodeName + " {}" }); + return; + } + + if (ConfigNode.Load(folder + file + ".cfg")?.HasNode(nodeName) != true) + { + UnityEngine.Debug.Log(Debug.Tag + " WARNING: Missing node => " + folder + file + "/" + nodeName); + + File.AppendAllText(folder + file + ".cfg", "\r\n" + nodeName + " {}"); + } + } + + void Start() + { + var configs = GameDatabase.Instance.GetConfigs(nodeName); + + for (int i = 0; i < configs?.Length; i++) + { + if (configs[i].url != (folder.Substring(9) + file + "/" + nodeName)) + configs[i].parent.configs.Remove(configs[i]); + } + } + } +} diff --git a/[Source]/SigmaReplacements/Heads/Version.cs b/[Source]/SigmaReplacements/Heads/Version.cs new file mode 100644 index 0000000..2c7b6f2 --- /dev/null +++ b/[Source]/SigmaReplacements/Heads/Version.cs @@ -0,0 +1,19 @@ +using UnityEngine; + + +namespace SigmaReplacements +{ + namespace Heads + { + [KSPAddon(KSPAddon.Startup.Instantly, true)] + public class Version : MonoBehaviour + { + public static readonly System.Version number = new System.Version("0.1.0"); + + void Awake() + { + UnityEngine.Debug.Log("[SigmaLog] Version Check: Sigma Replacements: Heads v" + number); + } + } + } +} diff --git a/[Source]/SigmaReplacements/SigmaReplacements.sln b/[Source]/SigmaReplacements/SigmaReplacements.sln new file mode 100644 index 0000000..51a1979 --- /dev/null +++ b/[Source]/SigmaReplacements/SigmaReplacements.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.16 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SigmaReplacementsHeads", "Heads\SigmaReplacementsHeads.csproj", "{D6D14E8B-1ED9-43D1-A9D2-4F3A4A6A6F4D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SigmaReplacementsSuits", "Suits\SigmaReplacementsSuits.csproj", "{B3769F47-5A16-43C9-995F-1B3B15BE97CC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SigmaReplacementsTextures", "Textures\SigmaReplacementsTextures.csproj", "{85E7DC1E-15EA-4C98-B6D3-52CB27BB9526}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D6D14E8B-1ED9-43D1-A9D2-4F3A4A6A6F4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6D14E8B-1ED9-43D1-A9D2-4F3A4A6A6F4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6D14E8B-1ED9-43D1-A9D2-4F3A4A6A6F4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6D14E8B-1ED9-43D1-A9D2-4F3A4A6A6F4D}.Release|Any CPU.Build.0 = Release|Any CPU + {B3769F47-5A16-43C9-995F-1B3B15BE97CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3769F47-5A16-43C9-995F-1B3B15BE97CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3769F47-5A16-43C9-995F-1B3B15BE97CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3769F47-5A16-43C9-995F-1B3B15BE97CC}.Release|Any CPU.Build.0 = Release|Any CPU + {85E7DC1E-15EA-4C98-B6D3-52CB27BB9526}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85E7DC1E-15EA-4C98-B6D3-52CB27BB9526}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85E7DC1E-15EA-4C98-B6D3-52CB27BB9526}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85E7DC1E-15EA-4C98-B6D3-52CB27BB9526}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E50D5E74-B8EE-48C9-9D22-5FCF86BB4E44} + EndGlobalSection +EndGlobal