Jump to content

Quest Script Woes


Recommended Posts

Posted

So I've got a small manager quest that I've been trying to get to work. The goal is simple: Have an attached script run a snippet of code each time the player loads a game, like how various mods are able to show a notification "You are now running version 2.1a of xyz."

 

Now, there's two ways that I've tried to go about this, both of which have been unsuccessful:

- have the quest start and stop each time the game is loaded, running fragments each time.

- have the quest never stop, running one large script with an OnInit() event.

 

I have tried looking at OnPlayerLoadGame() for Skyrim and Fallout 4, but I can't seem to get it to work, as my PlayerAlias script, like the example one for the Skyrim variant, fails to compile due to the function not being cast on a variable, and something about there being too much for a function.

 

My question is, how would I get this thing to work the way I want?

Posted

How are you registering OnPlayerLoadGame?

 

i register it in oninit as RegisterForRemoteEvent(Game.GetPlayer(), “OnPlayerLoadGame”)

 

then the event call is

Event Actor.OnPlayerLoadGame(Actor akSender)

;code

EndEvent

 

this is how I do it in pretty much any script, either to process updates to my mods, write to the trace log that such and such script had loaded, etc. 

Posted
1 hour ago, Carreau said:

How are you registering OnPlayerLoadGame?

 

i register it in oninit as RegisterForRemoteEvent(Game.GetPlayer(), “OnPlayerLoadGame”)

 

then the event call is

Event Actor.OnPlayerLoadGame(Actor akSender)

;code

EndEvent

 

this is how I do it in pretty much any script, either to process updates to my mods, write to the trace log that such and such script had loaded, etc. 

See, I didn't know that this was the kind of event that needed to be registered, especially not remotely. There's nothing on those pages that mentions that, and I only really know the basics of papyrus. I'm basically bumblefucking my way through this part. So to answer your question: I'm not registering it at all.

 

So is "Event Actor.OnPlayerLoadGame(Actor akSender)" the correct syntax? Or would I have to put either "Game.GetPlayer()" or an actor property that points to the player to replace either "Actor" or "akSender" ?

 

Would the following be similar to what you'd do?

 

Spoiler

Scriptname Evan555alpha:CAVersionMessageScript extends Quest
{This script will show messages about the current version.}

Group Main
	Message Property Enabled Auto Const Mandatory
	{The first time run message box.}

	Book Property CABook Auto Const
	{The book.}

	Message Property UpdateMessage Auto Const Mandatory
	{Message box for version 1.2}

	GlobalVariable Property CAVersion Auto Const Mandatory
	{Global to keep track of version. 1 denotes version 1.1, 2 denotes 1.2, etc. Incrememts by 1 for each "major" update.}
	
	Perk Property ChangePerk Auto Const Mandatory
	{The perk used in a check to prevent giving out the book twice.}
EndGroup

Event OnInit()
	RegisterForRemoteEvent(Game.GetPlayer(), "OnPlayerLoadGame")
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	Int CAVValue = CAVersion.GetValueInt()
	Utility.Wait(5)
	If ((CAVValue == 0) && Game.GetPlayer().HasPerk(ChangePerk) == 0)
		Enabled.Show()
		Utility.Wait(1)
		Game.GetPlayer().PlaceAtMe(CABook, 1)
		CAVersion.Mod(1)
		Debug.Trace("ChrysArmour First Time Message Shows.")
	ElseIf ((CAVValue == 0) && Game.GetPlayer().HasPerk(ChangePerk) == 1)
		UpdateMessage.Show()
		CAVersion.Mod(1)
		Debug.Trace("ChrysArmour First Time Message Shows.")
	EndIf
	If CAVVAlue == 1
		UpdateMessage.Show()
		CAVersion.Mod(1)
		Debug.Trace("ChrysArmour Version Shows. Version is " + CAVersion.GetValueInt())
	Else
		Debug.Trace("ChrysArmour Version script runs twice.")
	EndIf
EndEvent

 

 

Posted

The event is part of Actor script, so you prefix it with Actor.  This method is how I handle a ton of my scripts.

 

your functions look exactly how i handle them. 

