Jump to content

Would like some help with a quest script.


marieruth

Recommended Posts

The script I'm making is supposed to run repeatedly to check the player's speechcraft level, and depending on the player character's speechcraft level, will shorten the recovery time for using Shouts. I attached the script to a Quest since those can run repeatedly as far as I am aware with my wee bit of scripting experience in the GECK.

 

 

 

scriptname aaaShoutAdjustmentScript extends Quest Conditional

	Quest Property aaaShoutProperty Auto

	RegisterForUpdate(5)

	PlayerRef = Game.GetPlayer()

	Event OnUpdate()
		
			If (PlayerRef.GetBaseAV ("Speech") > 20)

				PlayerRef.ModAV ("ShoutRecoveryMult", -7)

			EndIf

			If (PlayeRef.GetBaseAV ("Speech") >  40)

				PlayerRef.ModAV ("ShoutRecoveryMult", -7)

			EndIf

			If (PlayerRef.GetBaseAV ("Speech") > 60)

				PlayerRef.ModAV ("ShoutRecoveryMult", -7)

			EndIf
	
			If (PlayerRef.GetBaseAV ("Speech") > 80)

				PlayerRef.ModAV ("ShoutRecoveryMult", -7)

			EndIf

	endEvent

 

 

 

I'm the most newbiest newb at papyrus scripting, but the script won't successfully compile, so I clearly did something wrong and I'm not sure what it was that I messed up on. Any assistance would be appreciated...

Link to comment
Share on other sites

	RegisterForUpdate(5)

	PlayerRef = Game.GetPlayer()

Those two lines cannot be outside of an event. Try putting them inside the OnInit() event. Another thing to consider is ensuring that there is some means to stop the update loop should the player wish to uninstall the mod. As it currently is, the player would get stuck with an endless amount of spam in their papyrus log should they uninstall.

 

But you might be better off using the Story Manager. There is an event which will kick off quests when the player levels a specified skill. Since you are checking the skill level of Speech this makes sense.

 

http://www.creationkit.com/Category:Story_Manager

http://www.creationkit.com/Category:Story_Manager_Events

http://www.creationkit.com/Skill_Increase

 

Another thing I notice, you are changing the recovery multiplier every 5 seconds. Without some sort of bool or other variable to prevent modification, the player will end up with absolutely 0 cool down. All it takes is a level of 21 in speech. -7 every 5 seconds will have a very big impact. I believe your intent was to subtract 7 additional every 20 levels gained in the speech skill.

Link to comment
Share on other sites

	RegisterForUpdate(5)

	PlayerRef = Game.GetPlayer()

Those two lines cannot be outside of an event. Try putting them inside the OnInit() event. Another thing to consider is ensuring that there is some means to stop the update loop should the player wish to uninstall the mod. As it currently is, the player would get stuck with an endless amount of spam in their papyrus log should they uninstall.

 

But you might be better off using the Story Manager. There is an event which will kick off quests when the player levels a specified skill. Since you are checking the skill level of Speech this makes sense.

 

http://www.creationkit.com/Category:Story_Manager

http://www.creationkit.com/Category:Story_Manager_Events

http://www.creationkit.com/Skill_Increase

 

Another thing I notice, you are changing the recovery multiplier every 5 seconds. Without some sort of bool or other variable to prevent modification, the player will end up with absolutely 0 cool down. All it takes is a level of 21 in speech. -7 every 5 seconds will have a very big impact. I believe your intent was to subtract 7 additional every 20 levels gained in the speech skill.

 

 

 

 

 

scriptname aaaShoutAdjustmentScript extends Quest Conditional

	Quest Property aaaShoutProperty Auto
	
	Event OnInit()
		;RegisterForUpdate(5)
		PlayerRef = Game.GetPlayer()
		float OriginalRecoveryTime
			OriginalRecoveryTime = OriginalRecoveryTime + Game.GetPlayer().GetBaseAV ("ShoutRecoveryMult")
		bool RecoverTier01
			RecoverTier01 = false
		bool RecoverTier02
			RecoverTier02 = false
		bool RecoverTier03
			RecoverTier03 = false
		bool RecoverTier04
			RecoverTier04 = false
	endEvent
	
	Event OnUpdate()
			If (PlayerRef.GetBaseAV ("Speech") > 20)
				PlayerRef.ModAV ("ShoutRecoveryMult", -7)
				RecoverTier01 = true
			EndIf
			
			If (PlayeRef.GetBaseAV ("Speech") >  40 && RecoverTier01 = true)
				PlayerRef.ModAV ("ShoutRecoveryMult", -7)
				RecoverTier02 = true
			EndIf
			
			If (PlayerRef.GetBaseAV ("Speech") > 60 && RecoverTier01 = true && RecoverTier02 = true)
				PlayerRef.ModAV ("ShoutRecoveryMult", -7)
				RecoverTier03 = true
			EndIf
			
			If (PlayerRef.GetBaseAV ("Speech") > 80 && RecoverTier01 = true && RecoverTier02 = true && RecoverTier03 = true)
				PlayerRef.ModAV ("ShoutRecoveryMult", -7)
			EndIf
	endEvent

 

 

 

