Jump to content

Prevent NV companions from entering a cell?


Belthan

Recommended Posts

When I need to script a scene and I don't want followers around, I use an external UDF which contains a scanner like JIP wrote. The difference is I scan for a follow package with GetTargetPackage = PlayerREF. This is the most reliable and generical solution I found with any kind of npcs, modded or vanilla. This is because some "temporary" companions (the first I can think about is the Inheritance guy) have not the TeamMate flagged, generally those without wheel, so I think even Willow in the first stage (didn't check, it's just a feeling). Then when I have a form with the refs, I simply restrain / setghost or disable, to make them unable to react and be harmed, because Waiting is not a reliable solution for me (modded ones could always use different var names for their custom packages, or even having Gamemode blocks that prevent unexpected behaviours forcing back these values). When the scene is completed, I do the contrary calling the same UDF and passing a different parameter.

 

I'm also wondering to expand this solution optionally scanning the find package, this avoid those rare (but still present) cases when a npc is looking for the player in the same exact moment when I'm running this script. Malcolm or the king guy in freeside are two examples, it already happened to me they broke my stuff :smile:

Edited by Fallout2AM
Link to comment
Share on other sites

When I need to script a scene and I don't want followers around, I use an external UDF which contains a scanner like JIP wrote. The difference is I scan for a follow package with GetTargetPackage = PlayerREF. This is the most reliable and generical solution I found with any kind of npcs, modded or vanilla. This is because some "temporary" companions (the first I can think about is the Inheritance guy) have not the TeamMate flagged, generally those without wheel, so I think even Willow in the first stage (didn't check, it's just a feeling). Then when I have a form with the refs, I simply restrain / setghost or disable, to make them unable to react and be harmed, because Waiting is not a reliable solution for me (modded ones could always use different var names for their custom packages, or even having Gamemode blocks that prevent unexpected behaviours forcing back these values). When the scene is completed, I do the contrary calling the same UDF and passing a different parameter.

 

I'm also wondering to expand this solution optionally scanning the find package, this avoid those rare (but still present) cases when a npc is looking for the player in the same exact moment when I'm running this script. Malcolm or the king guy in freeside are two examples, it already happened to me they broke my stuff :smile:

 

 

Yes, searching for the target on the follow package should yield better results when you want to find all the "companion" actors who are following the player. I like your entire solution; the restraining, ghost, etc. Very nice.

 

And there's also the thing to consider that not everyone who mods in NV likes the wheel, that there may be NPCs temp following from mods that may not have the wheel, etc so players with companions in their game that don't have GetPlayerTeammate to 1, as you say, won't get caught even though they are following the player. And yes, Willow wouldn't get caught before she's hired if one was using GetPlayerTeammate because I don't set it until she's hired.

 

The find package is a good idea, but you might want to look into dialogue pkgs as well. I suspect, although I didn't look at it, that Malcom Holmes is probably on a dialogue package when he's chasing you down to talk to you about star bottlecaps. A dialogue package, when set up as a force greet, acts like a find pkg but ends with a dialogue line.

Link to comment
Share on other sites

That's basically why I used this solution, my companions don't use the wheel :-O

I just checked Malcolm. You're right, it's Dialogue.

Restricting all these different kinds of packages could become dangerous if the whole scene requires some time. I could find myself surrounded by inactive zombies or suddenly all alone :) I can't foresee cases like that, it's just a feeling, like 99% of the things I do. At this point I would prefer sticking with the follow package target and hope that some npc don't pop up in the wrong time...

 

I attach the UDF as reference, if it's useful.

MQ is an external fake quest used to store vars values like the stage, since it's staged.

 

 

 

int DisableSwitch                                 ; 0 restrain - 1 unrestrain - 2 disable - 3 enable

int NumRefs

ref TempRef
ref TempPackage
int TempCounter


