Jump to content

KSP4X, looking for undocumented event


Recommended Posts

Hi,

I am developping a mod that adds an inventory to the game:

From the editor, dragging parts on a button stores them in your inventory.

Another button allows you to toggle between the complete part list and the ones currently in your inventory (it works as a filter on the part list).

Picking a part from your inventory should remove it... but i cannot find any event to help me determine when a part has been clicked in the list.

Alternatively knowing when a part was dropped in the VAB background (unattached) could also do the trick.

Has anyone seen such events? or can you think or a workaround?

Link to comment
Share on other sites

Picking a part from your inventory should remove it... but i cannot find any event to help me determine when a part has been clicked in the list.

Assuming you're talking about the stock editor part list and not some other list that's part of your inventory, the simplest way is to modify the prefab that gets used to create each part button. This should get you off the ground:

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
class EditPartListPrefab : MonoBehaviour
{
class ClickListener : MonoBehaviour
{
AvailablePart myPart;
EditorPartIcon icon;
bool mouseFlag = false;

void Start()
{
GetComponent<UIButton>().AddValueChangedDelegate(OnClick);
GetComponent<UIButton>().AddInputDelegate(OnInput);
myPart = GetComponent<EditorPartIcon>().partInfo;
icon = GetComponent<EditorPartIcon>();
}

void OnClick(IUIObject obj)
{
print("User clicked " + myPart.partPrefab.name);
}

void OnInput(ref POINTER_INFO ptr)
{
switch (ptr.evt)
{
case POINTER_INFO.INPUT_EVENT.MOVE:
if (!mouseFlag)
{
mouseFlag = true;
print("User moused over " + myPart.partPrefab.name);
}
break;
case POINTER_INFO.INPUT_EVENT.MOVE_OFF:
mouseFlag = false;
break;
}
}
}

void Start()
{
EditorPartList.Instance.iconPrefab.gameObject.AddComponent<ClickListener>();
}
}

Link to comment
Share on other sites

I would only count parts attached to the current vessel. The transparent stuff in the editor might behave in unexpected ways, like multiplying when symmetry mode changes. Just imagine dragging a subassembly including a 'one of a kind' part around. As you pass over a part with symmetry, the editor decides to spontaneously switch to 4x symmetry, and the assembly vanishes because you do not have enough parts.

Also, when dragging parts around you'd have to be sure to cover any way such a part could vanish (including gui glitches, other mods or whatever), because you need to put it back into the inventory. The current vessel on the other hand should always provide a list of its parts, so keeping things consistent is much easier.

Diagnostic calculations like mechjeb's delta-v are done whenever attaching a new part. This also gives the ability to set parts of the vessel aside to exclude them from the calculation. It would be quite tedious if I need to remove a complete lifter from the editor in order to see the stats of its payload. That is probably the main point why I would consider transparent parts as non-existent.

Edited by pellinor
Link to comment
Share on other sites

@xEvilReaperx

Thanks, it worked like a charm. Any idea how i could display a number in those icons? XD

@pellinor

Hi,

It actually works the way you described, but i ran into a little problem.

Parts are stored when dropped onto the "inventory" button.

Parts are removed from inventory when something gets attached to the ship.

So, the player can drag a part directly from the inventorylist to the store button..... which clones it.

I could hide the "store" button while inventory is active, but then the player must toggle back to factory to store legit ship parts...

I'll try to use the click event as a way of finding out where this part came from.

------

An alternative is to store anything that is "detached" from the ship.... but the ergonomy is terribly counter intuitive...

Edited by SiriusSam
Link to comment
Share on other sites

@xEvilReaperx

Thanks, it worked like a charm. Any idea how i could display a number in those icons? XD

You can put whatever you'd like in there. Here's a basic bug-filled (lots of edge cases need to be solved) version of what you want:

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
class EditPartListPrefab : MonoBehaviour
{
class ClickListener : MonoBehaviour
{
AvailablePart myPart;
EditorPartIcon icon;
SpriteText text;
int amount = 0;
bool mouseFlag = false;



void Start()
{
GetComponent<UIButton>().AddValueChangedDelegate(OnClick);
GetComponent<UIButton>().AddInputDelegate(OnInput);
myPart = GetComponent<EditorPartIcon>().partInfo;
icon = GetComponent<EditorPartIcon>();
text = transform.Find("CounterLabel").GetComponent<SpriteText>();

amount = EditPartListPrefab.Instance.GetPartQuantity(myPart);
UpdateCounter();
}

void OnClick(IUIObject obj)
{
print("User clicked " + myPart.partPrefab.name);

if (amount > 0)
{
--amount;
EditPartListPrefab.Instance.SetPartQuantity(myPart, amount);
UpdateCounter();
}
}

void UpdateCounter()
{
text.Text = amount.ToString();

if (amount == 0)
icon.SetGrey("Ran out of this item");
}


void OnInput(ref POINTER_INFO ptr)
{
switch (ptr.evt)
{
case POINTER_INFO.INPUT_EVENT.MOVE:
if (!mouseFlag)
{
mouseFlag = true;
print("User moused over " + myPart.partPrefab.name);
}
break;
case POINTER_INFO.INPUT_EVENT.MOVE_OFF:
mouseFlag = false;
break;
}
}
}



public static EditPartListPrefab Instance { private set; get; }
private Dictionary<AvailablePart, int> quantities = new Dictionary<AvailablePart, int>();


int GetPartQuantity(AvailablePart part)
{
return quantities[part];
}

void SetPartQuantity(AvailablePart part, int qty)
{
quantities[part] = qty;
}

void Start()
{
Instance = this;

// edit icon prefab
var iconPrefab = EditorPartList.Instance.iconPrefab.gameObject;

if (iconPrefab.GetComponent<ClickListener>() == null)
{
iconPrefab.AddComponent<ClickListener>();

GameObject labelHolder = new GameObject("CounterLabel");
var label = labelHolder.AddComponent<SpriteText>();
label.RenderCamera = Camera.allCameras.Where(c => (c.cullingMask & (1 << labelHolder.layer)) != 0).Single();

labelHolder.layer = LayerMask.NameToLayer("EzGUI_UI");
labelHolder.transform.parent = iconPrefab.transform;
labelHolder.transform.localPosition = Vector3.zero;
labelHolder.transform.Translate(new Vector3(EditorPartList.Instance.iconSize * 0.35f, EditorPartList.Instance.iconSize * -0.425f, label.RenderCamera.nearClipPlane - labelHolder.transform.position.z - 1f), Space.Self);

label.Text = "[count]";
label.alignment = SpriteText.Alignment_Type.Right;
label.font = UIManager.instance.defaultFont;
label.renderer.sharedMaterial = UIManager.instance.defaultFontMaterial;
label.SetColor(Color.white);
label.SetAnchor(SpriteText.Anchor_Pos.Lower_Right);
label.SetCharacterSize(12f);
}

// generate some random quantity for each part
PartLoader.LoadedPartsList.ForEach(ap => quantities.Add(ap, UnityEngine.Random.Range(0, 15)));
}
}

Link to comment
Share on other sites

Hello,

I implemented the counters. I just have a little bug :

When the VAB gets reloaded i get a lot of nullpointer exceptions. This disappears if i stop adding the click listener (but of course the counters don't update...).

I suppose the events don't get deleted, but i can't manage to fix it.

Here is the source and DLL:

http://3dstudios.fr/KSP4X/KSP4X.zip

Link to comment
Share on other sites

A lil bug in my logic ;) Change the prefab editor start method to this:

void Start()
{
Debug.Log("Start EditPartListPrefab");

// edit icon prefab
var iconPrefab = EditorPartList.Instance.iconPrefab.gameObject;

if (iconPrefab.GetComponent<ClickListener>() == null)
{
GameObject labelHolder = new GameObject("CounterLabel");
var label = labelHolder.AddComponent<SpriteText>();
labelHolder.layer = LayerMask.NameToLayer("EzGUI_UI");
label.RenderCamera = Camera.allCameras.Where(c => (c.cullingMask & (1 << labelHolder.layer)) != 0).Single();
labelHolder.transform.parent = iconPrefab.transform;
labelHolder.transform.localPosition = Vector3.zero;
labelHolder.transform.Translate(new Vector3(EditorPartList.Instance.iconSize * 0.35f, EditorPartList.Instance.iconSize * -0.425f, label.RenderCamera.nearClipPlane - labelHolder.transform.position.z - 1f), Space.Self);
label.Text = "[count]";
label.alignment = SpriteText.Alignment_Type.Right;
label.font = UIManager.instance.defaultFont;
label.renderer.sharedMaterial = UIManager.instance.defaultFontMaterial;
label.SetColor(Color.white);
label.SetAnchor(SpriteText.Anchor_Pos.Lower_Right);
label.SetCharacterSize(12f);
DontDestroyOnLoad(labelHolder);

iconPrefab.AddComponent<ClickListener>();
}
}

Edited by xEvilReeperx
Link to comment
Share on other sites

Thanks a lot, all nasty red messages are gone!

If by any chance you know how to get the Ship currently on the assembly line... (i must remove the parts from the catalog when the user enters the VAB). Problem is i can't find the Vessel... only its name (ShipAssembly.currentShipName).

Been foraging a lot in the DLL definition but with no luck so far.

I think i have taken care of most of the other problems.

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