Note: LucasForums Archive Project
The content here was reconstructed by scraping the Wayback Machine in an effort to restore some of what was lost when LF went down. The LucasForums Archive Project claims no ownership over the content or assets that were archived on archive.org.

This project is meant for research purposes only.

I need some help to make NPCs follow

Page: 1 of 1
 Phantasmgrl91
01-28-2007, 6:16 PM
#1
Ok, this is what I want to do. I am new to modding so any help I can get would be appreciated. Boa Durr has a puppet assigned to him but I dont believe that puppets can be assigned to the exile character, I was wondering if there is a way to assign an NPC to the exile without sacrificing other party members, basically just someone who can follow the exile around and help out in a fight like on onderon when some of there military is assigned to follow you yet you still keep kreia and whoever else you choose in your party, I want this NPC to be able to follow you around throughout the game, always be with you

is this possible to do? I have read the creating a puppet tutorial which is helpful though I want to assign it to the exile not a different party member. I'm starting to think that it is impossible :(
 SithRevan
01-28-2007, 6:23 PM
#2
Yeah, what you want is called a henchmen. Here is the code that I used for a henchmen once...


// k_fpm_heartbtxx

#include "k_inc_debug"
#include "k_inc_generic"
#include "k_inc_switch"
#include "k_inc_utility"



void main()
{



object oEnemy = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF) && !GetSoloMode())
{
if(GetPartyMemberByIndex(0) != OBJECT_SELF)
{
if(//GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOW &&
GetCurrentAction(OBJECT_SELF) != ACTION_WAIT &&
!GetIsConversationActive() &&
!GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE) &&
GetCommandable())
{

if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy))


ClearAllActions();
if(GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) < 5.0)
{
ClearAllActions();
ActionForceMoveToObject(GetPartyMemberByIndex(0), FALSE, 1.0);
//SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the bWalk routine.");
}
if(GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) > 5.0)
{
ClearAllActions();
ActionForceMoveToObject(GetPartyMemberByIndex(0), TRUE, 3.5);
//SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the bRun routine.");
}

}
}
}
else if(GetSoloMode() && GetCurrentAction(OBJECT_SELF) == ACTION_FOLLOWLEADER)
{
ClearAllActions();
}
if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBE AT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(1001));
}



}

You just put this in the "OnHeartbeat" function of the character and they should follow you around providing that they have been spawned near you in that level.
 Phantasmgrl91
01-28-2007, 6:35 PM
#3
i see, and this will follow the exile from planet to planet?
 SithRevan
01-28-2007, 6:39 PM
#4
No. To my knowledge that cannot be done. The character you attach this script to will have to be in the level for it to work. If you wanted to do that I would suggest using the "OnEnter" of each module to run a spawning script. That way you will be able to get that character in each level
 oldflash
01-30-2007, 9:25 AM
#5
Ok, this is what I want to do. I am new to modding so any help I can get would be appreciated. Boa Durr has a puppet assigned to him but I dont believe that puppets can be assigned to the exile character, I was wondering if there is a way to assign an NPC to the exile without sacrificing other party members, basically just someone who can follow the exile around and help out in a fight like on onderon when some of there military is assigned to follow you yet you still keep kreia and whoever else you choose in your party, I want this NPC to be able to follow you around throughout the game, always be with you

is this possible to do? I have read the creating a puppet tutorial which is helpful though I want to assign it to the exile not a different party member. I'm starting to think that it is impossible :(
I've done that with stoffe's help. If you want I can post all script sources (also included in final touch mod). Once the remote is activated it will follow (anywere, even on g0t0's yacht) the exile only (there are alot of checks for areas where the party leader is t3m4, mira, bao-dur's remote or another npc on g0t0's yacht).
 Miltiades
02-05-2007, 5:44 PM
#6
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?



The script SithRevan posted doesn't specify an NPC, because it has to be linked to the On_Heartbeat of the NPC. But this will make him follow as soon as the PC enters the module.

Also, with that script, the NPC doesn't attack. How do I make him attack whenever the PC attacks?
 stoffe
02-05-2007, 6:47 PM
#7
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:



#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:


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.


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:


#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();
}
}
}
 Miltiades
02-06-2007, 9:54 AM
#8
That first script didn't work, at least not with me. The NPC still follows me from as soon as I enter the module.

Also, if I want the NPC to attack, and I need the second script for it, how do I implement the second script into the first?
 stoffe
02-06-2007, 10:17 AM
#9
That first script didn't work, at least not with me. The NPC still follows me from as soon as I enter the module.

Oops, seems like I got one negation too many in the script. Remove the ! character on the line...

&& !GetLocalBoolean(OBJECT_SELF, 60)

...under the first if-statement, and it should hopefully work better. (It would be causing the NPC to follow when the variable was not set, instead of when it was set.)

Also, if I want the NPC to attack, and I need the second script for it, how do I implement the second script into the first?

