[Papyrus] Trouble with a custom function and actor values.

Post » Mon Jun 18, 2012 11:51 pm

I've written a script that modifies attack speed based on how much health the player has left. I am having two issues with it. Here is the script:
Spoiler

Scriptname HealthTrigger extends Quest{for each 10% change in life, increases/decreases attack speed}import Mathfloat Property IAS = 1.0 Autofloat Property PercentHealth = 100.0 Auto  int counter = 0int counterTwo = 0float x = 0.0 ; percent change in attack speedEvent OnInIt()registerForUpdate(1)Debug.Notification("IAS script active")Game.GetPlayer().forceAV("WeaponSpeedMult", 1.0) ; 0.0 by defaultGame.GetPlayer().forceAV("LeftWeaponSpeedMult", 1.0)endEventEvent OnUpdate()PercentHealth = Game.GetPlayer().GetAVPercentage("Health")counterTwo = 10 - Ceiling(PercentHealth * 10)x = ((counterTwo - counter) / 10.0 )If counter != counterTwoGame.GetPlayer().alterAV("WeaponSpeedMult", x )Game.GetPlayer().alterAV("LeftWeaponSpeedMult", x )Debug.Notification("Threshold passed. IAS: " + IAS)counter = counterTwoendIfendEventFunction alterAV(string asValueName, float afAmount)If afAmount > 0Game.GetPlayer().restoreAV(asValueName, afAmount)ElseGame.GetPlayer().damageAV(asValueName, afAmount)endIfendFunction

First issue: I originally didn't have the function alterAV() and it worked fine, but looked a little clumsy. I wanted to clean it up a bit, but now it doesn't compile. I'm getting a "function does not exist error" on alterAV() referencing the line where I try to call it.

UPDATE: This issue has been resolved. Here is the updated script:
Spoiler

Scriptname HealthTrigger extends Quest{for each 10% change in life, increases/decreases attack speed}import Mathfloat Property IAS = 1.0 Autofloat Property PercentHealth = 100.0 Auto  int counter = 0int counterTwo = 0float x = 0.0 ; percent change in attack speedEvent OnInIt()registerForUpdate(1)Debug.Notification("IAS script active")Game.GetPlayer().forceAV("WeaponSpeedMult", 1.0) ; 0.0 by defaultGame.GetPlayer().forceAV("LeftWeaponSpeedMult", 1.0)endEventEvent OnUpdate()PercentHealth = Game.GetPlayer().GetAVPercentage("Health")counterTwo = 10 - Ceiling(PercentHealth * 10)x = ((counterTwo - counter) / 10.0 )If counter != counterTwoalterAV(Game.GetPlayer(), "WeaponSpeedMult", x )alterAV(Game.GetPlayer(), "LeftWeaponSpeedMult", x )IAS = Game.GetPlayer().GetAV("WeaponSpeedMult")Debug.Notification("Threshold passed. IAS: " + IAS)counter = counterTwoendIfendEventFunction alterAV(actor playerHere, string asValueName, float afAmount) globalIf afAmount > 0playerHere.modAV(asValueName, afAmount)ElseplayerHere.damageAV(asValueName, afAmount)endIfendFunction

I also changed restoreAV() -> modAV() as restore wasn't working.

Second issue: The actor value WeaponSpeedMult starts at 0.0. In my script i forced it to 1.0 because otherwise as soon as the player loses 10% hp WeaponSpeedMult goes to 0.1. The player is now attacking at 0.1 instead of 1.1 speed. However, this seems to conflict with the Dual Flurry perk. I changed the magnitude of the perk effect from 1.2 -> 0.2 and 1.35 -> 0.35, but I'm still seeing it jump an extra 100% (so at 85% health with 2 1h equipped and DualFlurry30, I'm getting 2.3 attack speed instead of 1.3).

Anyone care to lend a hand? :biggrin:
User avatar
Jeff Tingler
 
Posts: 3609
Joined: Sat Oct 13, 2007 7:55 pm

Post » Mon Jun 18, 2012 6:04 pm

That function only exists on objects of type HealthTrigger (i.e. the type created by your script), but the return value of Game.GetPlayer() is Actor, for which the function doesn't exist. You'll want to add a parameter in which you can pass an Actor, and pass the player in there. It should also be a global function, as the "Self" variable will be inappropriate in this case, but that's really just going to be a semantic issue.

Cipscis

EDIT:

You might get something out of reading this - http://www.cipscis.com/skyrim/tutorials/externalaccess.aspx

Cipscis
User avatar
des lynam
 
Posts: 3444
Joined: Thu Jul 19, 2007 4:07 pm

Post » Mon Jun 18, 2012 10:01 pm

That function only exists on objects of type HealthTrigger (i.e. the type created by your script), but the return value of Game.GetPlayer() is Actor, for which the function doesn't exist. You'll want to add a parameter in which you can pass an Actor, and pass the player in there. It should also be a global function, as the "Self" variable will be inappropriate in this case, but that's really just going to be a semantic issue.

Cipscis

EDIT:

You might get something out of reading this - http://www.cipscis.com/skyrim/tutorials/externalaccess.aspx

Cipscis

Thank you! That did the trick. Would it be safe to add alterAV() to the Actor script as a global function? I don't like how modAV()/damageAV/ ect... don't recognize negative values.
User avatar
Beth Belcher
 
Posts: 3393
Joined: Tue Jun 13, 2006 1:39 pm

Post » Tue Jun 19, 2012 7:03 am

It would be better to include it in your own library as a global function. The problem with making changes to existing scripts is that your mod will become incompatible with any other mod that changes those scripts.

Cipscis
User avatar
Victor Oropeza
 
Posts: 3362
Joined: Sun Aug 12, 2007 4:23 pm


Return to V - Skyrim