Begin Function {DisableSwitch}

    if (DisableSwitch == 0) || (DisableSwitch == 2)

        if aCamMQ.CompStage == 0
            PrintC "Comp Stage 0"
            let aCamMQ.CompCounter := 0
            let NumRefs := GetNumRefs 200 1 1
            let TempRef := GetFirstRef 200 1 1
            if TempRef.GetCurrentAIPackage == 1
                if TempRef.GetPackageTarget == PlayerREF
                    ar_append aCamMQ.FollowRefs TempRef
                endif
            endif

            While (aCamMQ.CompCounter < NumRefs)
                let aCamMQ.CompCounter +=1
                Let TempRef := GetNextRef
                if TempRef.GetCurrentAIPackage == 1
                    if TempRef.GetPackageTarget == PlayerREF
                        ar_append aCamMQ.FollowRefs TempRef
                    endif
                endif
            Loop

            let aCamMQ.CompStage := 1
            let aCamMQ.CompCounter := 0
            PrintC "References added to the array"
            ar_dump aCamMQ.FollowRefs
            Return

        elseif aCamMQ.CompStage == 1

            let NumRefs := ar_size aCamMQ.FollowRefs
            Let TempCounter := (aCamMQ.CompCounter)
            Let TempRef := aCamMQ.FollowRefs[TempCounter]

            if TempCounter < NumRefs
                if TempRef
                    if (GetType TempRef == 42) || (GetType TempRef == 43)

                        if TempRef.GetIsGhost
                            PrintC "%n is Ghost" TempRef
                            if  (DisableSwitch == 0)
                                if TempRef.GetRestrained
                                    Let (aCamMQ.CompCounter) += 1
                                    PrintC "%n Restrained" TempRef
                                    Return
                                else
                                    TempRef.SetRestrained 1
                                    Return
                                endif
                            else
                                if TempRef.GetDisabled
                                    Let (aCamMQ.CompCounter) += 1
                                    PrintC "%n Disabled" TempRef
                                    Return
                                else
                                    TempRef.Disable
                                    Return
                                endif
                            endif
                        else
                            TempRef.SetGhost 1
                            Return
                        endif

                    endif
                endif

                Let (aCamMQ.CompCounter) += 1
                Return

            else
                SetFunctionValue 1
                Let aCamMq.CompCounter := 0
                Let aCamMq.CompStage := 0
                if aCamMQ.debug
                    ar_dump aCamMQ.FollowRefs
                endif
            endif
        endif

    elseif (DisableSwitch == 1) || (DisableSwitch == 3)

        Let NumRefs := ar_size aCamMQ.FollowRefs
        Let TempCounter := (aCamMQ.CompCounter)
        Let TempRef := aCamMQ.FollowRefs[TempCounter]

        if TempCounter  < NumRefs

            if TempRef
                if (GetType TempRef == 42) || (GetType TempRef == 43)
                    if TempRef.GetIsGhost
                        TempRef.SetGhost 0
                        Return
                    else
                        PrintC "%n is no more Ghost" TempRef
                        if  (DisableSwitch == 1)
                            if TempRef.GetRestrained
                                PrintC "Going to UnRestrain %n" TempRef
                                TempRef.SetRestrained 0
                                Return
                            else
                                PrintC "%n isn't Restrained" TempRef
                                Let aCamMQ.CompCounter += 1
                                Return
                            endif
                        else
                            if TempRef.GetDisabled
                                PrintC "Going to Enable %n" TempRef
                                TempRef.Enable
                                Return
                            else
                                PrintC "%n is Enabled" TempRef
                                Let aCamMQ.CompCounter += 1
                                Return
                            endif
                        endif
                    endif
                endif
            endif
            Let aCamMQ.CompCounter += 1
            Return
            
        else
            if aCamMQ.debug
                PrintC "done"
            endif

            Let aCamMQ.CompStage := 0
            Let aCamMQ.CompCounter := 0
            Let aCamMQ.FollowRefs := Ar_Construct "array"
            Let aCamMQ.FollowRefs := ar_list Pencil01
            SetFunctionValue 1
        endif
    endif
end

 

 

Link to comment
Share on other sites

  • 4 weeks later...

Wouldn't something like this be easier?

 

is EdeRef.Hired == 1 ;check if is hired

if EDEREF.getPlayerTeammate == 1 ;check if is a teammate

EDERef.setPlayerTeamate to 0 ;set teammate to zero change package to wait..he won't follow you anymore
now simply revert him to wait package
and he wont follow you anymore and will stay outside but still be hired
etc.
endi
endif

or simply set him to wait package from code would also do it no?

Edited by africaisstarving
Link to comment
Share on other sites

