Loogie Posted October 17, 2014 Posted October 17, 2014 So, I brought up this topic a long, long time ago at the beginning of the summer, then promptly forgot all the help anyone gave me. I have a script in Tryouts I'm attaching in a code block. This script is what tracks your female companions. I am a terrible scripter and what is here is the result of help from Prideslayer, User29, Ichabod, prayer and duct tape. What I need to figure out is 3 things: 1) Take the seven companions this scans for and put them in array for certain uses. 2) Put the seven companions in an array alongside the player for other uses. 3) When a girl is no longer a teammate, remove her from the array and her ref variable, and then reduce the CompanionCount variable by 1. Anybody higher in the list then moves down. For example, if I have a 7 female companions and the one Companion4 is dismissed, then I want 5 through 7 to each move down a slot and for the 7th companion slot to be open again with a count of 6 companions so the game will then once more scan for a seventh. Currently I just have this clearing on game load/restart so it doesn't break things permanently if a companion gets dismissed. 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 && (SexoutSlaveryPlayerQ.SlaveryID == 0) || 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
prideslayer Posted October 17, 2014 Posted October 17, 2014 This should be a workable starting point scn TryoutGirlGetterQuestSCRIPT Ref PotentialRef array_var arScanres array_var arFembots array_var entry Begin GameMode let arFembots := ar_Null let arFembots := ar_construct array if GetPCIsSex Female let arScanres := GetRefs 42, 0 foreach entry <- arScanres let PotentialRef := *entry if (PotentialRef.GetDead == 1) continue endif if (PotentialRef.GetIsCreature == 1) continue endif if (PotentialRef.GetIsSex Female == 0) continue endif if (PotentialRef.GetPlayerTeammate == 0) continue endif ar_append arFembots PotentialRef 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 arFembots End Thanks to Odessa for the for loop trick posted in sewerslave earlier.Thanks to DoctaSax further on in this thread. When this script is done, arFembots will hold all the matching actors. I'm not sure what the bottom half of the script is doing.. removing them if they've somehow become invalid? But they are never readded again? You'll probably want to rethink that overall somewhat anyway. ar_size arFembots Will tell you how many you have. Not limited to 9 any more. Edit: Copied "my" latest version here for the lazy thread readers.
prideslayer Posted October 17, 2014 Posted October 17, 2014 actually need to fix that idx a bit, one min. ok, should be fixed now. Obviously I haven't tested this, or even tried pasting it into the geck. It's simple enough that any problems should be easy to solve though.
Loogie Posted October 17, 2014 Author Posted October 17, 2014 Okay, so between this and the PMs, I think I get what you're putting down. With what you wrote, the array is cleared every five seconds, which means I don't need any fancy checks for valid actors and whatnot if I'm following correctly. I do still need the ref variables for other things that are already using them, plus it makes stripping and other things easier. So, does this look right to you? Also, in Vault 19 I want the scene to pick random girls out of the array. Am I better off writing some kind of random picker, or am I better off writing the scenes with static numbers and just shuffling the array? And how do I go ahead with the best option? scn TryoutGirlGetterQuestSCRIPT Ref PotentialRef Ref Companion1 Ref Companion2 Ref Companion3 Ref Companion4 Ref Companion5 Ref Companion6 Ref Companion7 array_var arFembots array_var i Begin GameMode if (GetGameLoaded || GetGameRestarted) let arFembots := ar_Null let arFembots := ar_construct array endif if GetPCIsSex Female Set PotentialTotal to GetNumRefs 42 0 Set PotentialREF to GetFirstRef 42 0 if PotentialTotal > 0 foreach i <- (ar_range 1, PotentialTotal) if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0) let arFembots[*i] := PotentialRef endif Set PotentialRef to GetNextRef loop endif endif let Companion1 := arFembots[0] let Companion2 := arFembots[1] let Companion3 := arFembots[2] let Companion4 := arFembots[3] let Companion5 := arFembots[4] let Companion6 := arFembots[5] let Companion7 := arFembots[6] End
prideslayer Posted October 17, 2014 Posted October 17, 2014 Nevermind, should have read the script first. Looks ok at a glance, why is it doublespaced now? heh.
Loogie Posted October 17, 2014 Author Posted October 17, 2014 I think it got flubby when I previewed it. Can I call "arFembots[0]" and so on directly in Sexout calls, or do I need to pass them to ref variables first?
prideslayer Posted October 17, 2014 Posted October 17, 2014 For the random choice, I would just pick a random number from 1 to array_size. int arLen int rndpick ref rndBot let arlen := ar_size arFembots let rndpick := Rand(0, arLen) let rndBot := arFembots[rndpick] ; do what you need to with rndbot Some of this you can probably condense down, but for readabilities sake, single lines in the example here. Edit: Should be ar_size not array_size, oops.
prideslayer Posted October 17, 2014 Posted October 17, 2014 I think in most cases you can use arFembots[#] directly, but in some cases, it may not work. I think it depends on what you try to do with it. If it saves OK in the geck, it's probably ok I'd think.
prideslayer Posted October 17, 2014 Posted October 17, 2014 Argh spamming up the thread because I can't read, but want you to get notified. To have the array totally rebuilt every time it runs, get rid of those GetGameLoaded checks around the ar_null/ar_construct.
DoctaSax Posted October 17, 2014 Posted October 17, 2014 Sticking scanned actors in an array doesn't really need a GetNextRef loop anymore: GetRefs. You should be able to pass an entry to a sexout udf as a parameter: call fnSexoutActSetRef "ActorA" somearrayvar[0] but can't call (reference) functions on them: somearrayvar[0].call someudf
Loogie Posted October 17, 2014 Author Posted October 17, 2014 Gotcha! Thanks for the help! Script compiles fine, except you didn't declar PotentialTotal, which I'm assuming is an int. So this is what I have in GECK. Put the debug lines back in so I can make sure the array is built and passing along info to the declared variables. Going to fire it up and report back. scn TryoutGirlGetterQuestSCRIPT Ref PotentialRef Ref Companion1 Ref Companion2 Ref Companion3 Ref Companion4 Ref Companion5 Ref Companion6 Ref Companion7 int PotentialTotal array_var arFembots array_var i 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 let arFembots := ar_Null let arFembots := ar_construct array if GetPCIsSex Female Set PotentialTotal to GetNumRefs 42 0 Set PotentialREF to GetFirstRef 42 0 if PotentialTotal > 0 foreach i <- (ar_range 1, PotentialTotal) if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0) let arFembots[*i] := PotentialRef endif Set PotentialRef to GetNextRef loop endif endif let Companion1 := arFembots[0] let Companion2 := arFembots[1] let Companion3 := arFembots[2] let Companion4 := arFembots[3] let Companion5 := arFembots[4] let Companion6 := arFembots[5] let Companion7 := arFembots[6] End
DoctaSax Posted October 17, 2014 Posted October 17, 2014 For the random choice, I would just pick a random number from 1 to array_size. int arLen int rndpick ref rndBot let arlen := ar_size arFembots let rndpick := Rand(0, arLen) let rndBot := arFembots[rndpick] ; do what you need to with rndbot Some of this you can probably condense down, but for readabilities sake, single lines in the example here. Edit: Should be ar_size not array_size, oops. if rndpick lands on the number equalling the array size, you'll get an invalid key, because a regular array's highest key is (array size - 1) For these random picks, I usually stick with NX_GetRandom 0 (size - 1)
Loogie Posted October 17, 2014 Author Posted October 17, 2014 Okay. Console spam I wanted it to do reported back with "NoName" for all 7 slots. Attached is the console spam I'm assuming NVSE provided. Script 2204cefc is, of course, the script we're talking about.
DoctaSax Posted October 17, 2014 Posted October 17, 2014 Probably because of this: foreach i <- (ar_range 1, PotentialTotal) if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0) let arFembots[*i] := PotentialRefA regular array starts at key zero but the fake for loop starts at 1. There can't be anything under 1 if there is nothing under zero.I'd go with something like: array_var ar_scanned array_var ar_filtered array_var entry ref PotentialRef let ar_scanned := GetRefs 200 let ar_filtered := ar_construct array foreach entry <- ar_scanned let PotentialRef := entry["value"] if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0) ar_append ar_filtered PotentialRef endif loop then pick one with something like int iMax int iKey let iMax := ar_size ar_filtered let iKey := NX_GetRandom 0 iMax let someref := ar_filtered[iKey]
prideslayer Posted October 17, 2014 Posted October 17, 2014 Thanks Doc, I figured you'd be along to set me right. Updated and modified a bit. I was in the middle of cooking dinner when I wrote that, had to keep heading back to the stove, no chance to sit and think. scn TryoutGirlGetterQuestSCRIPT Ref PotentialRef array_var arScanres array_var arFembots array_var entry Begin GameMode let arFembots := ar_Null let arFembots := ar_construct array if GetPCIsSex Female let arScanres := GetRefs 42, 0 foreach entry <- ar_Scanres let PotentialRef := *entry if (PotentialRef.GetPlayerTeammate == 1) && (PotentialRef.GetIsSex Female) && (PotentialREF.GetIsCreature == 0) && (PotentialREF.GetDead == 0) ar_append arFembots 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 arFembots End Docs is probably fine too, just a different scan target (NPC vs Actor) His should work fine for picking, but you do want to reduce iKey by one. NX_GetRandom is range inclusive. ref someRef let iMax := ar_size arScanres let iKey := NX_GetRandom 1 iMax let someref := arFembots[iKey - 1] I thought the NVSE Rand() wasn't inclusive on the upper limit, that's what the example on the wiki indicates. Rand(0, 100) should give you a value in [0..99]. Nx_GetRandom(0, 100) will give you a value in [0..100].
Loogie Posted October 17, 2014 Author Posted October 17, 2014 When I try to compile, it tells me that in "let arScanres := GetRefs 42, 0", that "Invalid operands for operator :="
prideslayer Posted October 17, 2014 Posted October 17, 2014 Weird, that should work. Maybe it doesn't like the ,0, or wants parens, or.. who knows. Try one/all of these ; try with parens let arScanres := GetRefs(42, 0) ; maybe it doesn't like the depth param?? let arScanres := GetRefs 42
Loogie Posted October 17, 2014 Author Posted October 17, 2014 Will do. Right now I need to hit the sack, I'll report back tomorrow evening.
Loogie Posted October 17, 2014 Author Posted October 17, 2014 Even with both of those ways you suggested, it still gives me the same error. EDIT: Changed arFembots to arTRGirls, found out it would also spit out this error on the couple of references to arFembots I didn't catch. Checked arScanres, it is spelled correctly.
prideslayer Posted October 17, 2014 Posted October 17, 2014 ahh, so all ok now, just mismatched names?
prideslayer Posted October 17, 2014 Posted October 17, 2014 If you do want to go filling in all those other static vars, Doc touched on something that might not have sunk in. Say there are only 3 people in the array (0, 1, 2). If you try doing "let Companion4 := arFembots[3]" you're going to get an error as well. You'll need to either set them all to 0 first so there's something there, or create a somewhat ugly if statement. This is where a switch statement from NVSE would really come in handy, to basically make a pretty version of this: int arCount let Companion1 := 0 let Companion2 := 0 let Companion3 := 0 let Companion4 := 0 let Companion5 := 0 let Companion6 := 0 let Companion7 := 0 let Companion8 := 0 let Companion9 := 0 let arCount := ar_size arFembots if (arCount >= 1) let Companion1 := arFembots[0] endif if (arCount >= 2) let Companion2 := arFembots[1] endif if (arCount >= 3) let Companion3 := arFembots[2] endif ; keep going up to 9. A switch statement (if we had one): switch (ar_size arFembots) { default: let Companion9 := arFembots[8] case 8: let Companion8 := arFembots[7] case 7: let Companion7 := arFembots[6] case 6: let Companion7 := arFembots[5] ; ... case 0: break; } This is really just another reason to ditch those vars. If you're intent on using them, I'd make a udf something like this: scn getFemCompanion int index ref retVal Begin Function{index} set retVal to 0 if eval((ar_size myquest.arFembots) >= index) let retVal := myquest.arFembots[index - 1] endif SetFunctionValue retVal End Then you can just do let Companion1 := call getFemCompanion(1) let Companion2 := call getFemCompanion(2) let Companion3 := call getFemCompanion(3)
Loogie Posted October 17, 2014 Author Posted October 17, 2014 No, it's spelled correctly. So it's not a mismatched name issue. As for the UDFs, that's a route I have considered. I'll play around with it. I need those vars so I can control those characters directly when it's needed.
prideslayer Posted October 17, 2014 Posted October 17, 2014 Ok, give me jsut a sec, I can try to see what's going on by actually opening the geck..
prideslayer Posted October 17, 2014 Posted October 17, 2014 As for the UDFs, that's a route I have considered. I'll play around with it. I need those vars so I can control those characters directly when it's needed. You still can, or you can just use the UDF to get one. I'm trying to get away from the idea that there are always just 9 of them.. some of which may be invalid at any point. It was a problem I saw with your existing/original one where maybe (after the cleanup stuff) companion1 was valid, but 2 and 3 werent, but 4 was.. etc.
prideslayer Posted October 17, 2014 Posted October 17, 2014 Ah there is still one typo in the one I provided on the first page (updated my first post). an ar_Scanres that should be arScanres (no underscore). Script saves fine for me after that change. Haven't tried running it. Tested fully, it's working fine and as intended, direct copy/paste of the one in my first post in the thread (updated the post to fix the typo).
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now