Ryyz Posted February 17, 2017 Share Posted February 17, 2017 (edited) So, I'm working on a Witcher Sign mod. If you've played the witcher series you know what it is. I'm working on Quen at the moment, which makes the user invulnerable from damage for a period of time or until a certain amount of damage is taken. So I copied the oakflesh spell since that basically does what I want, and I assume choosing on equip ability alduininvulernability makes the user invulnerable. Here's the problem. I don't want it to be invulnerable for the entire spell. The final tier will last about 40 seconds. That is waaaaaay too OP. People will be spamming that like crazy. So I wanna make it where the spell goes away after a certain amount of damage is sustained. I searched around and couldn't find an answer. I could stay with the damage resistance, but I'd like to make it as close to the Witcher as possible. If it's possible with scripting could you go in depth a little bit since I don't know much about papyrus. Also something else I need, that I don't wanna make another topic for is how to make static objects give spells. I'm sure its a script, I know how to add activators to objects just not the script needed to make it give a spell.I'm just asking this here too since both questions go hand-in-hand. They're made with lesser powers if that matters. Edited February 17, 2017 by Ryyz Link to comment Share on other sites More sharing options...
FrankFamily Posted February 17, 2017 Share Posted February 17, 2017 The only spell with "health" is a ward but that health is only affected by spells. Note dragonhide works differently to the other armor spells, it's closer to what you need but still won't go off after certain damage. Here's my idea, untested but should work. Make a magic effect, script archetype, and attach this script. By default the health of the spell is set to 100, you can change it in its properties.Basically what it does is update every 0.2 seconds (also configurable if it's unnecesary fast), check how much health it's missing, heal that and substract it from its own health count, when it runs out it should dispel itself. Scriptname InvincibleSpell extends activemagiceffect Float Property SpellBaseHP = 100.0 Auto String Property ActorValue = "Health" Auto Float Property UpdateSpeed = 0.2 Auto Actor Target Float HealthCurrent Float HealthPercent Float HealthToHeal Float SpellHP Event OnEffectStart(Actor akTarget, Actor akCaster) Target = akTarget SpellHP = SpellBaseHP RegisterForSingleUpdate(UpdateSpeed) EndEvent Event OnUpdate() If (SpellHP > 0.0) HealthPercent = Target.GetAVPercentage(ActorValue) If (HealthPercent < 1.0) HealthCurrent = Target.GetActorValue(ActorValue) HealthToHeal = ((HealthCurrent / HealthPercent) - HealthCurrent) If HealthToHeal > SpellHP HealthToHeal = SpellHP Endif Target.RestoreActorValue(ActorValue, HealthToHeal) SpellHP -= HealthToHeal Endif RegisterForSingleUpdate(UpdateSpeed) Else self.Dispel() Endif EndEventRegarding the activator adding spells to the player, that's really simple. Scriptname SpellGiver extends ObjectReference Spell Property SpellToGive Auto Event OnActivate(ObjectReference akActionRef) If akActionRef == Game.GetPlayer() akActionRef.AddSpell(SpellToGive) Endif EndEvent You just need to attach it to an activator and fill the property, check this tutorial if you don't know how: http://www.creationkit.com/index.php?title=Bethesda_Tutorial_Papyrus_Introduction_to_Properties_and_Functions Link to comment Share on other sites More sharing options...
Masterofnet Posted February 17, 2017 Share Posted February 17, 2017 Frank, Some advice. Do not define something outside an event unless you have to and do not define something unless you have to use it more than once in the same event. Also did you consider using while as opposed to regiseterforsingleupdate? Ryyz, Please include a little more detail on what you are attempting to do. How long does the spell last? How much damage are we talking about? Have you done any of your own research into spells, magic effects and scripts? You said you copied the Oak Flesh spell. Lets have a look at it. Here is a list of script functions and what they call keyword references. https://www.creationkit.com/index.php?title=Category:Script_Objectshttps://www.creationkit.com/index.php?title=While Link to comment Share on other sites More sharing options...
FrankFamily Posted February 17, 2017 Share Posted February 17, 2017 Which definition is unneeded?And regarding the 3 health floats defined in or out of the update event, i honestly doubt it makes any difference, but, if any, it could be worse to put them inside since they would be redefined every time it loops. Anyway its, imo, clearer and easier to understand the script this way, which is the point after all, optimization to certain depth gets pointless. Did not consider a while, I see no reason to do it, registerforsingleupdate is much shorter, clearer and safer for this. Link to comment Share on other sites More sharing options...
Masterofnet Posted February 17, 2017 Share Posted February 17, 2017 Which definition is unneeded?And regarding the 3 health floats defined in or out of the update event, i honestly doubt it makes any difference, but, if any, it could be worse to put them inside since they would be redefined every time it loops. Anyway its, imo, clearer and easier to understand the script this way, which is the point after all, optimization to certain depth gets pointless. Did not consider a while, I see no reason to do it, registerforsingleupdate is much shorter, clearer and safer for this. SpellHP It is just some advice. This should most likely be done by simply fortifying the targets health = to the amount of damage the target can sustain before the spell dispels. If and when Ryyz returns we will look into that. Link to comment Share on other sites More sharing options...
FrankFamily Posted February 17, 2017 Share Posted February 17, 2017 In a way yes, the property itself could be modified as the spell looses life but imo is easier to "see" the property as the configurable base life and then the variable as the current life of the spell, that is initialized on the oneffectstart and then used. Regarding fortify, it would indeed be a very simple to do something similar, its been a while since i last actually played skyrim but when the effect ends doesn't it remove the amount that was fortified? So that a guy with 1000 life, casts this, now has 1500 for example, gets 600 damage, 900 and the effect expires, it now should have 400. What i understood OP wanted and what I aimed to make is a 500 damage shield, as in: Guy with 1000 life, casts it, still 1000, gets 600 damage, first 500 stopped by the shield, the 100 leaves him at 900. Additionally the "If HealthToHeal > SpellHP" block could be removed so even if a single hit exceeds the shield's life it gets blocked completely (the guy above remains at 1000) but, of course, further hits aren't stopped since the spell is dispelled. It could also be achieved with a perk modifying incoming damage to 0, but how to know how much damage was stopped that way i have no idea. Link to comment Share on other sites More sharing options...
Ryyz Posted February 17, 2017 Author Share Posted February 17, 2017 Frank, Some advice. Do not define something outside an event unless you have to and do not define something unless you have to use it more than once in the same event. Also did you consider using while as opposed to regiseterforsingleupdate? Ryyz, Please include a little more detail on what you are attempting to do. How long does the spell last? How much damage are we talking about? Have you done any of your own research into spells, magic effects and scripts? You said you copied the Oak Flesh spell. Lets have a look at it. Here is a list of script functions and what they call keyword references. https://www.creationkit.com/index.php?title=Category:Script_Objecthttps://www.creationkit.com/index.php?title=WhileYesYes I have looked into all things to do with spells. The spell works perfectly in game. I changed the effect and other stuff.Scripts not so much. I've used Java for a long time as well as some Ruby. Papyrus is new to me.Also according to how long the spell lasts, I'm modelling it after a game series, I was thinking of using the shouts as a base, having three different tiers with power increasing after each tier. The way I figure it is that the time doubles. Like first is 10 seconds, second is 20, and third is 40. The amount of damage sustained would be according to the spell tier. I'm trying to remember how damage in Skyrim works... but I'm thinking that it would be like go like 1.5x every tier. So say we start with 150, then 225 then 340. I don't think that's do OP. Also I have done some research into Papyrus and I know some of the functions. Like floats, string, bools. strings and bools were easy since I've used them before. The only thing I really kept from Oak Flesh was the effect shader and editor keywords. I made some other stuff using photoshop and changed some things around. It's more like 99% custom and 1% Oak Flesh. Also sorry for not replying. I was asleep. I didn't go to bed til like 6AM. Was watching youtube. The only spell with "health" is a ward but that health is only affected by spells. Note dragonhide works differently to the other armor spells, it's closer to what you need but still won't go off after certain damage. Here's my idea, untested but should work. Make a magic effect, script archetype, and attach this script. By default the health of the spell is set to 100, you can change it in its properties.Basically what it does is update every 0.2 seconds (also configurable if it's unnecesary fast), check how much health it's missing, heal that and substract it from its own health count, when it runs out it should dispel itself. Scriptname InvincibleSpell extends activemagiceffect Float Property SpellBaseHP = 100.0 Auto String Property ActorValue = "Health" Auto Float Property UpdateSpeed = 0.2 Auto Actor Target Float HealthCurrent Float HealthPercent Float HealthToHeal Float SpellHP Event OnEffectStart(Actor akTarget, Actor akCaster) Target = akTarget SpellHP = SpellBaseHP RegisterForSingleUpdate(UpdateSpeed) EndEvent Event OnUpdate() If (SpellHP > 0.0) HealthPercent = Target.GetAVPercentage(ActorValue) If (HealthPercent < 1.0) HealthCurrent = Target.GetActorValue(ActorValue) HealthToHeal = ((HealthCurrent / HealthPercent) - HealthCurrent) If HealthToHeal > SpellHP HealthToHeal = SpellHP Endif Target.RestoreActorValue(ActorValue, HealthToHeal) SpellHP -= HealthToHeal Endif RegisterForSingleUpdate(UpdateSpeed) Else self.Dispel() Endif EndEventRegarding the activator adding spells to the player, that's really simple. Scriptname SpellGiver extends ObjectReference Spell Property SpellToGive Auto Event OnActivate(ObjectReference akActionRef) If akActionRef == Game.GetPlayer() akActionRef.AddSpell(SpellToGive) Endif EndEvent You just need to attach it to an activator and fill the property, check this tutorial if you don't know how: http://www.creationkit.com/index.php?title=Bethesda_Tutorial_Papyrus_Introduction_to_Properties_and_FunctionsThanks for that last script. As I said I know a lot about activators. As for the first one. I'll give it a try. As for your later past that is exactly how it works. Again sorry for the late reply. Link to comment Share on other sites More sharing options...
Masterofnet Posted February 17, 2017 Share Posted February 17, 2017 (edited) Good luck - don't give up. Edited February 17, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Ryyz Posted February 17, 2017 Author Share Posted February 17, 2017 Good luck - don't give up. So I tried and it works great. However, what about your idea? I'd like to try both and see what I like better. It also helps me out with scripting. When I see a full script whether it be java, ruby or anything I can determine what does what and use it in the future. Link to comment Share on other sites More sharing options...
Masterofnet Posted February 17, 2017 Share Posted February 17, 2017 On effect start Target.ModActorValue("health", 100) ; or what ever your damage% would be. On effect finish Target.RestoreActorValue("health", 100) ; or what ever your damage% would be. Target.ModActorValue("health", - 100) ; or what ever your damage% would be. Link to comment Share on other sites More sharing options...
Recommended Posts