Jump to content

Jamming an array into an existing script so I can fix Vault 19 and do new stuff too


Recommended Posts

Posted

I'll post what I have so far to get some insight into this.  I'll start dealing with the assigning girls to refs thing once I can get this part of the script to save.

scn TryoutGirlGetterQuestSCRIPT
 
Ref PotentialRef
Ref Companion1
Ref Companion2
Ref Companion3
Ref Companion4
Ref Companion5
Ref Companion6
Ref Companion7
int PotentialTotal
 
array_var arScanres
array_var arTRGirls
array_var entry
 
Begin GameMode
 
  let arTRGirls := ar_Null
  let arTRGirls := ar_construct array
  
  if GetPCIsSex Female
    let arScanres := GetRefs 42  <------------- THIS IS THE LINE THAT WON'T COMPILE
    foreach entry <- arScanres
      let PotentialRef := *entry
      if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0)
        ar_append arTRGirls PotentialRef
      endif
    loop
  endif
 
  ; Should arScanres be set to ar_Null here?  Doesnt seem like it should hurt
  let arScanres := ar_Null
 
  ; This takes the place of your console prints.
  ar_dump arTRGirls
 
  let Companion1 := arTRGirls[0]
  let Companion2 := arTRGirls[1]
  let Companion3 := arTRGirls[2]
  let Companion4 := arTRGirls[3]
  let Companion5 := arTRGirls[4]
  let Companion6 := arTRGirls[5]
  let Companion7 := arTRGirls[6]
 
End
Posted

I will look but PLEASE take heed. This..

 

  let Companion1 := arTRGirls[0]
  let Companion2 := arTRGirls[1]
  let Companion3 := arTRGirls[2]
  let Companion4 := arTRGirls[3]
  let Companion5 := arTRGirls[4]
  let Companion6 := arTRGirls[5]
  let Companion7 := arTRGirls[6]
..is not safe. I don't know if it'll crash or just not work right, but if there are less than 7 companions, it's going to be accessing undefined entries in the array. If there is only one companion and you try to access the 2nd entry in the array, it's like taking two steps towards a cliff you're only one step away from.
Posted

I agree it's not safe.  That's why I'm tackling it once I can get the script to compile.

 

And it would appear that my NVSE was not 4.5beta7 from Silverlock.  Updating to that fixed it.

 

Now to tackle assigning the girls.  In addition to assigning them to the variables, if one of them stops being a teammate, I'd like to clean out the array and let it rebuild.

Posted

The array will rebuild every time the script runs. You should have no problems running it every second or even faster, it's pretty lightweight. I'd be careful about running it too often if you expand the scan radius.

 

Of course you could also just use the sexout scanner, and populate the array from the formlist it provides, for actors that pass your checks. A future version of the scanner will take an array as an option rather than the formlist, but copying from one to the other is easy enough.

Posted

So if the array is constantly rebuilding, won't that constantly change which girl is assigned to what ref variable?  If it does I need to rework how I remove and return items to girls in captivity.

 

EDIT: Some shower thoughts.  If the array is constantly repopulating, this clears up a lot of things I don't like about my old system.  It'll shuffle up the list occasionally, so Powder Gangers and Legion and whatnot don't always go for the same girl first.  Also, if a girl stops being your companion, the array resetting will simply rebuild it without her.

 

As for things where I need to track the girls for things like returning their stuff, I can copy the array contents into something that isn't reset until I tell it to reset.  Also instead of having the random picker in Vault 19, I can just use a quest stage script to get a "snapshot" of the main array and set ref variables and then pass that information to the sex scenes.

Posted

This is the latest version:

 

 

scn TryoutGirlGetterQuestSCRIPT
 
Ref PotentialRef
Ref Companion1
Ref Companion2
Ref Companion3
Ref Companion4
Ref Companion5
Ref Companion6
Ref Companion7
Ref Companion8
Ref Companion9
 
int PotentialTotal
int arCount
 
array_var arScanres
array_var arTRGirls
array_var entry
 
