Jump to content

No method override for Astronaut Complex?


Recommended Posts

I noticed that the GUI for several of the buildings seems to prevent override methods. So I can't re-do part of the astronaut complex for my hiring kerbals mod I am working on. I'm working from the C# angle from the limited documentation from the assembly-CSharp.dll, as best as I can. Perhaps I am not finding the right hook? I can't see much about the astronaut complex at all to be honest. Is there a better place for looking for such information that does not involve trying to decompile things? (edit to clarify this last part).

Anyone know if I am missing something? Or if there is any chance that Squad might remove that so that one might use an override method on some of the methods for the sub-buildings?

I suspect the answer (From my search so far) is no to at least the first part. I think I will stick with just a button to pull up my new hiring interface but I thought it best to ask here before I gave up entirely on the idea.

Thanks in advance for any answers any of you may have, even if it is just to say 'no there isn't a way'. :D

-OakTree42

http://www.twitch.tv/oaktree42/

Edited by OakTree42
Clarify first part of the question
Link to comment
Share on other sites

Can you be more specific as to what you're trying to do?

  1. Prevent player from opening astronaut complex? (and/or open your custom window instead)
  2. Detect when the player is viewing (has entered) the AC?
  3. Edit text on AC building description when left/right-clicked?
  4. Modify GUI of AC itself (change button conditions etc)?

The first three are straightforward, the last item can be done but is somewhat tedious

Link to comment
Share on other sites

Sorry if I wasn't clear enough! My first attempt on this forum to ask questions about my mod efforts. I want to do 4. I want to take the left hand area where it shows kerbals you can hire and replace it with a hiring API that allows you to hire kerbals based on career, gender, courage, stupidity, fearless attribute and level. I would then have level limited on both the max level of kerbal of that career who is available currently on kerban at minus one to their level. And limited by the level of the building, meaning a hard limit of level 3. It would dynamically display how much said kerbal would cost and when you hit 'hire' it would randomly generate a name for that career type and create the kerbal, deduct the money and put him in your roster.

And that's pretty much all of it. So the goal would be to take the left hand side of the AC interface and remove the current window and replace it with one of my own design.

-OakTree42

http://www.twitch.tv/oaktree42/

Is this doable? I can handle tedious if it is doable and you can point me in the right direction.

Much appreciated for your speedy reply by the way! Thanks!!

-

Link to comment
Share on other sites

Replacing the panel with your own is a lot easier than trying to modify the existing one, which I can tell you from experience is a maintenance nightmare. Here's a rough mockup that should get you started:

