Jump to content

Adding an EVENT to a part in code


Recommended Posts

I want to be able to add and event to a par in code, but am struggling to figure out how to do this.

The reason is that I want to add / remove options when the player right clicks on a part while in flight. I need to be able to add / remove any umber of options, so I can't just hide/display them. Does anyone know how to do this, or think of another mod that already does it, so I can go an look at its code?

Thanks

Link to comment
Share on other sites

Okay, I thought about this a bit and the best answer I can give you is "maybe".

I would need more details on what you are trying to do, what I think you are trying to do should be possible, but your post leaves it vague enough the answer could also be that it is not possible.

D.

Link to comment
Share on other sites

Okay, I thought about this a bit and the best answer I can give you is "maybe".

I would need more details on what you are trying to do, what I think you are trying to do should be possible, but your post leaves it vague enough the answer could also be that it is not possible.

D.

I want to be able to right click on apart that have kerbals in it and choose things for a particular kerbal to do - so if there are six kerals in a part I would add six events - "Change Jeb's socks" ; "Change Bill's socks" ; "Change Bob's socks" etc etc. Or maybe there are other options depending on the situation.

Does that help? Does that turn your "maybe" into a "yes"?

Link to comment
Share on other sites

2 thoughts come to mind on how to do that.

The first is to make several empty KSPEvents that are hidden by default and only become visible when they are populated with an action.

This is probably the easier way, but however many fields you create is a hard limit. If you create 30 fields and end up with 33 actions, the last 3 actions would not be visible. Having said that, at 30 actions the menu would extend off the screen.

The second is to find where the right-click list is stored and dynamically add your actions to that list directly.

While probably more difficulty, this method is more flexible and does not have any limit on the number of actions you can add.

And this is as far as I can help you. I have not done anything that resembles either of those scenarios so I would not know where to start in terms of actually writing code.

D.

Link to comment
Share on other sites

Question: is the events you're trying to code time-critical (like you need to toggle your air intakes on an SSTO), or are they more 'do it when you're safely in orbit'? If it's the latter, you might have more options available to you...

If you don't mind learning how to make GUIs, you could make an event that shows/hides a window where you control the GUI and can loop through each crew in the part and display a button for them to change their socks. And... if there is a case where you need to change socks in an emergency, you could make two events, one that hides/shows the custom GUI window, and the other 'Emergency Change All Crew Socks' that just changes all the crews socks. Give me a few minutes to dig through my code that does stuff like this and I'll post it here.

EDIT: Code followeth. This may not compile, so be warned


private Boolean showingCrewSockUi = false;
private Rect crewSockUiWindow= new Rect(100f, 100f, 250f, 400f);
private Vector2 crewSockScrollPosition = new Vector2(0.0f, 0.0f);

[KSPEvent(guiActive=true, guiName="Manage Crew Socks")]
public void ManageCrewSocks()
{
if (!showingCrewSockUi )
{
RenderingManager.AddToPostDrawQueue(0, drawCrewSocks);
showingCrewSockUi = true;
}
}

[KSPAction("Manage Crew Socks")]
public void ManageCrewSocksAction(KSPActionParam param)
{
ManageCrewSocks();
}

public void drawCrewSocks()
{
if (showingCrewSockUi )
{
crewSockUiWindow= GUILayout.Window(424242, crewSockUiWindow, drawCrewSocksWindow, "Manage Crew Socks");
}
}

private void drawCrewSocksWindow(int id)
{
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("Click on a crew to change their socks!");
GUILayout.EndHorizontal();
crewSockScrollPosition = GUILayout.BeginScrollView(crewSockScrollPosition);
foreach (ProtoCrewMember kerbal in part.protoModuleCrew)
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("Change Socks of "+kerbal.name))
{
ChangeCrewsSocks(kerbal); // Your internal change sock function goeth here
}
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
GUILayout.BeginHorizontal();
if (GUILayout.Button("Close")
{
RenderingManager.RemoveFromPostDrawQueue(0, drawCrewSocks);
showingCrewSockUi = false;
}
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUI.DragWindow();
}

Basically what this *should* do is give you a right click menu option that when clicked, pops up a window that should show all the kerbals currently in that part, and if you click on their names, it will change their socks, and if you click on the close button, it closes the popup window.

Edited by notfirestorm
Adding code to example
Link to comment
Share on other sites

I could build a GUI (and know how a do so (although I am not very good at it!) )

However I am hoping to write a mod that purposly avoids displaying another GUI window. I am trying to make it appear very small, minimal and simple.

In answer to your question, I do not think time critical is a big concern for me.

Link to comment
Share on other sites

Alright, but a problem you'll probably hit trying to make right click buttons for every crew currently in the part is that

1) you are going to be forcing all parts of your type to have that number of crew capacity, and

2) I don't think you'll be able to change the name of the events to match the Kerbal's name currently in that seat, the events will be like "Change Kerbal's socks in Seat 1"

I applaud you trying not to resort to a popup window though, because they are annoying, but sometimes you don't have a choice.

EDIT: Actually I take #2 back. I think you can edit the text on the fly in the OnUpdate() override method:

if (part.protoModuleCrew.Count >= 1)
{
Events["ChangeKerbalsSocksInSeat1"].active = true;
Events["ChangeKerbalsSocksInSeat1"].guiText = "Change " + part.protoModuleCrew[0].name + "'s socks";
}

Edited by notfirestorm
Now with Code tags!
Link to comment
Share on other sites

You could also try to add an new element to Events. Though this will probably come with some issues you have to resolve manually, like GUIs not properly updating (though that might be an issue anyway; there was some expensive code to force-update the right menu in some forum thread) or KSP trying to save & restore your events. Haven't used it in a while, but the code could look sth like that:


class myBomb: PartModule{
void updateEvents(){
Events.Clear();
if(ExplodeEventAvailable){
Events.Add(new BaseEvent(Events, "explodeMyBomb", ()=>{
Part.Explode();
// more logic to dmg related stuff
}, new KSPEvent{ guiName = "Detonate NOW!", guiActive = true });
}
foreach(var vessel in VesselsInCloseRange){
Events.Add(new BaseEvent(Events, "targetVessel"+vessel.id, ()=>{
SetTarget(Vessel);
}, new KSPEvent{ guiName = "Target Vessel "+vessel.name, guiActive = true });
}
}
void Awake(){
updateEvents();
}
void SetTarget(Vessel vessel){
// ...
}
}

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