Begin GameMode
 
  let arTRGirls := ar_Null
  let arTRGirls := ar_construct array
  
  if GetPCIsSex Female
    let arScanres := GetRefs 42
    foreach entry <- arScanres
      let PotentialRef := *entry
      if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0)
        ar_append arTRGirls PotentialRef
      endif
    loop
  endif
 
  ; Should arScanres be set to ar_Null here?  Doesnt seem like it should hurt
  let arScanres := ar_Null
 
  ; This takes the place of your console prints.
  ar_dump arTRGirls
 
  let arCount := ar_size arTRGirls 
 
  if (arCount >= 1)
    let Companion1 := arTRGirls[0]
  endif
 
  if (arCount >= 2)
    let Companion2 := arTRGirls[1]
  endif
 
  if (arCount >= 3)
    let Companion3 := arTRGirls[2]
  endif
 
  if (arCount >= 4)
    let Companion4 := arTRGirls[3]
  endif
 
  if (arCount >= 5)
    let Companion5 := arTRGirls[4]
  endif
 
  if (arCount >= 6)
    let Companion6 := arTRGirls[5]
  endif
 
  if (arCount >= 7)
    let Companion7 := arTRGirls[6]
  endif
 
End
Posted

Dear diary: Jackpot.

 

post-155688-0-70849100-1413600828_thumb.jpg

 

Really loving the fact that the array dump gives you the IDs for the girls, too.

Posted

Some minor quibbles:

 

  let arTRGirls := ar_Null
 
let arTRGirls := ar_construct array

 

You shouldn't have to ar_null that array if you're going to construct it anew right after. The link between the var and the previous array it referred to is severed, and that array should be automatically cleaned up. Spares you a line.

 

In order to minimize load during the loop you could divide the if-condition like this:

 

foreach entry <- arScanres
 let PotentialRef := *entry

 if PotentialRef.GetPlayerTeammate == 0

   continue

 elseif PotentialRef.GetIsSex Male

   continue

 elseif PotentialRef.GetIsCreature

   continue

 elseif PotentialRef.GetDead

   continue

 endif

 ar_append arTRGirls PotentialRef

loop

 

More lines, but slightly better handling because the engine doesn't have to process all four conditions quite as often. I shouldn't make much impact but you never know, some people try insane NumGridsToLoad settings, wander through an intensely populated area etc, etc. This way at least your conscience is clear about having done all you could.

Posted

Some minor quibbles:

 

  let arTRGirls := ar_Null

  let arTRGirls := ar_construct array

 

You shouldn't have to ar_null that array if you're going to construct it anew right after. The link between the var and the previous array it referred to is severed, and that array should be automatically cleaned up. Spares you a line.

I wasn't sure, and decided to err on the side of caution there. Had enough trouble with bloating due to not clearing them explicitly in some situations, so decided to "just do it."

 

In order to minimize load during the loop you could divide the if-condition like this:

 

foreach entry <- arScanres

 let PotentialRef := *entry

 if PotentialRef.GetPlayerTeammate == 0

   continue

 elseif PotentialRef.GetIsSex Male

   continue

 elseif PotentialRef.GetIsCreature

   continue

 elseif PotentialRef.GetDead

   continue

 endif

 ar_append arTRGirls PotentialRef

loop

 

More lines, but slightly better handling because the engine doesn't have to process all four conditions quite as often. I shouldn't make much impact but you never know, some people try insane NumGridsToLoad settings, wander through an intensely populated area etc, etc. This way at least your conscience is clear about having done all you could.

Yeah, I find that sort of thing "ugly" and I'm a stickler for not aggressively "pre-optimizing" code that you're not sure needs it to begin with. It certainly would work that way, and is easier to add more conditions later. I'd probably put the GetDead first since it will eliminate dead males and females rather than letting dead females fall all the way through the checks.

 

Which way would be faster is just going to depend on how many corpses are laying around the cell. ;)

Posted

So if the array is constantly rebuilding, won't that constantly change which girl is assigned to what ref variable?  If it does I need to rework how I remove and return items to girls in captivity.

