Loogie Posted July 21, 2014 Posted July 21, 2014 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.
prideslayer Posted July 21, 2014 Posted July 21, 2014 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.
Loogie Posted July 21, 2014 Author Posted July 21, 2014 Okay. Looks like my homework is to research arrays, make a mess of things, then seek further advice.
prideslayer Posted July 21, 2014 Posted July 21, 2014 You can do it with the ref vars but it'll be a gigantic if/elseif/elseif/... statement that will only grow and get out of hand. Arrays are your friend!
Loogie Posted July 21, 2014 Author Posted July 21, 2014 I knew that was somewhere around here. Thanks Ny!
Odessa Posted July 21, 2014 Posted July 21, 2014 I wrote a Shuffle-Array UDF for soliciting, which is this example on the GECK wiki
prideslayer Posted July 21, 2014 Posted July 21, 2014 I wrote a Shuffle-Array UDF for soliciting, which is this example on the GECK wiki Looks great! Loogie you should be able to adapt that without many problems. You could even make it operate on an internal array instead of taking a param, and have it get the values from the quest vars at the start and re-set them to their new values at the end.
Loogie Posted July 21, 2014 Author Posted July 21, 2014 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
DoctaSax Posted July 21, 2014 Posted July 21, 2014 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
Loogie Posted July 21, 2014 Author Posted July 21, 2014 I'll play around with it. This script was written in the dark ages of summer 2013.
jaam Posted July 21, 2014 Posted July 21, 2014 Don't worry , its just that programmers have fiercely hunted down any usage of goto/label in code since the much darker ages of BASIC. For a scripter though, its natural , and it usually works.
prideslayer Posted July 21, 2014 Posted July 21, 2014 Yeah. We use exceptions now. Sounds more professional!
Odessa Posted July 21, 2014 Posted July 21, 2014 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.
prideslayer Posted July 21, 2014 Posted July 21, 2014 Looks wrong from here. Where is the getgameloaded? It's not in your quote, it's in sexoutslavery or something? Edit: Doh, loogies. Yes looks incorrect.
Loogie Posted July 21, 2014 Author Posted July 21, 2014 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?
Loogie Posted July 21, 2014 Author Posted July 21, 2014 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?
prideslayer Posted July 21, 2014 Posted July 21, 2014 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.
jaam Posted July 21, 2014 Posted July 21, 2014 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
Odessa Posted July 21, 2014 Posted July 21, 2014 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
Recommended Posts
Archived
This topic is now archived and is closed to further replies.