Jump to content

Damage health by percentage, or set to value


hiddenSeven

Recommended Posts

Hey, I've searched forums and the Creation Kit wiki and have come up blank on a good way to do this, so thought I'd put it out there.

 

I'm trying to create a debuff effect that reduces the player's health considerably, regardless of how much health they actually have. Basically, I'm trying to replicate something like the werewolf bloodlust effect from Daggerfall or Morrowind, where the player's health would be reduced TO a low number, rather than reduced BY a number. I want a health debuff that remains meaningful at all levels, but can never kill the player. The problem with the damage health spell effects in the game is that they reduce health by an absolute number. So I'm stuck with either a maximum of 99, lest it potentially kill a character that hasn't put points into health, but that nevertheless can feel very insignificant for a high level warrior character that has been pumping health.

 

The two ways I can think of doing this is either reduce health by a percentage of total health, that way the impact is always felt regardless of character, but high health characters still have more health than low health ones, or by simply setting health to a number, which isn't as ideal, but I think more workable. The goal is also to try to keep this as script light as possible, so as to not overburden the scripting system too much. Ideally I'd like this to be as close to as basic as a standard magic effect as possible.

 

I have some idea of how to do both these methods (though the percentage method is more script intensive) but both rely on either the SetActorValue or the ForceActorValue commands. I'm worried about this having potentially negative permanent effects. If anyone can advise me on this, or suggest alternate better methods, I'd appreciate it.

 

So far I'm thinking a script attached to a spell that on being added to the player gets their base Max health, stores it, then forces it to a lower number. On the spell being removed it would set it back to the stored number.

 

The one concern I have with this is it seems very easy for this to potentially break and result in permanently damaged health if not uninstalled correctly, and that there doesn't seem to be an event for the removal of spells/magic effects the same way there is for objects, which could lead to complications like more global variables and checking for things on global updates, which I want to avoid.

 

Any suggestions on how to achieve this effect?

Link to comment
Share on other sites

I had a similar problem modifying fists of steel to give more unarmed damage. I wanted to use Mod instead of Set so that other things are taken into effect. All I did was create an AppliedBonus integer variable in the script (outside a method) that stored whatever difference had been applied. That means that even if you screw it up, the next application or unapplication of the spell will fix it. Just make sure you take it into account:

 

int playerMaxHealth = player.GetAV("MaxHealth") - AppliedHealthMod

 

So if you've modded in -50 to the player, it will see that they have 150 max health currently but their real max health should be 200. Then use this variable instead of their current max health in all your calculations.

 

This is safe as long as the script isn't run a bunch of times at once. To be completely safe you can throw in a lock (http://www.creationkit.com/Threading_Notes_(Papyrus)#Locks). Note: I use WaitMenuMode instead of Wait, if there's a backup of threads waiting to run it'll keep calculating them even if, say, the inventory screen is open. You shouldn't have the same problems since it should be a short calculation, but it protects you in the rare case of two enemies giving you the debuff at nearly the same instant.

Link to comment
Share on other sites

The way I plan to use it there shouldn't be too much danger of it being applied multiple times quickly, since it's a constant debuff based on a hunger level (basically you need to feed as a werewolf or else you get hit with this debuff).

 

So I'm running a background script that checks this hungerlevel variable, and adds or removes the correct spell as necessary. As such there should only ever be one instance of this effect on the player at the same time.

 

Let me ask you this, though. Do you reckon it would be safer/better to do something like use your method and have something like

AppliedHealthMod = (player.GetAV("MaxHealth") / 2)

 

So that the effect reduces the health by half each time, rather than using a system that sets the health? All I'm really trying to accomplish is a damage health that scales to max health in some way, such that it can never kill the player, but is always quite large.

 

Also, I'm a little confused about what event I can call for when the magic effect is removed. Objects have OnEquipped and OnUnequipped, but I'm a little unclear on what the comparable is for spells. Is this what OnEffectStart and OnEffectFinish are used for? Sorry if this is really obvious, but I'm pretty new to payprus, and the CK wiki isn't always the most helpful. I'm worried about using OnEffectStart, since it says it retriggers when the player's race is changed, and since this is designed to be an effect on werewolf players that persists between both their forms, that could be a problem. Unless changing race also causes OnEffectFinish to trigger, in which case, no problem?

 

Thanks for any help on this one.

Link to comment
Share on other sites

If you store the applied value you don't have to worry about it re-triggering on changerace. And a lock makes everything nice and safe, even if you don't need it. When it's not used it won't affect the efficiency at all.

 

 

Actor Property PlayerRef Auto

bool Locked = false
int AppliedValue = 0

OnEffectStart
  if Locked
    while Locked
      Utility.WaitMenuMode(1.0)
    endWhile
  endIf

  Locked = true

  int iMaxHealth = PlayerRef.GetAV("MaxHealth") + AppliedValue
  int iTargetMaxHealth = iMaxHealth / 2 ;Define whatever function you want here
  int iDelta = iTargetMaxHealth - iMaxHealth - AppliedValue

  PlayerRef.ModAV("MaxHealth", iDelta)
  AppliedValue = iTargetMaxHealth - iMaxHealth

  Locked = false
end

OnEffectFinish
  if Locked
    while Locked
      Utility.WaitMenuMode(1.0)
    endWhile
  endIf

  Locked = true

  PlayerRef.ModAV("MaxHealth", -AppliedValue)
  AppliedValue = 0

  Locked = false
end
Link to comment
Share on other sites

  • Recently Browsing   0 members

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