Jump to content

Toggle Staging Icon


Recommended Posts

I'm trying to set up a part that can be removed from the staging list via a toggle that's only visible in the VAB or SPH. However, while I can get it to work properly in the editor whenever it loads into a new scene, during launch for example, the icon shows up in the staging list again. I have code in "OnStart" that should remove that icon, but it doesn't appear to work. You can see the code I'm using below.

I've had some luck in using an if statement that checks to see if "stageStatus" is on before setting the StagingIcon in "OnStart", but the problem there is that I can't create that icon until I load into a new scene if I go back to the editor while the stage display is off. For example, if I set it to off and go to the launchpad, the icon won't show up. Unfortunately, if I then revert to the VAB and click on the Stage Activation toggle to show it again it will show a blank icon until I go back to the launchpad.

Am I just on the wrong track here? How can I ensure that the icon won't show up when switching scenes if it's toggled off?


// Field
[KSPField(isPersistant = true, guiActive = false, guiActiveEditor = true, guiName = "Stage Activation")]
public string stageStatus = "On";

//Event
[KSPEvent(guiName = "Stage Activation", guiActive = false, guiActiveEditor = true)]
public void toggleStage()
{
if (stageStatus == "On")
{
stageStatus = "Off";
this.part.stackIcon.RemoveIcon();
Staging.SortIcons();
}
else
{
stageStatus = "On";
this.part.stackIcon.CreateIcon();
Staging.SortIcons();
}
}

//OnStart
public override void OnStart(StartState state)
{
this.part.stagingIcon = "RCS_MODULE";
if (stageStatus == "Off") {
this.part.stackIcon.RemoveIcon();
Staging.SortIcons();
}
}

Edited by Firov
Link to comment
Share on other sites

My guess would be because while you remove the StackIcon from the Part, Staging still has the icon registered, so when you go to the launchpad it shows that icon. And in the VAB, because you changed the part's PartIcon directly to be removed, it will be blank.

So I would try using something like:


Staging.RemoveIcon(Staging.FindIcon(this.part));

instead of this.part.stackIcon.RemoveIcon() like you're trying now.

Link to comment
Share on other sites

My guess would be because while you remove the StackIcon from the Part, Staging still has the icon registered, so when you go to the launchpad it shows that icon. And in the VAB, because you changed the part's PartIcon directly to be removed, it will be blank.

So I would try using something like:


Staging.RemoveIcon(Staging.FindIcon(this.part));

instead of this.part.stackIcon.RemoveIcon() like you're trying now.

Interesting idea! Thanks. I'll give this a shot and report back.

Link to comment
Share on other sites

Okay, I tested it and it does work reasonably well. Unfortunately, it's still incapable of drawing the right icon if you disable staging and then reenable it, at least until you change scenes, at which point it properly creates the icon.

It seems that, for whatever reason, "this.part.stagingIcon" only has any impact during initial scene load. Any other ideas?

Latest version


//Field
[KSPField(isPersistant = true, guiActive = false, guiActiveEditor = true, guiName = "Stage Activation")]
public string stageStatus = "On";
//Event
[KSPEvent(guiName = "Stage Activation", guiActive = false, guiActiveEditor = true)]
public void toggleStage()
{
if (stageStatus == "On") {
stageStatus = "Off";
Staging.RemoveIcon(Staging.FindIcon(this.part));
Staging.SortIcons();
}
else {
stageStatus = "On";
Staging.CreateIcon(this.part);
this.part.stagingIcon = "RCS_MODULE";
Staging.SortIcons();
}
}
//OnStart
public override void OnStart(StartState state)
{
if (state == StartState.Editor)
{
this.part.OnEditorAttach += OnEditorAttach;
this.part.OnEditorDetach += OnEditorDetach;
this.part.OnEditorDestroy += OnEditorDestroy;
OnEditorAttach();
}
if (stageStatus == "On") {
this.part.stagingIcon = "RCS_MODULE";
}
part.ActivatesEvenIfDisconnected = true;
}

