marieruth Posted November 14, 2014 Share Posted November 14, 2014 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 More sharing options...
IsharaMeradin Posted November 14, 2014 Share Posted November 14, 2014 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_Managerhttp://www.creationkit.com/Category:Story_Manager_Eventshttp://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 More sharing options...
marieruth Posted November 15, 2014 Author Share Posted November 15, 2014 (edited) 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_Managerhttp://www.creationkit.com/Category:Story_Manager_Eventshttp://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 November 15, 2014 by marieruth Link to comment Share on other sites More sharing options...
IsharaMeradin Posted November 15, 2014 Share Posted November 15, 2014 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 More sharing options...
IsharaMeradin Posted November 15, 2014 Share Posted November 15, 2014 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 imagehttp://i1235.photobucket.com/albums/ff438/Therin303/tutorial_zps84160e29.jpgAfter 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 EndEventThe 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 More sharing options...
marieruth Posted November 16, 2014 Author Share Posted November 16, 2014 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 imagehttp://i1235.photobucket.com/albums/ff438/Therin303/tutorial_zps84160e29.jpgAfter 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 EndEventThe 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 EndEventThe 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 More sharing options...
IsharaMeradin Posted November 16, 2014 Share Posted November 16, 2014 That's my bad. Wrote that from memory and a faulty one at that. Just switch it to OnEffectStart. Link to comment Share on other sites More sharing options...
SugarSteak Posted November 16, 2014 Share Posted November 16, 2014 (edited) 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 imagehttp://i1235.photobucket.com/albums/ff438/Therin303/tutorial_zps84160e29.jpgAfter 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 EndEventThe 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 EndEventThe 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: Scriptname aaa_SRMagEffectScript Extends ActiveMagicEffect Actor PlayerRef Event OnEffectStart(Actor akTarget, Actor akCaster) If akTarget == Game.GetPlayer() PlayerRef = akTarget 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 EndIf 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 November 16, 2014 by SugarSteak Link to comment Share on other sites More sharing options...
marieruth Posted November 16, 2014 Author Share Posted November 16, 2014 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 More sharing options...
IsharaMeradin Posted November 16, 2014 Share Posted November 16, 2014 That's because you aren't supposed to change that line. That line MUST remain as: Event OnEffectStart(Actor akTarget, Actor akCaster)The reason it is this way is so that you can script things to happen either to the target or to the one that cast the spell. Link to comment Share on other sites More sharing options...
Recommended Posts