I'm still not entirely sure of my script, it's a rather hot mess, but I added some variables to hopefully put in some blocks. I will have a spell that once cast it should restore the user's recovery time to the original stored variable, though I'm not sure how to make the script *stop* running when someone will cast that spell.. Also, after adding the PlayerRef variable within OnInit, I got output messages saying that PlayerRef is undefined.

 

And looking at the Story manager and events wiki page, do I not need to add in quest aliases for the skill increase stuff? The wiki only mentions references and locations for the quest. I don't know how to direct it to specifically the Speechcraft skill. Would I need to create a new Event entirely?

Edited by marieruth
Link to comment
Share on other sites

I am looking into this. I will let you know what I come up with. However, something to consider. ShoutRecoveryMult is a multiplier. This means that the value is used to modify the established cool down time for the shout used. Its base value is 1. Subtracting 7 from that will make a negative multiplier. It could cause things to go haywire.

 

A mult value of 1 means that the cool down times are at what is set in the CK. A mult of 2 would be twice the value. A mult of .5 would be half the value. I suggest using some other value. Perhaps 0.2 at the most. This would give mults of .8 .6 .4 & .2 leaving a small amount of room for other modifications such as an amulet of talos and the blessing of talos. It is something that you'll need to play with to ensure it does not break the game or cause other issues.

Link to comment
Share on other sites

I got it working. This is what I did. I created a new quest. I created an alias for the player. I assigned the following script to the player alias.

 

 

Scriptname abim_ShortenShoutRecoveryTEST extends ReferenceAlias  

Actor Property PlayerRef Auto
Float Property SRMM20 = -0.2 Auto
Float Property SRMM40 = -0.2 Auto
Float Property SRMM60 = -0.2 Auto
Float Property SRMM80 = -0.2 Auto

Bool Done80 = false
Bool Done60 = false
Bool Done40 = false
Bool Done20 = false

Float SRM
Float SC

Event OnInit()
	SRM = PlayerRef.GetAV("ShoutRecoveryMult")
	SC = PlayerRef.GetBaseAV("Speechcraft")
	If SC > 80 && Done80 == false
		Done80 = true
		ModSRM(SRMM80)
	ElseIf SC > 60 && Done60 == false
		Done60 = true
		ModSRM(SRMM60)
	ElseIf SC > 40 && Done40 == false
		Done40 = true
		ModSRM(SRMM40)
	ElseIf SC > 20 && Done20 == false
		Done20 = true
		ModSRM(SRMM20)
	EndIf
EndEvent

Function ModSRM(Float SRMM)
	Debug.Trace("Speechcraft level: "+SC) 
	Debug.Trace("Shout Recovery: "+SRM)
	PlayerRef.ModAV("ShoutRecoveryMult",SRMM)
	Float NSRM = PlayerRef.GetAV("ShoutRecoveryMult")
	If NSRM != SRM
		Debug.Trace("New Shout Recovery: "+NSRM)
	EndIf
EndFunction 

I set this script up to have float properties for each of the stages. They have a default value of -0.2 but since they are properties you can override them with whatever values you want. You can even use different values per stage if you desired.

I created a new quest node under the Skill Increase event of the Story Manager. I added the quest I created to the new quest node. See image

http://i1235.photobucket.com/albums/ff438/Therin303/tutorial_zps84160e29.jpg

After spam selling flawless diamonds to a couple merchants I managed to increase my speech above 40. See the relevant log text

[11/15/2014 - 01:30:32AM] Speechcraft level: 21.000000
[11/15/2014 - 01:30:32AM] Shout Recovery: 1.000000
[11/15/2014 - 01:30:32AM] New Shout Recovery: 0.800000