You'll want to track them separately in their own array that isn't being constantly repopulated by the scanner. If you put arFembots[3] into captivity, add them to the captive array.

 

ar_append arCaptives arFembots[3]
Or something like that.

 

It's going to be some amount of refactoring as we call it, but it'll be worth it in the end.

 

EDIT: Some shower thoughts.  If the array is constantly repopulating, this clears up a lot of things I don't like about my old system.  It'll shuffle up the list occasionally, so Powder Gangers and Legion and whatnot don't always go for the same girl first.  Also, if a girl stops being your companion, the array resetting will simply rebuild it without her.

Right, I mentioned that latter one in one of the posts. You won't have "gaps" in the list any more that you have to keep checking for. The shuffle is something you could do right after the array is built, but there is no need. Just pick a character at random out of the array when you want one.

 

int sz
int rnd
ref rndRef

let sz := ar_size arFembots
let rnd := NX_GetRandom 1 sz
let rndRef := arFembots[rnd - 1]

; rndRef now has a random ref from the array.

As for things where I need to track the girls for things like returning their stuff, I can copy the array contents into something that isn't reset until I tell it to reset.  Also instead of having the random picker in Vault 19, I can just use a quest stage script to get a "snapshot" of the main array and set ref variables and then pass that information to the sex scenes.

Yep, that's all exactly right.

Posted

Oh, you will probably want to add an additional check to the scanner to make sure they're not in the captivity array you create, unless you WANT captives to be in that list. I don't know if you do or not.

Posted

I'm liking this more and more. Hopefully I can have a reworked Vault 19 out within a week. Thanks for the help guys!

Posted

I'm liking this more and more. Hopefully I can have a reworked Vault 19 out within a week. Thanks for the help guys!

Thank jaam. If it wasn't for him, we'd still be in the dark ages of NVSE scripting and none of this would be possible. :D

Posted

Yeah, I find that sort of thing "ugly" and I'm a stickler for not aggressively "pre-optimizing" code that you're not sure needs it to begin with. It certainly would work that way, and is easier to add more conditions later. I'd probably put the GetDead first since it will eliminate dead males and females rather than letting dead females fall all the way through the checks.

 

Which way would be faster is just going to depend on how many corpses are laying around the cell. ;)

Complex if-lines somewhat offend my aesthetic sensitivities ;)

Also, the pre-optimizing, or thinking about it, can also make you reconsider lines like:

 

if (IsReference rActor) && (rActor.GetDead)

and the like

 

Actually there may be something there with checking gender on what could be a creature - I remember Hal cautioning against that.

Posted

That's tickling my brain a bit as well. To be safe anyone should do checks only in the order required to ensure that the refs used in the comparison are valid.

 

GetDead could safely be first given the scan parameter, but if that changes, then you'd have to check that the ref is an actor/creature before anything else. So yeah:

 

check dead

check creature

check gender

 

seems like the 'right' order to go in for this.

 

I always forget that the engine has no short-circuit boolean eval. I wonder if it does if you use compiler override?

Posted

if (PotentialRef.GetPlayerTeammate Female == 0)

doesn't look right to me. ;)

 

In terms of ordering, I'd stick the playerteammate one up top myself, thinking it's the rarer of the must-have conditions so it's a better first filter. But the main thing is the creature check should happen before the gender one, the rest is just splitting hairs.

Posted

Fixed that femaleteammate thing, oops. As for the rest, yeah, it's really not too important. Given the environment Loogie intends it to run in, I think most nearby females probably will be teammates.. unless the quest is left running all the time out in the wasteland.

Posted

That's tickling my brain a bit as well. To be safe anyone should do checks only in the order required to ensure that the refs used in the comparison are valid.

 

GetDead could safely be first given the scan parameter, but if that changes, then you'd have to check that the ref is an actor/creature before anything else. So yeah:

 

check dead

check creature

check gender

 

seems like the 'right' order to go in for this.

 

I always forget that the engine has no short-circuit boolean eval. I wonder if it does if you use compiler override?

 

nope, still no shortcuts :)

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...