Posted

I can't thank you enough, man. It's nice to finally be able to see that last debug trace in my logs.

Spoiler

Scriptname Evan555alpha:CAVersionMessageScript extends Quest
{This script will show messages about the current version.}

Group Main
	Message Property Enabled Auto Const Mandatory
	{The first time run message box.}

	Book Property CABook Auto Const
	{The book.}

	Message Property UpdateMessage Auto Const Mandatory
	{Message box for version 1.2}

	GlobalVariable Property CAVersion Auto Const Mandatory
	{Global to keep track of version. 1 denotes version 1.1, 2 denotes 1.2, etc. Incrememts by 1 for each "major" update.}
	
	Perk Property ChangePerk Auto Const Mandatory
	{The perk used in a check to prevent giving out the book twice.}
EndGroup

Group VersionInts
	Int Property PreviousVersion  Auto Mandatory
	{The value of the Previous version. So going from 1.1 to 1.2, we'd check for the 1.1 value.}
	Int Property CurrentVersion Auto Mandatory
	{The value of the current version. Previous Version + 1.}
EndGroup

Event OnInit()
	RegisterForRemoteEvent(Game.GetPlayer(), "OnPlayerLoadGame")
	ChrysArmourVersionDisplay()
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	ChrysArmourVersionDisplay()
EndEvent

Function ChrysArmourVersionDisplay()
	Int CAVValue = CAVersion.GetValueInt()
	Utility.Wait(5)
	If ((CAVValue == 0) && Game.GetPlayer().HasPerk(ChangePerk) == 0)
		Enabled.Show()
		Utility.Wait(1)
		Game.GetPlayer().PlaceAtMe(CABook, 1)
		CAVersion.SetValue(PreviousVersion)
		Debug.Trace("ChrysArmour First Time Message Shows.")
	ElseIf ((CAVValue == 0) && Game.GetPlayer().HasPerk(ChangePerk) == 1)
		CAVersion.SetValue(PreviousVersion)
		Debug.Trace("ChrysArmour First Time Message Shows.")
	EndIf
	If CAVVAlue <= PreviousVersion
		UpdateMessage.Show()
		CAVersion.SetValue(CurrentVersion)
		Debug.Trace("ChrysArmour Version Shows. Version is " + CAVersion.GetValueInt())
	Else
		Debug.Trace("ChrysArmour Version script runs twice.")
	EndIf
EndFunction

 

Spoilered is what I ended up going with.

Posted

You can also create an Alias in the quest based on the Player and add your scripts to that, you don't needt to register OnPlayerGameLoad then, it allows you to use pretty much every function then otherwise you may finding stuff you can't do in quest scripts or actor scripts without causing dirty edits.

Scriptname SynthPlayer:Synth4Power extends ReferenceAlias

{Power Management}

Group Misc
	Quest Property qMQ101 Auto Const
EndGroup

;-----------------------------------------------------------------------------------------------------------------------------

Actor rActor
String sScriptName = "Power"
Int iBootup
Int iDebugSetting

;-----------------------------------------------------------------------------------------------------------------------------

Event OnInit()
	Utility.Wait(1.0)
	rActor = Game.GetPlayer()
	fPowerLevel = 80.0
	fnInit()
	StartTimer(fFrequencyTimer, iTimerID)
EndEvent

Event OnPlayerLoadGame()
	fnInit()
EndEvent

Function fnInit()
	fPrevTime = Utility.GetCurrentGameTime()
EndFunction

 

Posted

Well, I don't know what's changed since then and now, but it's obvious that I spoke far too fucking soon. 

Alright, so, 1.2 will be released within the next day or two, maybe sooner. There is just one final issue I need to iron out, and that's the fucking quest and it's attached scripts. One of the scripts absolutely insists on running twice for some reason, and I have no idea why. There is only one thing in the plugin that references it, the quest, and that quest is supposed to start and never stop. I've tried not invoking the function in the OnInit() event, but then it just doesn't happen, so it has to be something in the function itself, something which I can't damn well see.

 

Spoiler

Scriptname Evan555alpha:CAVersionMessageScript extends Quest
{This script will show messages about the current version.}

Group Main
	Message Property Enabled Auto Const Mandatory
	{The first time run message box.}

	Book Property CABook Auto Const
	{The book.}

	Message Property UpdateMessage Auto Const Mandatory
	{Message box for version 1.2}

	GlobalVariable Property CAVersion Auto Const Mandatory
	{Global to keep track of version. 1 denotes version 1.1, 2 denotes 1.2, etc. Incrememts by 1 for each "major" update.}
	
	Perk Property ChangePerk Auto Const Mandatory
	{The perk used in a check to prevent giving out the book twice.}
	
	Perk Property DroneHealPerk Auto Const Mandatory
	{The Drone Heal Perk that we add to the player regardless of version first time run.}
	
	Perk Property CAFlightPerk Auto Const Mandatory
	{The flight perk that we add to the player like the drone perk.}
	
	Quest Property MQ102 Auto Const
	{The main quest of the game that we wait for completion before we start.}
EndGroup

Group VersionInts
	Int Property PreviousVersion  Auto Mandatory
	{The value of the Previous version. So going from 1.1 to 1.2, we'd check for the 1.1 value.}
	Int Property CurrentVersion Auto Mandatory
	{The value of the current version. Previous Version + 1.}
EndGroup

Event OnInit()
	Bool IsDone = MQ102.IsStageDone(10)
	While IsDone == False
		Utility.Wait(1.0)
	EndWhile
	RegisterForRemoteEvent(Game.GetPlayer(), "OnPlayerLoadGame")
	ChrysArmourVersionDisplay()
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	Bool IsDone = MQ102.IsStageDone(10)
	While IsDone == False
		Utility.Wait(1.0)
	EndWhile
	Utility.Wait(10)
	ChrysArmourVersionDisplay()
EndEvent

Function ChrysArmourVersionDisplay()
	Int CAVValue = CAVersion.GetValueInt()
	If ((CAVValue == 0) && (Game.GetPlayer().HasPerk(ChangePerk) == 0))
		Game.GetPlayer().AddPerk(DroneHealPerk, False)
		Game.GetPlayer().AddPerk(CAFlightPerk, False)
		Enabled.Show()
		Game.GetPlayer().PlaceAtMe(CABook, 1)
		CAVersion.SetValue(PreviousVersion)
		CAVValue = CAVersion.GetValueInt()
		Debug.Trace("Evan555alpha:ChrysArmour First Time Message Shows.")
		Utility.Wait(5)
	EndIf
	If ((CAVValue == 0) && (Game.GetPlayer().HasPerk(ChangePerk) == 1))
		Game.GetPlayer().AddPerk(DroneHealPerk, False)
		Game.GetPlayer().AddPerk(CAFlightPerk, False)
		CAVersion.SetValue(PreviousVersion)
		CAVValue = CAVersion.GetValueInt()
		Debug.Trace("Evan555alpha:Player already has perk.")
	EndIf
	If CAVVAlue <= PreviousVersion
		UpdateMessage.Show()
		CAVersion.SetValue(CurrentVersion)
		Debug.Trace("Evan555alpha:ChrysArmour Version Shows. Version is " + CAVersion.GetValueInt())
	Else
		Debug.Trace("Evan555alpha:ChrysArmour Version script runs twice.")
	EndIf
EndFunction

 

If anyone wants to tell me what the fuck is wrong with this script, feel free. I've been at it the past fucking hour and have had no success in getting that function to run once on game load.

Posted

Quests initialize twice. Once in game startup, and again on quest startup. To prevent that, you need to check “run once” in the creation kit. 

Posted
3 minutes ago, Carreau said:

Quests initialize twice. Once in game startup, and again on quest startup. To prevent that, you need to check “run once” in the creation kit. 

Wouldn't having it checked to run once break the entire point of the script? Or am I misunderstanding something here?

Posted

Welp, a new solution has been found; using OnQuestInit() instead of OnInit(). That way, there's no fucking around, possibly breaking the script by using the Run Once flag.

 

Thanks for pointing out what Run Once does, however.

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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