Odessa Posted December 16, 2014 Posted December 16, 2014 I'm in favor of a stringmap call convention (I already use one of my own). Since dialog scripts return 0 for GetCallingScript, you could workaround the issue with:  if eval 0 == args["ActorX"] && 0 == GetCallingScript    let ActorX := GetSelf endif  Or, perhaps use: 1009 == MenuMode
prideslayer Posted December 16, 2014 Posted December 16, 2014 I'm in favor of a stringmap call convention (I already use one of my own). I do this quite often at my dayjob. It's easier to extend interfaces that way than to run around changing the params and updating all the calling code. That said, do you know if it would work as I outlined above? Can I use that sort of evaluation (ar_map + getself) in the call to the UDF?  Since dialog scripts return 0 for GetCallingScript, you could workaround the issue with:  if eval 0 == args["ActorX"] && 0 == GetCallingScript    let ActorX := GetSelf endif  Or, perhaps use: 1009 == MenuMode I'm not sure what you're getting at here. What's actorX have to do with this?  To be honest the GetCallingScript thing is a minor annoyance, not a real problem. It would only become a real problem if somebody split their fnSexoutActPrep/Set/Run calls across different script fragments. This would then potentially conflict with another mod (or even the same mod) doing the same thing, with a different logical act.  The purpose of the GetCallingScript is so that scriptA can call fnSexoutActPrep in one frame.. maybe call the Set's a few frames later.. and call Run even a few acts after that, and scriptB can do the same thing, simultaneously. The GetCallingScript is used as a key into an array to facilitate that, so multiple mods can do this without overwriting eachothers vars.  The "real" solution was for fnSexoutActPrep to return a key value that's passed in all subsequent Prep/Run calls, but at the time I thought that would be "too much work" to save/use for modders. In light of this discussion, it would also make the UDF method unusable in script fragments because there's no local var available to hold the result of Prep.
Guest Posted December 16, 2014 Posted December 16, 2014  That should not be a permanent condition. I would say it happens once in every 20 or so GECK scripting session. It might also come from a specific error, but I don't have enough statistics to form an hypothesis.  Can't say 1 every 20, but I can tell you one of my common mistakes, which just CTDed when I wrote my previous post: If MyVar := something I use := on If as for Let   Jaam not sure if this helps you, but I'm noticing how it likes CTD when I make something wrong in the IFs, it could be that := but also checking a variable not declared. Of course it could simply be because it's the kinds of mistakes I do often Â
prideslayer Posted December 16, 2014 Posted December 16, 2014 powerup should be detecting those for you and not letting you save... so.. why aren't you using powerup?
jaam Posted December 16, 2014 Posted December 16, 2014 It might be related to if. Some error display already had to be deactivated because they used too many parameters, maybe if too. Â
prideslayer Posted December 16, 2014 Posted December 16, 2014 CTDs from powerup? I thought I was the one writing crazy code around here.. but I haven't managed to crash the GECK in a long time. Not since I had that fucko error in the sexout esm that crashed it every time you tried to quit.
Guest Posted December 17, 2014 Posted December 17, 2014 well pride it didn't start a long time ago. I would say a month maybe two. At start I thought it was because of some ESP, but then I noticed it was even on new ESPs. I did installed new dlls under NVSE, maybe this makes the difference. But also I do make a lot of mistakes when I write code, maybe I just make too many
prideslayer Posted December 17, 2014 Posted December 17, 2014 None of your mistakes should crash the geck. It's like errors in c++ code crashing the compiler, just should not be possible. Â OTOH this is the GECK we're talking about, it makes the impossible possible, right?
jaam Posted December 17, 2014 Posted December 17, 2014 Error reporting is a program. And any program can crash. And yes you could crash a compiler with bad syntax. I would be extremely surprised if it has never happened already. Â
jaam Posted December 17, 2014 Posted December 17, 2014 jaam, The only thing I know of that even comes close is the array iteration operator, but it's probably not something NX can do.  AJ, In cases like that, you're better served by just making the UDF take an array (stringmap) as an argument. Then you can do something like this: call mySexoutUDF ar_Map("actorA"::getself, "actorB"::playerRef, ...) Which MIGHT work, depending on how the UDF call likes (or doesn't) the ar_map evaluation rather than a straight var in that context. If it works, it's "hooray", and I'll put such a 'helper' UDF in sexout itself fairly soon. The UDF itself would just take the one stringmap parameter and then iterate through it making the sexout calls scn mySexoutUDF array_var arParams array_var arItem string_var sType Begin Function{arParams} call fnSexoutActPrep foreach item <- arParams let sType := TypeOf item["value"] if eval "Form" == sType call fnSexoutActSetRef item["key"] item["value"] elseif eval "Number" == sType call fnSexoutActSetFloat item["key"] item["value"] endif loop call fnSexoutActRun End This function is basically what fnSexoutActRun itself does. All the fnSexoutActSet* functions just store things in a stringmap like this, then ActRun goes through it in exactly the same way, setting the NX vars and then doing the CIOS.  Closest I can get is this: call npTestScriptFunc2Script ar_Map("actorA"::0, "actorB"::playerRef) but you should be able to decode 0 as getSelf in the called UDF: scn npTestScriptFunc2Script array_var aTiti ref self begin Function { aTiti } set self to GetSelf PrintC "Hello %n [%i]" self self end
prideslayer Posted December 17, 2014 Posted December 17, 2014 I "can't do that" since we have no distinction between null and 0. Â There are animations where actorA being null and B being set is 'normal'. Or A & C without B, or B&C without A, ad nauseum. Â I'll have to use a MAX_INT value instead. I'll define one as a global in sexout (0xffffffff) if there isn't one that's easy to use already. Â -------- Â I've *never* crashed a "white box" compiler (e.g. a MS, Borland, etc. product) with bad syntax, and I've been coding since.. hell turbo pascal 5.5 whenever that was. Just saying. Freeware compilers are another matter.
jaam Posted December 17, 2014 Posted December 17, 2014 A bad if was not enough anyway , The trick is what you pass needs to be a valid ref, or you need a placeHolder key name for "Use GetSelf as ActorA"
prideslayer Posted December 17, 2014 Posted December 17, 2014 It can be any ref type right? like.. a quest? Does it actually have to be a ref, or will a baseform work? Â This will work fine, just investigating my options.
prideslayer Posted December 18, 2014 Posted December 18, 2014 Ok cool, I'll experiment with that and see what the options are. Once I find one that works reliably I'll add one to sexout called soGetSelf and people can just pass that in.
ArgusSCCT Posted December 20, 2014 Posted December 20, 2014 Well I made that damnable menu, and surprisingly it works for the most part. The issue I've got with it right now, is that it doesn't show the messages as fast as I would like, for starters bringing up the main message takes a while, I have to hold down the key for a while, I don't know if that's how IsKeyPressed is supposed to work, I thought it was just pressing the key and that'd be it.  In any case, this is what I came up with:    scn 0AR15ModKitScript int iButtonA int iButtonB int iButtonC int iButtonD int iSetHotKey int iMenuHotKey int iContainsModKit int iMenuMessage int iIndex int iTenWeapons int iFifteenWeapons int iTwentyWeapons Begin GameMode Let iContainsModKit := playerREF.GetItemCount 0AR15ModKit Let iTenWeapons := playerREF.GetItemCount 0WeapAR1510in Let iFifteenWeapons := playerREF.GetItemCount 0WeapAR1515in Let iTwentyWeapons := playerREF.GetItemCount 0WeapAR1520in If(iTenWeapons >= 1) Let iIndex := 0 ElseIf (iFifteenWeapons >= 1) Let iIndex := 1 ElseIf (iTwentyWeapons >= 1) Let iIndex := 2 EndIf If (iSetHotKey == 0) Let iMenuHotKey := 37 Let iSetHotKey := 1 EndIf If (iContainsModKit > 0 && IsKeyPressed iMenuHotKey) ShowMessage 0AR15ModKitMenu EndIf ;------------------------------------------------------------------- ;Main menu, options include hot key configuration and weapon selection(10 in, 15 in and 20 in barrels) If (iMenuMessage == 0) Let iButtonA := GetButtonPressed If (iButtonA == -1) Return ElseIf (iButtonA == 0) Return ElseIf (iButtonA == 1) ShowMessage 0AR1510inModSelection Let iMenuMessage := 1 ElseIf (iButtonA == 2) ShowMessage 0AR1515inModSelection Let iMenuMessage := 2 ElseIf (iButtonA == 3) ShowMessage 0AR1520inModSelection Let iMenuMessage := 3 ElseIf (iButtonA == 4) Return EndIf EndIf ;-------------------------------------------------------------------- ;10in barrel menu, includes several mods for the 10in barrel version If (iMenuMessage == 1) Let iButtonB := GetButtonPressed If (iButtonA == -1) return ElseIf (iButtonB == 0) Let iIndex := 1 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 1) Let iIndex := 2 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 2) Let iIndex += 10 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 3) Let iIndex += 1000 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 4) Let iIndex += 100 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 5) Let iIndex -= 10 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 6) Let iIndex -= 1000 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 7) Let iIndex -= 100 Call 0AR15ModSelectionFunction 1, iIndex Return ElseIf (iButtonB == 8) ShowMessage 0AR15ModKitMenu Let iMenuMessage := 0 ElseIf (iButtonB == 9) Return EndIf EndIf ;------------------------------------------------------------------------------- ;15in barrel variant menu, mods for 15in version If (iMenuMessage == 2) Let iButtonC := GetButtonPressed If (iButtonA == -1) return ElseIf (iButtonC == 0) Let iIndex := 0 Call 0AR15ModSelectionFunction 2, iIndex Return ElseIf (iButtonC == 1) Let iIndex := 2 Call 0AR15ModSelectionFunction 2, iIndex Return ElseIf (iButtonC == 2) Let iIndex += 100 Call 0AR15ModSelectionFunction 2, iIndex Return ElseIf (iButtonC == 3) Let iIndex -= 100 Call 0AR15ModSelectionFunction 2, iIndex Return ElseIf (iButtonC == 4) ShowMessage 0AR15ModKitMenu Let iMenuMessage := 0 Return ElseIf (iButtonC == 5) Return EndIf EndIf ;------------------------------------------------------------------------------- If (iMenuMessage == 3) Let iButtonD := GetButtonPressed ElseIf (iButtonA == -1) return If (iButtonD == 0) Let iIndex := 0 Call 0AR15ModSelectionFunction 3, iIndex Return ElseIf (iButtonD == 1) Let iIndex := 1 Call 0AR15ModSelectionFunction 3, iIndex Return ElseIf (iButtonD == 2) Let iIndex += 10 Call 0AR15ModSelectionFunction 3, iIndex Return ElseIf (iButtonD == 2) Let iIndex += 100 Call 0AR15ModSelectionFunction 3, iIndex Return ElseIf (iButtonD == 3) Let iIndex -= 10 Call 0AR15ModSelectionFunction 3, iIndex Return ElseIf (iButtonD == 4) Let iIndex -= 100 Call 0AR15ModSelectionFunction 3, iIndex Return ElseIf (iButtonD == 5) ShowMessage 0AR15ModKitMenu Let iMenuMessage := 0 Return ElseIf (iButtonD == 6) Return EndIf EndIf End    Also wondering if I should just put the function call at the end of every menu, as in right before the EndIf of each If (iMenuMessage == x), instead of placing it in every block.Â
DoctaSax Posted December 20, 2014 Posted December 20, 2014 Well I made that damnable menu, and surprisingly it works for the most part. The issue I've got with it right now, is that it doesn't show the messages as fast as I would like, for starters bringing up the main message takes a while, I have to hold down the key for a while, I don't know if that's how IsKeyPressed is supposed to work, I thought it was just pressing the key and that'd be it. Â Â Depends on the script frequency, I guess. Â Also wondering if I should just put the function call at the end of every menu, as in right before the EndIf of each If (iMenuMessage == x), instead of placing it in every block. Doesn't hurt, especially because the parameter to the call is the same as iMenuMessage. You can probably also just put one GetButtonPressed & "return if < 0" up top.
DoctaSax Posted December 20, 2014 Posted December 20, 2014 So... does anyone know what causes topics to magically disappear from a quest's topics tab? They're all still there if I check the dialog tree, just not in the topics tab's left column where I actually need to see and select them. Tried with and without NVSE and PU. Redownloaded the geck. No difference. Â Â Â
Guest Posted December 20, 2014 Posted December 20, 2014 something like the issue Halstrom had with Windows 8? wrong window placement or something like this?just to be make an attempt, I would rename / move the GECK ini inside documents, so that it will re-create it. Of course I don't know about dialogues, but I do know it contains some infos about some windows and their placement
DoctaSax Posted December 20, 2014 Posted December 20, 2014 Oh, FFS, I'm such a doofus. The columns weren't aligned properly, all I needed to do was drag them right again. That's 3 hours of searching forums, switching out NVSE/PU/MO, investigating my geck inis and what not! Genius at work here!
ArgusSCCT Posted December 21, 2014 Posted December 21, 2014 Â Depends on the script frequency, I guess. Â Â Not sure I like that, the script is always running, I thought about that, and it might not be such a good idea. I guess if there's no other way I'd keep it like this, but I don't like its response time, it is simply too slow, especially when compared to menus from other mods. That said, I don't know if the amount of options and they size of the menu matters. I would guess it does, especially with the if statements.Â
asdf0 Posted December 23, 2014 Posted December 23, 2014 Question: I have a mod with some scripts (let's call it "Blah") and some reference ID variables, e.g. one called "ref" which I can access with Blah.ref (obviously). Now I thought I could check whether this reference is invalid (normally it should point to an actor) with something like if(Blah.ref == 0)which has worked fine so far, but after playing for several hours I have now a situation where this line returns FALSE, i.e. Blah.ref is NOT zero, but the script silently crashes anyway when I try to do anything with Blah.ref (e.g. set newRef to Blah.ref). So this reference seems invalid in some way. However, this linePrintC "%n - %i" Blah.ref Blah.refprints "<no name> - 00000000" which I thought means that no reference is stored in this variable, and so when evaluating the variable against 0 it should return TRUE, but apparently that isn't the case. So what's going on here? Is this a variable that points to an object that isn't loaded in memory because it exists in a faraway cell and isn't persistent? If so, how can I check whether doing anything with the reference will crash my script? I found the IsReference function, but I can't use it with the Blah.ref syntax since it needs an "explicit reference" (which I presume means a static reference). I have no idea how to proceed from here, please help...
prideslayer Posted December 23, 2014 Posted December 23, 2014 Use IsReference and/or IsFormValid instead..?
asdf0 Posted December 23, 2014 Posted December 23, 2014 What is the correct syntax for this? I tried if(IsReference Blah.ref == 0)and at that line when compiling I get the message "Syntax Error. Reference not allowed in this context." and "Missing parameter reference. Compiled Script not saved!"
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