Link to comment
Share on other sites

Maybe instead of Staging.CreateIcon,try Staging.AddToSelection instead? Staging.CreateIcon seems to return a StackIcon, leading me to guess that it simply returns the part's StackIcon rather than setting it in the staging area.

Edit: And maybe Staging.DisableIcon instead of RemoveIcon. I'm not sure if there will be a difference, but that would be the other thing I would try.

Edited by Rhidian
Link to comment
Share on other sites

Staging.CreateIcon is deprecated. Actuall, I'm 99% sure that staging icons currently do not use the Staging class. If I was you, I would modify the part.stackIcon proprety. Something like this

private string icon = string.Empty

public override void OnStart(StartState state)
{
string icon = this.part.stackIcon;
}

private void Update()
{
if (showIcon) { this.part.stackIcon = icon; }
else if (hideIcon) {this.part.stackIcon = string.Empty; }
}

Link to comment
Share on other sites

Rhidian, I'll give that a shot. Thanks.

Also, Chris. Thanks for the advice. It's appreciated.

However, I was originally trying to alter the part.stackIcon property, as is visible in my original post, but I met with extremely limited success. It did technically allow me to add or remove an icon but, much like the staging class method in my later post, recreating the icon always resulted in a blank box in the staging list, rather than the proper RCS icon.

As to your example, unfortunately stackIcon doesn't accept a string as an assignment value. It's looking for a VStackIcon. I assume you actually meant part.stackIcon.iconImage? If so, it still doesn't accept strings. Instead I have to use one of the default icons from the DefaultIcons enum. Which sadly doesn't allow a null value, or in your example, the empty string. However, that said, it's entirely possible that I simply misunderstood you.

Also, one final question for you, how do you know that the Staging class is deprecated? It seems like the documentation on the Kerbal API is a bit... spotty. Just curious if I've missed some documentation out there somewhere.

Thanks again to both of you.

edit - Also, part.stackIcon.iconImage appears to do nothing. Much like the rest of the functions related to stage icons... *sigh* This really isn't turning out to be as easy as I thought it would be when I decided it would be a "good idea" to add support for tweakable staging.

Edited by Firov
Link to comment
Share on other sites

Rhidian, I'll give that a shot. Thanks.

Also, Chris. Thanks for the advice. It's appreciated.

However, I was originally trying to alter the part.stackIcon property, as is visible in my original post, but I met with extremely limited success. It did technically allow me to add or remove an icon but, much like the staging class method in my later post, recreating the icon always resulted in a blank box in the staging list, rather than the proper RCS icon.

As to your example, unfortunately stackIcon doesn't accept a string as an assignment value. It's looking for a VStackIcon. I assume you actually meant part.stackIcon.iconImage? If so, it still doesn't accept strings. Instead I have to use one of the default icons from the DefaultIcons enum. Which sadly doesn't allow a null value, or in your example, the empty string. However, that said, it's entirely possible that I simply misunderstood you.

Also, one final question for you, how do you know that the Staging class is deprecated? It seems like the documentation on the Kerbal API is a bit... spotty. Just curious if I've missed some documentation out there somewhere.

Thanks again to both of you.

edit - Also, part.stackIcon.iconImage appears to do nothing. Much like the rest of the functions related to stage icons... *sigh* This really isn't turning out to be as easy as I thought it would be when I decided it would be a "good idea" to add support for tweakable staging.

Oh sorry, I have it all wrong.

Don't use this.part.stackIcon. Use this.part.stagingIcon This one is a string and does what you are looking for.

As for the staging class being deprecated, that's not entirely true, but my experiments with the staging class and staging icons all failed.

If changing this.part.stagingIcon does not work immediately, try sliding an "Staging.SortIcons();" after, it m,ight do the trick. I remember someone asked a while ago and that stagingIcon was the key to having it work.

If you want the list of the strings that stagingIcon takes as icons, take a look at the DefaultIcons enum, just use any of those values, as strings, and it will assign a correct icon.

Link to comment
Share on other sites

Previous Post

