Jump to content

Fallout New Vegas GECK & Scripting Help 101


Recommended Posts

Posted

It's easy to confuse GetIsReference with IsReference. I think you need IsReference here.

 

ref someRefVar

 

if IsReference someRefVar

    ; someRefVar refers to a reference

endif

 

whereas GetIsReference is the 'reference' variant of GetIsID (for base forms)

if someRefVar.GetIsReference somePersistentRefsEditorID

   ; someRefVar refers to somePersistentRef

endif

 

which is the same as

if someRefVar == somePersistentRefsEditorID

except that you can probably use it in dialog conditions

Posted

Yes it compiled, thank you!

 

Now the fact it doesn't work is a different thing... It seems the script broke and now I have those annoying random issues. Probably some dumb mistake, since for example I just compiled set nameofvar toanothervar, without spaces between to and anothervar... but well yes this is not interesting.

 

Thank you both of you!

Posted

What are your random issues?

 

A few things to remember about PlaceAtMe...

  • It takes a few frames for the function to complete. (MyReference could evaluate as true and still NOT point to an existing in world object... for a few frames)
  • If you pick up the item created, the reference is now invalid. (i.e. player picks it up and puts in inventory).
  • Many reference types will be unloaded on cell reset if created by PlaceAtMe.
Posted

I divide long scripts in branches or I would get overwhelmed when there are mistakes. I tried this branch few days ago and it was working. Today it doesn't work anymore, even if I didn't touch it (excluding when I tried to use GetIsReference and IsReference). But what you wrote about MyReference evaluating as true for few frames is quite scary, this means there's not a real way to test if it really exists for some frames and the consequences could be very bad (I Disable and MarkForDelete when it's true, I suppose this could lead to a CTD)

 

Essentially, the script allows the follower to "warp" behind the player if she goes too far away. I didn't want to use MoveTo because PlaceAtMe admits the parameter "behind the player", doing something like that with MoveTo would mean checking the player's angle etc. and you can't really foresee if there are obstacles or who knows what kind of ground.

 

So this is what I did:

 

if (MyReference.GetDistance player) > Certain distance
   if IsReference MyMarkerReference

      MyFollowerREF.Moveto MyMarkerReference
      MyMarkerReference.Disable
      MyMarkerReference.MarkForDelete
   else
      set MyMarkerReference to player.placeatme XMarker 1
   endif
endif
 

I tested it few days ago, a dozen of times, and it was working. Today it's not working anymore, never. Maybe my idea is wrong and it can't work in this way, maybe few days ago I was only lucky?

Posted

Why don't you let the markerref be a permanent reference and just use moveto player if the distance is too great and then go spanishspeakingdoggie.moveto xref?

Posted

I didn't want to use MoveTo because PlaceAtMe admits the parameter "behind the player", doing something like that with MoveTo would mean checking the player's angle etc. and you can't really foresee if there are obstacles or who knows what kind of ground.

 

Posted

Ah.  I just seem to remember in Skyrim that companions (or at least Anduniel  : P  ) seemed to pop-in a few feet off of the ground where you just were if you went too far away.  Don't know if this would involve SetPos or not.  I understand what you're going for, though.

Posted

What am I missing?  The Result End dialogue script below is what happens after the comp is hired.  However, the comp remains in sandbox mode (last package on her AI packages list) unless I console resetai.  Is it just too many things to be set with not enough time to execute so that it doesn't get to .evp? Do I need to move the .evp and some of the latter stuff to the quest script?

HopeREF.setplayerteammate 1
Set HopeCompMQ.iIsHired to 1
Set HopeCompMQ.iIsFired to 0
Set HopeCompMQ.iIsPacifist to 1
Set HopeCompMQ.iHasBeenHiredBefore to 1
player.addperk HopeCompStimhack
Set HopeCompMQ.iIsFollowingLong to 0
Set HopeCompMQ.iIsFollowingShort to 0
Set HopeCompMQ.iIsFollowingDefault to 1
HopeREF.evp
Posted

Yes that's very pretty, Serana too does it every time. I didn't take a look on how they do that in Skyrim, if it's by script or it's something "automatic". Using setpos indeed would be viable, a mixture of GetAngle and Sin to make them pop in behind the player. But what concern me is how they react to weird terrains. I.e. you move near a house and you notice the follower is not following anymore, you turn behind to take a look (so the house now remains behind your shoulders), in that moment the script runs since it has few seconds of delay, moving the follower inside the house. Or another example would be if you are running down a slope, will the follower warp inside the mountain? I think so. And I think with PlaceAtMe behind this doesn't happen.

 

