Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using KSP.UI;
- using System;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- namespace TRP_Hiring
- {
- [KSPAddon(KSPAddon.Startup.SpaceCentre, false)]
- class KSI_EditACPrefabs_SpaceCentre : MonoBehaviour
- {
- private void Awake() { gameObject.AddComponent<KSI_EditACPrefab>(); }
- }
- [KSPAddon(KSPAddon.Startup.EditorAny, false)]
- class KSI_EditACPrefabs_Editor : KSI_EditACPrefabs_SpaceCentre { }
- class KSI_EditACPrefab : MonoBehaviour
- {
- private void Awake()
- {
- try
- {
- var prefab = GetAstronautComplexScreenPrefab();
- // There isn't really any specific component we can look for to make it easier
- // without also making things less clear so a long transform path it is
- var listAndScrollbar = prefab.transform.Find(
- "RootCanvas/AstronautComplex anchor/GameObject/bg and aspectFitter/CrewAssignmentDialog");
- if (listAndScrollbar == null) throw new Exception("Couldn't find dialog Transform");
- // temporarily detach Panel/scrolllist_applicants
- // we can't just delete it (or set it inactive apparently) or AstronautComplex will throw an exception
- //
- // we CAN, however, delete all the UI bits from it
- var panel = listAndScrollbar.transform.Find("Panel");
- Debug.Log("var Panel Worked");
- // panel.SetParent(null);
- // Debug.Log("var Panel set to null");
- //panel.GetComponentsInChildren<ScrollRect>(true).ToList().ForEach(Destroy);
- //panel.GetComponentsInChildren<Image>(true).ToList().ForEach(Destroy);
- //panel.GetComponentsInChildren<CanvasRenderer>(true).ToList().ForEach(Destroy);
- //panel.GetComponentsInChildren<Mask>(true).ToList().ForEach(Destroy);
- //panel.GetComponentsInChildren<VerticalLayoutGroup>(true).ToList().ForEach(Destroy);
- //panel.GetComponentsInChildren<ContentSizeFitter>(true).ToList().ForEach(Destroy);
- Debug.Log("Destroy Set");
- // destroy all the other children
- foreach (Transform ch in listAndScrollbar.transform)
- Destroy(ch.gameObject);
- // reattach panel - AstronautComplex needs something inside here for something but now it won't be
- // rendering anything
- // panel.SetParent(listAndScrollbar);
- // we won't know what the dimensions our replacement will take until the UI is actually spawned,
- // so we'll slip a little trojan right alongside the component (RectTransform) that will contain
- // that info. This helper will create the GUI
- // listAndScrollbar.gameObject.AddComponent<CustomAstronautComplexUISpawner>();
- }
- catch (Exception e)
- {
- Debug.LogError("Failed to edit Astronaut Complex: " + e);
- }
- // Destroy(gameObject); // once the spawner is attached to the prefab, this object no longer needed
- }
- private static UICanvasPrefab GetAstronautComplexScreenPrefab()
- {
- // the scene has just been entered and the AC shouldn't have spawned yet
- var spawner = FindObjectOfType<KSP.UI.Screens.ACSceneSpawner>();
- if (spawner == null)
- throw new Exception("Did not find AC spawner");
- if (spawner.ACScreenPrefab == null)
- throw new Exception("AC spawner prefab is null");
- // this might look bizarre, but Unity seems to crash if you mess with this prefab like we're
- // about to do. Luckily ACScreenPrefab is public so we'll quickly make a copy and use that
- // as the "prefab" instead
- var prefab = Instantiate(spawner.ACScreenPrefab);
- prefab.gameObject.SetActive(false);
- spawner.ACScreenPrefab = prefab;
- Debug.Log(prefab.name);
- return prefab;
- }
- }
- // We'll have to wait until the AstronautComplex UI is actually spawned in
- // order to grab the dimensions of the area we'll be replacing. All the
- // visual bits should be handled by now so as soon as the panel is actually
- // visible, we can grab those dimensions and create the custom GUI using them
- class CustomAstronautComplexUISpawner : MonoBehaviour
- {
- private void Start()
- {
- #if DEBUG
- DebugDimensions();
- #endif
- // foreach (var textComponent in FindObjectsOfType<Component>()) Debug.Log(textComponent.name); This gave us the names of various 'parts'.
- Transform textTransform = FindObjectOfType<Text>().transform;
- while(textTransform != null)
- {
- Debug.Log(textTransform.name);
- textTransform = textTransform.transform.parent;
- }
- var vectors = new Vector3[4];
- var uiCam = UIMasterController.Instance.GetComponentInChildren<UIMainCamera>();
- if (uiCam == null)
- {
- Debug.LogError("UIMainCamera not found");
- return;
- }
- var camera = uiCam.GetComponent<Camera>();
- if (camera == null)
- {
- Debug.LogError("Camera attached to UIMainCamera not found");
- return;
- }
- GetComponent<RectTransform>().GetWorldCorners(vectors);
- for (int i = 0; i < 4; ++i)
- vectors[i] = camera.WorldToScreenPoint(vectors[i]);
- // note: these are in screen space
- var rect = new Rect(vectors[1].x, Screen.height - vectors[1].y, vectors[2].x - vectors[1].x,
- vectors[2].y - vectors[3].y);
- gameObject.AddComponent<CustomAstronautComplexUI>().Initialize(rect);
- Destroy(this);
- }
- private void DebugDimensions()
- {
- print("Debugging dimensions");
- var vectors = new Vector3[4];
- var camera = UIMasterController.Instance.GetComponentInChildren<UIMainCamera>().GetComponent<Camera>();
- GetComponent<RectTransform>().GetWorldCorners(vectors);
- foreach (var item in vectors)
- print("Corner: " + item);
- for (int i = 0; i < 4; ++i)
- {
- vectors[i] = camera.GetComponent<Camera>().WorldToScreenPoint(vectors[i]);
- print("Transformed corner: " + vectors[i]);
- }
- }
- }
- /// <summary>
- /// This bit draws the GUI using the legacy GUI. You could easily use the new GUI instead if you prefer
- /// </summary>
- class CustomAstronautComplexUI : MonoBehaviour
- {
- private Rect _areaRect = new Rect(-500f, -500f, 200f, 200f);
- private Vector2 _guiScalar = Vector2.one;
- private Vector2 _guiPivot = Vector2.zero;
- private Vector2 _scrollbar = Vector2.zero;
- private readonly Texture2D _portraitMale = AssetBase.GetTexture("kerbalicon_recruit");
- private readonly Texture2D _portraitFemale = AssetBase.GetTexture("kerbalicon_recruit_female");
- private GUIStyle _backgroundStyle; // the background of the whole area our GUI will cover
- private GUIStyle _scrollviewStyle; // style of the whole scrollview
- private GUIStyle _nameStyle; // style used for kerbal names
- private GUIStyle _listItemEntryStyle; // style used for background of each kerbal entry
- private void Awake()
- {
- enabled = false;
- _backgroundStyle = new GUIStyle(HighLogic.Skin.window)
- {
- padding = new RectOffset(),
- border = new RectOffset()
- };
- _scrollviewStyle = new GUIStyle(HighLogic.Skin.scrollView)
- {
- padding = new RectOffset(),
- border = new RectOffset()
- };
- _nameStyle = new GUIStyle(HighLogic.Skin.label);
- _nameStyle.fontSize = (int)(_nameStyle.fontSize * 1.6);
- _nameStyle.fontStyle = FontStyle.Bold;
- // set up a style that will cause the moused over entry to highlight itself. Makes the UI feel a little more
- // interactive
- _listItemEntryStyle = new GUIStyle(HighLogic.Skin.box);
- var clone = Instantiate(_listItemEntryStyle.normal.background);
- var pixels = clone.GetPixels32();
- // poor man's lighting algorithm
- for (int i = 0; i < pixels.Length; ++i)
- pixels[i] = new Color32(
- Math.Min((byte)255, (byte)(pixels[i].r + 25)),
- Math.Min((byte)255, (byte)(pixels[i].g + 25)),
- Math.Min((byte)255, (byte)(pixels[i].b + 25)),
- Math.Min((byte)255, (byte)(pixels[i].a + 25)));
- clone.SetPixels32(pixels);
- clone.Apply();
- _listItemEntryStyle.hover.background = clone;
- }
- public void Initialize(Rect guiRect)
- {
- var uiScaleMultiplier = GameSettings.UI_SCALE;
- // the supplied rect will have the UI scalar already factored in
- //
- // to respect the player's UI scale wishes, work out what the unscaled rect
- // would be. Then we'll apply the scale again in OnGUI so all of our GUILayout elements
- // will respect the multiplier
- var correctedRect = new Rect(guiRect.x, guiRect.y, guiRect.width / uiScaleMultiplier,
- guiRect.height / uiScaleMultiplier);
- _areaRect = correctedRect;
- _guiPivot = new Vector2(_areaRect.x, _areaRect.y);
- _guiScalar = new Vector2(GameSettings.UI_SCALE, GameSettings.UI_SCALE);
- enabled = true;
- }
- private static readonly string[] FlavorText = new[]
- {
- "Loves space! Does not have any other qualifications",
- "Enjoys explosions of all kinds",
- "Was dared to do it",
- "Craves fame",
- "Might have some kind of death wish",
- "Heard it paid well",
- "Wants to go very fast"
- };
- // these slightly reduce garbage created by avoiding array allocations which is one reason OnGUI
- // is so terrible
- private static readonly GUILayoutOption[] DefaultLayoutOptions = new GUILayoutOption[0];
- private static readonly GUILayoutOption[] PortraitOptions = { GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false) };
- private static readonly GUILayoutOption[] FixedWidth = { GUILayout.Width(220f) };
- private static readonly GUILayoutOption[] HireButtonOptions = { GUILayout.ExpandHeight(true), GUILayout.MaxHeight(40f), GUILayout.MinWidth(40f) };
- private static readonly GUILayoutOption[] StatOptions = { GUILayout.MaxWidth(100f) };
- private static readonly GUILayoutOption[] FlavorTextOptions = { GUILayout.MaxWidth(200f) };
- private void OnGUI()
- {
- GUIUtility.ScaleAroundPivot(_guiScalar, _guiPivot);
- GUILayout.BeginArea(_areaRect, _backgroundStyle);
- {
- _scrollbar = GUILayout.BeginScrollView(_scrollbar, false, true, HighLogic.Skin.horizontalScrollbar, HighLogic.Skin.verticalScrollbar, _scrollviewStyle, DefaultLayoutOptions);
- {
- for (int i = 0; i < 25; ++i) // make sure the scrollbars and stuff works as expected
- {
- bool male = i % 2 == 0;
- GUILayout.BeginHorizontal(_listItemEntryStyle, DefaultLayoutOptions);
- {
- GUILayout.Space(8f);
- GUILayout.Box(male ? _portraitMale : _portraitFemale, GUIStyle.none, PortraitOptions);
- GUILayout.BeginVertical(DefaultLayoutOptions);
- {
- GUILayout.Label(male ? "John Kerman" : "Jane Kerman", _nameStyle, FixedWidth);
- GUILayout.FlexibleSpace();
- // indent flavor text just a bit
- GUILayout.BeginHorizontal(DefaultLayoutOptions);
- {
- GUILayout.Space(20f);
- GUILayout.Label(FlavorText[i % FlavorText.Length], FlavorTextOptions);
- }
- GUILayout.EndHorizontal();
- }
- GUILayout.EndVertical();
- GUILayout.FlexibleSpace();
- GUILayout.BeginVertical(DefaultLayoutOptions);
- {
- GUILayout.FlexibleSpace();
- GUILayout.Label("Courage here", StatOptions);
- GUILayout.Label("Stupidity here", StatOptions);
- GUILayout.FlexibleSpace();
- }
- GUILayout.EndVertical();
- GUILayout.BeginVertical(DefaultLayoutOptions);
- {
- GUILayout.FlexibleSpace();
- GUILayout.Button("Hire", HighLogic.Skin.button, HireButtonOptions); // logic to hire Kerbal here
- GUILayout.FlexibleSpace();
- }
- GUILayout.EndVertical();
- }
- GUILayout.EndHorizontal();
- }
- }
- GUILayout.EndScrollView();
- }
- GUILayout.EndArea();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement