Jump to content
sarogahtyp

[Solution] getting entity where action menu is applied to - using method of parent class

Recommended Posts

when I was fighting with action menus I had a problem which little solution I want to share here fo people not such involved in classes and OOP.

 

I ll post a part of the code out of the biki to explain the problem I had:

 

class MyScriptedUserAction : ScriptedUserAction
{
	//------------------------------------------------------------------------------------------------
	override void PerformAction(IEntity pOwnerEntity, IEntity pUserEntity)
	{
		Print("MyScriptedUserAction.PerformAction() method reached");
		SCR_HintManagerComponent.GetInstance().ShowCustomHint("My test ground world - DONE", "TEST GROUND", 3.0);
	}

	//------------------------------------------------------------------------------------------------
	override bool CanBeShownScript(IEntity user)
	{
		return true;
	}
};

 

As you can see the method PerformAction (which is executed when pressing F key on this entry in game) has 2 paramaeters. First one is pOwnerEntity which is the entity of where you added the action menu to.

The second (pUserEntity) is just the character entity of the player who is watching and using the action menu.

 

The problem:

Now there is the method CanBeShownScript which boolean return value determines if this action menu entry is shown to the user or not.

And there is the problem. This method has only one parameter, the object where the action is applied to is missing. This can be a problem if you have a "Unflip Vehicle"-menu entry which should get shown only if the vehicle is flipped.

But you don't have the vehicle as a parameter of the method here. Therefore you can't check if it is flipped.

 

The solution:

What you have to know bout classes here is that in many classes you do not see all methods available in it. The reason for this is Inheritance. Most classes are inherited multiple times out of other (their parent-) classes. This means you can mostly find more methods available by viewing the declaration of those parent classes.
In this case I viewed some forefathers of the class MyScriptedUserAction.

These forefathers in this case were the classes: ScriptedUserAction and BaseUserAction

In BaseUserAction I found the desired GetOwner() method which gives you the object which is the menu applied to.

Here I show the start of that class. The last method of that part is the desired method:

class BaseUserAction: ScriptAndConfig
{
	// Injects
	//! The reason why action cannot be performed.
	//! Should be set in CanBePerformed check
	protected string m_sCannotPerformReason;
	
	//! Sets the reason why action couldn't be performed.
	//! Should be done in CanBePerformed check
	void SetCannotPerformReason(string reason)
	{
		m_sCannotPerformReason = reason;
	}
	
	//! Returns the reason why action couldn't be performed.
	//! It is valid only within and after CanBePerformed is called
	string GetCannotPerformReason()
	{
		return m_sCannotPerformReason;
	}
	
	//! Can be filled in scripts to be used as params when name is being formatted when displayed in UI
	string ActionNameParams[9];
	
	bool IsUserActionConsumable() { return false; }
	
	//! Returns the index of the context this action is registered in as or -1 if none
	proto external int GetContextIndex(string sContextName);
	//! Can this action be performed by the user?
	proto external bool CanBePerformed(IEntity user);
	//! Can this action be shown in the UI for the user?
	proto external bool CanBeShown(IEntity user);
	//! Does this action only have client side effect?
	proto external bool HasLocalEffectOnly();
	//! If HasLocalEffectOnly() is true this method tells if the server is supposed to broadcast this action to clients.
	proto external bool CanBroadcast();
	//! Should this action be performed every frame the input action is triggered?
	proto external bool ShouldPerformPerFrame();
	//! Return the name of this action.
	//! By default returns the value in UIInfo or empty string if UIInfo doesn't exist.
	proto external string GetActionName();
	//! Return the description of this action.
	//! By default returns the value in UIInfo or empty string if UIInfo doesn't exist.
	proto external string GetActionDescription();
	//! Returns the visibility range of this action in metres.
	proto external float GetVisibilityRange();
	//! Returns the duration of this action in seconds.
	proto external float GetActionDuration();
	//! Returns the progress of this action in seconds.
	proto external float GetActionProgress();
	//! Returns the UIInfo set for this user action or null if none.
	proto external UIInfo GetUIInfo();
	//! Returns the parent entity of this action.
	proto external IEntity GetOwner();                       // THIS IS THE DESIRED METHOD



 

No I know that I can just do this:

class MyScriptedUserAction : ScriptedUserAction
{
	//------------------------------------------------------------------------------------------------
	override void PerformAction(IEntity pOwnerEntity, IEntity pUserEntity)
	{
		Print("MyScriptedUserAction.PerformAction() method reached");
		SCR_HintManagerComponent.GetInstance().ShowCustomHint("My test ground world - DONE", "TEST GROUND", 3.0);
	}

	//------------------------------------------------------------------------------------------------
	override bool CanBeShownScript(IEntity user)
	{
        IEntity menuOwner = GetOwner();   // THIS IS THE SOLUTION
		return true;
	}
};

Now I can use menuOwner to determine if the menu should be shown. I could check if the vehicle is flipped for example.

Generally watching the parent declarations of classes is essential!

In script editor double click the parent class to mark it and then right click and then click "Goto Declaration".

  • Like 2

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×