also speaking of not liking the wheel. In my mod I made a COPY me method in which a follower imitates the player as in changes packages dynamically goes in sneak mode etc and you won't need teammate mode to do it. Is all scripted. If you wish I can share the code with you. So you can simply add a new dialogue option or simply add the script to your followers as a token even to make them teammate 0 but still be able to imitate you go sneak change packages melee/ranged etc based on what you're doing is like 2 dialogue options all you need something like Let's go/imitate Me and Wait here. Easy.

Edited by africaisstarving
Link to comment
Share on other sites

Wouldn't something like this be easier?

 

is EdeRef.Hired == 1 ;check if is hired

if EDEREF.getPlayerTeammate == 1 ;check if is a teammate

EDERef.setPlayerTeamate to 0 ;set teammate to zero change package to wait..he won't follow you anymore

now simply revert him to wait package

and he wont follow you anymore and will stay outside but still be hired

etc.

endi

endif

 

or simply set him to wait package from code would also do it no?

 

this implies that EDEREF exists, because you think about vanilla. In the case of companion mods, you should put it as master, or do a patch, or you should buildref it, using the new nvse functions to get the variable values, but this will break if the modder will change something on his companion mod. So I don't consider it a stable solution

Link to comment
Share on other sites

 

Wouldn't something like this be easier?

 

is EdeRef.Hired == 1 ;check if is hired

if EDEREF.getPlayerTeammate == 1 ;check if is a teammate

EDERef.setPlayerTeamate to 0 ;set teammate to zero change package to wait..he won't follow you anymore

now simply revert him to wait package

and he wont follow you anymore and will stay outside but still be hired

etc.

endi

endif

 

or simply set him to wait package from code would also do it no?

 

this implies that EDEREF exists, because you think about vanilla. In the case of companion mods, you should put it as master, or do a patch, or you should buildref it, using the new nvse functions to get the variable values, but this will break if the modder will change something on his companion mod. So I don't consider it a stable solution

 

but your solution, although compatible, is very complicated script code and very slow to process. would be easier and more efficient to simply create a patch or use getactionref / is action ref instead in conjunction with lists. i don't like using getrefnext ref type code is incredibly slow

 

have a blank quest with a script attached for holding variables

 

have 1 obj ref

obj

 

have 2 lists

- a permenent companion list

- a waiting ajusted companion list

 

add this code anywhere you wish

set QUEST.obj to player.getactionref

 

if QUEST.obj.getteammate == 1

 

;track permanent companion refs

if QUEST.obj == getFRomList QUEST.teammatelist == -1 ;not in list

save QUEST.obj to list perm companions

endif

 

; you just instructed a perm companion to wait ..or whatever trigger you wish..you

if QUEST.obj.getcurrentAIProjecture == follow ;he is set to follow you

 

if condition..ye youre moving to a new space/youre in aspecific spaceetc

set that teammate to do stuff remove teammate package etc

 

;save it to the list

if not QUST.obj == getFRomList QUEST.waitCompanionsList -1 ;not in list

save it to wait adjust list

endif

 

etc any other code you want adjusted here

 

.....

 

This will trigger on any activated actor ref and if conditions are true will do the code and save a list of perm companions as you interact with them. Makes more sense. actionref works with companion wheel, works with dialogue , works with attacking , healing, anything. And the key thing is it always works THE INSTANT you use that actor so it always works.

 

 

remember that in Quest Scripts refs and ref lists are persistent and kept in gamesave ..you can just build a companion list as you find/add/interact with them rather than permanently scanning

you don't need tocheck for individual packages..or packages with target player..check if actor is teammate 1 check if AI procedure is follow..they WILL ALWAYS be companions...thats it..ez to identify companions and dynamically build yourself the list of companion refs from any mod will be added to the perm comp list forever

 

also companion refs can be accessed from the list directly using getlistfromIndex or something and manipulated directly ..once you get the ref you can do anything you want with it. you can mass set them all to follow if you wish. iterate trough the list get each ref set each ref to changepackage etc. you can look to see if any of them is too far away from you get them to teleport to you or even if they are in combat to run way etc

Edited by africaisstarving
Link to comment
Share on other sites

  • Recently Browsing   0 members

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