<SNIP>

[11/15/2014 - 01:34:38AM] Speechcraft level: 36.000000
[11/15/2014 - 01:34:38AM] Shout Recovery: 0.800000
[11/15/2014 - 01:34:38AM] New Shout Recovery: 0.600000 

Not sure why the speechcraft level indicates it was 36. Unless because I was spam diamond selling and it never got a chance to update the base level. I had a skill level of 36 when I entered that particular merchant's building and I exited the game shortly after passing 41.

Feel free to replicate and test it out for yourself. As far as restoring the SRM, your spell should be fine. If the effect is scripted, then simply do something like:

Scriptname SomeScript Extends ActiveMagicEffect
 
Actor Property PlayerRef Auto
 
Event OnMagicEffectStart(...)
Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
If CSRM != OSRM
  If OSRM > CSRM
    PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  ElseIf OSRM < CSRM
    PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  EndIf
EndIf
EndEvent

The reason this should work is that the value of the base record does not change with ModAV, SetAV or even DamageAV. Those functions modify the values on the active reference not the base.

 

To confirm in-game what the values are when testing. You can use the console and type player.getav shoutrecoverymult when at a value of 1.000 it is identical to the base value.

 

 

Link to comment
Share on other sites

 

 

I got it working. This is what I did. I created a new quest. I created an alias for the player. I assigned the following script to the player alias.

 

 

Scriptname abim_ShortenShoutRecoveryTEST extends ReferenceAlias  

Actor Property PlayerRef Auto
Float Property SRMM20 = -0.2 Auto
Float Property SRMM40 = -0.2 Auto
Float Property SRMM60 = -0.2 Auto
Float Property SRMM80 = -0.2 Auto

Bool Done80 = false
Bool Done60 = false
Bool Done40 = false
Bool Done20 = false

Float SRM
Float SC

Event OnInit()
	SRM = PlayerRef.GetAV("ShoutRecoveryMult")
	SC = PlayerRef.GetBaseAV("Speechcraft")
	If SC > 80 && Done80 == false
		Done80 = true
		ModSRM(SRMM80)
	ElseIf SC > 60 && Done60 == false
		Done60 = true
		ModSRM(SRMM60)
	ElseIf SC > 40 && Done40 == false
		Done40 = true
		ModSRM(SRMM40)
	ElseIf SC > 20 && Done20 == false
		Done20 = true
		ModSRM(SRMM20)
	EndIf
EndEvent

Function ModSRM(Float SRMM)
	Debug.Trace("Speechcraft level: "+SC) 
	Debug.Trace("Shout Recovery: "+SRM)
	PlayerRef.ModAV("ShoutRecoveryMult",SRMM)
	Float NSRM = PlayerRef.GetAV("ShoutRecoveryMult")
	If NSRM != SRM
		Debug.Trace("New Shout Recovery: "+NSRM)
	EndIf
EndFunction 

I set this script up to have float properties for each of the stages. They have a default value of -0.2 but since they are properties you can override them with whatever values you want. You can even use different values per stage if you desired.

I created a new quest node under the Skill Increase event of the Story Manager. I added the quest I created to the new quest node. See image

http://i1235.photobucket.com/albums/ff438/Therin303/tutorial_zps84160e29.jpg

After spam selling flawless diamonds to a couple merchants I managed to increase my speech above 40. See the relevant log text

[11/15/2014 - 01:30:32AM] Speechcraft level: 21.000000
[11/15/2014 - 01:30:32AM] Shout Recovery: 1.000000
[11/15/2014 - 01:30:32AM] New Shout Recovery: 0.800000

<SNIP>

[11/15/2014 - 01:34:38AM] Speechcraft level: 36.000000
[11/15/2014 - 01:34:38AM] Shout Recovery: 0.800000
[11/15/2014 - 01:34:38AM] New Shout Recovery: 0.600000 

Not sure why the speechcraft level indicates it was 36. Unless because I was spam diamond selling and it never got a chance to update the base level. I had a skill level of 36 when I entered that particular merchant's building and I exited the game shortly after passing 41.

Feel free to replicate and test it out for yourself. As far as restoring the SRM, your spell should be fine. If the effect is scripted, then simply do something like:

Scriptname SomeScript Extends ActiveMagicEffect
 
Actor Property PlayerRef Auto
 
