Jump to content

Npc Cannot Path. Keeps Getting Stuck on the Ground


Recommended Posts

I can't think of any reason why you would have to delete him.

 

Are you adding all of his AI packages with that script? I personally wouldn't do that. I've had too many problems with companions deciding not to run their added script package after going through a door or teleporting somewhere (like fast travel). Instead, make a follow long package, a follow close package, a wait package, and a default package for when the NPC hasn't been hired. Then check your script variables (isFollowingLong, Waiting, etc) to enable each package. You'll find that this is much more reliable.

 

Also, make sure you add a line saying ALAmicusREF.evp after any AI package change. This will force him to re-evaluate his AI packages and (hopefully) choose one.

Link to comment
Share on other sites

By the way, this is a good companion tutorial. Do it this way and everything including the companion wheel will work.

http://www.nexusmods.com/newvegas/mods/45278/?

 

The tutorial shows two quests for the NPC, one to hire the NPC and one to run the NPC's dialog and companion functions. You don't need the quest to hire the NPC. That's entirely up to you if you want to have a quest or not. Alternately, you can just hire the companion through dialog. A hiring quest is not a requirement to make a working companion.

 

The dialog and companion function quest is a requirement though.

Edited by madmongo
Link to comment
Share on other sites

You realize that this NPC script runs every frame, so you are applying the script package 60 times per second if you are running at 60fps and probably locking up the AI.


Try:




If (HasBeenHired == 1)
if (ALAmicusREF.GetIsCurrentPackage ALAmicusSandBox == 1)
ALAmicusREF.removescriptpackage ALAmicusSandBox
endif
endif


If (HasBeenHired == 0)
if (ALAmicusREF.GetIsCurrentPackage ALAmicusSandBox == 0)
ALAmicusREF.addscriptpackage ALAmicusSandBox
endif
endif



Also the armor is being added every frame. Put another 'DoOnce2' on that section, or some other check, like 'GetItemCount'


Edit: And what madmongo said - it's better to avoid scriptpackages except for very short times - when the player is not going to be exiting the cell where the NPC is located. For the sandbox package, it will be ok, but for the follower packages, you should place them on the NPC object.

Link to comment
Share on other sites

 

You realize that this NPC script runs every frame, so you are applying the script package 60 times per second if you are running at 60fps and probably locking up the AI.
Try:
If (HasBeenHired == 1)
   if (ALAmicusREF.GetIsCurrentPackage ALAmicusSandBox == 1)
      ALAmicusREF.removescriptpackage ALAmicusSandBox
   endif
endif


If (HasBeenHired == 0)
   if (ALAmicusREF.GetIsCurrentPackage ALAmicusSandBox == 0)
      ALAmicusREF.addscriptpackage ALAmicusSandBox
   endif
endif
Also the armor is being added every frame. Put another 'DoOnce2' on that section, or some other check, like 'GetItemCount'
Edit: And what madmongo said - it's better to avoid scriptpackages except for very short times - when the player is not going to be exiting the cell where the NPC is located. For the sandbox package, it will be ok, but for the follower packages, you should place them on the NPC object.

 

The reason I used addscriptpackage was because he just kept sandboxing. But I will try that script.

Link to comment
Share on other sites

This is the script that didn't work.


If (GetItemCount ALArmorAmicus == 1) && (KillProfligates == 0)

ALAmicusREF.additem ALArmorLeatherReinforcedAmicus 1

ALAmicusREF.removeitem ALArmorAmicus 1

ALAmicusREF.removefromfaction VCaesarsLegionFaction

ALAmicusREF.equipitem ALArmorLeatherReinforcedAmicus


Elseif (GetItemCount ALArmorLeatherReinforcedAmicus == 1) && (KillProfligates == 1)

ALAmicusREF.addtofaction VCaesarsLegionFaction 0

ALAmicusREF.additem ALArmorAmicus 1

ALAmicusREF.equipitem ALArmorAmicus

Endif
Link to comment
Share on other sites

When you are new to scripting, avoid "compound conditionals": ones where two or more conditional tests have to be evaluated before you proceed to the "THEN" or "ELSE" result.

 