[KSPAddon(KSPAddon.Startup.SpaceCentre, false)]
public class ReprogramAstronautComplex : MonoBehaviour
{
private readonly ILog _log = new DebugLog("Reprogrammer");
private Rect _windowRect = default(Rect);
private AstronautComplexApplicantPanel _applicantPanel;

private void Start()
{
try
{
SetupSkin();

var complex = UIManager.instance.transform.Find("panel_AstronautComplex");

#if DEBUG
//DumpAssetBaseTextures();
//complex.gameObject.PrintComponents(new DebugLog("Complex"));
#endif

_applicantPanel = new AstronautComplexApplicantPanel(complex);

_windowRect = _applicantPanel.PanelArea;
_applicantPanel.Hide();

GameEvents.onGUIAstronautComplexSpawn.Add(AstronautComplexShown);
GameEvents.onGUIAstronautComplexDespawn.Add(AstronautComplexHidden);

enabled = false;
}
catch (Exception e)
{
_log.Error("Error: Encountered unhandled exception: " + e);
Destroy(this);
}

}

private void AstronautComplexShown()
{
enabled = true;
}

private void AstronautComplexHidden()
{
enabled = false;
}

private void OnDestroy()
{
GameEvents.onGUIAstronautComplexDespawn.Remove(AstronautComplexHidden);
GameEvents.onGUIAstronautComplexSpawn.Remove(AstronautComplexShown);
}

private void SetupSkin()
{
_customWindowSkin = new GUIStyle(HighLogic.Skin.window)
{
contentOffset = Vector2.zero,
padding = new RectOffset() { left = 0, right = HighLogic.Skin.window.padding.right, top = 0, bottom = 0}
};
}


private void DumpAssetBaseTextures()
{
// note: there are apparently null entries in this list for some reason, hence the check
FindObjectOfType<AssetBase>().textures.Where(t => t != null).ToList().ForEach(t => _log.Debug("AssetBase: " + t.name));
}


private Vector2 _scroll = default(Vector2);
private GUIStyle _customWindowSkin;


private readonly Texture2D _portraitMale = AssetBase.GetTexture("kerbalicon_recruit");
private readonly Texture2D _portraitFemale = AssetBase.GetTexture("kerbalicon_recruit_female");

private void OnGUI()
{
GUI.skin = HighLogic.Skin;
var roster = HighLogic.CurrentGame.CrewRoster;

GUILayout.BeginArea(_windowRect, _customWindowSkin);
{
GUILayout.Label("Candidates");
_scroll = GUILayout.BeginScrollView(_scroll, _customWindowSkin);
{
foreach (var applicant in roster.Applicants)
DrawListItem(applicant);
}
GUILayout.EndScrollView();
}
GUILayout.EndArea();
}

private void DrawListItem(ProtoCrewMember crew)
{
GUILayout.BeginVertical(_customWindowSkin, GUILayout.ExpandHeight(false));
{
GUILayout.BeginHorizontal(GUILayout.ExpandHeight(true), GUILayout.MaxHeight(_portraitMale.height),
GUILayout.ExpandWidth(true));
{
GUILayout.Label(crew.gender == ProtoCrewMember.Gender.Male ? _portraitMale : _portraitFemale);

GUILayout.BeginVertical(GUILayout.ExpandHeight(false), GUILayout.ExpandWidth(true));
{
GUILayout.BeginHorizontal();
GUILayout.Label(crew.name);
GUILayout.FlexibleSpace();
GUILayout.Label("Trained " + crew.experienceTrait.Title);
GUILayout.EndHorizontal();

GUILayout.Label("More info here");

GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Button("Hire Applicant", GUILayout.MaxWidth(100f)); // todo: hire logic
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
}
}


public class AstronautComplexApplicantPanel
{
private readonly Transform _applicantPanel;

public AstronautComplexApplicantPanel(Transform astronautComplex)
{
if (astronautComplex == null) throw new ArgumentNullException("astronautComplex");
_applicantPanel = astronautComplex.Find("CrewPanels/panel_applicants");

if (_applicantPanel == null)
throw new ArgumentException("No applicant panel found on " + astronautComplex.name);
}

public void Hide(bool tf = true)
{
_applicantPanel.gameObject.SetActive(!tf);
}


public Rect PanelArea
{
get
{
// whole panel is an EzGUI BTButton and we'll be needing to know about its renderer to come up
// with screen coordinates
var button = _applicantPanel.GetComponent<BTButton>() as SpriteRoot;

if (button == null)
throw new Exception("AstronautComplexApplicantPanel: Couldn't find BTButton on " +
_applicantPanel.name);

var uiCam = UIManager.instance.uiCameras.FirstOrDefault(uic => (uic.mask & (1 << _applicantPanel.gameObject.layer)) != 0);
if (uiCam == null)
throw new Exception("AstronautComplexApplicantPanel: Couldn't find a UICamera for panel");

var screenPos = uiCam.camera.WorldToScreenPoint(_applicantPanel.position);

return new Rect(screenPos.x, Screen.height - screenPos.y, button.PixelSize.x, button.PixelSize.y);
}
}
}

8fa0f47e1d.png
Link to comment
Share on other sites

I have used this code to great effect but have a sort of problem here. My hire system works now, but I have to leave and return to the complex to get the right side to refresh. Is there something here that I could call upon hiring? I tried the game event for onhire but that just seems to deduct cash and not actually do what I want.

I thought I had a hiring code issue but when I found it was working by leaving after I checked the save game file...

Also this does not seem to over-write the astronaut complex if it is entered via the vab/sph crew option. Is there a way to make that work?

Your help has been EXTREMELY helpful and I can not thank you enough for the help you have already given!

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...