revenant0713 Posted May 7, 2020 Share Posted May 7, 2020 So here's the scenario: I have a constant effect ability, which mods actor values (in this case, health). I want the magnitude to scale with the current amount of dragon souls the player has. Now I know how to do that via perk entry point, but there's a small problem. As a limit of CK, magnitudes are calculated when the ability is placed on the player. Modding via perks will not change the magnitude of the instance of the ability already in effect. The only way to apply the new values as dictated by the perk, is to dynamically remove and re-add the ability whenever the amount of dragon souls the player has changes. I have several options but I'm going nowhere quickly. I'm really not that good at Papyrus and I feel way out of my depth... but I really want to learn. Option 1: Running ScriptsMy first idea was to use a running script, periodically registering for updates and performing the RemoveSpell and AddSpell functions whenever the amount of Dragon Souls changed between updates. But... this seems to have a heavy performance cost for such a simple goal. Plus, uninstalling is a b**** when you have a running script in the background. I got this to work but I don't want to settle for this. Option 2: OnControlDown eventI figured I could run "If PlayerRef.GetAV("DragonSouls") != DragonSoulVariable" whenever the player pressed W, or Esc or Tab. If true, then set DragonSoulVariable to the new value of DragonSouls. But then this means the script will check for a change every time the aforementioned keys are pressed even when we know it is not necessary because no souls have been added or subtracted. I also got this to work, but it feels clunky.</spoiler> Option 3: ModEventsI'm hoping this is the way to do it; create a custom event that sends whenever PlayerRef.GetAV("DragonSouls") != DragonSoulVariable but I haven't been able to make it work. I've asked for help from reddit, but my inexperience with coding makes it difficult to understand some things. Option 4: Use a custom functionAccording to the guys at Reddit I don't need the ModEvent, if I can just use custom functions around a bool where PlayerRef.GetAV("DragonSouls") != DragonSoulVariable. But just the same, I've never really done that before and I don't know how to start. Can anyone help? I've been going nowhere for a few days now. Link to comment Share on other sites More sharing options...
dylbill Posted May 7, 2020 Share Posted May 7, 2020 Hello, there are two ways I would do this. The first is to just use a spell ability and not a perk. Put the magic effect a bunch of times on the spell, with the magnitude of each instance how much you want health to increase per dragon soul. Put the condition GetPCMiscStat Dragon Souls Collected > X on each magic effect instance, and have X increase one number per magic effect. So, you could put the magic effect 100 times on the spell, with a magnitude of 1 for each effect, and the condition GetPCMiscStat Dragon Souls Collected > 0, GetPCMiscStat Dragon Souls Collected > 1, GetPCMiscStat Dragon Souls Collected > 2 ect. That would increase the players health 1 per dragon soul collected, up to 100. This is limiting though because you'll only get increased health for however many magic effect instances you put on the spell. Another method is to use the Spell Ability to detect when the player absorbs a new dragon soul, and use ModAv on the magic effects script. This way, you don't have to use polling, or other script intensive methods. Make a new global variable, name it say DetectDragonSoulsGV, and Put the condition GetPCMiscStat Dragon Souls Collected != DetectDragonSoulsGV. (Check the use global box and choose the DetectDragonSoulsGV) Then put this script on the spell ability's magic effect and give it to the player: Scriptname MyModDetectDragonSoulIncrease extends ActiveMagicEffect Actor Property PlayerRef Auto GlobalVariable Property DetectDragonSoulsGV Auto Event OnEffectStart(Actor akTarget, Actor akCaster) ;effect starts after player aborbs a dragon soul PlayerRef.ModAv("Health", 1) Utility.Wait(1) DetectDragonSoulsGV.SetValue(Game.QueryStat("Dragon Souls Collected")) ;this nullifies the effect, so it can start again after abosrbing another dragon soul. EndEventUsing this method, you'd also need to do an initial script to mod health based on QueryStat("Dragon Souls Collected") Link to comment Share on other sites More sharing options...
revenant0713 Posted May 7, 2020 Author Share Posted May 7, 2020 (edited) Deleted. Accidentally quoted twice. Edited May 7, 2020 by revenant0713 Link to comment Share on other sites More sharing options...
revenant0713 Posted May 7, 2020 Author Share Posted May 7, 2020 (edited) Hello, there are two ways I would do this. The first is to just use a spell ability and not a perk. Put the magic effect a bunch of times on the spell, with the magnitude of each instance how much you want health to increase per dragon soul. Put the condition GetPCMiscStat Dragon Souls Collected > X on each magic effect instance, and have X increase one number per magic effect. So, you could put the magic effect 100 times on the spell, with a magnitude of 1 for each effect, and the condition GetPCMiscStat Dragon Souls Collected > 0, GetPCMiscStat Dragon Souls Collected > 1, GetPCMiscStat Dragon Souls Collected > 2 ect. That would increase the players health 1 per dragon soul collected, up to 100. This is limiting though because you'll only get increased health for however many magic effect instances you put on the spell. Another method is to use the Spell Ability to detect when the player absorbs a new dragon soul, and use ModAv on the magic effects script. This way, you don't have to use polling, or other script intensive methods. Make a new global variable, name it say DetectDragonSoulsGV, and Put the condition GetPCMiscStat Dragon Souls Collected != DetectDragonSoulsGV. (Check the use global box and choose the DetectDragonSoulsGV) Then put this script on the spell ability's magic effect and give it to the player: Scriptname MyModDetectDragonSoulIncrease extends ActiveMagicEffect Actor Property PlayerRef Auto GlobalVariable Property DetectDragonSoulsGV Auto Event OnEffectStart(Actor akTarget, Actor akCaster) ;effect starts after player aborbs a dragon soul PlayerRef.ModAv("Health", 1) Utility.Wait(1) DetectDragonSoulsGV.SetValue(Game.QueryStat("Dragon Souls Collected")) ;this nullifies the effect, so it can start again after abosrbing another dragon soul. EndEventUsing this method, you'd also need to do an initial script to mod health based on QueryStat("Dragon Souls Collected") That second method... I never thought of that. I'mma try it out. Though I'd prefer I think to use PlayerRef.GetActorValue(DragonSouls) rather than QueryStat because Dragon Souls Collected reportedly doesn't go down when you lose dragon souls. Thanks. Edited May 7, 2020 by revenant0713 Link to comment Share on other sites More sharing options...
Recommended Posts