EDIT: if you didn't do it, put it in the Script Begin and not Script End

Posted

As far as I know, the distance and direction parameters to PlaceAtMe don't work. The engine finds the nearest safe location and places the copy there. Although it may take the direction as a hint and try to put it there...

 

 I would not do the following:

MyFollowerREF.Moveto MyMarkerReference
MyMarkerReference.Disable
MyMarkerReference.MarkForDelete

I would do this:

integer iDoCleanup
if (IsReference MyMarkerReference)
    MyFollowerREF.Moveto MyMarkerReference
    set iDoCleanup to 1
endif
...
;different stage of script
if (1 == iDoCleanup)
    MyMarkerReference.Disable
    MyMarkerReference.MarkForDelete
endif

MoveTo causes an update of the 3d Scene Graph and will thus take many frames to complete.

Posted

In fact you may want to try something like:

 

If (MyFollowerREF.GetDistance Player > SomeDistance)
    if (IsReference MyMarkerReference)
        MyFollowerREF.MoveTo MyMarkerReference
    else
        set MyMarkerReference to player.placeatme XMarker 1
    endif
else
    if (IsReference MyMarkerReference)
        MyMarkerReference.Disable
        MyMarkerReference.MarkForDelete
    else
        return
    endif
endif
Posted

Scripting noob here, with what I guess is a noobish question: how can I make an actor hostile to the player in a dialogue result script? (I tried searching for this, both on the internet and withing the geck, but I can't recall a dialogue where this occurs, so I figured asking may save me a few hours of searching...).

Posted

Scripting noob here, with what I guess is a noobish question: how can I make an actor hostile to the player in a dialogue result script? (I tried searching for this, both on the internet and withing the geck, but I can't recall a dialogue where this occurs, so I figured asking may save me a few hours of searching...).

 

The easiest way I know is putting that NPC inside the player faction and with a Aggressive state, with some Confidence. Then, as result script in the dialogue, I would write something like this:

 

NPCREF.RemoveFromFaction player

NPCREF.StartCombat player

Posted

 

In fact you may want to try something like:

If (MyFollowerREF.GetDistance Player > SomeDistance)
    if (IsReference MyMarkerReference)
        MyFollowerREF.MoveTo MyMarkerReference
    else
        set MyMarkerReference to player.placeatme XMarker 1
    endif
else
    if (IsReference MyMarkerReference)
        MyMarkerReference.Disable
        MyMarkerReference.MarkForDelete
    else
        return
    endif
endif

 

Very smart solution, thank you, I'll try this one because I wouldn't know how to stage the previous one without introducing a lot of much more code.

 

EDIT: it CTDed at the second warp. I think there's some sync issue (I'm playing modded, not vanilla, I want to put the system under stress just to test a common scenario of a common user). For now I have placed the Disable and MarkForDelete in the same frame, just after the MoveTo, and it didn't CTDed after about 20 warps. But since you said it would require more frames to PlaceAtMe the reference, I feel it's not a stable solution especially with many mods/scripts that slowdown the system. I'll test more and more and more to see how it behaves.

 

EDIT AGAIN: after a while, it CTDed even with the other method. It's not stable, I'll give up and I'll use a MoveTo Player. Pity, it seemed a nice solution for me, to hide the follower warp.

Posted

 

Scripting noob here, with what I guess is a noobish question: how can I make an actor hostile to the player in a dialogue result script? (I tried searching for this, both on the internet and withing the geck, but I can't recall a dialogue where this occurs, so I figured asking may save me a few hours of searching...).

 

The easiest way I know is putting that NPC inside the player faction and with a Aggressive state, with some Confidence. Then, as result script in the dialogue, I would write something like this:

 

NPCREF.RemoveFromFaction player

NPCREF.StartCombat player

 

 

Neat, though in the end I did not even test this: turns out that having sunny start attacking the player messes up too many quests for my linking, so I ended up changing my design. But thanks for the quick answer!

Posted

AJ, the main reason I stated MoveTo updates the 3d Scene Graph is that when a call updates the graph it blocks thread execution until it completes.  MoveTo , unless the Player is the one being moved, immediately performs the move and updates the graph... this transfers control AWAY from your script to the rendering engine. Basically, ANY command which updates the scene graph will be the LAST command executed in a script THAT frame. The engine will try to get back to your script in the normal scheduling of script time and execute what came after that call... maybe. More likely it will run the script as if it were a new frame of execution.

 

Typically you solve this by updating a stage variable and then doing a MoveTo. When your script receives control again, the updated stage variable moves execution after the MoveTo to finish what needs to be done.

 

Your pseudo code might be:

Begin

    int StageVar

    if StageVar == 0
        Do I need to move?
            No = return
            Yes = set StageVar = 1, Move NPC
    elseif StageVar == 1
        Run a Timer for a couple of seconds
        Timer Complete?
             No = keep running timer
             Yes = set StageVar = 2 
    elseif StageVar == 2
        Set StageVar = 0
        Perform Cleanup (Disable, MarkForDelete)
    Endif

End
Posted

Typically you solve this by updating a stage variable and then doing a MoveTo.

 

 

I suppose you were referring the last example to PlaceAtMe, because of the fact it needs Delete and I believe this is the cause of CTDs in certain conditions (i.e. slowdowns during the creation of the reference).

 

I admit I didn't understand everything, but... I think I've seen that slowdown when I used MoveTo on a door: when I'm teleported on the other side, I see the graphic slowly "building" itself, it's a strange effect, I mean I don't notice it when I simply use a door to teleport, only if I use MoveTo in that door.

Anyway... You're perfectly right, staging it probably would solve it, I just feel it's becoming too big and I couldn't foresee all the consequences the other scripts could cause interacting with this one. I'ts just a feeling, I feel it would become dangerous...

 

I'm curious, you know a lot about what's "behind the scenes" concerning some commands. These things are not explained in the Beth guide, is there a place where I can find them?

Posted

@A.J.:  I checked to see how the Charon Improved mod handled calling him back to you with the radio.  It uses moveto with 128, 0, 0, and that fades him in (builds him in) behind you.  If I look too quickly, he isn't there.  When I spin back around, he is.  /possibly helpful?

Posted

problem with that 128 is that it's absolute and not relative (concerning directions, angles), that's the only reason why I was using PlaceAtMe instead of MoveTo. It was just an aestethical solution, mine, but I suppose I can live with MoveTo if this grants me stability and a shorter script :)

 

On the other hand, during tests I already have seen the "problems" of a MoveTo with offset (like the one you wrote about Charon Improved), in a case the dog got stuck inside the asphalt and in another case got stuck inside a building -_-

Posted

Just a little tidbit I found useful:

if bMove
    if (0 < dTimer)
        set dTimer to (dTimer - GetSecondsPassed)
    else
        set bMove to 0
        if (Player.GetAngle Z >= 0) && (Player.GetAngle Z < 90)
            ref.MoveTo Player, -50, -50, 10
        elseIf (Player.GetAngle Z >= 90) && (Player.GetAngle Z < 180)
            ref.MoveTo Player, -50, 50, 10
        elseIf (Player.GetAngle Z >= 180) && (Player.GetAngle Z < 270)
            ref.MoveTo Player, 50, 50, 10
        elseIf (Player.GetAngle Z >= 270) && (Player.GetAngle Z < 360)
            ref.MoveTo Player, 50, -50, 10
        endIf
    endif
endif

It grabs the Players angles and moves based on relation to them.

 

Posted

I'm curious, you know a lot about what's "behind the scenes" concerning some commands. These things are not explained in the Beth guide, is there a place where I can find them?

 

 

Unfortunately, like I did... Google. Reading blogs, forums, GECK wiki talk pages... and my FAVORITE... finding out that the GECK wiki authors didn't write something in the GECK wiki if it was already written in the Oblivion CS wiki... fucking GRRR... like the talk pages... you know, the ones where scripters detail how the behavior has gotchas and give actual behavior as compared to expected behavior.

 

EDIT: Oh... and I'm a programmer with over 30 years of experience writing code... that helps too ;)

Posted

What I love is that they must have restructured the TES wiki so that 99.999% of the links don't work anymore when going from the GECK wiki.

 

On a page in the GECK, there's a main page/tab and then there's also a Discussion tab at the top.  That's the one that astymma's talking about.  Most are empty.  Sometimes there is info with the expected vs. actual behavior.

Posted

Just a little tidbit I found useful

 

Mind if I "steal" it? :)

 

-----------------------------------

 

EDIT: just tried my idea, it didn't work as expected. Maybe a nice idea, but it only worked in my mind. Let's erase everything...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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