Event OnMagicEffectStart(...)
Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
If CSRM != OSRM
  If OSRM > CSRM
    PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  ElseIf OSRM < CSRM
    PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  EndIf
EndIf
EndEvent

The reason this should work is that the value of the base record does not change with ModAV, SetAV or even DamageAV. Those functions modify the values on the active reference not the base.

 

To confirm in-game what the values are when testing. You can use the console and type player.getav shoutrecoverymult when at a value of 1.000 it is identical to the base value.

 

 

 


I've run into some issues getting the script for the magic effect that will be used in the spell for restoring original recovery times to work. I fiddled with the code you gave me for a little while, and eventually changed it to this:

Scriptname aaa_SRMagEffectScript Extends ActiveMagicEffect

Actor Property PlayerRef Auto

Event OnMagicEffectStart(aaa_ShoutRecoveryMagEffect)
Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
If CSRM != OSRM
  If OSRM > CSRM
    PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  ElseIf OSRM < CSRM
    PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  EndIf
EndIf
EndEvent

The compiler prints this error:

 

Starting 1 compile threads for 1 files...
Compiling "aaa_SRMagEffectScript"...
C:\Steam\steamapps\common\skyrim\Data\Scripts\Source\temp\aaa_SRMagEffectScript.psc(5,51): missing ID at ')'
No output generated for aaa_SRMagEffectScript, compilation failed.
Batch compile of 1 files finished. 0 succeeded, 1 failed.
Failed on aaa_SRMagEffectScript
I tried looking through the CK wiki to see what I needed, but I only found a page for "OnEffectStart", but not for "OnMagicEffectStart".
Link to comment
Share on other sites

 

 

 

I got it working. This is what I did. I created a new quest. I created an alias for the player. I assigned the following script to the player alias.

 

 

Scriptname abim_ShortenShoutRecoveryTEST extends ReferenceAlias  

Actor Property PlayerRef Auto
Float Property SRMM20 = -0.2 Auto
Float Property SRMM40 = -0.2 Auto
Float Property SRMM60 = -0.2 Auto
Float Property SRMM80 = -0.2 Auto

Bool Done80 = false
Bool Done60 = false
Bool Done40 = false
Bool Done20 = false

Float SRM
Float SC

Event OnInit()
	SRM = PlayerRef.GetAV("ShoutRecoveryMult")
	SC = PlayerRef.GetBaseAV("Speechcraft")
	If SC > 80 && Done80 == false
		Done80 = true
		ModSRM(SRMM80)
	ElseIf SC > 60 && Done60 == false
		Done60 = true
		ModSRM(SRMM60)
	ElseIf SC > 40 && Done40 == false
		Done40 = true
		ModSRM(SRMM40)
	ElseIf SC > 20 && Done20 == false
		Done20 = true
		ModSRM(SRMM20)
	EndIf
EndEvent

Function ModSRM(Float SRMM)
	Debug.Trace("Speechcraft level: "+SC) 
	Debug.Trace("Shout Recovery: "+SRM)
	PlayerRef.ModAV("ShoutRecoveryMult",SRMM)
	Float NSRM = PlayerRef.GetAV("ShoutRecoveryMult")
	If NSRM != SRM
		Debug.Trace("New Shout Recovery: "+NSRM)
	EndIf
EndFunction 

I set this script up to have float properties for each of the stages. They have a default value of -0.2 but since they are properties you can override them with whatever values you want. You can even use different values per stage if you desired.

I created a new quest node under the Skill Increase event of the Story Manager. I added the quest I created to the new quest node. See image

http://i1235.photobucket.com/albums/ff438/Therin303/tutorial_zps84160e29.jpg

After spam selling flawless diamonds to a couple merchants I managed to increase my speech above 40. See the relevant log text

[11/15/2014 - 01:30:32AM] Speechcraft level: 21.000000
[11/15/2014 - 01:30:32AM] Shout Recovery: 1.000000
[11/15/2014 - 01:30:32AM] New Shout Recovery: 0.800000

<SNIP>

[11/15/2014 - 01:34:38AM] Speechcraft level: 36.000000
[11/15/2014 - 01:34:38AM] Shout Recovery: 0.800000
[11/15/2014 - 01:34:38AM] New Shout Recovery: 0.600000 

Not sure why the speechcraft level indicates it was 36. Unless because I was spam diamond selling and it never got a chance to update the base level. I had a skill level of 36 when I entered that particular merchant's building and I exited the game shortly after passing 41.

