Jump to content

[LE] Scripted Spell Magnitude?


Haravikk

Recommended Posts

I'm looking to create a magic effect in a mod that will apply a dynamic bonus to Speech depending upon a bunch of factors (including who the player is talking to), and I'm trying to decide what the best way to do it would be.

 

 

For example, the obvious way to do this would be to apply a spell with a scripted magic effect, with an OnEffectStart event calling PlayerRef.ModActorValue("Speechcraft", foo) to increase the player's Speech, an an OnEffectEnd event to reverse it. However I'm a bit wary of using this function as there's potential for it to leave the player's Speech skill permanently modified.

 

I've seen this happen in other mods, for example the Invested Magic mod (which makes spells like Oakflesh and such toggleable effects that reduce max Magicka, rather than having to re-cast all the time), where I noticed over time that my magicka was being permanently increased.

 

 

What I'm wondering is whether there is another way that I might do this that I haven't thought off that would be safer? What I would really like to be able to do is cast a spell using a scripted magnitude, so that the strength of the effect applied is fully managed by Skyrim rather than requiring any further script intervention.

 

The only other alternative I can think of is to have variations of the spell and just apply the bonus in increments of 5 or 10 or whatever, which would work, but feels a bit unwieldy, as with the range of factors I'm accounting for I could need quite a lot of different spells in total.

 

 

So yeah, does anyone have any ideas for how else I might do this? Would SKSE's SetNthEffectMagnitude() method be safe to use for this purpose?

Link to comment
Share on other sites

I'm going to try to help you, based on my experience.

 

