csbx Posted June 17 Share Posted June 17 'Headhunter: bounties redone' conflicts with my soon to be released mod and I was hoping for help creating a patch for it. My mod adds a function to the stage 10 fragment of BQ01-BQ04. The function calls with a parameter that reports to my function script which quest it is called from. ie. I call F(0) from BQ01, I call F(1) from BQ02. In vanilla, BQ01-BQ04 each have distinct scripts, so this is easy to do. But god emperor JaySerpa, from what I can see, invokes the same script for BQ01-BQ04. So I can't exactly just drop in my F(x). This s#*! is way above my pay grade, even if basic for many of those on this board. But my sense is that I don't want to dup his script into 4 unique ones--though that would work--but rather should make his single script work with some kind of conditional in there. What I think I want to do is something like: If [get this quest's name or id] = BQ01 runmyfunction(0) elseif [get this quest's name / id] = BQ02 runmy function(1) etc. Endif Does that seem reasonable ? and how do I run that conditional ? Getowningquest().getname() ? or something like this ? Link to comment Share on other sites More sharing options...
csbx Posted June 17 Author Share Posted June 17 (edited) I'm not really sure how to pull this off. But this is essentially what I think I'll want to do: csbmaglocationsquestscript myscript = (game.getformfromfile(0x02027A2F, "Modname.esp") as quest) as csbmaglocationsquestscript ; If self.getowningquest().getname() == "BQ01" myscript.FindTheAliasMarkerMatch(0) ;my function, located in script "csbmaglocationsquestscript" of a quest in my mod Elseif self.getowningquest().getname() == "BQ02" myscript.FindTheAliasMarkerMatch(1) Elseif self.getowningquest().getname() == "BQ03" myscript.FindTheAliasMarkerMatch(2) Elseif self.getowningquest().getname() == "BQ04" myscript.FindTheAliasMarkerMatch(3) Endif heh. Anyone know the proper way to actually do this ? Edited June 17 by csbx Link to comment Share on other sites More sharing options...
dylbill Posted June 17 Share Posted June 17 I'm not exactly sure what you're trying to accomplish, but I try not to edit any vanilla forms or scripts in my mods to avoid conflicts. If you're using GetName() I can assume your mod requires SKSE. So I would recommend using Papyrus Extender which includes PO3_Events For example, to listen for a quest stage change you can use this event: ;QUEST STAGE CHANGE Function RegisterForQuestStage(Form akForm, Quest akQuest) global native Function UnregisterForQuestStage(Form akForm, Quest akQuest) global native Function UnregisterForAllQuestStages(Form akForm) global native Event OnQuestStageChange(Quest akQuest, Int aiNewStage) EndEvent Link to comment Share on other sites More sharing options...
csbx Posted June 17 Author Share Posted June 17 (edited) 22 minutes ago, dylbill said: I'm not exactly sure what you're trying to accomplish, but I try not to edit any vanilla forms or scripts in my mods to avoid conflicts. If you're using GetName() I can assume your mod requires SKSE. So I would recommend using Papyrus Extender which includes PO3_Events For example, to listen for a quest stage change you can use this event: ;QUEST STAGE CHANGE Function RegisterForQuestStage(Form akForm, Quest akQuest) global native Function UnregisterForQuestStage(Form akForm, Quest akQuest) global native Function UnregisterForAllQuestStages(Form akForm) global native Event OnQuestStageChange(Quest akQuest, Int aiNewStage) EndEvent Hey dylbill -- your comments and help to others came up a lot in the preparation of the mod I'm working on. Thanks a lot. Yeah - there's a whole lot of edits to vanilla scripts. That's just the nature of the mod. I consider Even Better Quest Objectives one of my essential immersion mods in my load order and it goes pretty hard at making exactly those edits. Sometimes it's overwritten by other mods--and like my mod, it's not the end of the world. I've checked my 700 mod load order and script conflicts with other mods only amounted to 2. I'm working on the patches right now. So what I'm trying to do is to check for the name of the quest that the code I'm writing is running inside of--the owning quest, if you will. I'm not trying to listen for changes to another quest. I want to compare the name of the quest that is running my code (is bq01 running it ? or is it bq02 ? Each of those quests runs that same script so I have to make that check) to the names of the quests ie. BQ01, BQ02 etc. Edited June 17 by csbx Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 17 Share Posted June 17 sure but you need SKSE use SubString on "Self" and extract the Object name, with a certain delimiter you can also extract the script name if there is one, by changing the delimiter too easy peasy, but no way will vanilla @csbx be careful, when you ask a question that nothing to with nothing to do with Skyrim, and is 100% coding, this is just string manipulation. I knew exactly what you meant, I have even previously had to do this myself, I have 100% working code in this regard, but I am going to challenging you work it out yourself DO NOT LOOK, LOOKING MEANS YOU CAN NOT WORK IT OUT Spoiler String objectName = StringUtil.Substring( StringUtil.Split(Self, StringUtil.AsChar(32))[1], 1) Link to comment Share on other sites More sharing options...
dylbill Posted June 17 Share Posted June 17 Ok I think I understand now. You're editing fragments in BQ01-BQ04. The actual function is in another script yes? Does your script extend reference alias? If so, this is how I'd do it. Make a quest parameter in your function, then compare with the quest properties. Quest Property BQ01 Auto Quest Property BQ02 Auto Quest Property BQ03 Auto Quest Property BQ04 Auto Function runmyfunction(quest akQuest) If akQuest == BQ01 Elseif akQuest == BQ02 Elseif akQuest == BQ03 Elseif akQuest == BQ04 Endif EndFunction Then you can do this when you call the function. runmyfunction(Self.GetOwningQuest()) Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 17 Share Posted June 17 also try this Debug.MesasageBox(self.getowningquest().getname() + "== "BQ01") that the correct way to Debug it, to see what going wrong @csbx Once you develop good Debugging technique, I believe you will out grow this forum, you seem to be a good Coder @csbx seriously and no offense intended, your debugging is bad, else you would not be posting here, I can see in your code, you can write, remember on average code is 1 hour writing 10 hours testing, do not ignore this skill use the debugging code for what it meant for it is not a replacement for the game game proper notification and messagbox mechanism, calling strings in that manner is bad for performance, but OK where performance is not an issue like debugging YES I know it hard to do it correctly and using debug code inappropriately is easy Edit regarding SkyUI messageBoxes, you are in a menu and the game is paused, riddle me this, is performance is an issue, OFC NOT.. it is OK to use it then Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 17 Share Posted June 17 @dylbill it is a bitwise validation issue, he is comparing one string to another.. it OFC can be be achieve in many different ways, mine for example is fire and forget with no memory.. your is baked into game save forever.. it is best to writing code that not baked into game save If StringUtil.Substring( StringUtil.Split(Self, StringUtil.AsChar(32))[1], 1) == "BQ01" myscript.FindTheAliasMarkerMatch(0) ;my function, located in script "csbmaglocationsquestscript" of a quest in my mod Elseif StringUtil.Substring( StringUtil.Split(Self, StringUtil.AsChar(32))[1], 1) == "BQ02" myscript.FindTheAliasMarkerMatch(1) Elseif StringUtil.Substring( StringUtil.Split(Self, StringUtil.AsChar(32))[1], 1) == "BQ03" myscript.FindTheAliasMarkerMatch(2) Elseif StringUtil.Substring( StringUtil.Split(Self, StringUtil.AsChar(32))[1], 1) == "BQ04" myscript.FindTheAliasMarkerMatch(3) Endif but your method will work, but it requires 16 properties four pre quests Edit or a Control Quest to cut it back to four @csbxEDIT 2 BTW above would not be how would write it.. it just an example, sooner or later you come across this Generating states at runtime do not ignore string manipulation or you will be in a world of pain Link to comment Share on other sites More sharing options...
xkkmEl Posted June 17 Share Posted June 17 Best would be to avoid messing with existing scripts. Perhaps hooking into the same events to run your code "in parallel"? With four branches, the elseif cascade is a simple and reasonable choice. For more complex cases, I like to use states. In the OnInit, you set the quest's name as the current state, and then have various implementations of function or event defined in each state: event OnInit() gotoState( getId()) endevent state MQ00 function F() ... endfunction endstate state MQ01 function F() ... endfunction endstate function F() OnInit() F() endfunction Link to comment Share on other sites More sharing options...
dylbill Posted June 17 Share Posted June 17 6 hours ago, PeterMartyr said: @dylbill it is a bitwise validation issue, he is comparing one string to another.. it OFC can be be achieve in many different ways, mine for example is fire and forget with no memory.. your is baked into game save forever.. it is best to writing code that not baked into game save Sorry but I have to disagree. Direct properties are used by Bethesda all over the place, even in scripts that are only run once. I would not use GetName to compare because if another mod changes the name of the quest it breaks the function. Using properties directly is safer. If you really wanted a fire and forget method, I would use GetFormFromFile to get the quest forms and compare. Link to comment Share on other sites More sharing options...
Recommended Posts