Feel free to replicate and test it out for yourself. As far as restoring the SRM, your spell should be fine. If the effect is scripted, then simply do something like:

Scriptname SomeScript Extends ActiveMagicEffect
 
Actor Property PlayerRef Auto
 
Event OnMagicEffectStart(...)
Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
If CSRM != OSRM
  If OSRM > CSRM
    PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  ElseIf OSRM < CSRM
    PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  EndIf
EndIf
EndEvent

The reason this should work is that the value of the base record does not change with ModAV, SetAV or even DamageAV. Those functions modify the values on the active reference not the base.

 

To confirm in-game what the values are when testing. You can use the console and type player.getav shoutrecoverymult when at a value of 1.000 it is identical to the base value.

 

 

 

 

 

I've run into some issues getting the script for the magic effect that will be used in the spell for restoring original recovery times to work. I fiddled with the code you gave me for a little while, and eventually changed it to this:

Scriptname aaa_SRMagEffectScript Extends ActiveMagicEffect

Actor Property PlayerRef Auto

Event OnMagicEffectStart(aaa_ShoutRecoveryMagEffect)
Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
If CSRM != OSRM
  If OSRM > CSRM
    PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  ElseIf OSRM < CSRM
    PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  EndIf
EndIf
EndEvent

The compiler prints this error:

 

Starting 1 compile threads for 1 files...
Compiling "aaa_SRMagEffectScript"...
C:\Steam\steamapps\common\skyrim\Data\Scripts\Source\temp\aaa_SRMagEffectScript.psc(5,51): missing ID at ')'
No output generated for aaa_SRMagEffectScript, compilation failed.
Batch compile of 1 files finished. 0 succeeded, 1 failed.
Failed on aaa_SRMagEffectScript
I tried looking through the CK wiki to see what I needed, but I only found a page for "OnEffectStart", but not for "OnMagicEffectStart".

 

Well ...I just say a few words casually.

First ,no "OnMagicEffectStart“ function ,the "OnEffectStart" is that which you want .

Second , the event's format ...I don't know how to let you understand it ...

Nah ,look this:

 

  1. Scriptname aaa_SRMagEffectScript Extends ActiveMagicEffect
  2. Actor PlayerRef
  3. Event OnEffectStart(Actor akTarget, Actor akCaster)
  4. If akTarget == Game.GetPlayer()
  5. PlayerRef = akTarget
  6. Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
  7. Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
  8. If CSRM != OSRM
  9. If OSRM > CSRM
  10. PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  11. ElseIf OSRM < CSRM
  12. PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  13. EndIf
  14. EndIf
  15. EndIf
  16. EndEvent

Er , let's be honest ,maybe you should study more basic knowledge ,wiki is not a good teacher ,it's just a dictionary .

A advice is to find some simple scripts ,

"You cannot expect to understand These files within a couple of minutes. But if you see more and more , then you will gradually understand what's going on." --by fore

 

Well ,I'm not sure this is the best way ,but I've been there .

Edited by SugarSteak
Link to comment
Share on other sites

That's my bad. Wrote that from memory and a faulty one at that. Just switch it to OnEffectStart.

 

I'm still having some troubles with "OnEffectStart" ... After changing it, i got an output message saying that I was missing an ID. I looked at the CK wiki and noticed that the OnEffectStart parameters were supposed to appear something like (Actor Target, Actor Caster)

 

I am getting an output error for a "missing ID" directed at the location of the OnEffectStart Event. I'm not sure what else I need to add.

Event OnEffectStart(aaa_ShoutRecoveryMagEffect, Actor Player) doesn't seem to do anything that'll help, and doesn't seem logical anyhow.

scriptname aaa_SRMagEffectScript Extends ActiveMagicEffect

Actor Property PlayerRef Auto

Event OnEffectStart(aaa_ShoutRecoveryMagEffect)
Float OSRM = PlayerRef.GetBaseAV(ShoutRecoveryMult)
Float CSRM = PlayerRef.GetAV(ShoutRecoveryMult)
If CSRM != OSRM
  If OSRM > CSRM
    PlayerRef.ModAV(ShoutRecoverMult,OSRM-CSRM)
  ElseIf OSRM < CSRM
    PlayerRef.ModAV(ShoutRecoverMult,CSRM-OSRM)
  EndIf
EndIf
EndEvent

I am only getting errors for that Event line, but everything else seems okay.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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