Help with UIObject ActionTarget Script


#1

(I had to remove the underscores in UIObject_Input_ActionTargetScript in the title to have the topic created).

Some actions while riding a horse require the rider to select a target (like “Charge”). It works when I use a spell-like ability, but unfortunately a spell can only have 5 subspells, and I need more than that (the “Ride” feat is the main spell, and “mount”, “dismount”, “charge” and others are subspells. That way, the feat only requires a slot in the hotbar). I’d like not to have two or more sets of actions for the riding feat, so I tried using the context menu and the UIObject_Input_ActionTargetScript call.
But since right-clicking on a character to display the context menu also sets the target object, it seems UIObject_Input_ActionTargetScript runs the script without letting the player choose a different target.

I know how to select a target from a GUI launched in a conversation, but from the context menu, the same GUI/script skips the “select a target with the mouse” part, probably because right-clicking on the player targets him at the same time. Is there a way to “untarget” (like right-clicking on the ground) after contextmenu.xml is shown but before UIObject_Input_ActionTargetScript is called?


#2

so if i understand,

you already have 5 actions that appear under “Ride” in the contextmenu as child-spells
and you want a 6th action, but intend to use UIObject_Input_ActionTargetScript to fire it?

(or similar)

But the ActionTargetScript’s script fires as soon as it’s selected from the contextmenu?

Isn’t there a way to make items on the menu show/hide themselves based on the object that’s right-clicked? (eg. Hostile/Friendly, party/non-party)

 
btw, it seems strange to me that the script fires right away (‘strange’ but unsurprising). Because on my Examine screen – NOT the contextmenu – I have an InstantSlayer button, and after clicking it, the engine waits until a target is mouseovered+clicked.

Maybe, just maybe, there’s a way to set a “ready” (or “bypass”) variable that either bypasses the event on the first click (or is set to indicate when things are ready) … which, in this case, might require a recursive function (and a can o’ worms)

 
 
 
(i don’t believe there’s any way to untarget a player’s target (short of hacking the executable…))


#3

Exactly, and it’s because the Examine screen has something in it (the controlled PC actually).
When the GUI is displayed from a conversation, the Examine screen disappears, and ActionTargetScript waits for a target to be selected. But when it’s launched from the context menu the Examine screen is still present and ActionTargetScript uses the current target.
Is your InstantSlayer button available somewhere? Maybe having a look at it will show me how to achieve what I need.

Thanks for the advice btw


#4

here’s the xml in ‘examine.xml’

<!-- Instant Slayer, kevL's -->
<UIButton name="kL_INSTAKILL" x="252" y="10" width="22" height="22" capturemouseclicks="true"
    OnToolTip='UIObject_Tooltip_DisplayTooltipString("Instant Slayer","OBJECT_X","OBJECT_Y","SCREEN_TOOLTIP_2","ALIGN_NONE","ALIGN_NONE","0","0","ALIGN_LEFT")'
    OnLeftClick='UIObject_Input_ActionTargetScript("creature",29,31,0,"TRUE","gui_kl_slayer","target:object")' >
    <UIFrame state="up"         fill="align_e.tga" />
    <UIFrame state="down"       fill="align_n.tga" />
    <UIFrame state="focused"    fill="align_e.tga" />
    <UIFrame state="hilited"    fill="align_n.tga" />
    <UIFrame state="hifocus"    fill="align_n.tga" />
    <UIFrame state="disabled"   fill="b_empty.tga" />
</UIButton>

(it’s just an icon on the titlebar of the Examine screen)

and here’s the script

// 'gui_kl_slayer'
//
// by kevL's, 11.03.08
// special thanks to Lance Botelle, 'the Bard of Althea' & Tiniuc

void main(int iSlayed)
{
    // GUI SENDS OBJECT AS AN INT
    object oTarget = IntToObject(iSlayed);

/*  if (!GetIsPC(oTarget)
            && !GetIsOwnedByPlayer(oTarget)
            && !GetIsRosterMember(oTarget)
            && !GetIsPossessedFamiliar(oTarget)
            && !GetIsDM(oTarget)
            && !GetIsDead(oTarget)
            && GetObjectType(oTarget) == OBJECT_TYPE_CREATURE) */
//  if (!GetIsObjectValid(GetFactionLeader(oCreature)))
    {
        SetPlotFlag(oTarget, FALSE);
        SetImmortal(oTarget, FALSE);
        AssignCommand(oTarget, SetIsDestroyable(TRUE, FALSE, FALSE)); // bDestroyable, bRaiseable=TRUE, bSelectableWhenDead=FALSE

        effect eVis1 = EffectVisualEffect(VFX_FNF_IMPLOSION);
        effect eVis2 = EffectVisualEffect(VFX_HIT_SPELL_FLAMESTRIKE);
        effect eVis3 = EffectVisualEffect(VFX_FNF_ELECTRIC_EXPLOSION);
        effect eVis4 = EffectVisualEffect(VFX_FNF_MYSTICAL_EXPLOSION);
        effect eVis = EffectLinkEffects(eVis4, eVis3);
               eVis = EffectLinkEffects(eVis2, eVis);
               eVis = EffectLinkEffects(eVis1, eVis);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);

        effect eDeath = EffectDeath(TRUE, TRUE, TRUE, TRUE);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oTarget);
    }
}

#5

Ah, I think I see the difference: your UIObject_Input_ActionTargetScript(…) call is in the GUI for the Examine screen. Maybe the target is not set yet then.
Whereas my script is launched from contextmenu.xml, which comes after the Examine screen is filled.


#6

question? why does an Examine screen show at all – what part does it play wrt/ right-click contextmenu?

I mean, player can right-click (gets the contextmenu) and choose Examine from there … OR right-click (gets the contextmenu) and choose a Ride action … so, what’s Examine got to do with Riding actions?


#7

You’re right, it’s not the Examine screen. It’s actually the icon of the current target that shows up.

Yes, and that part works as expected. But right-clicking also sets the current target (and it’s the character who was right-clicked) and UIObject_Input_ActionTargetScript doesn’t display the targetting cursor but directly runs its action script.

Edit:
I changed “creature” to “placeable” in the parameters for UIObject_Input_ActionTargetScript() and as expected the targetting cursor appeared. So my problem definitely comes from having the target set with a right-click on the character…


#8

idk, would you be willing to move the node from where it appears now (in contextmenu.xml) and assign it under, say, “root-npc-hostile” and/or wherever else it should affect? That is, no longer put it under “root-default” (or wherever it is now). So basically it becomes a UIObject_Misc_ExecuteServerScript … ie. player right-clicks the Target, pops up the contextmenu, chooses the action, rather than right-clicking the PC-object

The only other solution i can think of is give in to the will of the engine and create your own gui Riding panel.


#9

:grinning:
Thanks a lot KevL’s. That worked!
I’ll have to create specific horse actions lists (you wouldn’t ask an enemy to dismount would you?) but at least the player can now interact with horses and enemies.

I’ll probably have to do it some time, but for now I’ll fix the few animations I still need to correct and release the pack. This enhanced UI will be for version 2.0, with riding classes and PrC.

Thanks again, that was most valuable! :+1:


Riding horses in NWN2