View Single Post
Old 02-05-2007, 08:47 PM   #7
stoffe
Mostly dormant
 
stoffe's Avatar
 
Status: Administrator
Join Date: Apr 2002
Posts: 5,834
Helpful! 10 year veteran! Notable contributor 
Quote:
Originally Posted by Miltiades
If I may, I too have a question regarding Henchmen. If I wanted an NPC to follow the PC after a conversation, how do I do that?
You can do this by making a heartbeat script that checks if a variable has been set, and only follows the player while this variable is set. Something like this might work:

Code:
#include "k_inc_generic"

void main() {
    // ST: Don't bother with this if the AI is off, the var is not set, the
    //     character is already moving, we're in a conversation/cutscene,
    //     or if the action queue is locked.
    if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF)
        && GetLocalBoolean(OBJECT_SELF, 60)
        && (GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT)
        && !GetIsConversationActive()
        && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
        && GetCommandable())
    {
        object oOwner = GetFirstPC();
        float fOwner = GetDistanceBetween(oOwner, OBJECT_SELF);
        
        // ST: If I'm not fighting someone...
        if (!GN_GetIsFighting(OBJECT_SELF)) {
            // ST: Run to owner if more than 8m away.
            if (fOwner > 8.0) {
                ClearAllActions();
                ActionForceMoveToObject(oOwner, TRUE, 2.0);
                return;
            }   
            // ST: Walk to owner is less than 8m but more than 3m away.
            else if (fOwner > 3.0) {
                ClearAllActions();
                ActionForceMoveToObject(oOwner, FALSE, 2.0);
                return;
            }
        }
        // ST: If I am fighting someone, but the owner is very far away,
        //     stop fighting and run to the owner.
        else if (fOwner > 20.0) {
            CancelCombat(OBJECT_SELF);
            ClearAllActions();
            ActionForceMoveToObject(oOwner, TRUE, 2.0);
            return; 
        }   
        
    }
    
    // ST: If the variable isn't set, or the character isn't moving, do standard heartbeat.
    if (!GetLocalBoolean(OBJECT_SELF, 60) || (GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT)) {
        ExecuteScript("k_ai_master", OBJECT_SELF, 1001);
    }
}
This script would only make the character it's set on follow the main character while Local Boolean 60 is set to true on them. So, to make them follow from a dialog you could run an action script from the dialog like:

Code:
void main() {
    SetLocalBoolean(OBJECT_SELF, 60, TRUE);
}
This assumes the player is in dialog with the character who should follow. If not, substitute OBJECT_SELF with an object reference to that character instead.

Quote:
Originally Posted by Miltiades
Also, with that script, the NPC doesn't attack. How do I make him attack whenever the PC attacks?
You should be able to do what by setting the NPC to faction 2 (Friendly_1), and then alter the characters OnCombatRound event script to only fight if the player is fighting. Something like this might work:

Code:
#include "k_inc_generic"

void main() {
    // ST: Char is not in follow mode. Just do combat round as usual.
    if (!GetLocalBoolean(OBJECT_SELF, 60)) {
        ExecuteScript("k_ai_master", OBJECT_SELF, 1003);        
    }
    else {
        // ST: Char is in combat mode, only fight if the player is fighting,
        //     we aren't in a dialog/cutscene, I'm commandable, there is an
        //     enemy nearby and we aren't already moving.
        object oPC = GetFirstPC();
        if (!GN_GetSpawnInCondition(SW_FLAG_AI_OFF)
            && !GetIsConversationActive()
            && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
            && GetCommandable()
            && GetIsInCombat(oPC, TRUE)
            && (GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT)
            && GetIsObjectValid(GetNearestCreature( CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, oPC, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, CREATURE_TYPE_IS_ALIVE, TRUE)))
        {   
            ExecuteScript("k_ai_master", OBJECT_SELF, 1003);
        }
        else if ((GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT) && GetIsInCombat(OBJECT_SELF)) {
            CancelCombat(OBJECT_SELF);
            ClearAllActions();  
        }
    }
}


mt

Last edited by stoffe; 02-06-2007 at 12:13 PM.
stoffe is offline   you may: quote & reply,