I don't know Chris, I think this might just be an impossible task, much like custom icons. Based on your advice I set up my module as below. Clicking the toggle button however doesn't disable the icon if it's already there, nor will it bring it back if the icon was set as disabled when you loaded into the editor. In fact, this version isn't even capable of generating a blank staging icon.

It will function properly when it loads onto the pad or runway, either having a stack icon if enabled or omit it if it's disabled, since I have a check in the "OnStart" method to create the icon only if it's enabled. Unfortunately, "this.part.stagingIcon" doesn't seem to work anywhere but in the OnStart method, and I have no idea why. I might be able to reinitialize the part to force it to go through OnStart again, but that's not something I've really looked into.

This "simple little tweak" has quickly gone from a minor nuisance to a serious annoyance.

Oh well. Any other ideas? Either way, I appreciate your help.


//Field
[KSPField(isPersistant = true, guiActive = false, guiActiveEditor = true, guiName = "Stage Activation")]
public string stageStatus = "On";

//Event
[KSPEvent(guiName = "Stage Activation", guiActive = false, guiActiveEditor = true)]
public void toggleStage()
{
if (stageStatus == "On")
{
stageStatus = "Off";
this.part.stagingIcon = string.Empty;
Staging.SortIcons();
}
else
{
stageStatus = "On";
this.part.stagingIcon = "RCS_MODULE";
Staging.SortIcons();
}
}

//OnStart
public override void OnStart(StartState state)
{
if (stageStatus == "On") {
this.part.stagingIcon = "RCS_MODULE";
}
}

Link to comment
Share on other sites

I don't know Chris, I think this might just be an impossible task, much like custom icons. Based on your advice I set up my module as below. Clicking the toggle button however doesn't disable the icon if it's already there, nor will it bring it back if the icon was set as disabled when you loaded into the editor. In fact, this version isn't even capable of generating a blank staging icon.

It will function properly when it loads onto the pad or runway, either having a stack icon if enabled or omit it if it's disabled, since I have a check in the "OnStart" method to create the icon only if it's enabled. Unfortunately, "this.part.stagingIcon" doesn't seem to work anywhere but in the OnStart method, and I have no idea why. I might be able to reinitialize the part to force it to go through OnStart again, but that's not something I've really looked into.

This "simple little tweak" has quickly gone from a minor nuisance to a serious annoyance.

Oh well. Any other ideas? Either way, I appreciate your help.

-snip-

I remember TaranisElsu successfully doing it, I'll poke him about what else was needed to update the icon.

EDIT:

https://github.com/taraniselsu/TacSelfDestruct/blob/master/Source/TacSelfDestruct.cs#L98-L118

You might want to take a peak at this code, it does work properly.

Edited by stupid_chris
Link to comment
Share on other sites

I remember TaranisElsu successfully doing it, I'll poke him about what else was needed to update the icon.

EDIT:

https://github.com/taraniselsu/TacSelfDestruct/blob/master/Source/TacSelfDestruct.cs#L98-L118

You might want to take a peak at this code, it does work properly.

Hey Chris. Thanks for the link. I'll have to take a look at that code, though I actually just figured it out myself. The code below is capable of creating the proper icon.

It turns out that I needed to use the part.stackIcon.iconImage property to assign the icon image, then use part.stackIcon.CreateIcon() to generate it, and finally staging.SortIcons to put it in the list. Oddly enough though, using this exact process in OnStart() doesn't successfully create the icon, but that's fine since "this.part.stagingIcon" does. Not that I can explain that apparent discrepancy.


[KSPEvent(guiName = "Stage Activation", guiActive = false, guiActiveEditor = true)]
public void toggleStage()
{
if (stageStatus == "On") {
stageStatus = "Off";
this.part.stackIcon.RemoveIcon();
Staging.SortIcons();
}
else {
stageStatus = "On";
this.part.stackIcon.iconImage = DefaultIcons.RCS_MODULE;
this.part.stackIcon.CreateIcon();
Staging.SortIcons();
}
}

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...