Jump to content

Change existing actions from other mods


Recommended Posts

Edit: Answered in last post.

Alright.

For the simplest test case of what I'm going, the existing ModuleGimbal used by engines has a single action, "Toggle Gimbal".

I am adding two more actions to this, "Enable Gimbal" and "Disable Gimbal". That is all straightforward and works fine.

The issue is that I have to use a different partModule so I have no control over where the actions appear in the editor. Currently the action list goes like this:

Toggle Gimbal

Jettison

Enable Gimbal

Disable Gimbal

Now, I can easily add the Toggle Gimbal action to my partModule as well, but that would leave two Toggle Gimbal actions on the part.

Is there any way I can prevent the existing Toggle Gimbal action from showing? I have not been able to find any methods or properties that would allow me to hide it, short of deleting it outright. However, I risk causing a cascade error if I delete an action someone else is linked to so I don't want to do this by deleting the action.

Anyone have any ideas?

D.

Edited by Diazo
Link to comment
Share on other sites

Just a quick example on how to modify actions on other modules:


public class ModuleDoStuff : PartModule
{
public override void OnStart(StartState state)
{
//find any ModuleEngines within the same part as your module
if (part.Modules.Contains("ModuleEngines")) {
//clear any actions.
part.Modules["ModuleEngines"].Actions.Clear();
}
}
}

This will simply clear all actions, but you could just as easily remove specific actions.

The hitch is that your module would need to be started after the ModuleEngines you wish to make changes to. IIRC, the modules are loaded in alphabetical order, but this might not be the case. Especially in case of modules added by ModuleManager.

In any case, this should be a starting place from which to do a bit of experimentation.

Link to comment
Share on other sites

It would be (slightly) better to do this in Update with a flag so you only do it once but, it is really dangerous to mess with other parts' Actions lists in this way. E.g. if the PartModule in question tries to do something to one of its actions later and the code hasn't been written to assume the action may not be present then it could cause serious issues. Also, even if the PartModule does handle the action not being present, you would still have to duplicate any changes it would normally try to make and these changes may be controlled by private stuff you can't mess with (easily).

Link to comment
Share on other sites

...it is really dangerous to mess with other parts' Actions lists in this way. E.g. if the PartModule in question tries to do something to one of its actions later and the code hasn't been written to assume the action may not be present then it could cause serious issues...

True. Maybe it would be safer simply to deactivate the action:


Actions["SomeNamedAction"].active = false;

If this will cause an update in the visual action list within the editor is a different question.

Link to comment
Share on other sites

First, I'm not messing with the action itself. That way lies nothing but a minefield of problems as I try to delete and then recreate the action.

Second, the BaseAction.active =false; does not hide the action in the editor GUI so it will not work for what I want.

At this point I think I'm going to have to accept I can't change the action and accept the fact that actions effecting the same thing may not line up next to each other in the editor GUI.

D.

Link to comment
Share on other sites

Use reflection. Get the the parmodule method list ( GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ), itteratate on it and check the attribute for each ( GetCustomAttributes(typeof(KSPEvent), true) ). Once you have that you should be able to change the guiActive of the action to false.

Get me on IRC or PM me if you need more detailed steps.

Edited by sarbian
Link to comment
Share on other sites

BaseAction has a .guiActive?

It has a .guiName but I did not see a .guiActive, will test ASAP. (At work, several hours until I can test.)

I started this thread because I thought BaseAction did not have a .guiActive.

If it does that solves my problems and I just can't read apparently.

D.

Link to comment
Share on other sites

BaseAction has a .guiActive?

It has a .guiName but I did not see a .guiActive, will test ASAP. (At work, several hours until I can test.)

I started this thread because I thought BaseAction did not have a .guiActive.

If it does that solves my problems and I just can't read apparently.

D.

Not directly, you have to use reflection to access the KSPEvent attribute which is what has guiActive...

Link to comment
Share on other sites

Erm, I'm not touching the Events, I'm talking about Actions.

As in, in action assignment mode in the editor, I want to hide an action so it does not display in the available actions list for the selected part to assign in to an action group.

(Random picture off the internet.)

Kz4S9NL.png

This shows where I want to hide the action, I want to be able to hide the "Activate" action so it does not show in the "Selection" column.

D.

Link to comment
Share on other sites

Okay, apparently I botched my testing last night.

BaseAction.active = false; does in fact hide the action in the editor.

I'm not sure why my tests last night showed otherwise, my best guess being I deactivated them too early and KSP set them back active on me between my active = false code running and checking their state in the editor.

So, issue is resolved.

D.

edit: Nope, baseaction.active=false will not work either. When baseaction.active=false, you can't activate the action so I get back into the same problem of removing the action so other code can't activate it. Effectively I've deleted the action anyway using this method so meh.

Edited by Diazo
Link to comment
Share on other sites

As in, in action assignment mode in the editor, I want to hide an action so it does not display in the available actions list for the selected part to assign in to an action group.

If you're only hiding it in the editor, that's pretty straightforward: just grab the list and remove items/reorder it. This snippet alphabetizes part actions and hides any called "Toggle"

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
class ToggleBegone : MonoBehaviour
{
void Start()
{
EditorActionGroups.Instance.partActionList.AddValueChangedDelegate(ReorderList);
}

void OnDestroy()
{
// assuming it's necessary anyway
EditorActionGroups.Instance.partActionList.RemoveValueChangedDelegate(ReorderList);
}

void ReorderList(IUIObject obj)
{
Log.Debug("Alphabetizing");

// Note: there are at least three types of UIListItems in this list:
// 1) the "title" entry, always first index, looks based off of 2) except named ActionPartTitle
// 2) "ActionPart" with a EditorActionPartItem component linking back to the relevant action
// 3) "ActionPartReset" which contains a EditorActionPartReset component. Always last, only appears
// if at least one action in the list was assigned to a group

List<IUIListObject> items = new List<IUIListObject>();
var partActions = EditorActionGroups.Instance.partActionList;

while (partActions.Count > 1)
{
if (partActions.GetItem(1).gameObject.GetComponent<EditorActionPartReset>() != null) break;

items.Add(partActions.GetItem(1));
partActions.RemoveItem(1, false, false);
}

List<IUIListObject> goodItems = new List<IUIListObject>();

items.ForEach(lo =>
{
if (lo.gameObject.GetComponent<EditorActionPartItem>().evt.guiName != "Toggle")
goodItems.Add(lo);
else GameObject.Destroy(lo.gameObject);
});

goodItems = items.OrderBy(o => o.gameObject.GetComponent<EditorActionPartItem>().evt.guiName).ToList();

for (int i = 0; i < goodItems.Count; ++i)
partActions.InsertItem(goodItems[i], 1 + i);
}
}

Edited by xEvilReeperx
Forgot to destroy excluded list items
Link to comment
Share on other sites

Now that is an interesting bit of code EvilReeper and not one I had really considered.

I'll going to have to decide how I proceed from here now, this opens up some options I had not considered.

Thanks for this.

D.

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