Jump to content

Grabbing refs randomly to assign to ref variables


Loogie

Recommended Posts

I don't even know if what I'm asking is possible.  Essentially what I would do is like to have a group of 8 people, and then randomly assign each of them to one of 8 quest ref variables with all of them being accounted for and nobody getting assigned a ref variable twice.

 

I already have half the work done - the 8 people are the player and up to 7 companions from the Tryout companion system.  In a dialog result script, I would like to assign each of them a quest ref variable, Girl1 through Girl8, randomly.  The only options I can come up involve a horribly bloated script and I can't help but think there must be a simpler way.

Link to comment

It's possible, there are a few ways to go about it, but what you want is a basic shuffle algorithm. It'll be much easier if you work on an NVSE array rather than 8 different ref vars. The basic premise is:

 

1. Pick an entry in the list at random (random 1..8 or 0..7)

2. Pick a second random entry.

3. Swap them.

4. Repeat 1-3 as many times as needed to shuffle the whole list.

 

An alternate approach is to pick a random number from 1..array_length, put that entry in refVar1, remove it from the array, and repeat the process until the array is empty.

Link to comment

Thanks Odessa.  That makes a lot of sense to me, but I'm horribly confused as to actually setup the array.

 

Here is the script I currently have that tracks the girls. I have it setup so the ref variables clear on game start and game reload, but the more I'm looking into arrays it looks like I can erase them in real time if they stop being a teammate.  Or maybe a combination of the current system so I can get to the refs more or less directly, and an array would be good.  I have two goals to accomplish with the array:

 

1) Make a dialog option along the lines of, "Which you like one of my companions?" if a male approaches the player for sex, which will then pop up a menu populated by the array.  This is similar to how Oblivion handles it for things like paying for inn stays with sex.

2) In my Vault 19 redo, I have a quest script where each sex position for a female is a ref variable.  I want to randomly populate these variables from the array, which the shuffle function will allow.  This will let me use one result script instead of 54.

 

 

scn TryoutGirlGetterQuestSCRIPT
 
Ref VarNPC
Ref Companion1
Ref Companion2
Ref Companion3
Ref Companion4
Ref Companion5
Ref Companion6
Ref Companion7
Ref PotentialRef
 
Short CompanionCount
Short TimerToggle
Short LoopCount
Short PotentialTotal
Short Loop1
 
Begin GameMode
 
;printtoconsole "Companion1: %n" Companion1
;printtoconsole "Companion2: %n" Companion2
;printtoconsole "Companion3: %n" Companion3
;printtoconsole "Companion4: %n" Companion4
;printtoconsole "Companion5: %n" Companion5
;printtoconsole "Companion6: %n" Companion6
;printtoconsole "Companion7: %n" Companion7
;printtoconsole "CompanionCount: %.0f" CompanionCount
 
if GetGameLoaded || GetGameRestarted && (SexoutSlaveryPlayerQ.SlaveryID == 0)
  set Companion1 to 0
  set Companion2 to 0
  set Companion3 to 0
  set Companion4 to 0
  set Companion5 to 0
  set Companion6 to 0
  set Companion7 to 0
  set CompanionCount to 0
endif
 
Set Loop1 to 0
  If GetPCIsSex Female
    Set LoopCount to 1
    Set PotentialTotal to GetNumRefs 42 0
    Set PotentialREF to GetFirstRef 42 0
    If PotentialTotal > 0
    Label Loop1
        If PotentialREF.GetPlayerTeammate == 1 && PotentialREF.GetIsSex Female && PotentialREF.GetIsCreature == 0 && PotentialREF.GetDead == 0
            Set VarNPC to PotentialRef
            If CompanionCount == 0 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female
                Set Companion1 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 1 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1
                Set Companion2 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 2 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2
                Set Companion3 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 3 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female&& VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3
                Set Companion4 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 4 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3 && VarNPC != Companion4
                Set Companion5 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 5 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3 && VarNPC != Companion4 && VarNPC != Companion5
                Set Companion6 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 6 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3 && VarNPC != Companion4 && VarNPC != Companion5 && VarNPC != Companion6
                Set Companion7 to VarNPC
                Set CompanionCount to CompanionCount + 1
            EndIf
        EndIf
        Set LoopCount to LoopCount + 1
        If LoopCount < PotentialTotal
            Set PotentialRef to GetNextRef
            GoTo Loop1
        EndIf
    EndIf
Endif
 
  if Companion1.GetPlayerTeammate == 0 && Companion1.IsFormValid
    set Companion1 to 0
    Set CompanionCount to CompanionCount -1
  endif
  if Companion2.GetPlayerTeammate == 0 && Companion2.IsFormValid
    set Companion2 to 0
    Set CompanionCount to CompanionCount -1
  endif
  if Companion3.GetPlayerTeammate == 0 && Companion3.IsFormValid
    set Companion3 to 0
    Set CompanionCount to CompanionCount -1
  endif
  if Companion4.GetPlayerTeammate == 0 && Companion4.IsFormValid
    set Companion4 to 0
    Set CompanionCount to CompanionCount -1
  endif
  if Companion5.GetPlayerTeammate == 0 && Companion5.IsFormValid
    set Companion5 to 0
    Set CompanionCount to CompanionCount -1
  endif
  if Companion6.GetPlayerTeammate == 0 && Companion6.IsFormValid
    set Companion6 to 0
    Set CompanionCount to CompanionCount -1
  endif
  if Companion7.GetPlayerTeammate == 0 && Companion7.IsFormValid
    set Companion7 to 0
    Set CompanionCount to CompanionCount -1
  endif