The reason for this is to make it clear to yourself that you have considered all the ramifications of all the conditions. To use your script as an example:

If (GetItemCount ALArmorAmicus == 1) && (KillProfligates == 0)

form a "logical AND conditional" where both conditions to either side of the "&&" form a third condition that will only be true if both "(GetItemCount ALArmorAmicus == 1)" is true and "(KillProfligates == 0)" is as well. If either one is false, the "logical AND" fails and you proceed to the "ELSE" statement (which in this instance is the "ELSEIF" conditional:

Elseif  (GetItemCount ALArmorLeatherReinforcedAmicus == 1) && (KillProfligates == 1)

where again two conditions must be true or you proceed to the (implied) "ELSE" which does nothing and falls through to the "ENDIF".

 

As a consequence you have no idea which of the four conditions are causing things to fail; nor have you allowed even for a debugging message for that possibility. In addition, because you are using the result of a function call (GetItemCount) as the "test variable" of your condition, you can't tell if you have a syntax error or the wrong "[ContainerRef]" in that function call. And you have to have set the value of "KillProfligates" previously. When learning to script it is usually better to set the result of a function call (i.e. "GetItemCount ALArmorAmicus") to a variable and only test variables in conditionals. That reduces the already considerable processing overhead of the conditional statement line, and gives an easier check for debugging purposes.

 

When starting out scripting it is often difficult to learn that you HAVE to think of every "IF" statement as having an "ELSE", even though it may only be implied by it's absence as "ELSE < do nothing >". Failing to consider the consequences of "ELSE" has tripped up many a programmer.

 

Using an existing script from the game or a tutorial is no substitute for understanding how it is working. When a script doesn't work you have to use debug statements to determine the values affecting script branching to understand why not. It is not uncommon for scripts in development to have more debugging code lines than actual code. See "TIP: Pass a variable number into a script message" under the "Scripting" section of the wiki "Getting started creating mods using GECK" article for the basics of a debugging message.

 

The compound conditional is a more sophisticated version of a "nested IF" condition, and can just as easily be presented (in more lines of code and "< pseudo-code >" statements, but who's counting?) as:
If (GetItemCount ALArmorAmicus == 1)
  < debug message indicating first condition is true >
  If (KillProfligates == 0)
    < debug message indicating second condition is true >
    <perform intended actions: add/remove items>
  Else
    < debug message indicating second condition is false >
    < "do nothing"; is this really what you want? >
  EndIf
Elseif  (GetItemCount ALArmorLeatherReinforcedAmicus == 1)
  < debug message indicating third condition is true >
  If (KillProfligates == 1)
    < debug message indicating fourth condition is true >
    <perform intended actions: add/remove items>
  Else
    < debug message indicating fourth condition is false >
    < "do nothing"; is this really what you want? >
  EndIf
Else
  < debug message indicating third condition is false >
  < "do nothing"; is this really what you want? >
EndIf

Learn to use indenting to keep clear that you have the correct number and grouping of the required elements of your nested IF statement.

 

Note the "||" symbol is used in place of the "&&" to create a "logical OR conditional" which is true if either one of the conditionals on either side of it are true; the reverse of the "logical AND". It is the equivalent of a series of "nested ELSEIF" statements.

 

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

I tried to fix that section of the script but it still works improperly.

If (GetItemCount ALArmorAmicus == 1)
		If (KillProfligates == 0)
			ALAmicusREF.additem ALArmorLeatherReinforcedAmicus 1
			ALAmicusREF.removeitem ALArmorAmicus 1
			ALAmicusREF.removefromfaction VCaesarsLegionFaction
			ALAmicusREF.equipitem ALArmorLeatherReinforcedAmicus
		Endif
	Endif
	If (GetItemCount ALArmorLeatherReinforcedAmicus == 1)
		If (KillProfligates == 1)
			ALAmicusREF.addtofaction VCaesarsLegionFaction 0
			ALAmicusREF.additem ALArmorAmicus 1
			ALAmicusREF.equipitem ALArmorAmicus
		Endif
	Endif
 If (DoOnce2 != 1)
   set KillProfligates to 1
   set DoOnce2 to 1
 Endif
Edited by GayLeonianNerd
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...