You don't, they are scripts for two separate events (assuming you don't mean the oneliner dialog action script when you say "the second script"). The first script posted was a custom script for the OnHeartbeat event of the NPC, while the third script was a custom script for the OnCombatRound event. You set them both in the UTC template of the NPC who should follow/attack (the Scripts tab if you use KotorTool's UTC editor).
 Miltiades
02-06-2007, 10:55 AM
#10
You don't, they are scripts for two separate events (assuming you don't mean the oneliner dialog action script when you say "the second script"). The first script posted was a custom script for the OnHeartbeat event of the NPC, while the third script was a custom script for the OnCombatRound event. You set them both in the UTC template of the NPC who should follow/attack (the Scripts tab if you use KotorTool's UTC editor).

Oh yeah, of course. But I don't see the OnCombatRound in the .utc file. There's OnAttacked and OnEndRound though.
 stoffe
02-06-2007, 11:00 AM
#11
Oh yeah, of course. But I don't see the OnCombatRound in the .utc file. There's OnAttacked and OnEndRound though.

It's ScriptEndRound if you go by the GFF field labels in the UTC file (since field labels can be at most 16 characters in length). That field is used for the script that fires once each round when you are in combat mode.
 Miltiades
02-06-2007, 11:45 AM
#12
Okay thanks. The NPC follows me correctly now, btw. One other question though:

If I want more than one NPC to follow me, I need to "substitute OBJECT_SELF with an object reference to that character instead.", like you said before. I don't know how to do that, could you explain? Or is it possible for them to follow te PC if they're involved in the conversation?
 stoffe
02-06-2007, 11:52 AM
#13
Okay thanks. The NPC follows me correctly now, btw. One other question though:

If I want more than one NPC to follow me, I need to "substitute OBJECT_SELF with an object reference to that character instead.", like you said before. I don't know how to do that, could you explain? Or is it possible for them to follow te PC if they're involved in the conversation?

If they both have those scripts set on their AI events, and have their faction set to Friendly_1 (or any that makes them hostile to enemies and enemies hostile to them), you could enable them all to follow in the same dialog action script if you know their tags, like


void main() {
SetLocalBoolean(GetObjectByTag("Follower1"), 60, TRUE);
SetLocalBoolean(GetObjectByTag("Follower2"), 60, TRUE);
}


...where you set Follower1 and Follower2 to the respective tags of your NPCs.
 Miltiades
02-06-2007, 12:26 PM
#14
Is that for when both are involved in the convo, or doesn't that matter?

If it doesn't, then it didn't work with me.
 stoffe
02-06-2007, 1:17 PM
#15
Is that for when both are involved in the convo, or doesn't that matter?

If it doesn't, then it didn't work with me.

It doesn't matter where that script is run from, as long as two characters with the specified tags exist in that area when the script is run.
 Miltiades
02-06-2007, 1:30 PM
#16
Okay, great, it works. Funny thing, though, is that they attack one round, and then stop. What's the problem?
 stoffe
02-06-2007, 1:42 PM
#17
Okay, great, it works. Funny thing, though, is that they attack one round, and then stop. What's the problem?

Are you attacking the enemies, or just standing cheering on the sidelines? :) I got the impression you only wanted the NPCs to attack enemies when the player was in combat, so there are a bunch of checks that try to block out the combat AI when there are enemies but the player is not fighting.

If you are fighting as well there could be other errors in the OnCombatRound script. Hard to spot all the mistakes you make when writing code in the tiny text area on these forums. :)
 Miltiades
02-06-2007, 1:56 PM
#18
I was fighting (after cheering on the sidelines :) ). As soon as I begun to fight, the NPCs also begon to fight, but only for one round.
 stoffe
02-06-2007, 2:14 PM
#19
I was fighting (after cheering on the sidelines :) ). As soon as I begun to fight, the NPCs also begon to fight, but only for one round.

Hmm... Try changing the second parameter to GetIsInCombat() to FALSE (it's TRUE now) and see if that makes a difference.

Also, are you fighting before or after the NPCs have been told to follow?



On second thought you'll probably need to add checks to the OnDialog and OnPerception scripts as well, if you want to (somewhat) reliably prevent the NPCs from attacking enemies they spot if the player isn't attacking.
 Miltiades
02-06-2007, 2:57 PM
#20
After they've been told to follow.

Anyway, I tried what you said, and yes, they start firing without the PC attacking. I don't really mind, if I change their perception range to short, there won't be much trouble.

The NPCs have managed to fight a little while longer, but still stop at some point during the attack. Weird. But maybe that was because this time, I wasn't fighting. I thought that because the NPCs began fighting without the PC fighting, it didn't matter anymore.
 stoffe
02-06-2007, 3:11 PM
#21
The NPCs have managed to fight a little while longer, but still stop at some point during the attack. Weird. But maybe that was because this time, I wasn't fighting. I thought that because the NPCs began fighting without the PC fighting, it didn't matter anymore.

That's probably/hopefully the reason, since that's how it was intended to work. If the player no longer fights the NPCs would stop as well. For example if the player decides to run away the NPCs shouldn't stay behind and fight.

If you want them to continue fighting even if the player stops the script conditionals in the OnCombatRoundEnd script have to be updated something like this: Find the GetIsInCombat() line you just edited, and change it from....

&& GetIsInCombat(oPC, FALSE)

...to...

&& (GetIsInCombat(oPC, FALSE) || GetIsInCombat(OBJECT_SELF))

This should hopefully make them keep fighting if the player is fighting, or they are fighting.
 Miltiades
02-06-2007, 3:22 PM
#22
As long as they keep fighting when the PC is fighting, I'm happy. I don't think I want them to keep fighting when the PC runs away for example, but it's handy to know. Thanks for all the help.
 Miltiades
02-17-2007, 8:57 AM
#23
Sorry for bringing this back up, but I noticed something. The NPCs following the PC do everything correct, fighting when the PC fights.

Only on one occasion they wouldn't fight. The hostile PC was close to a transition area. When I lured the hostile NPC away, the other NPCs began fighting them. Another explanation could be because the NPC is flanked by two banners.

If one of these reasons is correct, how do I fix it?
Page: 1 of 1