End
Link to comment

Loogie, I'd advise get rid of label/goto loops as much as possible, and replace them with while loops:

   ; Set LoopCount to 1 ; can be scrapped
    Set PotentialTotal to GetNumRefs 42 0
    Set PotentialREF to GetFirstRef 42 0
  ;  If PotentialTotal > 0  ; scrap
      while (LoopCount += 1) < PotentialTotal
  ; Label Loop1 ; scrap
        If PotentialREF.GetPlayerTeammate == 1 && PotentialREF.GetIsSex Female && PotentialREF.GetIsCreature == 0 && PotentialREF.GetDead == 0
            Set VarNPC to PotentialRef
            If CompanionCount == 0 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female
                Set Companion1 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 1 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1
                Set Companion2 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 2 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2
                Set Companion3 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 3 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female&& VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3
                Set Companion4 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 4 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3 && VarNPC != Companion4
                Set Companion5 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 5 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3 && VarNPC != Companion4 && VarNPC != Companion5
                Set Companion6 to VarNPC
                Set CompanionCount to CompanionCount + 1
            ElseIf CompanionCount == 6 && VarNPC.GetPlayerTeammate == 1 && VarNPC.GetIsSex Female && VarNPC != Companion1 && VarNPC != Companion2 && VarNPC != Companion3 && VarNPC != Companion4 && VarNPC != Companion5 && VarNPC != Companion6
                Set Companion7 to VarNPC
                Set CompanionCount to CompanionCount + 1
            EndIf
        EndIf
;        Set LoopCount to LoopCount + 1
 ;       If LoopCount < PotentialTotal
            Set PotentialRef to GetNextRef
  ;          GoTo Loop1
   ;     EndIf
     loop
 ;   EndIf
Link to comment

That script was in SexAssault once upon a time. I swapped it to:

array_var aCompanions
ref VarNPC

    let aCompanions := Ar_Construct "array"
    let VarNPC := GetFirstRef 42
    while VarNPC != 0
        if eval VarNPC.GetPlayerTeammate && VarNPC.GetIsSex "Female" && !(VarNPC.GetIsCreature) && !(VarNPC.GetDead)
            Ar_Append aCompanions, VarNPC
        endif
        let VarNPC := GetNextRef
    loop

One thing I notice, are you sure these brackets are right?

if GetGameLoaded || GetGameRestarted && (SexoutSlaveryPlayerQ.SlaveryID == 0)

 

This is true whenever a game is loaded. It is also true when restarted but only if slaveryID is 0.

Link to comment

If the player is enslaved by the Legion, NCRCF, or enslaved in Vault 19, they have a slavery ID.  If someone saves their game while enslaved I want to preserve the companion list as it is.  I'm guessing || and && can't be mixed on the same line?

Link to comment

That script was in SexAssault once upon a time. I swapped it to:

array_var aCompanions
ref VarNPC

    let aCompanions := Ar_Construct "array"
    let VarNPC := GetFirstRef 42
    while VarNPC != 0
        if eval VarNPC.GetPlayerTeammate && VarNPC.GetIsSex "Female" && !(VarNPC.GetIsCreature) && !(VarNPC.GetDead)
            Ar_Append aCompanions, VarNPC
        endif
        let VarNPC := GetNextRef
    loop

One thing I notice, are you sure these brackets are right?

if GetGameLoaded || GetGameRestarted && (SexoutSlaveryPlayerQ.SlaveryID == 0)

 

This is true whenever a game is loaded. It is also true when restarted but only if slaveryID is 0.

 

You replaced the entire script with just those few lines?

Link to comment

If the player is enslaved by the Legion, NCRCF, or enslaved in Vault 19, they have a slavery ID.  If someone saves their game while enslaved I want to preserve the companion list as it is.  I'm guessing || and && can't be mixed on the same line?

 

The problem is that this in your script:

GetGameLoaded || GetGameRestarted && (SexoutSlaveryPlayerQ.SlaveryID == 0)
Means proceed if:

1. A savegame is loaded

2. OR the game is started AND the slaveryId is 0.

 

in other words, it won't proceed on a new game (GetGameRestarted) if the slavery ID is *not* zero. I think what you really want is this?

 

(GetGameLoaded || GetGameRestarted) && (SexoutSlaveryPlayerQ.SlaveryID == 0)
This will proceed only if slaveryID is 0, no matter if it's a new game or a loaded save.
Link to comment

If the player is enslaved by the Legion, NCRCF, or enslaved in Vault 19, they have a slavery ID.  If someone saves their game while enslaved I want to preserve the companion list as it is.  I'm guessing || and && can't be mixed on the same line?

 

Yes you can. the question being how is the engine interpreting the condition, but considering || has priority over && this should work as YOU expected.

I would have use explicit parenthesis though, technically useless here, but so useful for anyone reading it month later :)

Link to comment

 

You replaced the entire script with just those few lines?

 

 

Pretty much, that sets aCompanions to an empty array, then fills it with all the valid companions. It supports any number, and you don't need ref variables, you would do aCompanions[X] (starting at 0) to get each one, or use a foreach loop.

 

However, it doesn't check if a companion is already in the array, or if existing contents are still valid like your code- you don't actually need to bother doing this if you empty and rebuild the array each time, but you can use Ar_Find, and a loop check for these if you wanted

Link to comment

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use