22using System.Collections.Generic;
33using System.Linq;
44using UnityEngine;
5+ using UnityEngine.UI;
6+ using KSP.UI;
7+ using IState = KSP.UI.UIStateImage.ImageState;
8+ using BState = KSP.UI.UIStateToggleButton.ButtonState;
9+ using Type = ProtoCrewMember.KerbalType;
10+ using Roster = ProtoCrewMember.RosterStatus;
511
612
713namespace SigmaReplacements
@@ -10,7 +16,7 @@ internal static class Extensions
1016 {
1117 internal static List<Info> Order(this List<Info> List)
1218 {
13- Debug.Log(List?. GetType()?.Name + ".Order", "Total count = " + List?.Count);
19+ Debug.Log(" List<" + List?.FirstOrDefault()?. GetType()?.Name + "> .Order", "Total count = " + List?.Count);
1420
1521 List<Info> DataBase = new List<Info>();
1622
@@ -19,7 +25,7 @@ internal static List<Info> Order(this List<Info> List)
1925 DataBase.AddRange(List.Where(h => string.IsNullOrEmpty(h?.name) && !string.IsNullOrEmpty(h?.collection)));
2026 DataBase.AddRange(List.Where(h => h != null && string.IsNullOrEmpty(h?.name) && string.IsNullOrEmpty(h?.collection)));
2127
22- Debug.Log(List?. GetType()?.Name + ".Order", "Valid count = " + List ?.Count);
28+ Debug.Log(" List<" + List?.FirstOrDefault()?. GetType()?.Name + "> .Order", "Valid count = " + DataBase ?.Count);
2329
2430 return DataBase;
2531 }
@@ -31,7 +37,8 @@ internal static void Load(this CrewMember[] array, ConfigNode node, int index)
3137
3238 array[index] = new CrewMember
3339 (
34- stats?.rosterStatus ?? kerbal.type,
40+ (int?)stats?.status > 3 ? 0 : (Type?)(int?)stats?.status ?? kerbal.type,
41+ (int?)stats?.status > 3 ? (Roster)((int)stats.status - 4) : kerbal.rosterStatus,
3542 !string.IsNullOrEmpty(stats?.name) ? stats.name : kerbal.name,
3643 stats?.gender ?? kerbal.gender,
3744 stats?.trait?.Length > 0 && !string.IsNullOrEmpty(stats.trait[0]) ? stats.trait[0] : kerbal.trait,
@@ -51,7 +58,7 @@ internal static void SetColor(this Material material, Color? color)
5158 }
5259 }
5360
54- internal static void SetTexture(this Material material, Texture newTex)
61+ internal static void SetTexture(this Material material, Texture newTex, bool flip = false )
5562 {
5663 if (material != null && newTex != null)
5764 {
@@ -64,6 +71,13 @@ internal static void SetTexture(this Material material, Texture newTex)
6471 }
6572
6673 material.mainTexture = newTex;
74+
75+ if (flip)
76+ {
77+ Vector2 scale = material.GetTextureScale("_MainTex");
78+ scale.x *= -1;
79+ material.SetTextureScale("_MainTex", scale);
80+ }
6781 }
6882 }
6983
@@ -85,36 +99,229 @@ internal static void SetNormal(this Material material, Texture newTex)
8599 }
86100 }
87101
88- internal static Texture At (this List<Texture> right , Texture item, List<Texture> left )
102+ internal static void SetEmissive (this Material material , Texture newTex, bool flip = false )
89103 {
90- if (item != null && left.Contains(item) && right?.Count > left.IndexOf(item))
91- return right[left.IndexOf(item)];
92- return null;
104+ if (material?.HasProperty("_Emissive") == true && newTex != null)
105+ {
106+ Texture oldTex = material.GetTexture("_Emissive");
107+
108+ if (oldTex != null)
109+ {
110+ newTex.anisoLevel = oldTex.anisoLevel;
111+ newTex.wrapMode = oldTex.wrapMode;
112+ }
113+
114+ material.SetTexture("_Emissive", newTex);
115+
116+ if (flip)
117+ {
118+ Vector2 scale = material.GetTextureScale("_Emissive");
119+ scale.x *= -1;
120+ material.SetTextureScale("_Emissive", scale);
121+ }
122+ }
93123 }
94124
95- internal static Color? At (this List<Color> right , Color? item, List<Color> left )
125+ internal static void SetTintColor (this Material material , Color? color, Material stockMaterial = null )
96126 {
97- if (item != null && left.Contains((Color)item) && right?.Count > left.IndexOf((Color)item))
98- return right[left.IndexOf((Color)item)];
99- return null;
127+ if (material != null)
128+ {
129+ if (color != null)
130+ material.SetColor("_TintColor", (Color)color);
131+
132+ else
133+
134+ if (stockMaterial?.HasProperty("_TintColor") == true)
135+ material.SetColor("_TintColor", stockMaterial.GetColor("_TintColor"));
136+ }
100137 }
101138
102- internal static Texture Pick (this List<Texture> list, ProtoCrewMember kerbal, bool useGameSeed )
139+ internal static void SetMainTexture (this Material material, Texture newTex, Material stockMaterial = null )
103140 {
104- if (list.Count == 1)
105- return list[0];
106- else if (list.Count > 1)
141+ if (material != null)
142+ {
143+ if (newTex == null)
144+ newTex = stockMaterial?.GetTexture("_MainTexture");
145+
146+ if (newTex == null) return;
147+
148+ Texture oldTex = material?.GetTexture("_MainTexture");
149+
150+ if (oldTex == newTex) return;
151+
152+ if (oldTex != null)
153+ {
154+ newTex.anisoLevel = oldTex.anisoLevel;
155+ newTex.wrapMode = oldTex.wrapMode;
156+ }
157+
158+ material.SetTexture("_MainTexture", newTex);
159+ }
160+ }
161+
162+ internal static void SetColor(this Image image, Color? color, Image stockImage = null)
163+ {
164+ if (image != null)
165+ {
166+ image.color = color ?? stockImage?.color ?? image.color;
167+ }
168+ }
169+
170+ internal static void SetTexture(this Image image, Texture newTex, Image stockImage = null, bool fit = false, bool resize = false, Vector2? resolution = null)
171+ {
172+ if (image?.sprite != null)
173+ {
174+ Vector2 scale = new Vector2(1, 1);
175+ if (stockImage?.sprite?.rect != null)
176+ {
177+ scale.x = stockImage.sprite.rect.width;
178+ scale.y = stockImage.sprite.rect.height;
179+ }
180+
181+ image.sprite = image.sprite.SetTexture(newTex ?? stockImage?.sprite?.texture, fit);
182+
183+ if (resize)
184+ {
185+ scale.x /= image.sprite.rect.width / (resolution?.x ?? 1);
186+ scale.y /= image.sprite.rect.height / (resolution?.y ?? 1);
187+
188+ if (stockImage?.rectTransform?.localScale != null)
189+ image.rectTransform.localScale = stockImage.rectTransform.localScale;
190+
191+ image.rectTransform.localScale = new Vector3(image.rectTransform.localScale.x / scale.x, image.rectTransform.localScale.y / scale.y, image.rectTransform.localScale.z);
192+ }
193+ }
194+ }
195+
196+ internal static void SetColor(this UIStateImage button, Color? color, UIStateImage stockButton)
197+ {
198+ Image image = button?.GetComponent<Image>();
199+
200+ if (image != null)
201+ {
202+ Image stockImage = stockButton?.GetComponent<Image>();
203+ image.SetColor(color, stockImage);
204+ }
205+ }
206+
207+ internal static void SetTexture(this UIStateImage button, Texture newTex, UIStateImage stockButton = null)
208+ {
209+ for (int i = 0; i < button?.states?.Length; i++)
210+ {
211+ IState state = button?.states[i];
212+
213+ if (state != null)
214+ {
215+ Texture stockTexture = stockButton?.states?.Length > i ? stockButton.states[i]?.sprite?.texture : null;
216+ state.sprite = state.sprite.SetTexture(newTex ?? stockTexture);
217+ }
218+ }
219+ }
220+
221+ internal static void SetColor(this UIStateToggleButton toggle, Color? color, UIStateToggleButton stockButton = null)
222+ {
223+ Image image = toggle?.GetComponent<Image>();
224+
225+ if (image != null && color != null)
226+ {
227+ Image stockImage = stockButton?.GetComponent<Image>();
228+ image.SetColor(color, stockImage);
229+ }
230+ }
231+
232+ internal static void SetTexture(this UIStateToggleButton toggle, Texture newTex, UIStateToggleButton stockToggle = null)
233+ {
234+ if (toggle != null)
235+ {
236+ BState[] states = { toggle.stateTrue, toggle.stateFalse };
237+ BState[] stockStates = { stockToggle?.stateTrue, stockToggle?.stateFalse };
238+ for (int i = 0; i < states?.Length; i++)
239+ {
240+ BState stock = stockStates[i];
241+ states[i].disabled = states[i].disabled.SetTexture(newTex ?? stock?.disabled?.texture);
242+ states[i].normal = states[i].normal.SetTexture(newTex ?? stock?.normal?.texture);
243+ states[i].highlight = states[i].highlight.SetTexture(newTex ?? stock?.highlight?.texture);
244+ states[i].pressed = states[i].pressed.SetTexture(newTex ?? stock?.pressed?.texture);
245+ }
246+ }
247+ }
248+
249+ internal static Sprite SetTexture(this Sprite sprite, Texture newTex, bool fit = false)
250+ {
251+ if (sprite == null || newTex == null) return sprite;
252+ if (sprite.texture == newTex) return sprite;
253+
254+ Texture oldTex = sprite?.texture;
255+
256+ if (oldTex != null)
257+ {
258+ newTex.anisoLevel = oldTex.anisoLevel;
259+ newTex.wrapMode = oldTex.wrapMode;
260+ }
261+
262+ Rect rect = sprite.rect;
263+ Vector2 pivot = sprite.pivot;
264+
265+ if (fit)
266+ {
267+ rect.width = newTex.width;
268+ rect.height = newTex.height;
269+ pivot = new Vector2(newTex.width * 0.5f, newTex.height * 0.5f);
270+ }
271+
272+ return Sprite.Create((Texture2D)newTex, rect, pivot);
273+ }
274+
275+ internal static Color? At(this List<Color?> list, Color? element, List<Color?> reference, ProtoCrewMember kerbal, bool useGameSeed, string name = "")
276+ {
277+ if (reference.Contains(element) && list?.Count > reference.IndexOf(element))
278+ return list[reference.IndexOf(element)];
279+ else
280+ return list.Pick(kerbal, useGameSeed, name);
281+ }
282+
283+ internal static Texture At(this List<Texture> list, Texture element, List<Texture> reference, ProtoCrewMember kerbal, bool useGameSeed, string name = "")
284+ {
285+ if (reference.Contains(element) && list?.Count > reference.IndexOf(element))
286+ return list[reference.IndexOf(element)];
287+ else
288+ return list.Pick(kerbal, useGameSeed, name);
289+ }
290+
291+ internal static Vector2? At(this List<Vector2?> list, Texture element, List<Texture> reference, ProtoCrewMember kerbal, bool useGameSeed, string name = "")
292+ {
293+ if (reference.Contains(element) && list?.Count > reference.IndexOf(element))
294+ return list[reference.IndexOf(element)];
295+ else
296+ return list.Pick(kerbal, useGameSeed, name);
297+ }
298+
299+ internal static Texture Pick(this List<Texture> list, ProtoCrewMember kerbal, bool useGameSeed, string name = "")
300+ {
301+ if (list?.Count > 1 && kerbal != null)
107302 return list[kerbal.Hash(useGameSeed) % list.Count];
303+ else if (list?.Count > 0)
304+ return list[name.Hash(useGameSeed) % list.Count];
108305 else
109306 return null;
110307 }
111308
112- internal static Color? Pick(this List<Color> list, ProtoCrewMember kerbal, bool useGameSeed)
309+ internal static Color? Pick(this List<Color? > list, ProtoCrewMember kerbal, bool useGameSeed, string name = "" )
113310 {
114- if (list.Count == 1)
115- return list[0];
116- else if (list.Count > 1)
311+ if (list?.Count > 1 && kerbal != null)
117312 return list[kerbal.Hash(useGameSeed) % list.Count];
313+ else if (list?.Count > 0)
314+ return list[name.Hash(useGameSeed) % list.Count];
315+ else
316+ return null;
317+ }
318+
319+ internal static Vector2? Pick(this List<Vector2?> list, ProtoCrewMember kerbal, bool useGameSeed, string name = "")
320+ {
321+ if (list?.Count > 1 && kerbal != null)
322+ return list[kerbal.Hash(useGameSeed) % list.Count];
323+ else if (list?.Count > 0)
324+ return list[name.Hash(useGameSeed) % list.Count];
118325 else
119326 return null;
120327 }
@@ -133,5 +340,16 @@ internal static int Hash(this ProtoCrewMember kerbal, bool useGameSeed)
133340
134341 return h;
135342 }
343+
344+ internal static int Hash(this string name, bool useGameSeed)
345+ {
346+ name = name ?? "";
347+
348+ int h = Math.Abs(name.GetHashCode());
349+
350+ if (useGameSeed && HighLogic.CurrentGame != null) h += Math.Abs(HighLogic.CurrentGame.Seed);
351+
352+ return h;
353+ }
136354 }
137355}
0 commit comments