Making a NPC go to a location

How do i make a npc run to a location that i specify through dialogue? By that i mean:

  1. talk to him about moving to a location
  2. dialogue closes and a pointer appears (similar to the to the pointer that targeted spells use)
  3. he moves to the exact location that i clicked

The key question is how to capture the target location.

Perhaps the easiest method is to use a Player Tool (you could make a new feat or spell, if preferred, but it’s more work).

ActionUseFeat, assigned to the PC at the end of the conversation, would generate the cursor. When the player clicks on a location, the Player Tool’s script would detect it via GetSpellTargetLocation(), then assign ActionMoveToLocation to the NPC.

1 Like

A nuance of this approach is that the player will have the “Pointing At Location” feat permanently, if you follow the tutorial exactly. Either you need to render it harmless when used out of context, or else assign the feat temporarily.

Sorry but it is impossible to trigger this kind of GUI interaction via scripting other than showing death screen. But what @Proleric wrote about is a functional substitute:

Player tool is actually preferred in this (and many similar cases) because its script is executed outside action queue (read: its instantaneous) and it requires no 2DA hacks. It is however usually used for actions that are used commonly and available all the time, like - well - feats.

If you need a one time “point somewhere from dialogue” then it might be an overkill. The location has to be close anyway, right? Maybe it’s enough to tell the NPC to move X meters in “direction I am facing now”?


Anyway here’s how one can move NPCs around with PLAYER TOOL method. No dialogue needed.

Save this code as x3_pl_tool01 script (the name must be exactly that):
void main()
{
    object oTarget = GetSpellTargetObject();
    location lWhere = GetSpellTargetLocation();

    // if a creature is targeted - save it as the NPC to move
    if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
    {
        SetLocalObject(OBJECT_SELF, "move", oTarget);
        FloatingTextStringOnCreature("Selected " + GetName(oTarget), OBJECT_SELF);
        return;
    }

    // if non-creature is targeted - recall NPC saved to move
    oTarget = GetLocalObject(OBJECT_SELF, "move");

    // no NPC saved?
    if(!GetIsObjectValid(oTarget))
    {
        FloatingTextStringOnCreature("No creature selected", OBJECT_SELF);
        return;
    }

    // move, clean memory
    AssignCommand(oTarget, ClearAllActions(TRUE));
    AssignCommand(oTarget, ActionMoveToLocation(lWhere));
    DeleteLocalObject(OBJECT_SELF, "move");
}

Then use this script (save it as anything, then execute it somewhere) to give your PC the Player Tool 1 feat:

void main()
{
    // adds PLAYER TOOL 1 feat to the first PC
    AddItemProperty(DURATION_TYPE_PERMANENT,
        ItemPropertyBonusFeat(IP_CONST_FEAT_PLAYER_TOOL_01),
        GetItemInSlot(INVENTORY_SLOT_CARMOUR, GetFirstPC()));
}

You can now target NPCs with player tool feat (find it in the radial menu). First click on the creature, then click where you want it to move.

Like @Proleric wrote, it is possible to dynamically add and remove this feat, but that’s against what feats are from user’s perspective and may be annoying to them.

2 Likes

It worked. Thanks guys.