If the magic effect you want to apply is applied via a spell/enchantment/potion/whatever which only has a single magic effect (just that speficic magic effect and nothing else), you can try to use a perk with "Mod Spell Magnitude" as the Perk Entry Point and either "Multiply Value", "Add Actor Value Mult", "Multiply Actor Value Mult", "Multiply 1 + Actor Value Mult", or any other option which suits your need as the function (as reference, read https://www.creationkit.com/index.php?title=Perk_Entry_Point and https://en.uesp.net/wiki/Tes5Mod:Mod_File_Format/PERK). You can set several Perk Entry Points for each factor you want to include in your overall Speech bonus. The end result will be the whole multiplier from each Perk Entry Points. Then set the actor value of the magic effect by "speechcraft" and set the magnitude by 1 (in your spell/enchantment/etc).

The perk should be added to the player character early (before this magic effect is applied) just to be safe. What you need to be aware from this method is that some Entry Points may overlap and some of them may not work (learn about perk "priorities"), so you need to test it in the game and check the calculation yourself (ie. use console command, write "player.getav speech" or something like that, then note the result, then compare with your own calculation, see if they are matching or not).

 

Another method is by adding the magic effect multiple times into the spell/enchantment/etc with each instance has its own condition. For example, the first instance may have condition "GetLevel (PlayerRef) >= 10", the second instance may have condition "GetQuestCompleted (whatever quest) == 1", etc. This only works if all of the factors you want to include can be covered by the existing condition functions (https://www.creationkit.com/index.php?title=Category:Condition_Functions). You can also try to combine both this method and the previous method, but you need to put each of them into a different spell/enchantment/etc (resulting in multiple spells/enchantments/etc), because as far as i know "Mod Spell Magnitude" only works for spells/enchantments/etc which has a single magic effect as its effect.

 

Another method is by doing the calculation in via papyrus script. As you have mentioned about it, i assume you already know how to use papyrus functions, so the issue is how to apply them temporarily (not permanent). This is quite simple. Just add a line in the script which stores the player's current Speechcraft value (ie. PlayerRef.GetActorValue("Speechcraft"), store it into a variable) inside OnEffectStart event. This stored current Speechcraft value will be recovered to the player when the effect ends (ie. OnEffectFinish event runs) by reapplying the value from the variable.

You can use either "ModActorValue" or "ForceActorValue" to modify the current value, but use it consistently. To use ModActorValue, you need to do the calculation first (ie. write lines to calculate the number based on the factors), then only take the modified number (ie. the calculation result minus the current value) to be used in the ModActorValue function. For example, the calculation result is 125 while the current value (current Speechcraft) is 100, so write the function by PlayerRef.ModActorValue("Speechcraft", 25). 25 is 125 minus 100. Then when the effect ends (OnEffectFinish runs), put PlayerRef.ModActorValue("Speechcraft", -25) to recover the value into the player's initial speech value. But if you want to use "ForceActorValue", you can simply take the value of 125 directly, so it'll be PlayerRef.ForceActorValue("Speechcraft", 125) in OnEffectStart and then PlayerRef.ForceActorValue("Speechcraft", 100) in OnEffectFinish. Remember that the 100 value here is taken from the stored current player's speech value (in the storage variable i explained previously). So choose which one you prefer.

 

You also asked about the usage of SetNthEffectMagnitude. As you can see, this function will not persist across game reloads, so once you exit the game while the effect is still running, you need to make additional calculation when you load the game later to make sure that the magnitude number is still applied on game load. For me, this option is not efficient because you need to do double scripted calculation for the same result, and besides you also need to consider the remaining duration of the effect (ie. must apply the magnitude along the remaining duration only). I suggest for you to use the previous methods instead.

Edited by qwertypol012
Link to comment
Share on other sites

I'm going to try to help you, based on my experience.

 

Thanks so much for such an extensive answer!

 

If the magic effect you want to apply is applied via a spell/enchantment/potion/whatever which only has a single magic effect (just that speficic magic effect and nothing else), you can try to use a perk with "Mod Spell Magnitude" as the Perk Entry Point and either "Multiply Value", "Add Actor Value Mult", "Multiply Actor Value Mult", "Multiply 1 + Actor Value Mult", or any other option which suits your need as the function (as reference, read https://www.creationkit.com/index.php?title=Perk_Entry_Point and https://en.uesp.net/wiki/Tes5Mod:Mod_File_Format/PERK). You can set several Perk Entry Points for each factor you want to include in your overall Speech bonus. The end result will be the whole multiplier from each Perk Entry Points. Then set the actor value of the magic effect by "speechcraft" and set the magnitude by 1 (in your spell/enchantment/etc).

The perk should be added to the player character early (before this magic effect is applied) just to be safe. What you need to be aware from this method is that some Entry Points may overlap and some of them may not work (learn about perk "priorities"), so you need to test it in the game and check the calculation yourself (ie. use console command, write "player.getav speech" or something like that, then note the result, then compare with your own calculation, see if they are matching or not).

 

Definitely going to read up on this more, though at first glance I think it sadly might not be suitable, as part of my calculation is based on a faction rank (sorry, should have specified that) which doesn't look like an option, and it's probably going to be easier to just pull a value out of a script.

 

 

Another method is by adding the magic effect multiple times into the spell/enchantment/etc with each instance has its own condition. For example, the first instance may have condition "GetLevel (PlayerRef) >= 10", the second instance may have condition "GetQuestCompleted (whatever quest) == 1", etc. This only works if all of the factors you want to include can be covered by the existing condition functions (https://www.creationkit.com/index.php?title=Category:Condition_Functions). You can also try to combine both this method and the previous method, but you need to put each of them into a different spell/enchantment/etc (resulting in multiple spells/enchantments/etc), because as far as i know "Mod Spell Magnitude" only works for spells/enchantments/etc which has a single magic effect as its effect.

 

Another method is by doing the calculation in via papyrus script. As you have mentioned about it, i assume you already know how to use papyrus functions, so the issue is how to apply them temporarily (not permanent). This is quite simple. Just add a line in the script which stores the player's current Speechcraft value (ie. PlayerRef.GetActorValue("Speechcraft"), store it into a variable) inside OnEffectStart event. This stored current Speechcraft value will be recovered to the player when the effect ends (ie. OnEffectFinish event runs) by reapplying the value from the variable.

 

Yeah I was initially thinking I might do a combination of the two; since the effect is only ever applied to the player I should be able to get away with just using a Conditional variable in my script for use with the get vm quest variable condition in the spell's effect conditions. The downside is I'm probably going to need to have quite a lot of effect entries in the spell to do it this way to get a decent range of values (e.g- increments of 5 or whatever), which is why I was interested in dynamic options.

 

 

But if you want to use "ForceActorValue", you can simply take the value of 125 directly, so it'll be PlayerRef.ForceActorValue("Speechcraft", 125) in OnEffectStart and then PlayerRef.ForceActorValue("Speechcraft", 100) in OnEffectFinish. Remember that the 100 value here is taken from the stored current player's speech value (in the storage variable i explained previously). So choose which one you prefer.

 

The thing that put me off using force actor value is that you can't predict what else might affect the value; for example, if my Speech was 60, and I apply a bonus of ten (Speech 70) but while the effect is applied I pass a persuasion check (Speech 71) then my Speech would still go back down to 60. I think you'd need to track both the original value and the upgraded value so you can compare that against the current before shifting down, which feels like it's asking for mistakes.

 

Also what puts me off mod value and force actor value is player's changing their load order, adding mods etc., this is I think what caused problems for me with Invested Magic as the scripts modding my Magicka (and returning it to me again) were probably being interrupted somehow, or firing in an odd order, so even if the values involved were correct they were only being partially applied. Might not be an issue for me as I'm only doing one spell, but it seems like it could be dicey.

 

 

You also asked about the usage of SetNthEffectMagnitude. As you can see, this function will not persist across game reloads, so once you exit the game while the effect is still running, you need to make additional calculation when you load the game later to make sure that the magnitude number is still applied on game load. For me, this option is not efficient because you need to do double scripted calculation for the same result, and besides you also need to consider the remaining duration of the effect (ie. must apply the magnitude along the remaining duration only). I suggest for you to use the previous methods instead.

 

Actually I hadn't noticed the persistence issue for SetNthEffectMagnitude, thanks for pointing that out! I wonder though if persistence is actually a problem? If the magnitude only matters when the spell is cast (in determining the magnitude of effect to apply) then maybe persistence wouldn't be an issue? In my case I would always be setting a new magnitude before each time the spell is cast, and the bonus will only be applied to the player, replacing any existing bonus, so maybe there wouldn't be any conflict there? Not sure how to go about testing that… though actually maybe it wouldn't matter? I only really need to apply the bonus when the player enters dialogue, which you can't save during anyway. Could still be an option?

 

 

Anyway, thanks again for such a detailed answer, given me a lot to think about on the various options!

Edited by Haravikk
Link to comment
Share on other sites

 

The thing that put me off using force actor value is that you can't predict what else might affect the value; for example, if my Speech was 60, and I apply a bonus of ten (Speech 70) but while the effect is applied I pass a persuasion check (Speech 71) then my Speech would still go back down to 60. I think you'd need to track both the original value and the upgraded value so you can compare that against the current before shifting down, which feels like it's asking for mistakes.

 

Also what puts me off mod value and force actor value is player's changing their load order, adding mods etc., this is I think what caused problems for me with Invested Magic as the scripts modding my Magicka (and returning it to me again) were probably being interrupted somehow, or firing in an odd order, so even if the values involved were correct they were only being partially applied. Might not be an issue for me as I'm only doing one spell, but it seems like it could be dicey.

 

Honestly, if i were you, i would have used ModActorValue already, because it can surely get the job done. By "job", i mean the calculation based on the factors you want. It's true that it cannot modify the actor value at run time (every single second), so this is the limitation. But what you need to know is that, you're making a "gameplay" feature here; and the thing about gameplay is that, if you can't get a thing work, there will always other different ways as alternatives to get the same or similar result. To reach the same or similar goal by using different methods or approaches, even if the end result is not exactly the same with what we wanted in the first time, as long as we get the same experience with the one we originally wanted.

 

Also, what you need to ask to yourself is, whether using complicated scripted lines is really worth it just to make a single variable work (in this case, it's the "change in Speech skill after the effect is applied") along with the increased script load? Is it really worth it? While at the same time, if you disregard it, you can make the overall idea of the feature works well with minimum script load. You need to consider cost and benefit as well. This is also something you need to think when you're making a "gameplay" feature.

 

Just 2 cents from me though, but you can consider it as an advice if you want

Edited by qwertypol012
Link to comment
Share on other sites

  • Recently Browsing   0 members

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