Jump to content

checking owning quest name question


Recommended Posts

'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

Posted (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 by csbx
Link to comment
Share on other sites

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

Posted (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 by csbx
Link to comment
Share on other sites

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

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

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

@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

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

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

  • Recently Browsing   0 members

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